| @@ -452,6 +452,7 @@ static bool isShmAvailable() throw() | |||
| } | |||
| #endif | |||
| //============================================================================== | |||
| class XBitmapImage : public Image | |||
| { | |||
| @@ -697,6 +698,7 @@ public: | |||
| checkMessageManagerIsLocked | |||
| deleteTaskBarIcon(); | |||
| deleteIconPixmaps(); | |||
| destroyWindow(); | |||
| @@ -1099,7 +1101,7 @@ public: | |||
| void setIcon (const Image& newIcon) | |||
| { | |||
| const int dataSize = newIcon.getWidth() * newIcon.getHeight() + 2; | |||
| uint32* const data = (uint32*) juce_malloc (dataSize); | |||
| uint32* const data = (uint32*) juce_malloc (dataSize * sizeof (uint32)); | |||
| int index = 0; | |||
| data[index++] = newIcon.getWidth(); | |||
| @@ -1114,9 +1116,46 @@ public: | |||
| XA_CARDINAL, 32, PropModeReplace, | |||
| (unsigned char*) data, dataSize); | |||
| juce_free (data); | |||
| deleteIconPixmaps(); | |||
| XWMHints* wmHints = XGetWMHints (display, windowH); | |||
| if (wmHints == 0) | |||
| wmHints = XAllocWMHints(); | |||
| wmHints->flags |= IconPixmapHint | IconMaskHint; | |||
| wmHints->icon_pixmap = juce_createColourPixmapFromImage (display, newIcon); | |||
| wmHints->icon_mask = juce_createMaskPixmapFromImage (display, newIcon); | |||
| XSetWMHints (display, windowH, wmHints); | |||
| XFree (wmHints); | |||
| XSync (display, False); | |||
| } | |||
| juce_free (data); | |||
| void deleteIconPixmaps() | |||
| { | |||
| XWMHints* wmHints = XGetWMHints (display, windowH); | |||
| if (wmHints != 0) | |||
| { | |||
| if ((wmHints->flags & IconPixmapHint) != 0) | |||
| { | |||
| wmHints->flags &= ~IconPixmapHint; | |||
| XFreePixmap (display, wmHints->icon_pixmap); | |||
| } | |||
| if ((wmHints->flags & IconMaskHint) != 0) | |||
| { | |||
| wmHints->flags &= ~IconMaskHint; | |||
| XFreePixmap (display, wmHints->icon_mask); | |||
| } | |||
| XSetWMHints (display, windowH, wmHints); | |||
| XFree (wmHints); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| @@ -2638,6 +2677,59 @@ bool Desktop::isScreenSaverEnabled() throw() | |||
| } | |||
| //============================================================================== | |||
| static Pixmap juce_createColourPixmapFromImage (Display* display, const Image& image) | |||
| { | |||
| const int width = image.getWidth(); | |||
| const int height = image.getHeight(); | |||
| uint32* const colour = (uint32*) juce_malloc (width * height * sizeof (uint32)); | |||
| int index = 0; | |||
| for (int y = 0; y < height; ++y) | |||
| for (int x = 0; x < width; ++x) | |||
| colour[index++] = image.getPixelAt (x, y).getARGB(); | |||
| XImage* ximage = XCreateImage (display, CopyFromParent, 24, ZPixmap, | |||
| 0, (char*) colour, width, height, 32, 0); | |||
| Pixmap pixmap = XCreatePixmap (display, DefaultRootWindow (display), | |||
| width, height, 24); | |||
| GC gc = XCreateGC (display, pixmap, 0, 0); | |||
| XPutImage (display, pixmap, gc, ximage, 0, 0, 0, 0, width, height); | |||
| XFreeGC (display, gc); | |||
| juce_free (colour); | |||
| return pixmap; | |||
| } | |||
| static Pixmap juce_createMaskPixmapFromImage (Display* display, const Image& image) | |||
| { | |||
| const int width = image.getWidth(); | |||
| const int height = image.getHeight(); | |||
| const int stride = (width + 7) >> 3; | |||
| uint8* const mask = (uint8*) juce_calloc (stride * height); | |||
| const bool msbfirst = (BitmapBitOrder (display) == MSBFirst); | |||
| for (int y = 0; y < height; ++y) | |||
| { | |||
| for (int x = 0; x < width; ++x) | |||
| { | |||
| const uint8 bit = (uint8) (1 << (msbfirst ? (7 - (x & 7)) : (x & 7))); | |||
| const int offset = y * stride + (x >> 3); | |||
| if (image.getPixelAt (x, y).getAlpha() >= 128) | |||
| mask[offset] |= bit; | |||
| } | |||
| } | |||
| Pixmap pixmap = XCreatePixmapFromBitmapData (display, DefaultRootWindow (display), | |||
| (char*) mask, width, height, 1, 0, 1); | |||
| juce_free (mask); | |||
| return pixmap; | |||
| } | |||
| void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw() | |||
| { | |||
| Window root = RootWindow (display, DefaultScreen (display)); | |||
| @@ -2669,7 +2761,7 @@ void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hot | |||
| uint8* const maskPlane = (uint8*) juce_calloc (stride * cursorH); | |||
| uint8* const sourcePlane = (uint8*) juce_calloc (stride * cursorH); | |||
| bool msbfirst = (BitmapBitOrder (display) == MSBFirst); | |||
| const bool msbfirst = (BitmapBitOrder (display) == MSBFirst); | |||
| for (int y = cursorH; --y >= 0;) | |||
| { | |||