+#if wxUSE_NANOX
+// Copy from the drawable to the wxImage
+bool wxGetImageFromDrawable(GR_DRAW_ID drawable, int srcX, int srcY, int width, int height, wxImage& image)
+{
+    GR_SCREEN_INFO sinfo;
+    int x, y;
+    GR_PIXELVAL *pixels;
+    GR_PALETTE* palette = NULL;
+    unsigned char rgb[3], *pp;
+
+    GrGetScreenInfo(&sinfo);
+
+    if (sinfo.pixtype == MWPF_PALETTE) {
+        if(!(palette = (GR_PALETTE*) malloc(sizeof(GR_PALETTE)))) {
+            return false;
+        }
+        GrGetSystemPalette(palette);
+    }
+
+    if(!(pixels = (GR_PIXELVAL*) malloc(sizeof(GR_PIXELVAL) * width * height)))
+    {
+        return false;
+    }
+
+    image.Create(width, height);
+
+    GrReadArea(drawable, srcX, srcY, width, height,
+            pixels);
+
+
+    for(x = 0; x < sinfo.cols; x++) {
+
+        pp = (unsigned char *)pixels +
+            ((x + (y * sinfo.cols)) *
+             sizeof(GR_PIXELVAL));
+
+        switch(sinfo.pixtype) {
+            /* FIXME: These may need modifying on big endian. */
+            case MWPF_TRUECOLOR0888:
+            case MWPF_TRUECOLOR888:
+                rgb[0] = pp[2];
+                rgb[1] = pp[1];
+                rgb[2] = pp[0];
+                break;
+            case MWPF_PALETTE:
+                rgb[0] = palette->palette[pp[0]].r;
+                rgb[1] = palette->palette[pp[0]].g;
+                rgb[2] = palette->palette[pp[0]].b;
+                break;
+            case MWPF_TRUECOLOR565:
+                rgb[0] = pp[1] & 0xf8;
+                rgb[1] = ((pp[1] & 0x07) << 5) |
+                    ((pp[0] & 0xe0) >> 3);
+                rgb[2] = (pp[0] & 0x1f) << 3;
+                break;
+            case MWPF_TRUECOLOR555:
+                rgb[0] = (pp[1] & 0x7c) << 1;
+                rgb[1] = ((pp[1] & 0x03) << 6) |
+                    ((pp[0] & 0xe0) >> 2);
+                rgb[2] = (pp[0] & 0x1f) << 3;
+                break;
+            case MWPF_TRUECOLOR332:
+                rgb[0] = pp[0] & 0xe0;
+                rgb[1] = (pp[0] & 0x1c) << 3;
+                rgb[2] = (pp[0] & 0x03) << 6;
+                break;
+            default:
+                fprintf(stderr, "Unsupported pixel "
+                        "format\n");
+                return 1;
+        }
+
+        image.SetRGB(x, y, rgb[0], rgb[1], rgb[2]);
+
+    }
+
+    free(pixels);
+    if(palette) free(palette);
+
+    return true;
+}
+
+#if 0
+int GrGetPixelColor(GR_SCREEN_INFO* sinfo, GR_PALETTE* palette, GR_PIXELVAL pixel,
+    unsigned char* red, unsigned char* green, unsigned char* blue)
+{
+    unsigned char rgb[3], *pp;
+
+    pp = (unsigned char*) & pixel ;
+
+    switch (sinfo.pixtype)
+    {
+        /* FIXME: These may need modifying on big endian. */
+        case MWPF_TRUECOLOR0888:
+        case MWPF_TRUECOLOR888:
+            rgb[0] = pp[2];
+            rgb[1] = pp[1];
+            rgb[2] = pp[0];
+            break;
+        case MWPF_PALETTE:
+            rgb[0] = palette->palette[pp[0]].r;
+            rgb[1] = palette->palette[pp[0]].g;
+            rgb[2] = palette->palette[pp[0]].b;
+            break;
+        case MWPF_TRUECOLOR565:
+            rgb[0] = pp[1] & 0xf8;
+            rgb[1] = ((pp[1] & 0x07) << 5) |
+                ((pp[0] & 0xe0) >> 3);
+            rgb[2] = (pp[0] & 0x1f) << 3;
+            break;
+        case MWPF_TRUECOLOR555:
+            rgb[0] = (pp[1] & 0x7c) << 1;
+            rgb[1] = ((pp[1] & 0x03) << 6) |
+                ((pp[0] & 0xe0) >> 2);
+            rgb[2] = (pp[0] & 0x1f) << 3;
+            break;
+        case MWPF_TRUECOLOR332:
+            rgb[0] = pp[0] & 0xe0;
+            rgb[1] = (pp[0] & 0x1c) << 3;
+            rgb[2] = (pp[0] & 0x03) << 6;
+            break;
+        default:
+            fprintf(stderr, "Unsupported pixel format\n");
+            return 0;
+    }
+
+
+    *(red) = rgb[0];
+    *(green) = rgb[1];
+    *(blue) = rgb[2];
+    return 1;
+}
+#endif
+
+#endif
+  // wxUSE_NANOX
+
+// ============================================================================
+// Bitmap handlers
+// ============================================================================
+
+#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()
+    {
+        SetName( wxT("XPM file") );
+        SetExtension( wxT("xpm") );
+        SetType( 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 *WXUNUSED(bitmap), const void* WXUNUSED(data), long WXUNUSED(flags),
+                        int WXUNUSED(width), int WXUNUSED(height), int WXUNUSED(depth) = 1)
+        { return false; }
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
+
+bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name,
+                                long WXUNUSED(flags), int WXUNUSED(desiredWidth),
+                                int WXUNUSED(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*) ((const 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 = (Pixmap) 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()
+    {
+        SetName( wxT("XPM data") );
+        SetExtension( wxT("xpm") );
+        SetType( wxBITMAP_TYPE_XPM_DATA );
+    };
+
+    virtual bool LoadFile(wxBitmap *WXUNUSED(bitmap),
+                          const wxString& WXUNUSED(name),
+                          long WXUNUSED(flags),
+                          int WXUNUSED(desiredWidth),
+                          int WXUNUSED(desiredHeight))
+        { return false; }
+
+    virtual bool SaveFile(const wxBitmap *WXUNUSED(bitmap),
+                          const wxString& WXUNUSED(name),
+                          int WXUNUSED(type),
+                          const wxPalette *WXUNUSED(palette) = NULL)
+        { return false; }
+
+    virtual bool Create(wxBitmap *bitmap, const void* data, long flags,
+                        int width, int height, int depth = 1);
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
+
+bool wxXPMDataHandler::Create(wxBitmap *bitmap, const void* bits,
+                              long WXUNUSED(flags),
+                              int WXUNUSED(width), int WXUNUSED(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 = (Pixmap) 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()
+    {
+        SetName( wxT("XBM data") );
+        SetExtension( wxT("xbm") );
+        SetType( wxBITMAP_TYPE_XBM_DATA );
+    };
+
+    virtual bool LoadFile(wxBitmap *WXUNUSED(bitmap),
+                          const wxString& WXUNUSED(name),
+                          long WXUNUSED(flags),
+                          int WXUNUSED(desiredWidth),
+                          int WXUNUSED(desiredHeight))
+        { return false; }
+
+    virtual bool SaveFile(const wxBitmap *WXUNUSED(bitmap),
+                          const wxString& WXUNUSED(name),
+                          int WXUNUSED(type),
+                          const wxPalette *WXUNUSED(palette) = NULL)
+        { return false; }
+
+    virtual bool Create(wxBitmap *bitmap, const void* data, long flags,
+                        int width, int height, int depth = 1);
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxXBMDataHandler, wxBitmapHandler)
+
+bool wxXBMDataHandler::Create( wxBitmap *bitmap, const void* bits,
+                               long WXUNUSED(flags),
+                               int width, int height, int WXUNUSED(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 =
+        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
+}