+IMPLEMENT_DYNAMIC_CLASS(wxXBMFileHandler, wxBitmapHandler)
+
+bool wxXBMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
+ int desiredWidth, int desiredHeight)
+{
+ M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
+
+ int hotX, hotY;
+ unsigned int w, h;
+ Pixmap pixmap;
+
+ Display *dpy = (Display*) wxGetDisplay();
+ M_BITMAPDATA->m_display = (WXDisplay*) dpy;
+
+ int value = XReadBitmapFile (dpy, RootWindow (dpy, DefaultScreen (dpy)),
+ (char*) (const char*) name, &w, &h, &pixmap, &hotX, &hotY);
+ M_BITMAPHANDLERDATA->m_width = w;
+ M_BITMAPHANDLERDATA->m_height = h;
+ M_BITMAPHANDLERDATA->m_depth = 1;
+ M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
+
+ if ((value == BitmapFileInvalid) ||
+ (value == BitmapOpenFailed) ||
+ (value == BitmapNoMemory))
+ {
+ M_BITMAPHANDLERDATA->m_ok = FALSE;
+ M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) 0;
+ }
+ else
+ M_BITMAPHANDLERDATA->m_ok = TRUE;
+
+ return M_BITMAPHANDLERDATA->m_ok ;
+}
+
+class WXDLLEXPORT wxXBMDataHandler: public wxBitmapHandler
+{
+ DECLARE_DYNAMIC_CLASS(wxXBMDataHandler)
+public:
+ inline wxXBMDataHandler()
+ {
+ m_name = "XBM data";
+ m_extension = "xbm";
+ m_type = wxBITMAP_TYPE_XBM_DATA;
+ };
+
+ virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
+};
+IMPLEMENT_DYNAMIC_CLASS(wxXBMDataHandler, wxBitmapHandler)
+
+bool wxXBMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
+{
+ M_BITMAPHANDLERDATA->m_width = width;
+ M_BITMAPHANDLERDATA->m_height = height;
+ M_BITMAPHANDLERDATA->m_depth = 1;
+ M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
+
+ Display *dpy = (Display*) wxGetDisplay();
+ M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
+
+ M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) XCreateBitmapFromData (dpy, RootWindow (dpy, DefaultScreen (dpy)), (char*) data, width, height);
+ M_BITMAPHANDLERDATA->m_ok = (M_BITMAPHANDLERDATA->m_pixmap != (WXPixmap) 0) ;
+
+ // code for wxControl. TODO: can we avoid doing this until we need it?
+ // E.g. have CreateButtonPixmaps which is called on demand.
+ XImage* image = (XImage *) XtMalloc (sizeof (XImage));
+ image->width = width;
+ image->height = height;
+ image->data = (char*) data;
+ image->depth = 1;
+ image->xoffset = 0;
+ image->format = XYBitmap;
+ image->byte_order = LSBFirst;
+ image->bitmap_unit = 8;
+ image->bitmap_bit_order = LSBFirst;
+ image->bitmap_pad = 8;
+ image->bytes_per_line = (width + 7) >> 3;
+
+ char tmp[128];
+ sprintf (tmp, "Im%x", (unsigned int) image);
+ XmInstallImage (image, tmp);
+
+ // Build our manually stipped pixmap.
+
+ int bpl = (width + 7) / 8;
+ char *data1 = new char[height * bpl];
+ char* bits = (char*) data;
+ int i;
+ for (i = 0; i < height; i++)
+ {
+ int mask = i % 2 ? 0x55 : 0xaa;
+ int j;
+ for (j = 0; j < bpl; j++)
+ data1[i * bpl + j] = bits[i * bpl + j] & mask;
+ }
+ XImage* insensImage = (XImage *) XtMalloc (sizeof (XImage));
+ insensImage->width = width;
+ insensImage->height = height;
+ insensImage->data = data1;
+ insensImage->depth = 1;
+ insensImage->xoffset = 0;
+ insensImage->format = XYBitmap;
+ insensImage->byte_order = LSBFirst;
+ insensImage->bitmap_unit = 8;
+ insensImage->bitmap_bit_order = LSBFirst;
+ insensImage->bitmap_pad = 8;
+ insensImage->bytes_per_line = bpl;
+
+ sprintf (tmp, "Not%x", (unsigned int)insensImage);
+ XmInstallImage (insensImage, tmp);
+
+ M_BITMAPHANDLERDATA->m_image = (WXImage*) image;
+ M_BITMAPHANDLERDATA->m_insensImage = (WXImage*) insensImage;
+
+ return TRUE;
+}
+
+#if wxUSE_XPM
+class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
+{
+ DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
+public:
+ inline wxXPMFileHandler()
+ {
+ m_name = "XPM file";
+ m_extension = "xpm";
+ m_type = wxBITMAP_TYPE_XPM;
+ };
+
+ virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
+ int desiredWidth, int desiredHeight);
+ virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
+
+bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
+ int desiredWidth, int desiredHeight)
+{
+ Display *dpy = (Display*) wxGetDisplay();
+ M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
+
+ XpmAttributes xpmAttr;
+ Pixmap pixmap;
+ Pixmap mask = 0;
+
+ M_BITMAPHANDLERDATA->m_ok = FALSE;
+ xpmAttr.valuemask = XpmReturnInfos | XpmCloseness;
+ xpmAttr.closeness = 40000;
+ int errorStatus = XpmReadFileToPixmap(dpy,
+ RootWindow(dpy, DefaultScreen(dpy)), (char*) (const char*) name,
+ &pixmap, &mask, &xpmAttr);
+
+ if (errorStatus == XpmSuccess)
+ {
+ M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
+ if ( mask )
+ {
+ M_BITMAPHANDLERDATA->m_bitmapMask = new wxMask;
+ M_BITMAPHANDLERDATA->m_bitmapMask->SetPixmap((WXPixmap) mask);
+ }
+
+ unsigned int depthRet;
+ int xRet, yRet;
+ unsigned int widthRet, heightRet, borderWidthRet;
+ Window rootWindowRet;
+ XGetGeometry(dpy, pixmap, &rootWindowRet, &xRet, &yRet,
+ &widthRet, &heightRet, &borderWidthRet, &depthRet);
+
+ M_BITMAPHANDLERDATA->m_width = xpmAttr.width;
+ M_BITMAPHANDLERDATA->m_height = xpmAttr.height;
+
+ /*
+ if ( xpmAttr.npixels > 2 )
+ {
+ M_BITMAPHANDLERDATA->m_depth = 8; // TODO: next time not just a guess :-) ...
+ } else
+ {
+ M_BITMAPHANDLERDATA->m_depth = 1; // mono
+ }
+ */
+
+ M_BITMAPHANDLERDATA->m_depth = depthRet;
+
+ M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
+
+ XpmFreeAttributes(&xpmAttr);
+
+ M_BITMAPHANDLERDATA->m_ok = TRUE;
+ return TRUE;
+ } else
+ {
+// XpmDebugError(errorStatus, name);
+ M_BITMAPHANDLERDATA->m_ok = FALSE;
+ return FALSE;
+ }
+}
+
+bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
+{
+ if (M_BITMAPHANDLERDATA->m_ok && M_BITMAPHANDLERDATA->m_pixmap)
+ {
+ Display *dpy = (Display*) M_BITMAPHANDLERDATA->m_display;
+ int errorStatus = XpmWriteFileFromPixmap(dpy, (char*) (const char*) name,
+ (Pixmap) M_BITMAPHANDLERDATA->m_pixmap,
+ (M_BITMAPHANDLERDATA->m_bitmapMask ? (Pixmap) M_BITMAPHANDLERDATA->m_bitmapMask->GetPixmap() : (Pixmap) 0),
+ (XpmAttributes *) NULL);
+ if (errorStatus == XpmSuccess)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ else
+ return FALSE;
+}
+
+class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
+{
+ DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
+public:
+ inline wxXPMDataHandler()
+ {
+ m_name = "XPM data";
+ m_extension = "xpm";
+ m_type = wxBITMAP_TYPE_XPM_DATA;
+ };
+
+ virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
+};
+IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
+
+bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
+{
+ M_BITMAPHANDLERDATA->m_width = width;
+ M_BITMAPHANDLERDATA->m_height = height;
+ M_BITMAPHANDLERDATA->m_depth = 1;
+ M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
+
+ Display *dpy = (Display*) wxGetDisplay();
+ M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
+
+ XpmAttributes xpmAttr;
+
+ xpmAttr.valuemask = XpmReturnInfos; /* nothing yet, but get infos back */
+
+ XpmColorSymbol symbolicColors[4];
+ if (sg_Control && sg_Control->GetMainWidget())
+ {
+ symbolicColors[0].name = "foreground";
+ symbolicColors[0].value = NULL;
+ symbolicColors[1].name = "background";
+ symbolicColors[1].value = NULL;
+ XtVaGetValues((Widget) sg_Control->GetMainWidget(),
+ XmNforeground, &symbolicColors[0].pixel,
+ XmNbackground, &symbolicColors[1].pixel,NULL);
+ xpmAttr.numsymbols = 2;
+ xpmAttr.colorsymbols = symbolicColors;
+ xpmAttr.valuemask |= XpmColorSymbols; // add flag
+ }
+
+ Pixmap pixmap;
+ Pixmap mask = 0;
+ int ErrorStatus = XpmCreatePixmapFromData(dpy, RootWindow(dpy, DefaultScreen(dpy)),
+ (char**) data, &pixmap, &mask, &xpmAttr);
+ if (ErrorStatus == XpmSuccess)
+ {
+ // Set attributes
+ M_BITMAPHANDLERDATA->m_width = xpmAttr.width;
+ M_BITMAPHANDLERDATA->m_height = xpmAttr.height;
+
+ unsigned int depthRet;
+ int xRet, yRet;
+ unsigned int widthRet, heightRet, borderWidthRet;
+ Window rootWindowRet;
+ XGetGeometry(dpy, pixmap, &rootWindowRet, &xRet, &yRet,
+ &widthRet, &heightRet, &borderWidthRet, &depthRet);
+
+ /*
+ if ( xpmAttr.npixels > 2 )
+ {
+ M_BITMAPHANDLERDATA->m_depth = 8; // next time not just a guess :-) ...
+ } else
+ {
+ M_BITMAPHANDLERDATA->m_depth = 1; // mono
+ }
+ */
+
+ M_BITMAPHANDLERDATA->m_depth = depthRet;
+
+ M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
+ XpmFreeAttributes(&xpmAttr);
+ M_BITMAPHANDLERDATA->m_ok = TRUE;
+ M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
+ if ( mask )
+ {
+ M_BITMAPHANDLERDATA->m_bitmapMask = new wxMask;
+ M_BITMAPHANDLERDATA->m_bitmapMask->SetPixmap((WXPixmap) mask);
+ }
+ }
+ else
+ {
+// XpmDebugError(ErrorStatus, NULL);
+ M_BITMAPHANDLERDATA->m_ok = FALSE;
+ }
+ return M_BITMAPHANDLERDATA->m_ok ;
+}
+
+#endif