+// ============================================================================
+// Bitmap handlers
+// ============================================================================
+
+IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler, wxBitmapHandlerBase);
+
+#define M_BMPHANDLERDATA ((wxBitmapRefData *)bitmap->GetRefData())
+
+#if wxUSE_XPM
+
+#if wxHAVE_LIB_XPM || wxUSE_STREAMS
+
+// ----------------------------------------------------------------------------
+// wxXPMFileHandler
+// ----------------------------------------------------------------------------
+
+class wxXPMFileHandler : public wxBitmapHandler
+{
+ DECLARE_DYNAMIC_CLASS(wxXPMFileHandler);
+public:
+ 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(const wxBitmap *bitmap, const wxString& name,
+ int type, const wxPalette *palette = NULL);
+
+ virtual bool Create(wxBitmap *bitmap, void *data, long flags,
+ int width, int height, int depth = 1)
+ { return FALSE; }
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler);
+
+bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name,
+ long flags, int desiredWidth,
+ int desiredHeight)
+{
+#if wxHAVE_LIB_XPM
+ if (!bitmap->GetRefData())
+ bitmap->SetRefData( new wxBitmapRefData() );
+
+ M_BMPHANDLERDATA->m_display = wxGlobalDisplay();
+
+ Display *xdisplay = (Display*) M_BMPHANDLERDATA->m_display;
+
+ int xscreen = DefaultScreen( xdisplay );
+ Window xroot = RootWindow( xdisplay, xscreen );
+
+ int bpp = DefaultDepth( xdisplay, xscreen );
+
+ XpmAttributes xpmAttr;
+ xpmAttr.valuemask = XpmReturnInfos; // nothing yet, but get infos back
+
+ Pixmap pixmap;
+ Pixmap mask = 0;
+
+ int ErrorStatus = XpmReadFileToPixmap( xdisplay, xroot,
+ (char*) name.c_str(),
+ &pixmap, &mask, &xpmAttr);
+
+ if (ErrorStatus == XpmSuccess)
+ {
+ M_BMPHANDLERDATA->m_width = xpmAttr.width;
+ M_BMPHANDLERDATA->m_height = xpmAttr.height;
+
+ M_BMPHANDLERDATA->m_bpp = bpp; // mono as well?
+
+ XpmFreeAttributes(&xpmAttr);
+
+ M_BMPHANDLERDATA->m_bitmap = (WXPixmap) pixmap;
+
+ if (mask)
+ {
+ M_BMPHANDLERDATA->m_mask = new wxMask;
+ M_BMPHANDLERDATA->m_mask->SetBitmap( (WXPixmap) mask );
+ M_BMPHANDLERDATA->m_mask->SetDisplay( xdisplay );
+ }
+ }
+ else
+ {
+ UnRef();
+
+ return FALSE;
+ }
+
+ return TRUE;
+#elif wxUSE_STREAMS
+ wxXPMDecoder decoder;
+ wxFileInputStream stream(name);
+ if (stream.Ok())
+ {
+ wxImage image(decoder.ReadFile(stream));
+ return image.Ok() && bitmap->CreateFromImage(image);
+ }
+
+ return FALSE;
+#else // !wxHAVE_LIB_XPM && !wxUSE_STREAMS
+ return FALSE;
+#endif // wxHAVE_LIB_XPM / wxUSE_STREAMS
+}
+
+bool wxXPMFileHandler::SaveFile(const wxBitmap *bitmap, const wxString& name,
+ int type,
+ const wxPalette *WXUNUSED(palette))
+{
+ wxImage image(bitmap->ConvertToImage());
+ if (image.Ok()) return image.SaveFile( name, (wxBitmapType)type );
+
+ return FALSE;
+}
+
+#endif // wxHAVE_LIB_XPM || wxUSE_STREAMS
+
+// ----------------------------------------------------------------------------
+// wxXPMDataHandler
+// ----------------------------------------------------------------------------
+
+class wxXPMDataHandler : public wxBitmapHandler
+{
+ DECLARE_DYNAMIC_CLASS(wxXPMDataHandler);
+public:
+ wxXPMDataHandler()
+ {
+ m_name = "XPM data";
+ m_extension = "xpm";
+ m_type = wxBITMAP_TYPE_XPM_DATA;
+ };
+
+ virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
+ int desiredWidth, int desiredHeight)
+ { return FALSE; }
+
+ virtual bool SaveFile(const wxBitmap *bitmap, const wxString& name,
+ int type, const wxPalette *palette = NULL)
+ { return FALSE; }
+
+ 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 *bits,
+ long WXUNUSED(flags),
+ int width, int height, int WXUNUSED(depth))
+{
+#if wxHAVE_LIB_XPM
+ wxCHECK_MSG( bits != NULL, FALSE, wxT("invalid bitmap data") )
+
+ if (!bitmap->GetRefData())
+ bitmap->SetRefData( new wxBitmapRefData() );
+
+ M_BMPHANDLERDATA->m_display = wxGlobalDisplay();
+
+ Display *xdisplay = (Display*) M_BMPHANDLERDATA->m_display;
+
+ int xscreen = DefaultScreen( xdisplay );
+ Window xroot = RootWindow( xdisplay, xscreen );
+
+ int bpp = DefaultDepth( xdisplay, xscreen );
+
+ XpmAttributes xpmAttr;
+ xpmAttr.valuemask = XpmReturnInfos; // nothing yet, but get infos back
+
+ Pixmap pixmap = 0;
+ Pixmap mask = 0;
+
+ int ErrorStatus = XpmCreatePixmapFromData( xdisplay, xroot, (char**) bits,
+ &pixmap, &mask, &xpmAttr );
+
+ if (ErrorStatus == XpmSuccess)
+ {
+ M_BMPHANDLERDATA->m_width = xpmAttr.width;
+ M_BMPHANDLERDATA->m_height = xpmAttr.height;
+
+ M_BMPHANDLERDATA->m_bpp = bpp; // mono as well?
+
+#if __WXDEBUG__
+ unsigned int depthRet;
+ int xRet, yRet;
+ unsigned int widthRet, heightRet, borderWidthRet;
+ XGetGeometry( xdisplay, pixmap, &xroot, &xRet, &yRet,
+ &widthRet, &heightRet, &borderWidthRet, &depthRet);
+
+ wxASSERT_MSG( bpp == (int)depthRet, wxT("colour depth mismatch") );
+#endif
+
+ XpmFreeAttributes(&xpmAttr);
+
+ M_BMPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
+
+ if (mask)
+ {
+ M_BMPHANDLERDATA->m_mask = new wxMask;
+ M_BMPHANDLERDATA->m_mask->SetBitmap( (WXPixmap) mask );
+ M_BMPHANDLERDATA->m_mask->SetDisplay( xdisplay );
+ }
+ return TRUE;
+ }
+ else
+ {
+ bitmap->UnRef();
+
+ return FALSE;
+ }
+#else // !wxHAVE_LIB_XPM
+ wxXPMDecoder decoder;
+ wxImage image(decoder.ReadData((const char **)bits));
+ return image.Ok() && bitmap->CreateFromImage(image);
+#endif // wxHAVE_LIB_XPM/!wxHAVE_LIB_XPM
+}
+
+#endif // wxUSE_XPM
+
+// ----------------------------------------------------------------------------
+// wxXBMDataHandler
+// ----------------------------------------------------------------------------
+
+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 LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
+ int desiredWidth, int desiredHeight)
+ { return FALSE; }
+
+ virtual bool SaveFile(const wxBitmap *bitmap, const wxString& name,
+ int type, const wxPalette *palette = NULL)
+ { return FALSE; }
+
+ 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 *bits,
+ long WXUNUSED(flags),
+ int width, int height, int depth)
+{
+#if !wxUSE_NANOX
+ if (!bitmap->GetRefData())
+ bitmap->SetRefData( new wxBitmapRefData() );
+
+ M_BMPHANDLERDATA->m_display = wxGlobalDisplay();
+
+ Display *xdisplay = (Display*) M_BMPHANDLERDATA->m_display;
+
+ int xscreen = DefaultScreen( xdisplay );
+ Window xroot = RootWindow( xdisplay, xscreen );
+
+ M_BMPHANDLERDATA->m_mask = (wxMask *) NULL;
+ M_BMPHANDLERDATA->m_bitmap =
+ (WXPixmap) XCreateBitmapFromData( xdisplay, xroot,
+ (char *) bits, width, height );
+ M_BMPHANDLERDATA->m_width = width;
+ M_BMPHANDLERDATA->m_height = height;
+ M_BMPHANDLERDATA->m_bpp = 1;
+
+ return TRUE;
+#else
+ wxCHECK_MSG( M_BMPHANDLERDATA->m_bitmap, FALSE,
+ wxT("couldn't create bitmap") );
+#endif
+}
+
+void wxBitmap::InitStandardHandlers()
+{
+ AddHandler(new wxXBMDataHandler);
+#if wxUSE_XPM
+#if wxHAVE_LIB_XPM || wxUSE_STREAMS
+ AddHandler(new wxXPMFileHandler);
+#endif
+ AddHandler(new wxXPMDataHandler);
+#endif
+}