Index: /trunk/src/gui/image/qpixmap.h
===================================================================
--- /trunk/src/gui/image/qpixmap.h	(revision 259)
+++ /trunk/src/gui/image/qpixmap.h	(revision 260)
@@ -60,4 +60,5 @@
 class QVariant;
 class QX11Info;
+class QIcon;
 
 class QPixmapData;
@@ -146,4 +147,10 @@
     HBITMAP toWinHBITMAP(HBitmapFormat format = NoAlpha) const;
     static QPixmap fromWinHBITMAP(HBITMAP hbitmap, HBitmapFormat format = NoAlpha);
+#endif
+
+#if defined(Q_WS_PM)
+    HBITMAP toPmHBITMAP(HBITMAP *mask = 0) const;
+    static HPOINTER toPmHPOINTER(const QIcon &icon, bool isPointer = false,
+                                 int hotX = 0, int hotY = 0);
 #endif
 
Index: /trunk/src/gui/image/qpixmap_pm.cpp
===================================================================
--- /trunk/src/gui/image/qpixmap_pm.cpp	(revision 259)
+++ /trunk/src/gui/image/qpixmap_pm.cpp	(revision 260)
@@ -45,5 +45,205 @@
 #include "qpixmap_raster_p.h"
 
+#include "qicon.h"
+
+#include "qt_os2.h"
+
 QT_BEGIN_NAMESPACE
+
+HPS qt_alloc_mem_ps(int w, int h, HPS compat = 0)
+{
+    HDC hdcCompat = NULLHANDLE;
+    if (compat)
+        hdcCompat = GpiQueryDevice(compat);
+
+    static const PSZ hdcData[4] = { "Display", NULL, NULL, NULL };
+    HDC hdc = DevOpenDC(0, OD_MEMORY, "*", 4, (PDEVOPENDATA) hdcData, hdcCompat);
+    if (!hdc) {
+        qWarning( "alloc_mem_dc: DevOpenDC failed with %08lX!", WinGetLastError(0));
+        return NULLHANDLE;
+    }
+    SIZEL size = { w, h };
+    HPS hps = GpiCreatePS(0, hdc, &size, PU_PELS | GPIA_ASSOC | GPIT_MICRO);
+    if (hps == NULLHANDLE) {
+        qWarning("alloc_mem_dc: GpiCreatePS failed wit %08lX!", WinGetLastError(0));
+        return NULLHANDLE;
+    }
+    // @todo later
+//  if (QColor::hPal()) {
+//      GpiSelectPalette(hps, QColor::hPal());
+//  } else {
+        // direct RGB mode
+        GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL);
+//  }
+    return hps;
+}
+
+void qt_free_mem_ps(HPS hps)
+{
+    HDC hdc = GpiQueryDevice(hps);
+    GpiAssociate(hps, NULLHANDLE);
+    GpiDestroyPS(hps);
+    DevCloseDC(hdc);
+}
+
+/*!
+    Creates a \c HBITMAP equivalent to the QPixmap. Returns the \c HBITMAP
+    handle.
+
+    If \a mask is not NULL, the mask mode is turned. In this mode, the bitmap
+    mask is also created from the QPixmap's mask and returned in the given
+    variable. This bitmap mask will contain two vertically adjacent sections,
+    the first of which is the AND mask and the second one is the XOR mask
+    (according to WinCreatePointer() specification). Also, in mask mode, the
+    HBITMAP returned for the pixmap itself will be prepared for masking (with
+    transparent pixels made black). This mode is useful for creating system
+    icons and pointers (\sa toPmHPOINTER()).
+
+    Note that if the pixmap does neither have a maks nor the alpha channel but
+    \a mask is not NULL, a NULLHANDLE value will be stored there.
+
+    It is the caller's responsibility to free both returned \c HBITMAP handes
+    after use.
+
+    \warning This function is only available on OS/2.
+*/
+HBITMAP QPixmap::toPmHBITMAP(HBITMAP *mask) const
+{
+    if (data->classId() != QPixmapData::RasterClass) {
+        QPixmapData *data = new QRasterPixmapData(depth() == 1 ?
+                                                  QPixmapData::BitmapType : QPixmapData::PixmapType);
+        data->fromImage(toImage(), Qt::AutoColor);
+        return QPixmap(data).toPmHBITMAP(mask);
+    }
+
+    QRasterPixmapData* d = static_cast<QRasterPixmapData*>(data);
+    int w = d->image.width();
+    int h = d->image.height();
+
+    HPS hps = qt_alloc_mem_ps(w, h);
+    if (hps == NULLHANDLE)
+        return NULLHANDLE;
+
+    HBITMAP hbm = NULLHANDLE;
+    HBITMAP hbmMask = NULLHANDLE;
+
+    QImage image = d->image.convertToFormat(QImage::Format_ARGB32).mirrored();
+
+    // bitmap header + 2 palette entries (for the mask)
+    char bmi[sizeof(BITMAPINFOHEADER2) + 4 * 2];
+    memset(bmi, 0, sizeof(bmi));
+    BITMAPINFOHEADER2 &bmh = *(PBITMAPINFOHEADER2)bmi;
+    bmh.cbFix = sizeof(BITMAPINFOHEADER2);
+    PULONG pal = (PULONG)(bmi + sizeof(BITMAPINFOHEADER2));
+
+    // create the normal bitmap from the pixmap data
+    bmh.cx = w;
+    bmh.cy = h;
+    bmh.cPlanes = 1;
+    bmh.cBitCount = 32;
+    hbm = GpiCreateBitmap(hps, &bmh, CBM_INIT, (PBYTE)(const uchar *)image.bits(),
+                          (PBITMAPINFO2)&bmi);
+
+    if (mask && hasAlpha()) {
+        // get the mask. We prefer QImage::createAlphaMask() over QPixmap::mask()
+        // since the former will dither while the latter will convert any
+        // non-zero alpha value to an opaque pixel
+        QImage mask = image.createAlphaMask().mirrored();
+
+        // create the mask bitmap (AND and XOR stripes)
+        bmh.cbFix = sizeof(BITMAPINFOHEADER2);
+        bmh.cx = w;
+        bmh.cy = h;
+        bmh.cPlanes = 1;
+        bmh.cBitCount = 1;
+        bmh.cclrUsed = 2;
+        pal[0] = 0;
+        pal[1] = 0x00FFFFFF;
+        hbmMask = GpiCreateBitmap(hps, &bmh, 0, NULL, NULL);
+
+        // create AND mask (XOR mask is left zeroed -- it's okay)
+        GpiSetBitmap(hps, hbmMask);
+
+        POINTL ptls[] = {
+            { 0, h }, { w - 1, h * 2 - 1 }, // dst: inclusive-inclusive
+            { 0, 0 }, { w, h }, // src: inclusive-exclusive
+        };
+        GpiDrawBits(hps, (PBYTE)(const uchar *)mask.bits(), (PBITMAPINFO2)&bmi,
+                    4, ptls, ROP_NOTSRCCOPY, BBO_IGNORE);
+
+        // prepare the bitmap for masking by setting transparent pixels to black
+        GpiSetBitmap(hps, hbmMask);
+
+        ptls[0].y -= h;
+        ptls[1].y -= h;
+        enum { AllImageAttrs = IBB_COLOR | IBB_BACK_COLOR |
+                               IBB_MIX_MODE | IBB_BACK_MIX_MODE };
+        IMAGEBUNDLE ib = { CLR_TRUE, CLR_FALSE, FM_OVERPAINT, BM_OVERPAINT };
+        GpiSetAttrs(hps, PRIM_IMAGE, AllImageAttrs, 0, (PBUNDLE)&ib);
+        GpiDrawBits(hps, (PBYTE)(const uchar *)mask.bits(), (PBITMAPINFO2)&bmi,
+                    4, ptls, ROP_SRCAND, BBO_IGNORE);
+    }
+
+    qt_free_mem_ps(hps);
+
+    if (mask)
+        *mask = hbmMask;
+
+    return hbm;
+}
+
+/*!
+    Creates a \c HPOINTER from the given QIcon. Returns the \c HPOINTER handle.
+
+    If \a isPointer is \c true, an icon size closest to the system pointer size
+    is chosen, otherwise to the system icon size. \a hotX and \a hotY define the
+    hot spot.
+
+    It is the caller's responsibility to free the \c HPOINTER data
+    after use.
+
+    \warning This function is only available on OS/2.
+*/
+// static
+HPOINTER QPixmap::toPmHPOINTER(const QIcon &icon, bool isPointer,
+                               int hotX, int hotY)
+{
+    if (icon.isNull())
+        return NULLHANDLE;
+
+    int w = WinQuerySysValue(HWND_DESKTOP, isPointer ? SV_CXPOINTER : SV_CXICON);
+    int h = WinQuerySysValue(HWND_DESKTOP, isPointer ? SV_CYPOINTER : SV_CYICON);
+    QSize size = icon.actualSize(QSize(w, h));
+    QSize sizeMini = icon.actualSize(QSize(w / 2, h / 2));
+
+    QPixmap pm = icon.pixmap(size);
+    QPixmap pmMini = icon.pixmap(sizeMini);
+    if (pm.isNull() && pmMini.isNull())
+        return NULLHANDLE;
+
+    if (pm.isNull()) {
+        // if we only have the mini icon, use it as a normal one;
+        // WinCreatePointerIndirect() will figure that and not scale it
+        pm = pmMini;
+        pmMini = QPixmap();
+    }
+
+    POINTERINFO info;
+    info.fPointer = isPointer;
+    info.xHotspot = hotX;
+    info.yHotspot = hotY;
+    info.hbmColor = pm.toPmHBITMAP(&info.hbmPointer);
+    if (!pmMini.isNull())
+    info.hbmMiniColor = pmMini.toPmHBITMAP(&info.hbmMiniPointer);
+
+    HPOINTER hIcon = WinCreatePointerIndirect(HWND_DESKTOP, &info);
+
+    GpiDeleteBitmap(info.hbmPointer);
+    GpiDeleteBitmap(info.hbmColor);
+    GpiDeleteBitmap(info.hbmMiniPointer);
+    GpiDeleteBitmap(info.hbmMiniColor);
+
+    return hIcon;
+}
 
 QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h )
Index: /trunk/src/gui/kernel/qwindowdefs_pm.h
===================================================================
--- /trunk/src/gui/kernel/qwindowdefs_pm.h	(revision 259)
+++ /trunk/src/gui/kernel/qwindowdefs_pm.h	(revision 260)
@@ -60,4 +60,5 @@
 typedef LHANDLE HWND;
 typedef LHANDLE HPS;
+typedef LHANDLE HBITMAP;
 typedef LHANDLE HPOINTER;
 typedef LHANDLE HRGN;
Index: /trunk/src/gui/util/qsystemtrayicon_pm.cpp
===================================================================
--- /trunk/src/gui/util/qsystemtrayicon_pm.cpp	(revision 259)
+++ /trunk/src/gui/util/qsystemtrayicon_pm.cpp	(revision 260)
@@ -63,5 +63,4 @@
     ~QSystemTrayIconSys();
 
-    HBITMAP createIconMask(const QBitmap &bitmap);
     void createIcon();
 
@@ -93,15 +92,9 @@
 }
 
-HBITMAP QSystemTrayIconSys::createIconMask(const QBitmap &bitmap)
-{
-    // @todo
-    return NULL;
-}
-
 void QSystemTrayIconSys::createIcon()
 {
     HPOINTER hIconToDestroy = hIcon;
 
-    // @todo
+    hIcon = QPixmap::toPmHPOINTER(q->icon());
 
     if (hIconToDestroy != NULLHANDLE)
@@ -212,5 +205,5 @@
 void QSystemTrayIconPrivate::updateMenu_sys()
 {
-
+    // nothing to do
 }
 
