+wxBitmap::~wxBitmap()
+{
+}
+
+bool wxBitmap::Create( int width, int height, int depth )
+{
+    UnRef();
+
+    if ( width <= 0 || height <= 0 )
+    {
+        return false;
+    }
+
+    if (depth == 32)
+    {
+        SetPixbuf(gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, width, height), 32);
+    }
+    else
+    {
+        if (depth != 1)
+        {
+            const GdkVisual* visual = wxTheApp->GetGdkVisual();
+            if (depth == -1)
+                depth = visual->depth;
+
+            wxCHECK_MSG(depth == visual->depth, false, wxT("invalid bitmap depth"));
+        }
+
+        SetPixmap(gdk_pixmap_new(wxGetRootWindow()->window, width, height, depth));
+    }
+
+    return Ok();
+}
+
+wxBitmap wxBitmap::Rescale(int clipx, int clipy, int clipwidth, int clipheight, int newx, int newy) const
+{
+    wxBitmap bmp;
+
+    wxCHECK_MSG(Ok(), bmp, wxT("invalid bitmap"));
+
+    if (newy==M_BMPDATA->m_width && newy==M_BMPDATA->m_height)
+        return *this;
+
+    int width = wxMax(newx, 1);
+    int height = wxMax(newy, 1);
+    width = wxMin(width, clipwidth);
+    height = wxMin(height, clipheight);
+
+    // scale pixbuf if available and it has alpha or there is no mask
+    if (M_BMPDATA->m_pixbuf != NULL && (
+        M_BMPDATA->m_mask == NULL || gdk_pixbuf_get_has_alpha(M_BMPDATA->m_pixbuf)))
+    {
+        bmp.SetPixbuf(gdk_pixbuf_new(GDK_COLORSPACE_RGB,
+                                     gdk_pixbuf_get_has_alpha(M_BMPDATA->m_pixbuf),
+                                     8, width, height), M_BMPDATA->m_bpp);
+        gdk_pixbuf_scale(M_BMPDATA->m_pixbuf, bmp.GetPixbuf(),
+                         0, 0, width, height,
+                         clipx, clipy,
+                         (double)newx/GetWidth(), (double)newy/GetHeight(),
+                         GDK_INTERP_BILINEAR);
+    }
+    else
+    {
+        GdkImage* img = gdk_drawable_get_image(
+            M_BMPDATA->m_pixmap, 0, 0, M_BMPDATA->m_width, M_BMPDATA->m_height);
+
+        wxCHECK_MSG(img, bmp, wxT("couldn't create image"));
+
+        GdkGC *gc = NULL;
+        GdkPixmap *dstpix = NULL;
+        char *dst = NULL;
+        long dstbyteperline = 0;
+
+        if (GetDepth() != 1)
+        {
+            bmp.Create(width, height, gdk_drawable_get_depth(M_BMPDATA->m_pixmap));
+            dstpix = bmp.GetPixmap();
+            gc = gdk_gc_new( dstpix );
+        }
+        else
+        {
+            dstbyteperline = (width + 7) / 8;
+            dst = (char*) malloc(dstbyteperline*height);
+        }
+
+        // be careful to use the right scaling factor
+        float scx = (float)M_BMPDATA->m_width/(float)newx;
+        float scy = (float)M_BMPDATA->m_height/(float)newy;
+        // prepare accel-tables
+        int *tablex = (int *)calloc(width,sizeof(int));
+        int *tabley = (int *)calloc(height,sizeof(int));
+
+        // accel table filled with clipped values
+        for (int x = 0; x < width; x++)
+            tablex[x] = (int) (scx * (x+clipx));
+        for (int y = 0; y < height; y++)
+            tabley[y] = (int) (scy * (y+clipy));
+
+        // Main rescaling routine starts here
+        for (int h = 0; h < height; h++)
+        {
+            char outbyte = 0;
+            int old_x = -1;
+            guint32 old_pixval = 0;
+
+            for (int w = 0; w < width; w++)
+            {
+                guint32 pixval;
+                int x = tablex[w];
+                if (x == old_x)
+                    pixval = old_pixval;
+                else
+                {
+                    pixval = gdk_image_get_pixel( img, x, tabley[h] );
+                    old_pixval = pixval;
+                    old_x = x;
+                }
+
+                if ( dst )
+                {
+                    if (pixval)
+                    {
+                        char bit=1;
+                        char shift = bit << (w % 8);
+                        outbyte |= shift;
+                    }
+
+                    if ((w+1)%8==0)
+                    {
+                        dst[h*dstbyteperline+w/8] = outbyte;
+                        outbyte = 0;
+                    }
+                }
+                else
+                {
+                    GdkColor col;
+                    col.pixel = pixval;
+                    gdk_gc_set_foreground( gc, &col );
+                    gdk_draw_point( dstpix, gc, w, h);
+                }
+            }
+
+            // do not forget the last byte
+            if ( dst && (width % 8 != 0) )
+                dst[h*dstbyteperline+width/8] = outbyte;
+        }
+
+        g_object_unref (img);
+        if (gc) g_object_unref (gc);
+
+        if ( dst )
+        {
+            bmp = wxBitmap(dst, width, height, 1);
+            free( dst );
+        }
+
+        if (GetMask())
+        {
+            dstbyteperline = (width + 7) / 8;
+            dst = (char*) malloc(dstbyteperline*height);
+            img = gdk_drawable_get_image(GetMask()->GetBitmap(), 0, 0, GetWidth(), GetHeight());
+
+            for (int h = 0; h < height; h++)
+            {
+                char outbyte = 0;
+                int old_x = -1;
+                guint32 old_pixval = 0;
+
+                for (int w = 0; w < width; w++)
+                {
+                    guint32 pixval;
+                    int x = tablex[w];
+                    if (x == old_x)
+                        pixval = old_pixval;
+                    else
+                    {
+                        pixval = gdk_image_get_pixel( img, x, tabley[h] );
+                        old_pixval = pixval;
+                        old_x = x;
+                    }
+
+                    if (pixval)
+                    {
+                        char bit=1;
+                        char shift = bit << (w % 8);
+                        outbyte |= shift;
+                    }
+
+                    if ((w+1)%8 == 0)
+                    {
+                        dst[h*dstbyteperline+w/8] = outbyte;
+                        outbyte = 0;
+                    }
+                }
+
+                // do not forget the last byte
+                if (width % 8 != 0)
+                    dst[h*dstbyteperline+width/8] = outbyte;
+            }
+            wxMask* mask = new wxMask;
+            mask->m_bitmap = gdk_bitmap_create_from_data( wxGetRootWindow()->window, (gchar *) dst, width, height );
+            bmp.SetMask(mask);
+
+            free( dst );
+            g_object_unref (img);
+        }
+
+        free( tablex );
+        free( tabley );
+    }
+
+    return bmp;
+}
+
+bool wxBitmap::CreateFromImage(const wxImage& image, int depth)
+{
+    UnRef();
+
+    wxCHECK_MSG( image.Ok(), false, wxT("invalid image") );
+    wxCHECK_MSG( depth == -1 || depth == 1, false, wxT("invalid bitmap depth") );
+
+    if (image.GetWidth() <= 0 || image.GetHeight() <= 0)
+        return false;
+
+    // create pixbuf if image has alpha and requested depth is compatible
+    if (image.HasAlpha() && (depth == -1 || depth == 32))
+        return CreateFromImageAsPixbuf(image);
+
+    // otherwise create pixmap, if alpha is present it will be converted to mask
+    return CreateFromImageAsPixmap(image, depth);
+}
+
+bool wxBitmap::CreateFromImageAsPixmap(const wxImage& image, int depth)
+{
+    const int w = image.GetWidth();
+    const int h = image.GetHeight();
+    if (depth == 1)
+    {
+        // create XBM format bitmap
+
+        // one bit per pixel, each row starts on a byte boundary
+        const size_t out_size = size_t((w + 7) / 8) * unsigned(h);
+        wxByte* out = new wxByte[out_size];
+        // set bits are black
+        memset(out, 0xff, out_size);
+        const wxByte* in = image.GetData();
+        unsigned bit_index = 0;
+        for (int y = 0; y < h; y++)
+        {
+            for (int x = 0; x < w; x++, in += 3, bit_index++)
+                if (in[0] == 255 && in[1] == 255 && in[2] == 255)
+                    out[bit_index >> 3] ^= 1 << (bit_index & 7);
+            // move index to next byte boundary
+            bit_index = (bit_index + 7) & ~7u;
+        }
+        SetPixmap(gdk_bitmap_create_from_data(wxGetRootWindow()->window, (char*)out, w, h));
+        delete[] out;
+    }
+    else
+    {
+        SetPixmap(gdk_pixmap_new(wxGetRootWindow()->window, w, h, depth));
+        GdkGC* gc = gdk_gc_new(M_BMPDATA->m_pixmap);
+        gdk_draw_rgb_image(
+            M_BMPDATA->m_pixmap, gc,
+            0, 0, w, h,
+            GDK_RGB_DITHER_NONE, image.GetData(), w * 3);
+        g_object_unref(gc);
+    }
+
+    const wxByte* alpha = image.GetAlpha();
+    if (alpha != NULL || image.HasMask())
+    {
+        // create mask as XBM format bitmap
+
+        const size_t out_size = size_t((w + 7) / 8) * unsigned(h);
+        wxByte* out = new wxByte[out_size];
+        memset(out, 0xff, out_size);
+        unsigned bit_index = 0;
+        if (alpha != NULL)
+        {
+            for (int y = 0; y < h; y++)
+            {
+                for (int x = 0; x < w; x++, bit_index++)
+                    if (*alpha++ < wxIMAGE_ALPHA_THRESHOLD)
+                        out[bit_index >> 3] ^= 1 << (bit_index & 7);
+                bit_index = (bit_index + 7) & ~7u;
+            }
+        }
+        else
+        {
+            const wxByte r_mask = image.GetMaskRed();
+            const wxByte g_mask = image.GetMaskGreen();
+            const wxByte b_mask = image.GetMaskBlue();
+            const wxByte* in = image.GetData();
+            for (int y = 0; y < h; y++)
+            {
+                for (int x = 0; x < w; x++, in += 3, bit_index++)
+                    if (in[0] == r_mask && in[1] == g_mask && in[2] == b_mask)
+                        out[bit_index >> 3] ^= 1 << (bit_index & 7);
+                bit_index = (bit_index + 7) & ~7u;
+            }
+        }
+        wxMask* mask = new wxMask;
+        mask->m_bitmap = gdk_bitmap_create_from_data(M_BMPDATA->m_pixmap, (char*)out, w, h);
+        SetMask(mask);
+        delete[] out;
+    }
+    return true;
+}
+
+bool wxBitmap::CreateFromImageAsPixbuf(const wxImage& image)
+{
+    wxASSERT(image.HasAlpha());
+
+    int width = image.GetWidth();
+    int height = image.GetHeight();
+
+    Create(width, height, 32);
+    GdkPixbuf* pixbuf = M_BMPDATA->m_pixbuf;
+    if (!pixbuf)
+        return false;
+
+    // Copy the data:
+    const unsigned char* in = image.GetData();
+    unsigned char *out = gdk_pixbuf_get_pixels(pixbuf);
+    unsigned char *alpha = image.GetAlpha();
+
+    int rowpad = gdk_pixbuf_get_rowstride(pixbuf) - 4 * width;
+
+    for (int y = 0; y < height; y++, out += rowpad)
+    {
+        for (int x = 0; x < width; x++, alpha++, out += 4, in += 3)
+        {
+            out[0] = in[0];
+            out[1] = in[1];
+            out[2] = in[2];
+            out[3] = *alpha;
+        }
+    }
+
+    return true;