]> git.saurik.com Git - wxWidgets.git/blobdiff - src/x11/bitmap.cpp
updated xml project file with latest changes (spinctrl, display, msgout, ...)
[wxWidgets.git] / src / x11 / bitmap.cpp
index 6d4c558c3ee03d875698ff8511ac934068aaa8a1..38f8aba90aa5190be4e6d83baf921cc29c945f39 100644 (file)
 #include "wx/log.h"
 #include "wx/image.h"
 #include "wx/app.h"
+#if wxUSE_NANOX
+#include "wx/dcmemory.h"
+#endif
 
 #include "wx/x11/private.h"
 
+/* No point in using libXPM for NanoX */
+#if wxUSE_NANOX
+#undef wxHAVE_LIB_XPM
+#define wxHAVE_LIB_XPM 0
+
+// Copy from the drawable to the wxImage
+bool wxGetImageFromDrawable(GR_DRAW_ID drawable, int srcX, int srcY, int width, int height, wxImage& image);
+#endif
+
+#if wxUSE_XPM
 #if wxHAVE_LIB_XPM
-    #include <X11/xpm.h>
+#include <X11/xpm.h>
+#else
+#include "wx/xpmdecod.h"
+#include "wx/wfstream.h"
+#endif
 #endif
 #include <math.h>
 
@@ -65,6 +82,7 @@ wxMask::~wxMask()
 bool wxMask::Create( const wxBitmap& bitmap,
                      const wxColour& colour )
 {
+#if !wxUSE_NANOX
     if (m_bitmap)
     {
         XFreePixmap( (Display*) m_display, (Pixmap) m_bitmap );
@@ -79,11 +97,8 @@ bool wxMask::Create( const wxBitmap& bitmap,
     m_display = bitmap.GetDisplay();
     
     Display *xdisplay = (Display*) m_display;
-
     int xscreen = DefaultScreen( xdisplay );
     Window xroot = RootWindow( xdisplay, xscreen );
-    Visual* xvisual = DefaultVisual( xdisplay, xscreen );
-    int bpp = DefaultDepth( xdisplay, xscreen );
     
     m_bitmap = (WXPixmap) XCreatePixmap( xdisplay, xroot, image.GetWidth(), image.GetHeight(), 1 );
     GC gc = XCreateGC( xdisplay, (Pixmap) m_bitmap, 0, NULL );
@@ -99,18 +114,8 @@ bool wxMask::Create( const wxBitmap& bitmap,
     unsigned char green = colour.Green();
     unsigned char blue = colour.Blue();
 
-    XVisualInfo vinfo_template;
-    XVisualInfo *vi;
-
-    vinfo_template.visual = xvisual;
-    vinfo_template.visualid = XVisualIDFromVisual( xvisual );
-    vinfo_template.depth = bpp;
-    int nitem = 0;
-
-    vi = XGetVisualInfo( xdisplay, VisualIDMask|VisualDepthMask, &vinfo_template, &nitem );
-    wxASSERT_MSG( vi, wxT("No visual info") );
+    int bpp = wxTheApp->m_visualDepth;
     
-    if ((bpp == 16) && (vi->red_mask != 0xf800)) bpp = 15;
     if (bpp == 15)
     {
         red = red & 0xf8;
@@ -132,11 +137,13 @@ bool wxMask::Create( const wxBitmap& bitmap,
 
     XSetForeground( xdisplay, gc, BlackPixel(xdisplay,xscreen) );
 
-    for (int j = 0; j < image.GetHeight(); j++)
+    int width = image.GetWidth();
+    int height = image.GetHeight();
+    for (int j = 0; j < height; j++)
     {
         int start_x = -1;
         int i;
-        for (i = 0; i < image.GetWidth(); i++)
+        for (i = 0; i < width; i++)
         {
             if ((data[index] == red) &&
                 (data[index+1] == green) &&
@@ -162,6 +169,10 @@ bool wxMask::Create( const wxBitmap& bitmap,
     XFreeGC( xdisplay, gc );
 
     return TRUE;
+#else
+    return FALSE;
+#endif
+    // wxUSE_NANOX
 }
 
 bool wxMask::Create( const wxBitmap& bitmap, int paletteIndex )
@@ -178,6 +189,7 @@ bool wxMask::Create( const wxBitmap& bitmap, int paletteIndex )
 
 bool wxMask::Create( const wxBitmap& bitmap )
 {
+#if !wxUSE_NANOX
     if (m_bitmap)
     {
         XFreePixmap( (Display*) m_display, (Pixmap) m_bitmap );
@@ -205,6 +217,10 @@ bool wxMask::Create( const wxBitmap& bitmap )
     XFreeGC( (Display*) m_display, gc );
 
     return TRUE;
+#else
+    return FALSE;
+#endif
+    // wxUSE_NANOX
 }
 
 //-----------------------------------------------------------------------------
@@ -286,6 +302,13 @@ bool wxBitmap::Create( int width, int height, int depth )
     M_BMPDATA->m_mask = (wxMask *) NULL;
     M_BMPDATA->m_width = width;
     M_BMPDATA->m_height = height;
+
+#if wxUSE_NANOX
+    M_BMPDATA->m_pixmap = (WXPixmap) GrNewPixmap(width, height, NULL);
+    M_BMPDATA->m_bpp = bpp;
+
+    wxASSERT_MSG( M_BMPDATA->m_pixmap, wxT("Bitmap creation failed") );
+#else
     if (depth == 1)
     {
         M_BMPDATA->m_bitmap = (WXPixmap) XCreatePixmap( (Display*) M_BMPDATA->m_display, xroot, width, height, 1 );
@@ -302,12 +325,14 @@ bool wxBitmap::Create( int width, int height, int depth )
         
         M_BMPDATA->m_bpp = depth;
     }
-
+#endif
     return Ok();
 }
 
 bool wxBitmap::CreateFromXpm( const char **bits )
 {
+#if wxUSE_XPM
+#if wxHAVE_LIB_XPM
     UnRef();
 
     wxCHECK_MSG( bits != NULL, FALSE, wxT("invalid bitmap data") )
@@ -345,7 +370,7 @@ bool wxBitmap::CreateFromXpm( const char **bits )
         XGetGeometry( xdisplay, pixmap, &xroot, &xRet, &yRet,
             &widthRet, &heightRet, &borderWidthRet, &depthRet);
 
-        wxASSERT_MSG( bpp == (int)depthRet, wxT("colour depth mismatch") )
+        wxASSERT_MSG( bpp == (int)depthRet, wxT("colour depth mismatch") );
 #endif
 
         XpmFreeAttributes(&xpmAttr);
@@ -358,6 +383,7 @@ bool wxBitmap::CreateFromXpm( const char **bits )
             M_BMPDATA->m_mask->SetBitmap( (WXPixmap) mask );
             M_BMPDATA->m_mask->SetDisplay( xdisplay );
         }
+       return TRUE;
     }
     else
     {
@@ -365,12 +391,127 @@ bool wxBitmap::CreateFromXpm( const char **bits )
         
         return FALSE;
     }
-
-    return TRUE;
+#else
+    wxXPMDecoder decoder;
+    wxImage image(decoder.ReadData(bits));
+    if (image.Ok())
+       return CreateFromImage(image);
+    else
+       return FALSE;
+#endif
+#endif
+    return FALSE;
 }
 
 bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
 {
+#if wxUSE_NANOX
+    if (!image.Ok())
+    {
+        wxASSERT_MSG(image.Ok(), "Invalid wxImage passed to wxBitmap::CreateFromImage.");
+        return FALSE;
+    }
+    
+    int w = image.GetWidth();
+    int h = image.GetHeight();
+    
+    if (!Create(w, h, depth))
+        return FALSE;
+
+    // Unfortunately the mask has to be screen-depth since
+    // 1-bpp bitmaps don't seem to be supported
+    // TODO: implement transparent drawing, presumably
+    // by doing several blits as per the Windows
+    // implementation because Nano-X doesn't support
+    // XSetClipMask.
+    // TODO: could perhaps speed this function up
+    // by making a buffer of pixel values,
+    // and then calling GrArea to write that to the
+    // pixmap. See demos/nxroach.c.
+
+    bool hasMask = image.HasMask();
+    
+    GC pixmapGC = GrNewGC();
+    Pixmap pixmap = (Pixmap) GetPixmap();
+
+    GC maskGC = 0;
+    Pixmap maskPixmap = 0;
+
+    unsigned char maskR = 0;
+    unsigned char maskG = 0;
+    unsigned char maskB = 0;
+
+    if (hasMask)
+    {
+        maskR = image.GetMaskRed();
+        maskG = image.GetMaskGreen();
+        maskB = image.GetMaskBlue();
+        
+        maskGC = GrNewGC();
+        maskPixmap = GrNewPixmap(w, h, 0);
+        if (!maskPixmap)
+            hasMask = FALSE;
+        else
+        {
+            wxMask* mask = new wxMask;
+            mask->SetBitmap((WXPixmap) maskPixmap);
+            SetMask(mask);
+        }
+    }
+
+    GR_COLOR lastPixmapColour = 0;
+    GR_COLOR lastMaskColour = 0;
+    
+    int i, j;
+    for (i = 0; i < w; i++)
+    {
+        for (j = 0; j < h; j++)
+        {
+            unsigned char red = image.GetRed(i, j);
+            unsigned char green = image.GetGreen(i, j);
+            unsigned char blue = image.GetBlue(i, j);
+
+            GR_COLOR colour = GR_RGB(red, green, blue);
+
+            // Efficiency measure
+            if (colour != lastPixmapColour || (i == 0 && j == 0))
+            {
+                GrSetGCForeground(pixmapGC, colour);
+                lastPixmapColour = colour;
+            }
+            
+            GrPoint(pixmap, pixmapGC, i, j);
+            
+            if (hasMask)
+            {
+                // scan the bitmap for the transparent colour and set the corresponding
+                // pixels in the mask to BLACK and the rest to WHITE
+                if (maskR == red && maskG == green && maskB == blue)
+                {
+                    colour = GR_RGB(0, 0, 0);
+                }
+                else
+                {
+                    colour = GR_RGB(255, 255, 255);
+                }
+                if (colour != lastMaskColour || (i == 0 && j == 0))
+                {
+                    GrSetGCForeground(maskGC, colour);
+                    lastMaskColour = colour;
+                }
+                GrPoint(maskPixmap, maskGC, i, j);
+            }
+        }
+    }
+
+    GrDestroyGC(pixmapGC);
+    if (hasMask)
+        GrDestroyGC(maskGC);
+    
+    return TRUE;
+#else
+    // !wxUSE_NANOX
+    
     UnRef();
 
     wxCHECK_MSG( image.Ok(), FALSE, wxT("invalid image") )
@@ -386,7 +527,7 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
     Window xroot = RootWindow( xdisplay, xscreen );
     Visual* xvisual = DefaultVisual( xdisplay, xscreen );
     
-    int bpp = DefaultDepth( xdisplay, xscreen );
+    int bpp = wxTheApp->m_visualDepth;
     
     int width = image.GetWidth();
     int height = image.GetHeight();
@@ -436,20 +577,6 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
             SetMask( mask );
         }
 
-        // Retrieve info
-
-        XVisualInfo vinfo_template;
-        XVisualInfo *vi;
-
-        vinfo_template.visual = xvisual;
-        vinfo_template.visualid = XVisualIDFromVisual( xvisual );
-        vinfo_template.depth = bpp;
-        int nitem = 0;
-
-        vi = XGetVisualInfo( xdisplay, VisualIDMask|VisualDepthMask, &vinfo_template, &nitem );
-        wxASSERT_MSG( vi, wxT("No visual info") );
-
-        if ((bpp == 16) && (vi->red_mask != 0xf800)) bpp = 15;
         if (bpp < 8) bpp = 8;
 
         // Render
@@ -459,22 +586,22 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
 
         if (bpp > 8)
         {
-            if ((vi->red_mask > vi->green_mask) && (vi->green_mask > vi->blue_mask))      b_o = RGB;
-            else if ((vi->red_mask > vi->blue_mask) && (vi->blue_mask > vi->green_mask))  b_o = RBG;
-            else if ((vi->blue_mask > vi->red_mask) && (vi->red_mask > vi->green_mask))   b_o = BRG;
-            else if ((vi->blue_mask > vi->green_mask) && (vi->green_mask > vi->red_mask)) b_o = BGR;
-            else if ((vi->green_mask > vi->red_mask) && (vi->red_mask > vi->blue_mask))   b_o = GRB;
-            else if ((vi->green_mask > vi->blue_mask) && (vi->blue_mask > vi->red_mask))  b_o = GBR;
+            if ((wxTheApp->m_visualRedMask > wxTheApp->m_visualGreenMask) && (wxTheApp->m_visualGreenMask > wxTheApp->m_visualBlueMask))      b_o = RGB;
+            else if ((wxTheApp->m_visualRedMask > wxTheApp->m_visualBlueMask) && (wxTheApp->m_visualBlueMask > wxTheApp->m_visualGreenMask))  b_o = RBG;
+            else if ((wxTheApp->m_visualBlueMask > wxTheApp->m_visualRedMask) && (wxTheApp->m_visualRedMask > wxTheApp->m_visualGreenMask))   b_o = BRG;
+            else if ((wxTheApp->m_visualBlueMask > wxTheApp->m_visualGreenMask) && (wxTheApp->m_visualGreenMask > wxTheApp->m_visualRedMask)) b_o = BGR;
+            else if ((wxTheApp->m_visualGreenMask > wxTheApp->m_visualRedMask) && (wxTheApp->m_visualRedMask > wxTheApp->m_visualBlueMask))   b_o = GRB;
+            else if ((wxTheApp->m_visualGreenMask > wxTheApp->m_visualBlueMask) && (wxTheApp->m_visualBlueMask > wxTheApp->m_visualRedMask))  b_o = GBR;
         }
 
-        XFree( vi );
-
         int r_mask = image.GetMaskRed();
         int g_mask = image.GetMaskGreen();
         int b_mask = image.GetMaskBlue();
 
         unsigned char* data = image.GetData();
         wxASSERT_MSG( data, "No image data" );
+        
+        unsigned char *colorCube = wxTheApp->m_colorCube;
 
         bool hasMask = image.HasMask();
 
@@ -503,27 +630,7 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
                     case 8:
                     {
                         int pixel = 0;
-#if 0                        
-                        if (wxTheApp->m_colorCube)
-                        {
-                            pixel = wxTheApp->m_colorCube[ ((r & 0xf8) << 7) + ((g & 0xf8) << 2) + ((b & 0xf8) >> 3) ];
-                        }
-                        else
-                        {
-                            GdkColormap *cmap = gtk_widget_get_default_colormap();
-                            GdkColor *colors = cmap->colors;
-                            int max = 3 * (65536);
-    
-                            for (int i = 0; i < cmap->size; i++)
-                            {
-                                int rdiff = (r << 8) - colors[i].red;
-                                int gdiff = (g << 8) - colors[i].green;
-                                int bdiff = (b << 8) - colors[i].blue;
-                                int sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
-                                if (sum < max) { pixel = i; max = sum; }
-                            }
-                        }
-#endif    
+                        pixel = colorCube[ ((r & 0xf8) << 7) + ((g & 0xf8) << 2) + ((b & 0xf8) >> 3) ];
                         XPutPixel( data_image, x, y, pixel );
                         break;
                     }
@@ -598,7 +705,6 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
 
         GC gc = XCreateGC( xdisplay, (Pixmap) M_BMPDATA->m_pixmap, 0, NULL );
         XPutImage( xdisplay, (Pixmap) M_BMPDATA->m_pixmap, gc, data_image, 0, 0, 0, 0, width, height );
-
         XDestroyImage( data_image );
         XFreeGC( xdisplay, gc );
 
@@ -607,7 +713,7 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
         if (image.HasMask())
         {
             GC gc = XCreateGC( xdisplay, (Pixmap) GetMask()->GetBitmap(), 0, NULL );
-            XPutImage( xdisplay, (Pixmap) GetMask()->GetBitmap(), gc, data_image, 0, 0, 0, 0, width, height );
+            XPutImage( xdisplay, (Pixmap) GetMask()->GetBitmap(), gc, mask_image, 0, 0, 0, 0, width, height );
 
             XDestroyImage( mask_image );
             XFreeGC( xdisplay, gc );
@@ -615,24 +721,8 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
     }
 
     return TRUE;
-}
-
-static void wxCalcPrecAndShift( unsigned long mask, int *shift, int *prec )
-{
-  *shift = 0;
-  *prec = 0;
-
-  while (!(mask & 0x1))
-    {
-      (*shift)++;
-      mask >>= 1;
-    }
-
-  while (mask & 0x1)
-    {
-      (*prec)++;
-      mask >>= 1;
-    }
+#endif
+    // wxUSE_NANOX
 }
 
 wxImage wxBitmap::ConvertToImage() const
@@ -643,12 +733,14 @@ wxImage wxBitmap::ConvertToImage() const
 
     Display *xdisplay = (Display*) M_BMPDATA->m_display;
     wxASSERT_MSG( xdisplay, wxT("No display") );
-    
-    int xscreen = DefaultScreen( xdisplay );
-    Visual* xvisual = DefaultVisual( xdisplay, xscreen );
-    
-    int bpp = DefaultDepth( xdisplay, xscreen );
-    
+
+#if wxUSE_NANOX
+    //int bpp = DefaultDepth(xdisplay, xscreen);
+    wxGetImageFromDrawable((Pixmap) GetPixmap(), 0, 0, GetWidth(), GetHeight(), image);
+    return image;
+#else
+    // !wxUSE_NANOX
+    int bpp = wxTheApp->m_visualDepth;
     XImage *x_image = NULL;
     if (GetPixmap())
     {
@@ -701,53 +793,29 @@ wxImage wxBitmap::ConvertToImage() const
 
     if (GetPixmap())
     {
-        // Retrieve info
-
-        XVisualInfo vinfo_template;
-        XVisualInfo *vi;
-
-        vinfo_template.visual = xvisual;
-        vinfo_template.visualid = XVisualIDFromVisual( xvisual );
-        vinfo_template.depth = bpp;
-        int nitem = 0;
-
-        vi = XGetVisualInfo( xdisplay, VisualIDMask|VisualDepthMask, &vinfo_template, &nitem );
-        wxASSERT_MSG( vi, wxT("No visual info") );
-        
-        int red_prec,green_prec,blue_prec;
-        int red_shift,green_shift,blue_shift;
-        wxCalcPrecAndShift( vi->red_mask, &red_shift, &red_prec );
-        wxCalcPrecAndShift( vi->green_mask, &green_shift, &green_prec );
-        wxCalcPrecAndShift( vi->blue_mask, &blue_shift, &blue_prec );
-        if (bpp == 16) bpp = red_prec + green_prec + blue_prec;
-        
-        red_shift_right = red_shift;
-        red_shift_left = 8-red_prec;
-        green_shift_right = green_shift;
-        green_shift_left = 8-green_prec;
-        blue_shift_right = blue_shift;
-        blue_shift_left = 8-blue_prec;
+        red_shift_right = wxTheApp->m_visualRedShift;
+        red_shift_left = 8-wxTheApp->m_visualRedPrec;
+        green_shift_right = wxTheApp->m_visualGreenShift;
+        green_shift_left = 8-wxTheApp->m_visualGreenPrec;
+        blue_shift_right = wxTheApp->m_visualBlueShift;
+        blue_shift_left = 8-wxTheApp->m_visualBluePrec;
         
-#if 0
-        use_shift = (vi->visual->c_class == TrueColor) || (vi->visual->c_class == DirectColor);
-#else
-        use_shift = TRUE;
-#endif
-        
-        XFree( vi );
+        use_shift = (wxTheApp->m_visualType == GrayScale) || (wxTheApp->m_visualType != PseudoColor);
     }
+    
     if (GetBitmap())
     {
         bpp = 1;
     }
 
+    XColor *colors = (XColor*) wxTheApp->m_visualColormap;
 
-//    GdkColormap *cmap = gtk_widget_get_default_colormap();
-
+    int width = GetWidth();
+    int height = GetHeight();
     long pos = 0;
-    for (int j = 0; j < GetHeight(); j++)
+    for (int j = 0; j < height; j++)
     {
-        for (int i = 0; i < GetWidth(); i++)
+        for (int i = 0; i < width; i++)
         {
             unsigned long pixel = XGetPixel( x_image, i, j );
             if (bpp == 1)
@@ -771,14 +839,12 @@ wxImage wxBitmap::ConvertToImage() const
                 data[pos+1] = (pixel >> green_shift_right) << green_shift_left;
                 data[pos+2] = (pixel >> blue_shift_right)  << blue_shift_left;
             }
-#if 0
-            else if (cmap->colors)
+            else if (colors)
             {
-                data[pos] =   cmap->colors[pixel].red   >> 8;
-                data[pos+1] = cmap->colors[pixel].green >> 8;
-                data[pos+2] = cmap->colors[pixel].blue  >> 8;
+                data[pos] =   colors[pixel].red   >> 8;
+                data[pos+1] = colors[pixel].green >> 8;
+                data[pos+2] = colors[pixel].blue  >> 8;
             }
-#endif
             else
             {
                 wxFAIL_MSG( wxT("Image conversion failed. Unknown visual type.") );
@@ -801,8 +867,9 @@ wxImage wxBitmap::ConvertToImage() const
 
     XDestroyImage( x_image );
     if (x_image_mask) XDestroyImage( x_image_mask );
-
     return image;
+#endif
+    // wxUSE_NANOX
 }
 
 wxBitmap::wxBitmap( const wxBitmap& bmp )
@@ -817,6 +884,7 @@ wxBitmap::wxBitmap( const wxString &filename, int type )
 
 wxBitmap::wxBitmap( const char bits[], int width, int height, int WXUNUSED(depth) )
 {
+#if !wxUSE_NANOX
     m_refData = new wxBitmapRefData();
 
     M_BMPDATA->m_display = wxGlobalDisplay();
@@ -831,7 +899,7 @@ wxBitmap::wxBitmap( const char bits[], int width, int height, int WXUNUSED(depth
     M_BMPDATA->m_width = width;
     M_BMPDATA->m_height = height;
     M_BMPDATA->m_bpp = 1;
-
+#endif
     wxCHECK_RET( M_BMPDATA->m_bitmap, wxT("couldn't create bitmap") );
 }
 
@@ -970,6 +1038,8 @@ bool wxBitmap::LoadFile( const wxString &name, int type )
 
     if (type == wxBITMAP_TYPE_XPM)
     {
+#if wxUSE_XPM
+#if wxHAVE_LIB_XPM
         m_refData = new wxBitmapRefData();
 
         M_BMPDATA->m_display = wxGlobalDisplay();
@@ -1013,6 +1083,29 @@ bool wxBitmap::LoadFile( const wxString &name, int type )
             
             return FALSE;
         }
+#else
+#if wxUSE_STREAMS
+       wxXPMDecoder decoder;
+       wxFileInputStream stream(name);
+       if (stream.Ok())
+       {
+            wxImage image(decoder.ReadFile(stream));
+           if (image.Ok())
+               return CreateFromImage(image);
+           else
+               return FALSE;
+       }
+       else
+           return FALSE;
+#else
+       return FALSE;
+#endif
+       // wxUSE_STREAMS
+#endif
+       // wxHAVE_LIB_XPM
+#endif
+       // wxUSE_XPM
+       return FALSE;
     }
     else // try if wxImage can load it
     {
@@ -1088,3 +1181,140 @@ WXDisplay *wxBitmap::GetDisplay() const
     return M_BMPDATA->m_display;
 }
 
+#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
+