Moved hGCClipRgn handling to the graphics driver.

diff --git a/dlls/gdi/gdi_private.h b/dlls/gdi/gdi_private.h
index a4d2078..3928153 100644
--- a/dlls/gdi/gdi_private.h
+++ b/dlls/gdi/gdi_private.h
@@ -140,7 +140,7 @@
     INT      (*pSetDIBits)(PHYSDEV,HBITMAP,UINT,UINT,LPCVOID,const BITMAPINFO*,UINT);
     INT      (*pSetDIBitsToDevice)(PHYSDEV,INT,INT,DWORD,DWORD,INT,INT,UINT,UINT,LPCVOID,
                                    const BITMAPINFO*,UINT);
-    VOID     (*pSetDeviceClipping)(PHYSDEV,HRGN);
+    VOID     (*pSetDeviceClipping)(PHYSDEV,HRGN,HRGN);
     BOOL     (*pSetDeviceGammaRamp)(PHYSDEV,LPVOID);
     INT      (*pSetMapMode)(PHYSDEV,INT);
     DWORD    (*pSetMapperFlags)(PHYSDEV,DWORD);
diff --git a/dlls/wineps/clipping.c b/dlls/wineps/clipping.c
index 2dfa37c..5b07ee6 100644
--- a/dlls/wineps/clipping.c
+++ b/dlls/wineps/clipping.c
@@ -27,7 +27,7 @@
 /***********************************************************************
  *           PSDRV_SetDeviceClipping
  */
-VOID PSDRV_SetDeviceClipping( PSDRV_PDEVICE *physDev, HRGN ignored )
+void PSDRV_SetDeviceClipping( PSDRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn )
 {
     /* We could set a dirty flag here to speed up PSDRV_SetClip */
     return;
diff --git a/dlls/x11drv/bitblt.c b/dlls/x11drv/bitblt.c
index 9579dff..0f01832 100644
--- a/dlls/x11drv/bitblt.c
+++ b/dlls/x11drv/bitblt.c
@@ -31,7 +31,6 @@
 #include "wingdi.h"
 #include "winreg.h"
 #include "winuser.h"
-#include "gdi.h"
 #include "x11drv.h"
 #include "wine/debug.h"
 
@@ -1142,7 +1141,7 @@
     rect.bottom = yDst + heightDst;
     if (widthDst < 0) SWAP_INT32( &rect.left, &rect.right );
     if (heightDst < 0) SWAP_INT32( &rect.top, &rect.bottom );
-    GetRgnBox( physDevDst->dc->hGCClipRgn, &clipRect );
+    GetRgnBox( physDevDst->region, &clipRect );
     if (!IntersectRect( visRectDst, &rect, &clipRect )) return FALSE;
 
       /* Get the source visible rectangle */
diff --git a/dlls/x11drv/clipping.c b/dlls/x11drv/clipping.c
index 5f1515c..2072117 100644
--- a/dlls/x11drv/clipping.c
+++ b/dlls/x11drv/clipping.c
@@ -109,11 +109,13 @@
 /***********************************************************************
  *           X11DRV_SetDeviceClipping
  */
-void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN hrgn )
+void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn )
 {
     RGNDATA *data;
 
-    if (!(data = X11DRV_GetRegionData( hrgn, 0 ))) return;
+    CombineRgn( physDev->region, vis_rgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY );
+    if (!(data = X11DRV_GetRegionData( physDev->region, 0 ))) return;
+
     wine_tsx11_lock();
     XSetClipRectangles( gdi_display, physDev->gc, physDev->org.x, physDev->org.y,
                         (XRectangle *)data->Buffer, data->rdh.nCount, YXBanded );
diff --git a/dlls/x11drv/graphics.c b/dlls/x11drv/graphics.c
index d1f2466..41f0d99 100644
--- a/dlls/x11drv/graphics.c
+++ b/dlls/x11drv/graphics.c
@@ -1284,12 +1284,15 @@
 {
     XImage *image;
     RECT rect;
+    POINT pt;
 
     TRACE("X11DRV_ExtFloodFill %d,%d %06lx %d\n", x, y, color, fillType );
 
-    if (!PtVisible( physDev->hdc, x, y )) return FALSE;
-    if (GetClipBox( physDev->hdc, &rect ) == ERROR) return FALSE;
-    LPtoDP( physDev->hdc, (LPPOINT)&rect, 2 );
+    pt.x = x;
+    pt.y = y;
+    LPtoDP( physDev->hdc, &pt, 1 );
+    if (!PtInRegion( physDev->region, pt.x, pt.y )) return FALSE;
+    GetRgnBox( physDev->region, &rect );
 
     wine_tsx11_lock();
     image = XGetImage( gdi_display, physDev->drawable,
@@ -1301,10 +1304,6 @@
 
     if (X11DRV_SetupGCForBrush( physDev ))
     {
-        POINT pt;
-	pt.x = x;
-	pt.y = y;
-	LPtoDP(physDev->hdc, &pt, 1);
 	/* Update the pixmap from the DIB section */
 	X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
 
diff --git a/dlls/x11drv/init.c b/dlls/x11drv/init.c
index f2c8e4c..89843b8 100644
--- a/dlls/x11drv/init.c
+++ b/dlls/x11drv/init.c
@@ -95,10 +95,8 @@
     if (!X11DRV_DC_Funcs) X11DRV_DC_Funcs = dc->funcs;  /* hack */
 
     physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*physDev) );
-    if(!physDev) {
-        ERR("Can't allocate physDev\n");
-	return FALSE;
-    }
+    if (!physDev) return FALSE;
+
     *pdev = physDev;
     physDev->hdc = dc->hSelf;
     physDev->dc  = dc;  /* FIXME */
@@ -113,11 +111,7 @@
         physDev->drawable  = root_window;
         physDev->depth     = screen_depth;
     }
-    physDev->org.x = physDev->org.y = 0;
-    physDev->drawable_org.x = physDev->drawable_org.y = 0;
-
-    physDev->current_pf   = 0;
-    physDev->used_visuals = 0;
+    physDev->region = CreateRectRgn( 0, 0, 0, 0 );
 
     wine_tsx11_lock();
     physDev->gc = XCreateGC( gdi_display, physDev->drawable, 0, NULL );
@@ -136,6 +130,7 @@
 {
     if(physDev->xrender)
       X11DRV_XRender_DeleteDC( physDev );
+    DeleteObject( physDev->region );
     wine_tsx11_lock();
     XFreeGC( gdi_display, physDev->gc );
     while (physDev->used_visuals-- > 0)
diff --git a/dlls/x11drv/text.c b/dlls/x11drv/text.c
index 85dde73..5d88a52 100644
--- a/dlls/x11drv/text.c
+++ b/dlls/x11drv/text.c
@@ -56,6 +56,7 @@
     XChar2b		*str2b = NULL;
     BOOL		dibUpdateFlag = FALSE;
     BOOL                result = TRUE;
+    HRGN                saved_region = 0;
     POINT               pt;
     DC *dc = physDev->dc;
     UINT align = GetTextAlign( physDev->hdc );
@@ -218,8 +219,12 @@
 
     if (flags & ETO_CLIPPED)
     {
-        SaveVisRgn16( HDC_16(physDev->hdc) );
-        IntersectVisRect16( HDC_16(physDev->hdc), lprect->left, lprect->top, lprect->right, lprect->bottom );
+        HRGN clip_region = CreateRectRgn( lprect->left, lprect->top, lprect->right, lprect->bottom );
+        /* make a copy of the current device region */
+        saved_region = CreateRectRgn( 0, 0, 0, 0 );
+        CombineRgn( saved_region, physDev->region, 0, RGN_COPY );
+        X11DRV_SetDeviceClipping( physDev, saved_region, clip_region );
+        DeleteObject( clip_region );
     }
 
       /* Draw the text background if necessary */
@@ -411,7 +416,12 @@
     }
     wine_tsx11_unlock();
 
-    if (flags & ETO_CLIPPED) RestoreVisRgn16( HDC_16(physDev->hdc) );
+    if (flags & ETO_CLIPPED)
+    {
+        /* restore the device region */
+        X11DRV_SetDeviceClipping( physDev, saved_region, 0 );
+        DeleteObject( saved_region );
+    }
     goto END;
 
 FAIL:
diff --git a/dlls/x11drv/x11drv.h b/dlls/x11drv/x11drv.h
index 2975646..9f756de 100644
--- a/dlls/x11drv/x11drv.h
+++ b/dlls/x11drv/x11drv.h
@@ -91,6 +91,7 @@
     Drawable      drawable;
     POINT         org;          /* DC origin relative to drawable */
     POINT         drawable_org; /* Origin of drawable relative to screen */
+    HRGN          region;       /* Device region (visible region & clip region) */
     X_PHYSFONT    font;
     X_PHYSPEN     pen;
     X_PHYSBRUSH   brush;
@@ -170,6 +171,7 @@
 				 UINT flags, const RECT *lprect,
 				 LPCWSTR str, UINT count, const INT *lpDx );
 extern LONG X11DRV_SetBitmapBits( HBITMAP hbitmap, const void *bits, LONG count );
+extern void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn );
 extern INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest,
 				       INT yDest, DWORD cx, DWORD cy,
 				       INT xSrc, INT ySrc,
diff --git a/dlls/x11drv/xrender.c b/dlls/x11drv/xrender.c
index 4df7c76..e335d74 100644
--- a/dlls/x11drv/xrender.c
+++ b/dlls/x11drv/xrender.c
@@ -952,6 +952,7 @@
     int textPixel, backgroundPixel;
     INT *deltas = NULL;
     INT char_extra;
+    HRGN saved_region = 0;
     UINT align = GetTextAlign( hdc );
     COLORREF textColor = GetTextColor( hdc );
 
@@ -1127,8 +1128,12 @@
 
     if (flags & ETO_CLIPPED)
     {
-        SaveVisRgn16( HDC_16(hdc) );
-        IntersectVisRect16( HDC_16(hdc), lprect->left, lprect->top, lprect->right, lprect->bottom );
+        HRGN clip_region = CreateRectRgn( lprect->left, lprect->top, lprect->right, lprect->bottom );
+        /* make a copy of the current device region */
+        saved_region = CreateRectRgn( 0, 0, 0, 0 );
+        CombineRgn( saved_region, physDev->region, 0, RGN_COPY );
+        X11DRV_SetDeviceClipping( physDev, saved_region, clip_region );
+        DeleteObject( clip_region );
     }
 
     if(X11DRV_XRender_Installed) {
@@ -1151,7 +1156,7 @@
                   physDev->xrender->pict, hdc, physDev->drawable);
 	}
 
-	if ((data = X11DRV_GetRegionData( physDev->dc->hGCClipRgn, 0 )))
+	if ((data = X11DRV_GetRegionData( physDev->region, 0 )))
 	{
 	    wine_tsx11_lock();
 	    pXRenderSetPictureClipRectangles( gdi_display, physDev->xrender->pict,
@@ -1465,7 +1470,11 @@
         HeapFree(GetProcessHeap(), 0, deltas);
 
     if (flags & ETO_CLIPPED)
-        RestoreVisRgn16( HDC_16(hdc) );
+    {
+        /* restore the device region */
+        X11DRV_SetDeviceClipping( physDev, saved_region, 0 );
+        DeleteObject( saved_region );
+    }
 
     retv = TRUE;
 
diff --git a/include/gdi.h b/include/gdi.h
index afb6262..3c45695 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -115,7 +115,6 @@
     int           flags;
     HRGN          hClipRgn;     /* Clip region (may be 0) */
     HRGN          hVisRgn;      /* Visible region (must never be 0) */
-    HRGN          hGCClipRgn;   /* GC clip region (ClipRgn AND VisRgn) */
     HPEN          hPen;
     HBRUSH        hBrush;
     HFONT         hFont;
diff --git a/objects/clipping.c b/objects/clipping.c
index de15845..08382a4 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -39,8 +39,6 @@
  */
 void CLIPPING_UpdateGCRegion( DC * dc )
 {
-    if (!dc->hGCClipRgn) dc->hGCClipRgn = CreateRectRgn( 0, 0, 0, 0 );
-
     if (!dc->hVisRgn)
     {
         ERR("hVisRgn is zero. Please report this.\n" );
@@ -49,12 +47,8 @@
 
     if (dc->flags & DC_DIRTY) ERR( "DC is dirty. Please report this.\n" );
 
-    if (!dc->hClipRgn)
-        CombineRgn( dc->hGCClipRgn, dc->hVisRgn, 0, RGN_COPY );
-    else
-        CombineRgn(dc->hGCClipRgn, dc->hClipRgn, dc->hVisRgn, RGN_AND);
     if (dc->funcs->pSetDeviceClipping)
-        dc->funcs->pSetDeviceClipping( dc->physDev, dc->hGCClipRgn );
+        dc->funcs->pSetDeviceClipping( dc->physDev, dc->hVisRgn, dc->hClipRgn );
 }
 
 
@@ -345,20 +339,18 @@
  */
 BOOL WINAPI PtVisible( HDC hdc, INT x, INT y )
 {
-    BOOL ret = FALSE;
+    POINT pt;
+    BOOL ret;
     DC *dc = DC_GetDCUpdate( hdc );
 
     TRACE("%p %d,%d\n", hdc, x, y );
     if (!dc) return FALSE;
-    if (dc->hGCClipRgn)
-    {
-        POINT pt;
 
-        pt.x = x;
-        pt.y = y;
-        LPtoDP( hdc, &pt, 1 );
-        ret = PtInRegion( dc->hGCClipRgn, pt.x, pt.y );
-    }
+    pt.x = x;
+    pt.y = y;
+    LPtoDP( hdc, &pt, 1 );
+    ret = PtInRegion( dc->hVisRgn, pt.x, pt.y );
+    if (ret && dc->hClipRgn) ret = PtInRegion( dc->hClipRgn, pt.x, pt.y );
     GDI_ReleaseObj( hdc );
     return ret;
 }
@@ -369,26 +361,23 @@
  */
 BOOL WINAPI RectVisible( HDC hdc, const RECT* rect )
 {
-    BOOL ret = FALSE;
+    RECT tmpRect;
+    BOOL ret;
     DC *dc = DC_GetDCUpdate( hdc );
     if (!dc) return FALSE;
     TRACE("%p %ld,%ldx%ld,%ld\n", hdc, rect->left, rect->top, rect->right, rect->bottom );
-    if (dc->hGCClipRgn)
-    {
-        POINT pt[2];
-	RECT tmpRect;
 
-        pt[0].x = rect->left;
-        pt[0].y = rect->top;
-        pt[1].x = rect->right;
-        pt[1].y = rect->bottom;
-        LPtoDP( hdc, pt, 2 );
-	tmpRect.left	= pt[0].x;
-	tmpRect.top	= pt[0].y;
-	tmpRect.right	= pt[1].x;
-	tmpRect.bottom	= pt[1].y;
-        ret = RectInRegion( dc->hGCClipRgn, &tmpRect );
+    tmpRect = *rect;
+    LPtoDP( hdc, (POINT *)&tmpRect, 2 );
+
+    if (dc->hClipRgn)
+    {
+        HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
+        CombineRgn( hrgn, dc->hVisRgn, dc->hClipRgn, RGN_AND );
+        ret = RectInRegion( hrgn, &tmpRect );
+        DeleteObject( hrgn );
     }
+    else ret = RectInRegion( dc->hVisRgn, &tmpRect );
     GDI_ReleaseObj( hdc );
     return ret;
 }
@@ -402,7 +391,14 @@
     INT ret;
     DC *dc = DC_GetDCUpdate( hdc );
     if (!dc) return ERROR;
-    ret = GetRgnBox( dc->hGCClipRgn, rect );
+    if (dc->hClipRgn)
+    {
+        HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
+        CombineRgn( hrgn, dc->hVisRgn, dc->hClipRgn, RGN_AND );
+        ret = GetRgnBox( hrgn, rect );
+        DeleteObject( hrgn );
+    }
+    else ret = GetRgnBox( dc->hVisRgn, rect );
     DPtoLP( hdc, (LPPOINT)rect, 2 );
     GDI_ReleaseObj( hdc );
     return ret;
diff --git a/objects/dc.c b/objects/dc.c
index bd11b7a..6c5430a 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -78,7 +78,6 @@
     dc->flags               = 0;
     dc->hClipRgn            = 0;
     dc->hVisRgn             = 0;
-    dc->hGCClipRgn          = 0;
     dc->hPen                = GetStockObject( BLACK_PEN );
     dc->hBrush              = GetStockObject( WHITE_BRUSH );
     dc->hFont               = GetStockObject( SYSTEM_FONT );
@@ -335,7 +334,7 @@
 
     /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
 
-    newdc->hGCClipRgn = newdc->hVisRgn = 0;
+    newdc->hVisRgn = 0;
     if (dc->hClipRgn)
     {
 	newdc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
@@ -764,7 +763,6 @@
 	dc->saveLevel--;
         if (dcs->hClipRgn) DeleteObject( dcs->hClipRgn );
         if (dcs->hVisRgn) DeleteObject( dcs->hVisRgn );
-        if (dcs->hGCClipRgn) DeleteObject( dcs->hGCClipRgn );
         PATH_DestroyGdiPath(&dcs->path);
         GDI_FreeObject( hdcs, dcs );
     }
@@ -782,7 +780,6 @@
 
     if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
     if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
-    if (dc->hGCClipRgn) DeleteObject( dc->hGCClipRgn );
     PATH_DestroyGdiPath(&dc->path);
 
     GDI_FreeObject( hdc, dc );