]> git.saurik.com Git - wxWidgets.git/blobdiff - src/x11/dcclient.cpp
ensure that the copies of the bitmap passed to wxMemoryDC ctor are not modified when...
[wxWidgets.git] / src / x11 / dcclient.cpp
index 13cfe8ad9ab98006b61d618f9acf9211ff468775..ec9b8826b55068bc37df8ea2e70570a265d98a21 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        x11/dcclient.cpp
+// Name:        src/x11/dcclient.cpp
 // Purpose:     wxClientDC class
 // Author:      Julian Smart, Robert Roebling
 // Modified by:
@@ -9,25 +9,42 @@
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-    #pragma implementation "dcclient.h"
-#endif
+// for compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
 
 #include "wx/dcclient.h"
-#include "wx/dcmemory.h"
-#include "wx/window.h"
-#include "wx/app.h"
-#include "wx/image.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/app.h"
+    #include "wx/window.h"
+    #include "wx/math.h"
+    #include "wx/image.h"
+    #include "wx/module.h"
+#endif
+
+#include "wx/fontutil.h"
+#include "wx/vector.h"
 
 #include "wx/x11/private.h"
+#include "wx/x11/dcclient.h"
+#include "wx/x11/dcmemory.h"
+
+#if wxUSE_UNICODE
+#include "glib.h"
+#include "pango/pangox.h"
+#ifdef HAVE_PANGO_XFT
+    #include "pango/pangoxft.h"
+#endif
 
-#include <math.h>
+#include "pango_x.cpp"
+#endif
 
 //-----------------------------------------------------------------------------
 // local defines
 //-----------------------------------------------------------------------------
 
-#define USE_PAINT_REGION 1
+// VZ: what is this for exactly??
+#define USE_PAINT_REGION 0
 
 //-----------------------------------------------------------------------------
 // local data
@@ -117,11 +134,11 @@ static GC wxGetPoolGC( Window window, wxPoolGCType type )
             wxGCPool[i].m_gc = XCreateGC( wxGlobalDisplay(), window, 0, NULL );
             XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool[i].m_gc, FALSE );
             wxGCPool[i].m_type = type;
-            wxGCPool[i].m_used = FALSE;
+            wxGCPool[i].m_used = false;
         }
         if ((!wxGCPool[i].m_used) && (wxGCPool[i].m_type == type))
         {
-            wxGCPool[i].m_used = TRUE;
+            wxGCPool[i].m_used = true;
             return wxGCPool[i].m_gc;
         }
     }
@@ -137,7 +154,7 @@ static void wxFreePoolGC( GC gc )
     {
         if (wxGCPool[i].m_gc == gc)
         {
-            wxGCPool[i].m_used = FALSE;
+            wxGCPool[i].m_used = false;
             return;
         }
     }
@@ -149,49 +166,40 @@ static void wxFreePoolGC( GC gc )
 // wxWindowDC
 // ----------------------------------------------------------------------------
 
-IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC)
+IMPLEMENT_ABSTRACT_CLASS(wxWindowDCImpl, wxX11DCImpl)
 
-wxWindowDC::wxWindowDC()
+wxWindowDCImpl::wxWindowDCImpl( wxDC *owner )
+  : wxX11DCImpl( owner )
 {
-    m_display = (WXDisplay *) NULL;
-    m_penGC = (WXGC *) NULL;
-    m_brushGC = (WXGC *) NULL;
-    m_textGC = (WXGC *) NULL;
-    m_bgGC = (WXGC *) NULL;
-    m_cmap = (WXColormap *) NULL;
-    m_isMemDC = FALSE;
-    m_isScreenDC = FALSE;
-    m_owner = (wxWindow *)NULL;
+    Init();
 }
 
-wxWindowDC::wxWindowDC( wxWindow *window )
+wxWindowDCImpl::wxWindowDCImpl( wxDC* owner, wxWindow *window )
+  : wxX11DCImpl( owner )
 {
     wxASSERT_MSG( window, wxT("DC needs a window") );
 
-    m_display = (WXDisplay *) NULL;
-    m_penGC = (WXGC *) NULL;
-    m_brushGC = (WXGC *) NULL;
-    m_textGC = (WXGC *) NULL;
-    m_bgGC = (WXGC *) NULL;
-    m_cmap = (WXColormap *) NULL;
-    m_owner = (wxWindow *)NULL;
-    m_isMemDC = FALSE;
-    m_isScreenDC = FALSE;
+    Init();
+
     m_font = window->GetFont();
 
-    m_window = (WXWindow*) window->GetMainWindow();
+    m_x11window = (WXWindow*) window->GetMainWindow();
 
     // not realized ?
-    if (!m_window)
+    if (!m_x11window)
     {
          // don't report problems
-         m_ok = TRUE;
+         m_ok = true;
 
          return;
     }
 
     m_display = (WXDisplay *) wxGlobalDisplay();
-    
+
+#if wxUSE_UNICODE
+    m_fontdesc = window->GetFont().GetNativeFontInfo()->description;
+#endif
+
     int screen = DefaultScreen( (Display*) m_display );
     m_cmap = (WXColormap) DefaultColormap( (Display*) m_display, screen );
 
@@ -199,46 +207,72 @@ wxWindowDC::wxWindowDC( wxWindow *window )
 
     /* this must be done after SetUpDC, bacause SetUpDC calls the
        repective SetBrush, SetPen, SetBackground etc functions
-       to set up the DC. SetBackground call m_owner->SetBackground
+       to set up the DC. SetBackground call m_window->SetBackground
        and this might not be desired as the standard dc background
        is white whereas a window might assume gray to be the
        standard (as e.g. wxStatusBar) */
 
-    m_owner = window;
+    m_window = window;
 }
 
-wxWindowDC::~wxWindowDC()
+wxWindowDCImpl::~wxWindowDCImpl()
 {
     Destroy();
 }
 
-void wxWindowDC::SetUpDC()
+void wxWindowDCImpl::Init()
 {
-    m_ok = TRUE;
+    m_display = (WXDisplay *) NULL;
+    m_penGC = (WXGC *) NULL;
+    m_brushGC = (WXGC *) NULL;
+    m_textGC = (WXGC *) NULL;
+    m_bgGC = (WXGC *) NULL;
+    m_cmap = (WXColormap *) NULL;
+    m_isMemDC = false;
+    m_isScreenDC = false;
+    m_x11window = (WXWindow*) NULL;
+
+#if wxUSE_UNICODE
+    m_context = wxTheApp->GetPangoContext();
+    m_fontdesc = (PangoFontDescription *)NULL;
+#endif
+}
+
+void wxWindowDCImpl::SetUpDC()
+{
+    m_ok = true;
 
     wxASSERT_MSG( !m_penGC, wxT("GCs already created") );
 
+    bool ismono = false;
+    if (m_isMemDC)
+    {
+        wxMemoryDCImpl *mem_impl = (wxMemoryDCImpl *) this;
+        if (mem_impl->GetSelectedBitmap().IsOk())
+            ismono = mem_impl->GetSelectedBitmap().GetDepth() == 1;
+    }
+
     if (m_isScreenDC)
     {
-        m_penGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxPEN_SCREEN );
-        m_brushGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxBRUSH_SCREEN );
-        m_textGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxTEXT_SCREEN );
-        m_bgGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxBG_SCREEN );
+        m_penGC = (WXGC*) wxGetPoolGC( (Window) m_x11window, wxPEN_SCREEN );
+        m_brushGC = (WXGC*) wxGetPoolGC( (Window) m_x11window, wxBRUSH_SCREEN );
+        m_textGC = (WXGC*) wxGetPoolGC( (Window) m_x11window, wxTEXT_SCREEN );
+        m_bgGC = (WXGC*) wxGetPoolGC( (Window) m_x11window, wxBG_SCREEN );
     }
     else
-    if (m_isMemDC && (((wxMemoryDC*)this)->m_selected.GetDepth() == 1))
+    if (m_isMemDC && ismono)
     {
-        m_penGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxPEN_MONO );
-        m_brushGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxBRUSH_MONO );
-        m_textGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxTEXT_MONO );
-        m_bgGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxBG_MONO );
+        m_penGC = (WXGC*) wxGetPoolGC( (Window) m_x11window, wxPEN_MONO );
+        m_brushGC = (WXGC*) wxGetPoolGC( (Window) m_x11window, wxBRUSH_MONO );
+        m_textGC = (WXGC*) wxGetPoolGC( (Window) m_x11window, wxTEXT_MONO );
+        m_bgGC = (WXGC*) wxGetPoolGC( (Window) m_x11window, wxBG_MONO );
     }
     else
     {
-        m_penGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxPEN_COLOUR );
-        m_brushGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxBRUSH_COLOUR );
-        m_textGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxTEXT_COLOUR );
-        m_bgGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxBG_COLOUR );
+        m_penGC = (WXGC*) wxGetPoolGC( (Window) m_x11window, wxPEN_COLOUR );
+        m_brushGC = (WXGC*) wxGetPoolGC( (Window) m_x11window, wxBRUSH_COLOUR );
+        m_textGC = (WXGC*) wxGetPoolGC( (Window) m_x11window, wxTEXT_COLOUR );
+        m_bgGC = (WXGC*) wxGetPoolGC( (Window) m_x11window, wxBG_COLOUR );
     }
 
     /* background colour */
@@ -246,6 +280,9 @@ void wxWindowDC::SetUpDC()
     m_backgroundBrush.GetColour().CalcPixel( m_cmap );
     unsigned long bg_col = m_backgroundBrush.GetColour().GetPixel();
 
+    m_textForegroundColour = *wxBLACK;
+    m_textBackgroundColour = *wxWHITE;
+
     /* m_textGC */
     m_textForegroundColour.CalcPixel( m_cmap );
     XSetForeground( (Display*) m_display, (GC) m_textGC, m_textForegroundColour.GetPixel() );
@@ -277,7 +314,7 @@ void wxWindowDC::SetUpDC()
     /* m_bgGC */
     XSetForeground( (Display*) m_display, (GC) m_bgGC, bg_col );
     XSetBackground( (Display*) m_display, (GC) m_bgGC, bg_col );
-    
+
     XSetFillStyle( (Display*) m_display, (GC) m_bgGC, FillSolid );
 
     /* ROPs */
@@ -295,7 +332,7 @@ void wxWindowDC::SetUpDC()
     {
         int xscreen = DefaultScreen( (Display*) m_display );
         Window xroot = RootWindow( (Display*) m_display, xscreen );
-    
+
         hatch_bitmap    = hatches;
         hatch_bitmap[0] = XCreateBitmapFromData( (Display*) m_display, xroot, bdiag_bits, bdiag_width, bdiag_height );
         hatch_bitmap[1] = XCreateBitmapFromData( (Display*) m_display, xroot, cdiag_bits, cdiag_width, cdiag_height );
@@ -306,99 +343,86 @@ void wxWindowDC::SetUpDC()
     }
 }
 
-void wxWindowDC::DoGetSize( int* width, int* height ) const
+void wxWindowDCImpl::DoGetSize( int* width, int* height ) const
 {
-    wxCHECK_RET( m_owner, _T("GetSize() doesn't work without window") );
+    wxCHECK_RET( m_window, _T("GetSize() doesn't work without window") );
 
-    m_owner->GetSize(width, height);
+    m_window->GetSize(width, height);
 }
 
-void wxWindowDC::DoFloodFill( wxCoord x, wxCoord y,
-                           const wxColour & col, int style )
-{
-    if (GetBrush().GetStyle() == wxTRANSPARENT)
-    {
-        wxLogDebug(wxT("In FloodFill, current brush is transparent, no filling done"));
-        return ;
-    }
-    int height = 0;
-    int width  = 0;
-    this->GetSize(&width, &height);
-    //it would be nice to fail if we don't get a sensible size...
-    if (width < 1 || height < 1)
-    {
-        wxLogError(wxT("In FloodFill, dc.GetSize routine failed, method not supported by this DC"));
-        return ;
-    }
-
-    //this is much faster than doing the individual pixels
-    wxMemoryDC memdc;
-    wxBitmap bitmap(width, height);
-    memdc.SelectObject(bitmap);
-    memdc.Blit(0, 0, width, height, (wxDC*) this, 0, 0);
-    memdc.SelectObject(wxNullBitmap);
+extern bool wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y,
+                          const wxColour & col, int style);
 
-    wxImage image(bitmap);
-    image.DoFloodFill (x,y, GetBrush(), col, style, GetLogicalFunction());
-    bitmap = wxBitmap(image);
-    memdc.SelectObject(bitmap);
-    this->Blit(0, 0, width, height, &memdc, 0, 0);
-    memdc.SelectObject(wxNullBitmap);
+bool wxWindowDCImpl::DoFloodFill(wxCoord x, wxCoord y,
+                             const wxColour& col, int style)
+{
+    return wxDoFloodFill(GetOwner(), x, y, col, style);
 }
 
-bool wxWindowDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const
+bool wxWindowDCImpl::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const
 {
     // Generic (and therefore rather inefficient) method.
     // Could be improved.
     wxMemoryDC memdc;
     wxBitmap bitmap(1, 1);
     memdc.SelectObject(bitmap);
-    memdc.Blit(0, 0, 1, 1, (wxDC*) this, x1, y1);
+    memdc.Blit(0, 0, 1, 1, GetOwner(), x1, y1);
     memdc.SelectObject(wxNullBitmap);
-    wxImage image(bitmap);
+    wxImage image(bitmap.ConvertToImage());
     col->Set(image.GetRed(0, 0), image.GetGreen(0, 0), image.GetBlue(0, 0));
-    return TRUE;
+    return true;
 }
 
-void wxWindowDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 )
+void wxWindowDCImpl::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     if (m_pen.GetStyle() != wxTRANSPARENT)
     {
-        if (m_window)
-            XDrawLine( (Display*) m_display, (Window) m_window, 
-                (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
+        if (m_x11window)
+        {
+            // This hack is for the iPaq: XDrawLine draws
+            // nothing, whereas XDrawLines works...
+            wxPoint points[2];
+            points[0].x = x1;
+            points[0].y = y1;
+            points[1].x = x2;
+            points[1].y = y2;
+            DoDrawLines( 2, points, 0, 0 );
+
+            // XDrawLine( (Display*) m_display, (Window) m_x11window,
+            //    (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
+        }
 
         CalcBoundingBox(x1, y1);
         CalcBoundingBox(x2, y2);
     }
 }
 
-void wxWindowDC::DoCrossHair( wxCoord x, wxCoord y )
+void wxWindowDCImpl::DoCrossHair( wxCoord x, wxCoord y )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     if (m_pen.GetStyle() != wxTRANSPARENT)
     {
         int w = 0;
         int h = 0;
-        GetSize( &w, &h );
+        DoGetSize( &w, &h );
         wxCoord xx = XLOG2DEV(x);
         wxCoord yy = YLOG2DEV(y);
-        if (m_window)
+        if (m_x11window)
         {
-            XDrawLine( (Display*) m_display, (Window) m_window,
+            XDrawLine( (Display*) m_display, (Window) m_x11window,
                 (GC) m_penGC, 0, yy, XLOG2DEVREL(w), yy );
-            XDrawLine( (Display*) m_display, (Window) m_window,
+            XDrawLine( (Display*) m_display, (Window) m_x11window,
                 (GC) m_penGC, xx, 0, xx, YLOG2DEVREL(h) );
         }
     }
 }
 
-void wxWindowDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc )
+void wxWindowDCImpl::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     wxCoord xx1 = XLOG2DEV(x1);
     wxCoord yy1 = YLOG2DEV(y1);
@@ -436,7 +460,7 @@ void wxWindowDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCo
     while (alpha2 <= 0) alpha2 += 360*64;
     while (alpha1 > 360*64) alpha1 -= 360*64;
 
-    if (m_window)
+    if (m_x11window)
     {
         if (m_brush.GetStyle() != wxTRANSPARENT)
         {
@@ -445,30 +469,30 @@ void wxWindowDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCo
                 XSetTSOrigin( (Display*) m_display, (GC) m_textGC,
                                       m_deviceOriginX % m_brush.GetStipple()->GetWidth(),
                                       m_deviceOriginY % m_brush.GetStipple()->GetHeight() );
-                                      
-                XFillArc( (Display*) m_display, (Window) m_window,
+
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 );
-                    
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_textGC, 0, 0 );
             } else
             if (IS_15_PIX_HATCH(m_brush.GetStyle()))
             {
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % 15, m_deviceOriginY % 15 );
-                                      
-                XFillArc( (Display*) m_display, (Window) m_window,
+
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 );
-                    
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             } else
             if (IS_16_PIX_HATCH(m_brush.GetStyle()))
             {
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % 16, m_deviceOriginY % 16 );
-                
-                XFillArc( (Display*) m_display, (Window) m_window,
+
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 );
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             } else
             if (m_brush.GetStyle() == wxSTIPPLE)
@@ -476,28 +500,28 @@ void wxWindowDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCo
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % m_brush.GetStipple()->GetWidth(),
                                       m_deviceOriginY % m_brush.GetStipple()->GetHeight() );
-                                      
-                XFillArc( (Display*) m_display, (Window) m_window,
+
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 );
-                    
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             }
             else
             {
-                XFillArc( (Display*) m_display, (Window) m_window,
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 );
             }
         }
 
         if (m_pen.GetStyle() != wxTRANSPARENT)
         {
-            XDrawArc( (Display*) m_display, (Window) m_window,
+            XDrawArc( (Display*) m_display, (Window) m_x11window,
                (GC) m_penGC, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 );
-               
-            XDrawLine( (Display*) m_display, (Window) m_window,
+
+            XDrawLine( (Display*) m_display, (Window) m_x11window,
                (GC) m_penGC, xx1, yy1, xxc, yyc );
-               
-            XDrawLine( (Display*) m_display, (Window) m_window,
+
+            XDrawLine( (Display*) m_display, (Window) m_x11window,
                (GC) m_penGC, xxc, yyc, xx2, yy2 );
         }
     }
@@ -506,9 +530,9 @@ void wxWindowDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCo
     CalcBoundingBox (x2, y2);
 }
 
-void wxWindowDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double sa, double ea )
+void wxWindowDCImpl::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double sa, double ea )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     wxCoord xx = XLOG2DEV(x);
     wxCoord yy = YLOG2DEV(y);
@@ -519,7 +543,7 @@ void wxWindowDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxCoord
     if (ww < 0) { ww = -ww; xx = xx - ww; }
     if (hh < 0) { hh = -hh; yy = yy - hh; }
 
-    if (m_window)
+    if (m_x11window)
     {
         wxCoord start = wxCoord(sa * 64.0);
         wxCoord end = wxCoord((ea-sa) * 64.0);
@@ -531,30 +555,30 @@ void wxWindowDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxCoord
                 XSetTSOrigin( (Display*) m_display, (GC) m_textGC,
                                       m_deviceOriginX % m_brush.GetStipple()->GetWidth(),
                                       m_deviceOriginY % m_brush.GetStipple()->GetHeight() );
-                
-                XFillArc( (Display*) m_display, (Window) m_window,
+
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_textGC, xx, yy, ww, hh, start, end );
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_textGC, 0, 0 );
             } else
             if (IS_15_PIX_HATCH(m_brush.GetStyle()))
             {
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % 15, m_deviceOriginY % 15 );
-                
-                XFillArc( (Display*) m_display, (Window) m_window,
+
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xx, yy, ww, hh, start, end );
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             } else
             if (IS_16_PIX_HATCH(m_brush.GetStyle()))
             {
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % 16, m_deviceOriginY % 16 );
-                
-                XFillArc( (Display*) m_display, (Window) m_window,
+
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xx, yy, ww, hh, start, end );
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             } else
             if (m_brush.GetStyle() == wxSTIPPLE)
@@ -562,22 +586,22 @@ void wxWindowDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxCoord
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % m_brush.GetStipple()->GetWidth(),
                                       m_deviceOriginY % m_brush.GetStipple()->GetHeight() );
-                
-                XFillArc( (Display*) m_display, (Window) m_window,
+
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xx, yy, ww, hh, start, end );
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             }
             else
             {
-                XFillArc( (Display*) m_display, (Window) m_window,
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xx, yy, ww, hh, start, end );
             }
         }
 
         if (m_pen.GetStyle() != wxTRANSPARENT)
         {
-            XDrawArc( (Display*) m_display, (Window) m_window,
+            XDrawArc( (Display*) m_display, (Window) m_x11window,
                 (GC) m_penGC, xx, yy, ww, hh, start, end );
         }
     }
@@ -586,20 +610,20 @@ void wxWindowDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxCoord
     CalcBoundingBox (x + width, y + height);
 }
 
-void wxWindowDC::DoDrawPoint( wxCoord x, wxCoord y )
+void wxWindowDCImpl::DoDrawPoint( wxCoord x, wxCoord y )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
-    if ((m_pen.GetStyle() != wxTRANSPARENT) && m_window)
-        XDrawPoint( (Display*) m_display, (Window) m_window,
+    if ((m_pen.GetStyle() != wxTRANSPARENT) && m_x11window)
+        XDrawPoint( (Display*) m_display, (Window) m_x11window,
                 (GC) m_penGC, XLOG2DEV(x), YLOG2DEV(y) );
 
     CalcBoundingBox (x, y);
 }
 
-void wxWindowDC::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset )
+void wxWindowDCImpl::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     if (m_pen.GetStyle() == wxTRANSPARENT) return;
     if (n <= 0) return;
@@ -609,18 +633,19 @@ void wxWindowDC::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCoord
     {
         xpoints[i].x = XLOG2DEV (points[i].x + xoffset);
         xpoints[i].y = YLOG2DEV (points[i].y + yoffset);
-        
+
         CalcBoundingBox( points[i].x + xoffset, points[i].y + yoffset );
     }
-    XDrawLines( (Display*) m_display, (Window) m_window, (GC) m_penGC, xpoints, n, 0 );
+    XDrawLines( (Display*) m_display, (Window) m_x11window, (GC) m_penGC, xpoints, n, 0 );
 
     delete[] xpoints;
 }
 
-void wxWindowDC::DoDrawPolygon( int n, wxPoint points[],
-                                wxCoord xoffset, wxCoord yoffset, int fillStyle )
+void wxWindowDCImpl::DoDrawPolygon( int n, wxPoint points[],
+                                wxCoord xoffset, wxCoord yoffset,
+                                int WXUNUSED(fillStyle) )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     if (n <= 0) return;
 
@@ -630,44 +655,44 @@ void wxWindowDC::DoDrawPolygon( int n, wxPoint points[],
     {
         xpoints[i].x = XLOG2DEV (points[i].x + xoffset);
         xpoints[i].y = YLOG2DEV (points[i].y + yoffset);
-        
+
         CalcBoundingBox (points[i].x + xoffset, points[i].y + yoffset);
     }
 
-    if (m_window)
+    if (m_x11window)
     {
         if (m_brush.GetStyle() != wxTRANSPARENT)
         {
-        
+
             if ((m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE) && (m_brush.GetStipple()->GetMask()))
             {
                 XSetTSOrigin( (Display*) m_display, (GC) m_textGC,
                                       m_deviceOriginX % m_brush.GetStipple()->GetWidth(),
                                       m_deviceOriginY % m_brush.GetStipple()->GetHeight() );
-                
-                XFillPolygon( (Display*) m_display, (Window) m_window,
+
+                XFillPolygon( (Display*) m_display, (Window) m_x11window,
                     (GC) m_textGC, xpoints, n, Complex, 0);
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_textGC, 0, 0 );
             } else
             if (IS_15_PIX_HATCH(m_brush.GetStyle()))
             {
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % 15, m_deviceOriginY % 15 );
-                
-                XFillPolygon( (Display*) m_display, (Window) m_window,
+
+                XFillPolygon( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xpoints, n, Complex, 0);
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             } else
             if (IS_16_PIX_HATCH(m_brush.GetStyle()))
             {
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % 16, m_deviceOriginY % 16 );
-                
-                XFillPolygon( (Display*) m_display, (Window) m_window,
+
+                XFillPolygon( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xpoints, n, Complex, 0);
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             } else
             if (m_brush.GetStyle() == wxSTIPPLE)
@@ -675,15 +700,15 @@ void wxWindowDC::DoDrawPolygon( int n, wxPoint points[],
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % m_brush.GetStipple()->GetWidth(),
                                       m_deviceOriginY % m_brush.GetStipple()->GetHeight() );
-                
-                XFillPolygon( (Display*) m_display, (Window) m_window,
+
+                XFillPolygon( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xpoints, n, Complex, 0);
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             }
             else
             {
-                XFillPolygon( (Display*) m_display, (Window) m_window,
+                XFillPolygon( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xpoints, n, Complex, 0);
             }
         }
@@ -694,16 +719,16 @@ void wxWindowDC::DoDrawPolygon( int n, wxPoint points[],
             xpoints[i].x = xpoints[0].x;
             xpoints[i].y = xpoints[0].y;
 
-            XDrawLines( (Display*) m_display, (Window) m_window, (GC) m_penGC, xpoints, n + 1, 0);
+            XDrawLines( (Display*) m_display, (Window) m_x11window, (GC) m_penGC, xpoints, n + 1, 0);
         }
     }
 
     delete[] xpoints;
 }
 
-void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
+void wxWindowDCImpl::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     wxCoord xx = XLOG2DEV(x);
     wxCoord yy = YLOG2DEV(y);
@@ -716,8 +741,8 @@ void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord h
     // CMB: handle -ve width and/or height
     if (ww < 0) { ww = -ww; xx = xx - ww; }
     if (hh < 0) { hh = -hh; yy = yy - hh; }
-    
-    if (m_window)
+
+    if (m_x11window)
     {
         if (m_brush.GetStyle() != wxTRANSPARENT)
         {
@@ -726,30 +751,30 @@ void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord h
                 XSetTSOrigin( (Display*) m_display, (GC) m_textGC,
                                       m_deviceOriginX % m_brush.GetStipple()->GetWidth(),
                                       m_deviceOriginY % m_brush.GetStipple()->GetHeight() );
-                
-                XFillRectangle( (Display*) m_display, (Window) m_window,
+
+                XFillRectangle( (Display*) m_display, (Window) m_x11window,
                     (GC) m_textGC, xx, yy, ww, hh );
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_textGC, 0, 0 );
             } else
             if (IS_15_PIX_HATCH(m_brush.GetStyle()))
             {
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % 15, m_deviceOriginY % 15 );
-                
-                XFillRectangle( (Display*) m_display, (Window) m_window,
+
+                XFillRectangle( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xx, yy, ww, hh );
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             } else
             if (IS_16_PIX_HATCH(m_brush.GetStyle()))
             {
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % 16, m_deviceOriginY % 16 );
-                
-                XFillRectangle( (Display*) m_display, (Window) m_window,
+
+                XFillRectangle( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xx, yy, ww, hh );
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             } else
             if (m_brush.GetStyle() == wxSTIPPLE)
@@ -757,22 +782,22 @@ void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord h
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % m_brush.GetStipple()->GetWidth(),
                                       m_deviceOriginY % m_brush.GetStipple()->GetHeight() );
-                
-                XFillRectangle( (Display*) m_display, (Window) m_window,
+
+                XFillRectangle( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xx, yy, ww, hh );
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             }
             else
             {
-                XFillRectangle( (Display*) m_display, (Window) m_window,
+                XFillRectangle( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xx, yy, ww, hh );
             }
         }
 
         if (m_pen.GetStyle () != wxTRANSPARENT)
         {
-            XDrawRectangle( (Display*) m_display, (Window) m_window,
+            XDrawRectangle( (Display*) m_display, (Window) m_x11window,
                 (GC) m_penGC, xx, yy, ww-1, hh-1 );
         }
     }
@@ -781,14 +806,132 @@ void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord h
     CalcBoundingBox( x + width, y + height );
 }
 
-void wxWindowDC::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius )
+void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius )
 {
-   // later
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
+
+    if (radius < 0.0) radius = - radius * ((width < height) ? width : height);
+
+    wxCoord xx = XLOG2DEV(x);
+    wxCoord yy = YLOG2DEV(y);
+    wxCoord ww = m_signX * XLOG2DEVREL(width);
+    wxCoord hh = m_signY * YLOG2DEVREL(height);
+    wxCoord rr = XLOG2DEVREL((wxCoord)radius);
+
+    // CMB: handle -ve width and/or height
+    if (ww < 0) { ww = -ww; xx = xx - ww; }
+    if (hh < 0) { hh = -hh; yy = yy - hh; }
+
+    // CMB: if radius is zero use DrawRectangle() instead to avoid
+    // X drawing errors with small radii
+    if (rr == 0)
+    {
+            XDrawRectangle( (Display*) m_display, (Window) m_x11window,
+                (GC) m_penGC, x, y, width, height);
+        return;
+    }
+
+    // CMB: draw nothing if transformed w or h is 0
+    if (ww == 0 || hh == 0) return;
+
+    // CMB: adjust size if outline is drawn otherwise the result is
+    // 1 pixel too wide and high
+    if (m_pen.GetStyle() != wxTRANSPARENT)
+    {
+        ww--;
+        hh--;
+    }
+
+    if (m_x11window)
+    {
+        // CMB: ensure dd is not larger than rectangle otherwise we
+        // get an hour glass shape
+        wxCoord dd = 2 * rr;
+        if (dd > ww) dd = ww;
+        if (dd > hh) dd = hh;
+        rr = dd / 2;
+
+        if (m_brush.GetStyle() != wxTRANSPARENT)
+        {
+            if ((m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE) && (m_brush.GetStipple()->GetMask()))
+            {
+                XSetTSOrigin( (Display*) m_display, (GC) m_textGC,
+                              m_deviceOriginX % m_brush.GetStipple()->GetWidth(),
+                              m_deviceOriginY % m_brush.GetStipple()->GetHeight() );
+                XFillRectangle( (Display*) m_display, (Window) m_x11window, (GC) m_textGC, xx+rr, yy, ww-dd+1, hh );
+                XFillRectangle( (Display*) m_display, (Window) m_x11window, (GC) m_textGC, xx, yy+rr, ww, hh-dd+1 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_textGC, xx, yy, dd, dd, 90*64, 90*64 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_textGC, xx+ww-dd, yy, dd, dd, 0, 90*64 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_textGC, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_textGC, xx, yy+hh-dd, dd, dd, 180*64, 90*64 );
+                XSetTSOrigin( (Display*) m_display, (GC) m_textGC, 0, 0);
+            } else
+            if (IS_15_PIX_HATCH(m_brush.GetStyle()))
+            {
+                XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 15, m_deviceOriginY % 15 );
+                XFillRectangle( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx+rr, yy, ww-dd+1, hh );
+                XFillRectangle( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx, yy+rr, ww, hh-dd+1 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx, yy, dd, dd, 90*64, 90*64 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx+ww-dd, yy, dd, dd, 0, 90*64 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx, yy+hh-dd, dd, dd, 180*64, 90*64 );
+                XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0);
+            } else
+            if (IS_16_PIX_HATCH(m_brush.GetStyle()))
+            {
+                XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 16, m_deviceOriginY % 16 );
+                XFillRectangle( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx+rr, yy, ww-dd+1, hh );
+                XFillRectangle( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx, yy+rr, ww, hh-dd+1 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx, yy, dd, dd, 90*64, 90*64 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx+ww-dd, yy, dd, dd, 0, 90*64 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx, yy+hh-dd, dd, dd, 180*64, 90*64 );
+                XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0);
+            } else
+            if (m_brush.GetStyle() == wxSTIPPLE)
+            {
+                XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
+                              m_deviceOriginX % m_brush.GetStipple()->GetWidth(),
+                              m_deviceOriginY % m_brush.GetStipple()->GetHeight() );
+                XFillRectangle( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx+rr, yy, ww-dd+1, hh );
+                XFillRectangle( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx, yy+rr, ww, hh-dd+1 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx, yy, dd, dd, 90*64, 90*64 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx+ww-dd, yy, dd, dd, 0, 90*64 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 );
+                XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx, yy+hh-dd, dd, dd, 180*64, 90*64 );
+                XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0);
+            }
+            else
+            {
+               XFillRectangle( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx+rr, yy, ww-dd+1, hh );
+               XFillRectangle( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx, yy+rr, ww, hh-dd+1 );
+               XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx, yy, dd, dd, 90*64, 90*64 );
+               XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx+ww-dd, yy, dd, dd, 0, 90*64 );
+               XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 );
+               XFillArc( (Display*) m_display, (Window) m_x11window, (GC) m_brushGC, xx, yy+hh-dd, dd, dd, 180*64, 90*64 );
+            }
+        }
+     if (m_pen.GetStyle() != wxTRANSPARENT)
+        {
+            XDrawLine( (Display*) m_display, (Window) m_x11window, (GC) m_penGC, xx+rr+1, yy, xx+ww-rr, yy );
+            XDrawLine( (Display*) m_display, (Window) m_x11window, (GC) m_penGC, xx+rr+1, yy+hh, xx+ww-rr, yy+hh );
+            XDrawLine( (Display*) m_display, (Window) m_x11window, (GC) m_penGC, xx, yy+rr+1, xx, yy+hh-rr );
+            XDrawLine( (Display*) m_display, (Window) m_x11window, (GC) m_penGC, xx+ww, yy+rr+1, xx+ww, yy+hh-rr );
+            XDrawArc( (Display*) m_display, (Window) m_x11window, (GC) m_penGC, xx, yy, dd, dd, 90*64, 90*64 );
+            XDrawArc( (Display*) m_display, (Window) m_x11window, (GC) m_penGC, xx+ww-dd, yy, dd, dd, 0, 90*64 );
+            XDrawArc( (Display*) m_display, (Window) m_x11window, (GC) m_penGC, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 );
+            XDrawArc( (Display*) m_display, (Window) m_x11window, (GC) m_penGC, xx, yy+hh-dd, dd, dd, 180*64, 90*64 );
+        }
+    }
+
+    // this ignores the radius
+    CalcBoundingBox( x, y );
+    CalcBoundingBox( x + width, y + height );
 }
 
-void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
+void wxWindowDCImpl::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     wxCoord xx = XLOG2DEV(x);
     wxCoord yy = YLOG2DEV(y);
@@ -799,7 +942,7 @@ void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord hei
     if (ww < 0) { ww = -ww; xx = xx - ww; }
     if (hh < 0) { hh = -hh; yy = yy - hh; }
 
-    if (m_window)
+    if (m_x11window)
     {
         if (m_brush.GetStyle() != wxTRANSPARENT)
         {
@@ -808,30 +951,30 @@ void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord hei
                 XSetTSOrigin( (Display*) m_display, (GC) m_textGC,
                                       m_deviceOriginX % m_brush.GetStipple()->GetWidth(),
                                       m_deviceOriginY % m_brush.GetStipple()->GetHeight() );
-                
-                XFillArc( (Display*) m_display, (Window) m_window,
+
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_textGC, xx, yy, ww, hh, 0, 360*64 );
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_textGC, 0, 0 );
             } else
             if (IS_15_PIX_HATCH(m_brush.GetStyle()))
             {
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % 15, m_deviceOriginY % 15 );
-                
-                XFillArc( (Display*) m_display, (Window) m_window,
+
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xx, yy, ww, hh, 0, 360*64 );
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             } else
             if (IS_16_PIX_HATCH(m_brush.GetStyle()))
             {
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % 16, m_deviceOriginY % 16 );
-                
-                XFillArc( (Display*) m_display, (Window) m_window,
+
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xx, yy, ww, hh, 0, 360*64 );
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             } else
             if (m_brush.GetStyle() == wxSTIPPLE)
@@ -839,22 +982,22 @@ void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord hei
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC,
                                       m_deviceOriginX % m_brush.GetStipple()->GetWidth(),
                                       m_deviceOriginY % m_brush.GetStipple()->GetHeight() );
-                
-                XFillArc( (Display*) m_display, (Window) m_window,
+
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xx, yy, ww, hh, 0, 360*64 );
-                
+
                 XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 );
             }
             else
             {
-                XFillArc( (Display*) m_display, (Window) m_window,
+                XFillArc( (Display*) m_display, (Window) m_x11window,
                     (GC) m_brushGC, xx, yy, ww, hh, 0, 360*64 );
             }
         }
 
         if (m_pen.GetStyle () != wxTRANSPARENT)
         {
-            XDrawArc( (Display*) m_display, (Window) m_window,
+            XDrawArc( (Display*) m_display, (Window) m_x11window,
                 (GC) m_penGC, xx, yy, ww, hh, 0, 360*64 );
         }
     }
@@ -863,20 +1006,20 @@ void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord hei
     CalcBoundingBox( x + width, y + height );
 }
 
-void wxWindowDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y)
+void wxWindowDCImpl::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y)
 {
-    DoDrawBitmap(icon, x, y, TRUE);
+    DoDrawBitmap(icon, x, y, true);
 }
 
 #if wxUSE_NANOX
-void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
+void wxWindowDCImpl::DoDrawBitmap( const wxBitmap &bitmap,
                                wxCoord x, wxCoord y,
                                bool useMask )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
+
+    wxCHECK_RET( bitmap.IsOk(), wxT("invalid bitmap") );
 
-    wxCHECK_RET( bitmap.Ok(), wxT("invalid bitmap") );
-    
     bool is_mono = (bitmap.GetBitmap() != NULL);
 
     /* scale/translate size and position */
@@ -889,7 +1032,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
     CalcBoundingBox( x, y );
     CalcBoundingBox( x + w, y + h );
 
-    if (!m_window) return;
+    if (!m_x11window) return;
 
     int ww = XLOG2DEVREL(w);
     int hh = YLOG2DEVREL(h);
@@ -907,14 +1050,14 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
     wxBitmap use_bitmap;
     if ((w != ww) || (h != hh))
     {
-        wxImage image( bitmap );
+        wxImage image( bitmap.ConvertToImage() );
         image.Rescale( ww, hh );
 #if 0
         if (is_mono)
             use_bitmap = image.ConvertToMonoBitmap(255,255,255);
         else
 #endif
-            use_bitmap = image.ConvertToBitmap();
+            use_bitmap = image;
     }
     else
     {
@@ -945,10 +1088,10 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
         // In DoBlit, we may be able to eliminate this step
         // if we check if the rop = copy
 #if 0
-        GrCopyArea(bufPixmap, gc, 0, 0, w, h, (Window) m_window,
+        GrCopyArea(bufPixmap, gc, 0, 0, w, h, (Window) m_x11window,
                   0, 0, GR_MODE_COPY);
 #endif
-            
+
         // Copy src to buffer using selected raster op (none selected
         // in DrawBitmap, so just use Gxcopy)
         GrCopyArea(bufPixmap, gc, 0, 0, w, h, pixmap,
@@ -959,22 +1102,22 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
         GrSetGCForeground(gc, BLACK);
         GrCopyArea(bufPixmap, gc, 0, 0, w, h, maskPixmap,
                     0, 0, GR_MODE_AND);
-                       
+
         // set unmasked area in dest to BLACK
         GrSetGCBackground(gc, BLACK);
         GrSetGCForeground(gc, WHITE);
-        GrCopyArea((Window) m_window, gc, xx, yy, w, h, maskPixmap,
+        GrCopyArea((Window) m_x11window, gc, xx, yy, w, h, maskPixmap,
                    0, 0, GR_MODE_AND);
 
         // OR buffer to dest
-        GrCopyArea((Window) m_window, gc, xx, yy, w, h, bufPixmap,
+        GrCopyArea((Window) m_x11window, gc, xx, yy, w, h, bufPixmap,
                    0, 0, GR_MODE_OR);
 
         GrDestroyGC(gc);
         GrDestroyWindow(bufPixmap);
     }
     else
-      XCopyArea( (Display*) m_display, (Pixmap) use_bitmap.GetPixmap(), (Window) m_window,
+      XCopyArea( (Display*) m_display, (Pixmap) use_bitmap.GetPixmap(), (Window) m_x11window,
             (GC) m_penGC, 0, 0, w, h, xx, yy );
 
     /* remove mask again if any */
@@ -988,14 +1131,14 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
 #else
 
 // Normal X11
-void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
+void wxWindowDCImpl::DoDrawBitmap( const wxBitmap &bitmap,
                                wxCoord x, wxCoord y,
                                bool useMask )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
+
+    wxCHECK_RET( bitmap.IsOk(), wxT("invalid bitmap") );
 
-    wxCHECK_RET( bitmap.Ok(), wxT("invalid bitmap") );
-    
     bool is_mono = (bitmap.GetBitmap() != NULL);
 
     // scale/translate size and position
@@ -1008,7 +1151,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
     CalcBoundingBox( x, y );
     CalcBoundingBox( x + w, y + h );
 
-    if (!m_window) return;
+    if (!m_x11window) return;
 
     int ww = XLOG2DEVREL(w);
     int hh = YLOG2DEVREL(h);
@@ -1026,14 +1169,14 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
     wxBitmap use_bitmap;
     if ((w != ww) || (h != hh))
     {
-        wxImage image( bitmap );
+        wxImage image( bitmap.ConvertToImage() );
         image.Rescale( ww, hh );
 #if 0
         if (is_mono)
             use_bitmap = image.ConvertToMonoBitmap(255,255,255);
         else
 #endif
-            use_bitmap = image.ConvertToBitmap();
+            use_bitmap = image;
     }
     else
     {
@@ -1043,63 +1186,90 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
     // apply mask if any
     WXPixmap mask = NULL;
     if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap();
-    
-        if (useMask && mask)
+
+    bool setClipMask = false;
+
+    if (!m_currentClippingRegion.IsNull() || (useMask && mask))
+    {
+        // XSetClipMask() call is necessary (because of clip region and/or transparent mask)
+        setClipMask = true;
+        Pixmap new_pixmap = 0;
+
+        if (!m_currentClippingRegion.IsNull())
         {
-            WXPixmap new_mask = NULL;
-#if 0
-            if (!m_currentClippingRegion.IsNull())
+            // clipping necessary => create new_pixmap
+            Display *xdisplay = (Display*) m_display;
+            int xscreen = DefaultScreen( xdisplay );
+            Window xroot = RootWindow( xdisplay, xscreen );
+
+            new_pixmap = XCreatePixmap( xdisplay, xroot, ww, hh, 1 );
+            GC gc = XCreateGC( xdisplay, new_pixmap, 0, NULL );
+
+            XSetForeground( xdisplay, gc, BlackPixel(xdisplay,xscreen) );
+
+            XSetFillStyle( xdisplay, gc, FillSolid );
+            XFillRectangle( xdisplay, new_pixmap, gc, 0, 0, ww, hh );
+
+            XSetForeground( xdisplay, gc, WhitePixel(xdisplay,xscreen) );
+
+            if (useMask && mask)
             {
-                GdkColor col;
-                new_mask = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, 1 );
-                GdkGC *gc = gdk_gc_new( new_mask );
-                col.pixel = 0;
-                gdk_gc_set_foreground( gc, &col );
-                gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh );
-                col.pixel = 0;
-                gdk_gc_set_background( gc, &col );
-                col.pixel = 1;
-                gdk_gc_set_foreground( gc, &col );
-                gdk_gc_set_clip_region( gc, m_currentClippingRegion.GetRegion() );
-                gdk_gc_set_clip_origin( gc, -xx, -yy );
-                gdk_gc_set_fill( gc, GDK_OPAQUE_STIPPLED );
-                gdk_gc_set_stipple( gc, mask );
-                gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh );
-                gdk_gc_unref( gc );
+                // transparent mask => call XSetStipple
+                XSetFillStyle( xdisplay, gc, FillStippled );
+                XSetTSOrigin( xdisplay, gc, 0, 0);
+                XSetStipple( xdisplay, gc, (Pixmap) mask);
             }
-#endif
-            if (is_mono)
+
+            wxVector<XRectangle> rects;
+            for ( wxRegionIterator iter(m_currentClippingRegion);
+                  iter;
+                  ++iter )
             {
-                if (new_mask)
-                    XSetClipMask( (Display*) m_display, (GC) m_textGC, (Pixmap) new_mask );
-                else
-                    XSetClipMask( (Display*) m_display, (GC) m_textGC, (Pixmap) mask );
-                XSetClipOrigin( (Display*) m_display, (GC) m_textGC, xx, yy );
+                XRectangle rect;
+                rect.x = iter.GetX() - xx;
+                rect.y = iter.GetY() - yy;
+                rect.width = iter.GetWidth();
+                rect.height = iter.GetHeight();
+                rects.push_back(rect);
             }
+
+            XFillRectangles(xdisplay, new_pixmap, gc, &rects[0], rects.size());
+
+            XFreeGC( xdisplay, gc );
+        }
+
+        if (is_mono)
+        {
+            if (new_pixmap)
+                XSetClipMask( (Display*) m_display, (GC) m_textGC, new_pixmap );
             else
-            {
-                if (new_mask)
-                    XSetClipMask( (Display*) m_display, (GC) m_penGC, (Pixmap) new_mask );
-                else
-                    XSetClipMask( (Display*) m_display, (GC) m_penGC, (Pixmap) mask );
-                XSetClipOrigin( (Display*) m_display, (GC) m_penGC, xx, yy );
-            }
-            
-            if (new_mask)
-               XFreePixmap( (Display*) m_display, (Pixmap) new_mask );
+                XSetClipMask( (Display*) m_display, (GC) m_textGC, (Pixmap) mask );
+            XSetClipOrigin( (Display*) m_display, (GC) m_textGC, xx, yy );
+        }
+        else
+        {
+            if (new_pixmap)
+                XSetClipMask( (Display*) m_display, (GC) m_penGC, new_pixmap );
+            else
+                XSetClipMask( (Display*) m_display, (GC) m_penGC, (Pixmap) mask );
+            XSetClipOrigin( (Display*) m_display, (GC) m_penGC, xx, yy );
         }
 
+        if (new_pixmap)
+            XFreePixmap( (Display*) m_display, new_pixmap );
+    }
+
     // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
     // drawing a mono-bitmap (XBitmap) we use the current text GC
     if (is_mono)
-        XCopyPlane( (Display*) m_display, (Pixmap) use_bitmap.GetBitmap(), (Window) m_window,
-            (GC) m_textGC, 0, 0, wh, xx, yy, 1 );
+        XCopyPlane( (Display*) m_display, (Pixmap) use_bitmap.GetBitmap(), (Window) m_x11window,
+            (GC) m_textGC, 0, 0, ww, hh, xx, yy, 1 );
     else
-        XCopyArea( (Display*) m_display, (Pixmap) use_bitmap.GetPixmap(), (Window) m_window,
-            (GC) m_penGC, 0, 0, wh, xx, yy );
+        XCopyArea( (Display*) m_display, (Pixmap) use_bitmap.GetPixmap(), (Window) m_x11window,
+            (GC) m_penGC, 0, 0, ww, hh, xx, yy );
 
     // remove mask again if any
-    if (useMask && mask)
+    if (setClipMask)
     {
         if (is_mono)
         {
@@ -1120,7 +1290,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
 #endif
   // wxUSE_NANOX/!wxUSE_NANOX
 
-bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
+bool wxWindowDCImpl::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
                          wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func, bool useMask,
                          wxCoord xsrcMask, wxCoord ysrcMask )
 {
@@ -1129,32 +1299,35 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he
       of the source dc, but scales correctly on the target dc and
       knows about possible mask information in a memory dc. */
 
-    wxCHECK_MSG( Ok(), FALSE, wxT("invalid window dc") );
+    wxCHECK_MSG( IsOk(), false, wxT("invalid window dc") );
 
-    wxCHECK_MSG( source, FALSE, wxT("invalid source dc") );
+    wxCHECK_MSG( source, false, wxT("invalid source dc") );
 
-    if (!m_window) return FALSE;
+    if (!m_x11window) return false;
 
     // transform the source DC coords to the device ones
-    xsrc = source->XLOG2DEV(xsrc);
-    ysrc = source->YLOG2DEV(ysrc);
+    xsrc = source->LogicalToDeviceX(xsrc);
+    ysrc = source->LogicalToDeviceY(ysrc);
 
     wxClientDC *srcDC = (wxClientDC*)source;
     wxMemoryDC *memDC = (wxMemoryDC*)source;
+    wxWindowDCImpl *src_impl = (wxWindowDCImpl*) srcDC->GetImpl();
 
-    bool use_bitmap_method = FALSE;
-    bool is_mono = FALSE;
+    bool use_bitmap_method = false;
+    bool is_mono = false;
 
-    // TODO: use the mask origin when drawing transparently 
+    // TODO: use the mask origin when drawing transparently
     if (xsrcMask == -1 && ysrcMask == -1)
     {
         xsrcMask = xsrc;
         ysrcMask = ysrc;
     }
-    
-    if (srcDC->m_isMemDC)
+
+    if (src_impl->m_isMemDC)
     {
-        if (!memDC->m_selected.Ok()) return FALSE;
+        wxBitmap selected = memDC->GetSelectedBitmap();
+
+        if (!selected.IsOk()) return false;
 
         /* we use the "XCopyArea" way to copy a memory dc into
            y different window if the memory dc BOTH
@@ -1162,34 +1335,34 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he
            b) it is clipped
            c) is not 1-bit */
 
-        if (useMask && (memDC->m_selected.GetMask()))
+        if (useMask && (selected.GetMask()))
         {
            /* we HAVE TO use the direct way for memory dcs
               that have mask since the XCopyArea doesn't know
               about masks */
-            use_bitmap_method = TRUE;
+            use_bitmap_method = true;
         }
-        else if (memDC->m_selected.GetDepth() == 1)
+        else if (selected.GetDepth() == 1)
         {
            /* we HAVE TO use the direct way for memory dcs
               that are bitmaps because XCopyArea doesn't cope
               with different bit depths */
-            is_mono = TRUE;
-            use_bitmap_method = TRUE;
+            is_mono = true;
+            use_bitmap_method = true;
         }
         else if ((xsrc == 0) && (ysrc == 0) &&
-                 (width == memDC->m_selected.GetWidth()) &&
-                 (height == memDC->m_selected.GetHeight()))
+                 (width == selected.GetWidth()) &&
+                 (height == selected.GetHeight()))
         {
            /* we SHOULD use the direct way if all of the bitmap
               in the memory dc is copied in which case XCopyArea
               wouldn't be able able to boost performace by reducing
               the area to be scaled */
-            use_bitmap_method = TRUE;
+            use_bitmap_method = true;
         }
         else
         {
-            use_bitmap_method = FALSE;
+            use_bitmap_method = false;
         }
     }
 
@@ -1209,7 +1382,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he
         wxRegion tmp( xx,yy,ww,hh );
         tmp.Intersect( m_currentClippingRegion );
         if (tmp.IsEmpty())
-            return TRUE;
+            return true;
     }
 
     int old_logical_func = m_logicalFunction;
@@ -1217,9 +1390,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he
 
     if (use_bitmap_method)
     {
+        wxBitmap selected = memDC->GetSelectedBitmap();
+
         // scale/translate bitmap size
-        wxCoord bm_width = memDC->m_selected.GetWidth();
-        wxCoord bm_height = memDC->m_selected.GetHeight();
+        wxCoord bm_width = selected.GetWidth();
+        wxCoord bm_height = selected.GetHeight();
 
         wxCoord bm_ww = XLOG2DEVREL( bm_width );
         wxCoord bm_hh = YLOG2DEVREL( bm_height );
@@ -1229,7 +1404,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he
 
         if ((bm_width != bm_ww) || (bm_height != bm_hh))
         {
-            wxImage image( memDC->m_selected );
+            wxImage image( selected.ConvertToImage() );
             image = image.Scale( bm_ww, bm_hh );
 
 #if 0
@@ -1237,11 +1412,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he
                 use_bitmap = image.ConvertToMonoBitmap(255,255,255);
             else
 #endif
-                use_bitmap = image.ConvertToBitmap();
+                use_bitmap = image;
         }
         else
         {
-            use_bitmap = memDC->m_selected;
+            use_bitmap = selected;
         }
 
         // apply mask if any
@@ -1288,19 +1463,18 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he
                     XSetClipMask( (Display*) m_display, (GC) m_penGC, (Pixmap) mask );
                 XSetClipOrigin( (Display*) m_display, (GC) m_penGC, xx, yy );
             }
-            
+
             if (new_mask)
                XFreePixmap( (Display*) m_display, (Pixmap) new_mask );
         }
 
         // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
         // drawing a mono-bitmap (XBitmap) we use the current text GC
-
         if (is_mono)
-            XCopyPlane( (Display*) m_display, (Pixmap) use_bitmap.GetBitmap(), (Window) m_window,
+            XCopyPlane( (Display*) m_display, (Pixmap) use_bitmap.GetBitmap(), (Window) m_x11window,
                 (GC) m_textGC, xsrc, ysrc, width, height, xx, yy, 1 );
         else
-            XCopyArea( (Display*) m_display, (Pixmap) use_bitmap.GetPixmap(), (Window) m_window,
+            XCopyArea( (Display*) m_display, (Pixmap) use_bitmap.GetPixmap(), (Window) m_x11window,
                 (GC) m_penGC, xsrc, ysrc, width, height, xx, yy );
 
         // remove mask again if any
@@ -1324,6 +1498,14 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he
     }
     else // use_bitmap_method
     {
+        wxDCImpl *impl = srcDC->GetImpl();
+        wxWindowDCImpl *x11_impl = wxDynamicCast(impl, wxWindowDCImpl);
+        if (!x11_impl)
+        {
+            SetLogicalFunction( old_logical_func );
+            return false;
+        }
+
         if ((width != ww) || (height != hh))
         {
             /* Draw source window into a bitmap as we cannot scale
@@ -1343,54 +1525,74 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he
 
             // copy including child window contents
             XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, IncludeInferiors );
-            XCopyArea( (Display*) m_display, (Window) srcDC->GetWindow(), (Window) bitmap.GetPixmap(),
+            XCopyArea( (Display*) m_display, (Window) x11_impl->GetX11Window(), (Window) bitmap.GetPixmap(),
                        (GC) m_penGC, xsrc, ysrc, width, height, 0, 0 );
             XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, ClipByChildren );
 
             // scale image
-            wxImage image( bitmap );
+            wxImage image( bitmap.ConvertToImage() );
             image = image.Scale( ww, hh );
 
             // convert to bitmap
-            bitmap = image.ConvertToBitmap();
+            bitmap = image;
 
             // draw scaled bitmap
-            XCopyArea( (Display*) m_display, (Window) bitmap.GetPixmap(), (Window) m_window, 
+            XCopyArea( (Display*) m_display, (Window) bitmap.GetPixmap(), (Window) m_x11window,
                        (GC) m_penGC, 0, 0, width, height, xx, yy );
         }
         else
         {
             // No scaling and not a memory dc with a mask either
-
             // copy including child window contents
             XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, IncludeInferiors );
-            XCopyArea( (Display*) m_display, (Window) srcDC->GetWindow(), (Window) m_window, 
+            XCopyArea( (Display*) m_display, (Window) x11_impl->GetX11Window(), (Window) m_x11window,
                        (GC) m_penGC, xsrc, ysrc, width, height, xx, yy );
             XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, ClipByChildren );
         }
     }
 
     SetLogicalFunction( old_logical_func );
-    
-    return TRUE;
+
+    return true;
 }
 
-void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
+void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
+
+    if (!m_x11window) return;
+
+    x = XLOG2DEV(x);
+    y = YLOG2DEV(y);
 
-    if (!m_window) return;
+#if wxUSE_UNICODE
+    PangoLayout *layout = pango_layout_new(m_context);
+    pango_layout_set_font_description(layout, m_fontdesc);
 
+    const wxCharBuffer data = wxConvUTF8.cWC2MB( text );
+    pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data ));
+
+    // Measure layout.
+    int w,h;
+    pango_layout_get_pixel_size(layout, &w, &h);
+    wxCoord width = w;
+    wxCoord height = h;
+
+    // Draw layout.
+    x11_draw_layout( (Drawable) m_x11window, (GC) m_textGC, x, y, layout, m_textForegroundColour );
+
+    g_object_unref( G_OBJECT( layout ) );
+
+    CalcBoundingBox (x + width, y + height);
+    CalcBoundingBox (x, y);
+#else
     XFontStruct *xfont = (XFontStruct*) m_font.GetFontStruct( m_scaleY, m_display );
 
     wxCHECK_RET( xfont, wxT("invalid font") );
 
-    x = XLOG2DEV(x);
-    y = YLOG2DEV(y);
-
     // First draw a rectangle representing the text background, if a text
     // background is specified
-    if (m_textBackgroundColour.Ok () && (m_backgroundMode != wxTRANSPARENT))
+    if (m_textBackgroundColour.IsOk () && (m_backgroundMode != wxTRANSPARENT))
     {
         // Since X draws from the baseline of the text, must add the text height
         int cx = 0;
@@ -1402,14 +1604,15 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
         slen = strlen(text);
         XCharStruct overall_return;
 
-        (void)XTextExtents(xfont, (char*) text.c_str(), slen, &direction,
+        (void)XTextExtents(xfont, (const char*) text.c_str(), slen, &direction,
                                  &ascent, &descent, &overall_return);
 
         cx = overall_return.width;
         cy = ascent + descent;
         m_textBackgroundColour.CalcPixel(m_cmap);
+        m_textForegroundColour.CalcPixel(m_cmap);
         XSetForeground ((Display*) m_display, (GC) m_textGC, m_textBackgroundColour.GetPixel());
-        XFillRectangle( (Display*) m_display, (Window) m_window,
+        XFillRectangle( (Display*) m_display, (Window) m_x11window,
                     (GC) m_textGC, x, y, cx, cy );
         XSetForeground ((Display*) m_display, (GC) m_textGC, m_textForegroundColour.GetPixel());
 
@@ -1417,11 +1620,13 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
 
     XSetFont( (Display*) m_display, (GC) m_textGC, xfont->fid );
 #if !wxUSE_NANOX
-    if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+    // This may be a test for whether the font is 16-bit, but it also
+    // seems to fail for valid 8-bit fonts too.
+    if (1) // (xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
 #endif
     {
-        XDrawString( (Display*) m_display, (Window) m_window, 
-            (GC) m_textGC, x, y + XFontStructGetAscent(xfont), text.c_str(), text.Len() );
+        XDrawString( (Display*) m_display, (Window) m_x11window,
+            (GC) m_textGC, x, y + XFontStructGetAscent(xfont), text.c_str(), text.length() );
     }
 
 #if 0
@@ -1429,41 +1634,77 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
     {
         wxCoord ul_y = y + XFontStructGetAscent(font);
         if (font->descent > 0) ul_y++;
-        gdk_draw_line( m_window, m_textGC, x, ul_y, x + width, ul_y);
+        gdk_draw_line( m_x11window, m_textGC, x, ul_y, x + width, ul_y);
     }
 
     width = wxCoord(width / m_scaleX);
     height = wxCoord(height / m_scaleY);
-    
+
     CalcBoundingBox (x + width, y + height);
     CalcBoundingBox (x, y);
 #endif
+#endif
 }
 
-void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, double angle )
+void wxWindowDCImpl::DoDrawRotatedText(const wxString& WXUNUSED(text),
+                                   wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
+                                   double WXUNUSED(angle))
 {
-    // later
+    wxFAIL_MSG( "not implemented" );
 }
 
-void wxWindowDC::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoord *height,
+void wxWindowDCImpl::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoord *height,
                                 wxCoord *descent, wxCoord *externalLeading,
-                                wxFont *font ) const
+                                const wxFont *font ) const
 {
-    wxCHECK_RET( Ok(), "invalid dc" );
+    wxCHECK_RET( IsOk(), wxT("invalid dc") );
+
+    if (string.empty())
+    {
+        if (width) (*width) = 0;
+        if (height) (*height) = 0;
+        return;
+    }
+
+#if wxUSE_UNICODE
+    PangoLayout *layout = pango_layout_new( m_context );
+
+    if (font)
+        pango_layout_set_font_description( layout, font->GetNativeFontInfo()->description );
+    else
+        pango_layout_set_font_description(layout, m_fontdesc);
+
+    const wxCharBuffer data = wxConvUTF8.cWC2MB( string );
+    pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data ));
 
+    // Measure text.
+    int w,h;
+    pango_layout_get_pixel_size(layout, &w, &h);
+
+    if (width) (*width) = (wxCoord) w;
+    if (height) (*height) = (wxCoord) h;
+    if (descent)
+    {
+        // Do something about metrics here. TODO.
+        (*descent) = 0;
+    }
+    if (externalLeading) (*externalLeading) = 0;  // ??
+
+    g_object_unref( G_OBJECT( layout ) );
+#else
     wxFont fontToUse = m_font;
     if (font) fontToUse = *font;
 
-    wxCHECK_RET( fontToUse.Ok(), "invalid font" );
+    wxCHECK_RET( fontToUse.IsOk(), wxT("invalid font") );
 
     XFontStruct *xfont = (XFontStruct*) fontToUse.GetFontStruct( m_scaleY, m_display );
 
     wxCHECK_RET( xfont, wxT("invalid font") );
-    
+
     int direction, ascent, descent2;
     XCharStruct overall;
 
-    XTextExtents( xfont, (char*) string.c_str(), string.Len(), &direction,
+    XTextExtents( xfont, (const char*) string.c_str(), string.length(), &direction,
         &ascent, &descent2, &overall);
 
     if (width)
@@ -1474,13 +1715,29 @@ void wxWindowDC::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoor
         *descent = (wxCoord)(descent2 / m_scaleY );
     if (externalLeading)
         *externalLeading = 0; // ??
+#endif
 }
 
-wxCoord wxWindowDC::GetCharWidth() const
+wxCoord wxWindowDCImpl::GetCharWidth() const
 {
-    wxCHECK_MSG( Ok(), 0, "invalid dc" );
-    
-    wxCHECK_MSG( m_font.Ok(), 0, "invalid font" );
+    wxCHECK_MSG( IsOk(), 0, wxT("invalid dc") );
+
+#if wxUSE_UNICODE
+    PangoLayout *layout = pango_layout_new( m_context );
+
+    if (m_fontdesc)
+        pango_layout_set_font_description(layout, m_fontdesc);
+    else
+        pango_layout_set_font_description(layout, this->GetFont().GetNativeFontInfo()->description);
+
+    pango_layout_set_text(layout, "H", 1 );
+    int w,h;
+    pango_layout_get_pixel_size(layout, &w, &h);
+    g_object_unref( G_OBJECT( layout ) );
+
+    return w;
+#else
+    wxCHECK_MSG( m_font.IsOk(), 0, wxT("invalid font") );
 
     XFontStruct *xfont = (XFontStruct*) m_font.GetFontStruct( m_scaleY, m_display );
 
@@ -1488,17 +1745,33 @@ wxCoord wxWindowDC::GetCharWidth() const
 
     int direction, ascent, descent;
     XCharStruct overall;
-    
+
     XTextExtents( xfont, "H", 1, &direction, &ascent, &descent, &overall );
-        
+
     return (wxCoord)(overall.width / m_scaleX);
+#endif
 }
 
-wxCoord wxWindowDC::GetCharHeight() const
+wxCoord wxWindowDCImpl::GetCharHeight() const
 {
-    wxCHECK_MSG( Ok(), 0, "invalid dc" );
-    
-    wxCHECK_MSG( m_font.Ok(), 0, "invalid font" );
+    wxCHECK_MSG( IsOk(), 0, wxT("invalid dc") );
+
+#if wxUSE_UNICODE
+    PangoLayout *layout = pango_layout_new( m_context );
+
+    if (m_fontdesc)
+        pango_layout_set_font_description(layout, m_fontdesc);
+    else
+        pango_layout_set_font_description(layout, this->GetFont().GetNativeFontInfo()->description);
+
+    pango_layout_set_text(layout, "H", 1 );
+    int w,h;
+    pango_layout_get_pixel_size(layout, &w, &h);
+    g_object_unref( G_OBJECT( layout ) );
+
+    return h;
+#else
+    wxCHECK_MSG( m_font.IsOk(), 0, wxT("invalid font") );
 
     XFontStruct *xfont = (XFontStruct*) m_font.GetFontStruct( m_scaleY, m_display );
 
@@ -1506,17 +1779,18 @@ wxCoord wxWindowDC::GetCharHeight() const
 
     int direction, ascent, descent;
     XCharStruct overall;
-    
+
     XTextExtents( xfont, "H", 1, &direction, &ascent, &descent, &overall );
-        
+
     return (wxCoord)((ascent+descent) / m_scaleY);
+#endif
 }
 
-void wxWindowDC::Clear()
+void wxWindowDCImpl::Clear()
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
-    if (!m_window) return;
+    if (!m_x11window) return;
 
     /* - we either are a memory dc or have a window as the
        owner. anything else shouldn't happen.
@@ -1525,41 +1799,45 @@ void wxWindowDC::Clear()
        much pain to keep the DC's and the window's back-
        ground colour in synch. */
 
-    if (m_owner)
+    if (m_window)
     {
         int width,height;
-        m_owner->GetSize( &width, &height );
-        XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_bgGC, 0, 0, width, height );
+        m_window->GetSize( &width, &height );
+        XFillRectangle( (Display*) m_display, (Window) m_x11window, (GC) m_bgGC, 0, 0, width, height );
         return;
     }
 
     if (m_isMemDC)
     {
         int width,height;
-        GetSize( &width, &height );
-        XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_bgGC, 0, 0, width, height );
+        DoGetSize( &width, &height );
+        XFillRectangle( (Display*) m_display, (Window) m_x11window, (GC) m_bgGC, 0, 0, width, height );
         return;
     }
 }
 
-void wxWindowDC::SetFont( const wxFont &font )
+void wxWindowDCImpl::SetFont( const wxFont &font )
 {
-    wxCHECK_RET( Ok(), "invalid dc" );
+    wxCHECK_RET( IsOk(), wxT("invalid dc") );
 
     m_font = font;
+
+#if wxUSE_UNICODE
+    m_fontdesc = font.GetNativeFontInfo()->description;
+#endif
 }
 
-void wxWindowDC::SetPen( const wxPen &pen )
+void wxWindowDCImpl::SetPen( const wxPen &pen )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     if (m_pen == pen) return;
 
     m_pen = pen;
 
-    if (!m_pen.Ok()) return;
+    if (!m_pen.IsOk()) return;
 
-    if (!m_window) return;
+    if (!m_x11window) return;
 
     int width = m_pen.GetWidth();
     if (width <= 0)
@@ -1676,24 +1954,24 @@ void wxWindowDC::SetPen( const wxPen &pen )
     XSetForeground( (Display*) m_display, (GC) m_penGC, m_pen.GetColour().GetPixel() );
 }
 
-void wxWindowDC::SetBrush( const wxBrush &brush )
+void wxWindowDCImpl::SetBrush( const wxBrush &brush )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     if (m_brush == brush) return;
 
     m_brush = brush;
 
-    if (!m_brush.Ok()) return;
+    if (!m_brush.IsOk()) return;
 
-    if (!m_window) return;
+    if (!m_x11window) return;
 
     m_brush.GetColour().CalcPixel( m_cmap );
     XSetForeground( (Display*) m_display, (GC) m_brushGC, m_brush.GetColour().GetPixel() );
-    
+
     XSetFillStyle( (Display*) m_display, (GC) m_brushGC, FillSolid );
 
-    if ((m_brush.GetStyle() == wxSTIPPLE) && (m_brush.GetStipple()->Ok()))
+    if ((m_brush.GetStyle() == wxSTIPPLE) && (m_brush.GetStipple()->IsOk()))
     {
         if (m_brush.GetStipple()->GetPixmap())
         {
@@ -1713,7 +1991,7 @@ void wxWindowDC::SetBrush( const wxBrush &brush )
         XSetStipple( (Display*) m_display, (GC) m_textGC, (Pixmap) m_brush.GetStipple()->GetMask()->GetBitmap() );
     }
 
-    if (IS_HATCH(m_brush.GetStyle()))
+    if (m_brush.IsHatch())
     {
         XSetFillStyle( (Display*) m_display, (GC) m_brushGC, FillStippled );
         int num = m_brush.GetStyle() - wxBDIAGONAL_HATCH;
@@ -1721,20 +1999,20 @@ void wxWindowDC::SetBrush( const wxBrush &brush )
     }
 }
 
-void wxWindowDC::SetBackground( const wxBrush &brush )
+void wxWindowDCImpl::SetBackground( const wxBrush &brush )
 {
    /* CMB 21/7/98: Added SetBackground. Sets background brush
     * for Clear() and bg colour for shapes filled with cross-hatch brush */
 
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     if (m_backgroundBrush == brush) return;
 
     m_backgroundBrush = brush;
 
-    if (!m_backgroundBrush.Ok()) return;
+    if (!m_backgroundBrush.IsOk()) return;
 
-    if (!m_window) return;
+    if (!m_x11window) return;
 
     m_backgroundBrush.GetColour().CalcPixel( m_cmap );
     XSetBackground( (Display*) m_display, (GC) m_brushGC, m_backgroundBrush.GetColour().GetPixel() );
@@ -1744,7 +2022,7 @@ void wxWindowDC::SetBackground( const wxBrush &brush )
 
     XSetFillStyle( (Display*) m_display, (GC) m_bgGC, FillSolid );
 
-    if ((m_backgroundBrush.GetStyle() == wxSTIPPLE) && (m_backgroundBrush.GetStipple()->Ok()))
+    if ((m_backgroundBrush.GetStyle() == wxSTIPPLE) && (m_backgroundBrush.GetStipple()->IsOk()))
     {
         if (m_backgroundBrush.GetStipple()->GetPixmap())
         {
@@ -1758,7 +2036,7 @@ void wxWindowDC::SetBackground( const wxBrush &brush )
         }
     }
 
-    if (IS_HATCH(m_backgroundBrush.GetStyle()))
+    if (m_backgroundBrush.IsHatch())
     {
         XSetFillStyle( (Display*) m_display, (GC) m_bgGC, FillStippled );
         int num = m_backgroundBrush.GetStyle() - wxBDIAGONAL_HATCH;
@@ -1766,9 +2044,9 @@ void wxWindowDC::SetBackground( const wxBrush &brush )
     }
 }
 
-void wxWindowDC::SetLogicalFunction( int function )
+void wxWindowDCImpl::SetLogicalFunction( int function )
 {
-    wxCHECK_RET( Ok(), "invalid dc" );
+    wxCHECK_RET( IsOk(), wxT("invalid dc") );
 
     int x_function;
 
@@ -1776,9 +2054,9 @@ void wxWindowDC::SetLogicalFunction( int function )
         return;
 
     // VZ: shouldn't this be a CHECK?
-    if (!m_window)
+    if (!m_x11window)
         return;
-        
+
     switch (function)
     {
     case wxCLEAR:
@@ -1839,49 +2117,49 @@ void wxWindowDC::SetLogicalFunction( int function )
     // operations (i.e. DrawText/DrawRotatedText).
     // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
     XSetFunction( (Display*) m_display, (GC) m_textGC, x_function );
-    
+
     m_logicalFunction = function;
 }
 
-void wxWindowDC::SetTextForeground( const wxColour &col )
+void wxWindowDCImpl::SetTextForeground( const wxColour &col )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     // don't set m_textForegroundColour to an invalid colour as we'd crash
     // later then (we use m_textForegroundColour.GetColor() without checking
     // in a few places)
-    if ( !col.Ok() || (m_textForegroundColour == col) )
+    if ( !col.IsOk() || (m_textForegroundColour == col) )
         return;
 
     m_textForegroundColour = col;
 
-    if (m_window)
+    if (m_x11window)
     {
         m_textForegroundColour.CalcPixel( m_cmap );
         XSetForeground( (Display*) m_display, (GC) m_textGC, m_textForegroundColour.GetPixel() );
     }
 }
 
-void wxWindowDC::SetTextBackground( const wxColour &col )
+void wxWindowDCImpl::SetTextBackground( const wxColour &col )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     // same as above
-    if ( !col.Ok() || (m_textBackgroundColour == col) )
+    if ( !col.IsOk() || (m_textBackgroundColour == col) )
         return;
 
     m_textBackgroundColour = col;
 
-    if (m_window)
+    if (m_x11window)
     {
         m_textBackgroundColour.CalcPixel( m_cmap );
         XSetBackground( (Display*) m_display, (GC) m_textGC, m_textBackgroundColour.GetPixel() );
     }
 }
 
-void wxWindowDC::SetBackgroundMode( int mode )
+void wxWindowDCImpl::SetBackgroundMode( int mode )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     m_backgroundMode = mode;
 
@@ -1889,7 +2167,7 @@ void wxWindowDC::SetBackgroundMode( int mode )
     GrSetGCUseBackground((GC) m_textGC, mode == wxTRANSPARENT ? FALSE : TRUE);
 #endif
 
-    if (!m_window) return;
+    if (!m_x11window) return;
 
     // CMB 21/7/98: fill style of cross-hatch brushes is affected by
     // transparent/solid background mode
@@ -1901,28 +2179,34 @@ void wxWindowDC::SetBackgroundMode( int mode )
     }
 }
 
-void wxWindowDC::SetPalette( const wxPalette& palette )
+void wxWindowDCImpl::SetPalette( const wxPalette& WXUNUSED(palette) )
 {
 #if 0
-    if (m_window)
+    if (m_x11window)
     {
-        if (palette.Ok())
+        if (palette.IsOk())
             /* Use GetXColormap */
-            XSetWindowColormap ((Display*) m_display, (Window) m_window->GetXWindow(),
+            XSetWindowColormap ((Display*) m_display, (Window) m_x11window->GetXWindow(),
             (Colormap) palette.GetXColormap());
         else
             /* Use wxGetMainColormap */
-            XSetWindowColormap ((Display*) m_display, (Window) m_window->GetXWindow(),
+            XSetWindowColormap ((Display*) m_display, (Window) m_x11window->GetXWindow(),
             (Colormap) wxTheApp->GetMainColormap(m_display));
     }
 #endif
 }
 
-void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
+void wxWindowDCImpl::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
+
+    if (!m_x11window) return;
+
+    if (width <= 0)
+        width = 1;
 
-    if (!m_window) return;
+    if (height <= 0)
+        height = 1;
 
     wxRect rect;
     rect.x = XLOG2DEV(x);
@@ -1930,19 +2214,19 @@ void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoo
     rect.width = XLOG2DEVREL(width);
     rect.height = YLOG2DEVREL(height);
 
-    if (!m_currentClippingRegion.IsNull())
+    if (!m_currentClippingRegion.IsEmpty())
         m_currentClippingRegion.Intersect( rect );
     else
-        m_currentClippingRegion.Union( rect );
+        m_currentClippingRegion = rect;
 
 #if USE_PAINT_REGION
-    if (!m_paintClippingRegion.IsNull())
+    if (!m_paintClippingRegion.IsEmpty())
         m_currentClippingRegion.Intersect( m_paintClippingRegion );
 #endif
 
     wxCoord xx, yy, ww, hh;
     m_currentClippingRegion.GetBox( xx, yy, ww, hh );
-    wxDC::DoSetClippingRegion( xx, yy, ww, hh );
+    wxX11DCImpl::DoSetClippingRegion( xx, yy, ww, hh );
 
     XSetRegion( (Display*) m_display, (GC) m_penGC, (Region) m_currentClippingRegion.GetX11Region() );
     XSetRegion( (Display*) m_display, (GC) m_brushGC, (Region) m_currentClippingRegion.GetX11Region() );
@@ -1950,9 +2234,9 @@ void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoo
     XSetRegion( (Display*) m_display, (GC) m_bgGC, (Region) m_currentClippingRegion.GetX11Region() );
 }
 
-void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion& region )
+void wxWindowDCImpl::DoSetDeviceClippingRegion( const wxRegion& region )
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
     if (region.Empty())
     {
@@ -1960,21 +2244,21 @@ void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion& region )
         return;
     }
 
-    if (!m_window) return;
+    if (!m_x11window) return;
 
-    if (!m_currentClippingRegion.IsNull())
+    if (!m_currentClippingRegion.IsEmpty())
         m_currentClippingRegion.Intersect( region );
     else
-        m_currentClippingRegion.Union( region );
+        m_currentClippingRegion = region;
 
 #if USE_PAINT_REGION
-    if (!m_paintClippingRegion.IsNull())
+    if (!m_paintClippingRegion.IsEmpty())
         m_currentClippingRegion.Intersect( m_paintClippingRegion );
 #endif
 
     wxCoord xx, yy, ww, hh;
     m_currentClippingRegion.GetBox( xx, yy, ww, hh );
-    wxDC::DoSetClippingRegion( xx, yy, ww, hh );
+    wxX11DCImpl::DoSetClippingRegion( xx, yy, ww, hh );
 
     XSetRegion( (Display*) m_display, (GC) m_penGC, (Region) m_currentClippingRegion.GetX11Region() );
     XSetRegion( (Display*) m_display, (GC) m_brushGC, (Region) m_currentClippingRegion.GetX11Region() );
@@ -1982,11 +2266,11 @@ void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion& region )
     XSetRegion( (Display*) m_display, (GC) m_bgGC, (Region) m_currentClippingRegion.GetX11Region() );
 }
 
-void wxWindowDC::DestroyClippingRegion()
+void wxWindowDCImpl::DestroyClippingRegion()
 {
-    wxCHECK_RET( Ok(), wxT("invalid window dc") );
+    wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
-    wxDC::DestroyClippingRegion();
+    wxDCImpl::DestroyClippingRegion();
 
     m_currentClippingRegion.Clear();
 
@@ -1995,7 +2279,7 @@ void wxWindowDC::DestroyClippingRegion()
         m_currentClippingRegion.Union( m_paintClippingRegion );
 #endif
 
-    if (!m_window) return;
+    if (!m_x11window) return;
 
     if (m_currentClippingRegion.IsEmpty())
     {
@@ -2013,7 +2297,7 @@ void wxWindowDC::DestroyClippingRegion()
     }
 }
 
-void wxWindowDC::Destroy()
+void wxWindowDCImpl::Destroy()
 {
     if (m_penGC) wxFreePoolGC( (GC) m_penGC );
     m_penGC = NULL;
@@ -2025,17 +2309,17 @@ void wxWindowDC::Destroy()
     m_bgGC = NULL;
 }
 
-void wxWindowDC::ComputeScaleAndOrigin()
+void wxWindowDCImpl::ComputeScaleAndOrigin()
 {
     /* CMB: copy scale to see if it changes */
     double origScaleX = m_scaleX;
     double origScaleY = m_scaleY;
 
-    wxDC::ComputeScaleAndOrigin();
+    wxDCImpl::ComputeScaleAndOrigin();
 
     /* CMB: if scale has changed call SetPen to recalulate the line width */
     if ((m_scaleX != origScaleX || m_scaleY != origScaleY) &&
-        (m_pen.Ok()))
+        (m_pen.IsOk()))
     {
       /* this is a bit artificial, but we need to force wxDC to think
          the pen has changed */
@@ -2045,12 +2329,12 @@ void wxWindowDC::ComputeScaleAndOrigin()
   }
 }
 
-wxSize wxWindowDC::GetPPI() const
+wxSize wxWindowDCImpl::GetPPI() const
 {
     return wxSize(100, 100);
 }
 
-int wxWindowDC::GetDepth() const
+int wxWindowDCImpl::GetDepth() const
 {
     wxFAIL_MSG(wxT("not implemented"));
 
@@ -2061,39 +2345,40 @@ int wxWindowDC::GetDepth() const
 // wxClientDC
 //-----------------------------------------------------------------------------
 
-IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC)
+IMPLEMENT_ABSTRACT_CLASS(wxClientDCImpl, wxWindowDCImpl)
 
-wxClientDC::wxClientDC( wxWindow *window )
-          : wxWindowDC( window )
+wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *window )
+          : wxWindowDCImpl( owner, window )
 {
     wxCHECK_RET( window, _T("NULL window in wxClientDC::wxClientDC") );
-    
-    m_window = (WXWindow*) window->GetClientWindow();
-    
-#if wxUSE_TWO_WINDOWS
-#else
+
+    m_x11window = (WXWindow*) window->GetClientAreaWindow();
+
+    // Adjust the client area when the wxWindow is not using 2 X11 windows.
+    if (m_x11window == (WXWindow*) window->GetMainWindow())
+    {
         wxPoint ptOrigin = window->GetClientAreaOrigin();
         SetDeviceOrigin(ptOrigin.x, ptOrigin.y);
         wxSize size = window->GetClientSize();
-        SetClippingRegion(wxPoint(0, 0), size);
-#endif
+        DoSetClippingRegion( 0, 0, size.x, size.y );
+    }
 }
 
-void wxClientDC::DoGetSize(int *width, int *height) const
+void wxClientDCImpl::DoGetSize(int *width, int *height) const
 {
-    wxCHECK_RET( m_owner, _T("GetSize() doesn't work without window") );
+    wxCHECK_RET( m_window, _T("GetSize() doesn't work without window") );
 
-    m_owner->GetClientSize( width, height );
+    m_window->GetClientSize( width, height );
 }
 
 // ----------------------------------------------------------------------------
 // wxPaintDC
 // ----------------------------------------------------------------------------
 
-IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxClientDC)
+IMPLEMENT_ABSTRACT_CLASS(wxPaintDCImpl, wxClientDCImpl)
 
-wxPaintDC::wxPaintDC(wxWindow* window)
-  : wxClientDC(window)
+wxPaintDCImpl::wxPaintDCImpl(wxDC *owner, wxWindow* window)
+  : wxClientDCImpl(owner, window)
 {
 #if USE_PAINT_REGION
     if (!window->GetClipPaintRegion())
@@ -2120,8 +2405,15 @@ wxPaintDC::wxPaintDC(wxWindow* window)
 class wxDCModule : public wxModule
 {
 public:
-    bool OnInit();
-    void OnExit();
+    // we must be cleaned up before wxDisplayModule which closes the global
+    // display
+    wxDCModule()
+    {
+        AddDependency(wxClassInfo::FindClass(_T("wxX11DisplayModule")));
+    }
+
+    bool OnInit() { wxInitGCPool(); return true; }
+    void OnExit() { wxCleanUpGCPool(); }
 
 private:
     DECLARE_DYNAMIC_CLASS(wxDCModule)
@@ -2129,13 +2421,3 @@ private:
 
 IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule)
 
-bool wxDCModule::OnInit()
-{
-    wxInitGCPool();
-    return TRUE;
-}
-
-void wxDCModule::OnExit()
-{
-    wxCleanUpGCPool();
-}