Index: trunk/src/kernel/qpixmap_pm.cpp
===================================================================
--- trunk/src/kernel/qpixmap_pm.cpp	(revision 55)
+++ trunk/src/kernel/qpixmap_pm.cpp	(revision 56)
@@ -186,4 +186,6 @@
 {
     if ( data && data->deref() ) {		// last reference lost
+        if ( hps )
+            GpiSetBitmap( hps, 0 );
 	if ( data->mask ) {
 	    delete data->mask;
@@ -194,6 +196,4 @@
         }
 	if ( data->hbm ) {
-            if ( hps )
-                GpiSetBitmap( hps, 0 );
             GpiDeleteBitmap( data->hbm );
             data->hbm = 0;
@@ -1129,6 +1129,7 @@
 
 // Prepares for painting the masked pixmap: precomposes and selects the
-// masked pixmap into this pixmap's hps. If prepare = FALSE, it does the
-// cleanup. Currently used from ::bitBlt().
+// masked pixmap (with transparent pixels made black) into this pixmap's hps.
+// If prepare = FALSE, it does the cleanup. Currently used in ::bitBlt()
+// and in QPixmap::createIcon().
 void QPixmap::prepareForMasking( bool prepare )
 {
@@ -1185,4 +1186,71 @@
 }
 
+HPOINTER QPixmap::createIcon( bool pointer, int hotX, int hotY, bool mini )
+{
+    HPOINTER icon = NULLHANDLE;
+
+    if ( !isNull() ) {
+        int w = WinQuerySysValue( HWND_DESKTOP, pointer ? SV_CXPOINTER : SV_CXICON );
+        int h = WinQuerySysValue( HWND_DESKTOP, pointer ? SV_CYPOINTER : SV_CYICON );
+        if ( mini ) {
+            w /= 2;
+            h /= 2;
+        }
+        
+        QPixmap pm = *this;
+        if ( data->w != w || data->h != h ) {
+#if !defined(QT_NO_IMAGE_SMOOTHSCALE)
+            // do smooth resize until icon is two or more times bigger
+            // than the pixmap
+            if ( data->w * 2 > w || data->h * 2 > h ) {
+                QImage i = convertToImage();
+                pm = QPixmap( i.smoothScale( w, h ) );
+            } else
+#endif
+            {
+                pm = QPixmap( w, h );
+                POINTL ptls[] = {
+                    { 0, 0 }, { w, h },
+                    { 0, 0 }, { data->w, data->h },
+                };
+                GpiBitBlt( pm.hps, hps, 4, ptls, ROP_SRCCOPY, BBO_IGNORE );
+            }
+        }
+        
+        QBitmap msk( w, h * 2, TRUE );
+        if ( pm.data->mask ) {
+            // create AND mask (XOR mask is left zeroed -- it's ok)  
+            POINTL ptls[] = {
+                { 0, h }, { w, h * 2 },
+                { 0, 0 }, { w, h },
+            };
+            GpiBitBlt( msk.hps, pm.data->mask->hps, 4, ptls, ROP_NOTSRCCOPY, BBO_IGNORE );
+            pm.prepareForMasking( TRUE );
+        }
+        
+        // unselect bitmap handles from hps
+        GpiSetBitmap( pm.hps, 0 );        
+        GpiSetBitmap( msk.hps, 0 );
+        
+        POINTERINFO info;
+        info.fPointer = pointer;
+        info.xHotspot = hotX;
+        info.yHotspot = hotY;
+        info.hbmPointer = msk.data->hbm;
+        info.hbmColor = pm.data->mask ? pm.data->maskedHbm : pm.data->hbm;
+        info.hbmMiniPointer = 0;
+        info.hbmMiniColor = 0;
+        icon = WinCreatePointerIndirect( HWND_DESKTOP, &info );
+
+        if ( pm.mask() )
+            pm.prepareForMasking( FALSE );
+        
+        GpiSetBitmap( msk.hps, msk.data->hbm );        
+        GpiSetBitmap( pm.hps, pm.data->hbm );        
+    }
+    
+    return icon;
+}
+
 void QPixmap::attachHandle( HBITMAP hbm )
 {
@@ -1225,4 +1293,46 @@
 
     return hbm;
+}
+
+/*!
+    \internal
+
+    Creates an OS/2 icon or pointer from two given pixmaps.
+    
+    \param pointer true to create a pointer, false to create an icon
+    \param hotX X coordinate of the action point within the pointer/icon
+    \param hotY Y coordinate of the action point within the pointer/icon
+    \param normal pixmap for a normal-sized pointer/icon
+    \param mini pixmap for a mini-sized pointer/icon
+    
+    \note Due to a bug in WinCreatePointerIndirect, you can specify either
+    \a normal pixmap or \a mini pixmap, but not both (if both are specified,
+    \a normal will be used). This may be fixed later. 
+*/
+// static
+HPOINTER QPixmap::createIcon( bool pointer, int hotX, int hotY,
+                              const QPixmap *normal, const QPixmap *mini )
+{
+    // Due to a bug in WinCreatePointerIndirect (it always ignores
+    // hbmMiniPointer and hbmMiniColor fields), we can specify either a normal
+    // icon (and get a mini icon autocreated by PM) or a mini icon (with a
+    // normal icon autocreated by PM), but not both. This methods still accepts
+    // pixmaps for both icon sizes (assuming that we will find a workaround one
+    // day) but uses only one of them.
+    
+    if ( normal && !normal->isNull() ) {
+#ifdef QT_CHECK_RANGE
+        if ( mini && !mini->isNull() )
+            qWarning( "QPixmap::createIcon(): due to a bug in WinCreatePointerIndirect "
+                      "either a normal or a mini pixmap should be specified, "
+                      "but not both. Will use a normal pixmap." );
+#endif    
+        return const_cast <QPixmap *> (normal)->createIcon( pointer, hotX, hotY, false );
+    }
+    
+    if ( mini && !mini->isNull() )
+        return const_cast <QPixmap *> (mini)->createIcon( pointer, hotX, hotY, true );
+    
+    return 0;
 }
 
