Changed DC members w.hVisRgn, w.hClipRgn, amd w.hGCClipRgn to
coordinates relative to the device, not the DC origin. This is
necessary to correctly implement GetClipRgn16 and InquireVisRgn.
SelectVisRgn also expects region in device-relative coordinates.
Adapted the rest of Wine to this coordinate change.
Implemented ExtSelectClipRgn.

diff --git a/graphics/path.c b/graphics/path.c
index bd5dffd..23698d3 100644
--- a/graphics/path.c
+++ b/graphics/path.c
@@ -424,7 +424,7 @@
 BOOL32 WINAPI SelectClipPath32(HDC32 hdc, INT32 iMode)
 {
    GdiPath *pPath;
-   HRGN32  hrgnPath, hrgnClip;
+   HRGN32  hrgnPath;
    BOOL32  success;
    
    /* Get pointer to path */
@@ -444,17 +444,7 @@
    /* Construct a region from the path */
    if(PATH_PathToRegion(pPath, GetPolyFillMode32(hdc), &hrgnPath))
    {
-      hrgnClip=CreateRectRgn32(0, 0, 0, 0);
-      if(hrgnClip==(HRGN32)0)
-         success=FALSE;
-      else
-      {
-         success=(GetClipRgn32(hdc, hrgnClip)!=-1) &&
-	    (CombineRgn32(hrgnClip, hrgnClip, hrgnPath, iMode)!=ERROR) &&
-	    (SelectClipRgn32(hdc, hrgnClip)!=ERROR);
-	 DeleteObject32(hrgnClip);
-      }
-
+      success = ExtSelectClipRgn( hdc, hrgnPath, iMode ) != ERROR;
       DeleteObject32(hrgnPath);
 
       /* Empty the path */
diff --git a/graphics/x11drv/bitblt.c b/graphics/x11drv/bitblt.c
index 87ddb15..fc146d7 100644
--- a/graphics/x11drv/bitblt.c
+++ b/graphics/x11drv/bitblt.c
@@ -1035,7 +1035,6 @@
     if (widthDst < 0) SWAP_INT32( &rect.left, &rect.right );
     if (heightDst < 0) SWAP_INT32( &rect.top, &rect.bottom );
     GetRgnBox32( dcDst->w.hGCClipRgn, &clipRect );
-    OffsetRect32( &clipRect, dcDst->w.DCOrgX, dcDst->w.DCOrgY );
     if (!IntersectRect32( visRectDst, &rect, &clipRect )) return FALSE;
 
       /* Get the source visible rectangle */
@@ -1046,7 +1045,6 @@
     if (heightSrc < 0) SWAP_INT32( &rect.top, &rect.bottom );
     /* Apparently the clip region is only for output, so use hVisRgn here */
     GetRgnBox32( dcSrc->w.hVisRgn, &clipRect );
-    OffsetRect32( &clipRect, dcSrc->w.DCOrgX, dcSrc->w.DCOrgY );
     if (!IntersectRect32( visRectSrc, &rect, &clipRect )) return FALSE;
 
       /* Intersect the rectangles */
diff --git a/graphics/x11drv/clipping.c b/graphics/x11drv/clipping.c
index bf5f880..60f9319 100644
--- a/graphics/x11drv/clipping.c
+++ b/graphics/x11drv/clipping.c
@@ -54,8 +54,8 @@
     else
         pXrect = NULL;
 
-    TSXSetClipRectangles( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY, 
-                pXrect, obj->rgn->numRects, YXBanded );
+    TSXSetClipRectangles( display, dc->u.x.gc, 0, 0,
+                          pXrect, obj->rgn->numRects, YXBanded );
 
     if(pXrect)
         HeapFree( GetProcessHeap(), 0, pXrect );
diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c
index b4b70d5..750c757 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -619,7 +619,8 @@
     if (!(tmpVisRgn = CreateRectRgn32( 0, 0, 0, 0 ))) return FALSE;
 
       /* Transform region into device co-ords */
-    if (!REGION_LPTODP( hdc, tmpVisRgn, hrgn )) {
+    if (  !REGION_LPTODP( hdc, tmpVisRgn, hrgn )
+        || OffsetRgn32( tmpVisRgn, dc->w.DCOrgX, dc->w.DCOrgY ) == ERROR) {
         DeleteObject32( tmpVisRgn );
 	return FALSE;
     }
@@ -638,8 +639,8 @@
     GetRgnBox32( dc->w.hGCClipRgn, &box );
     if (DC_SetupGCForBrush( dc ))
 	TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + box.left, dc->w.DCOrgY + box.top,
-		        box.right-box.left, box.bottom-box.top );
+		          box.left, box.top,
+		          box.right-box.left, box.bottom-box.top );
 
       /* Restore the visible region */
 
@@ -876,8 +877,8 @@
     if (GetRgnBox32( dc->w.hGCClipRgn, &rect ) == ERROR) return FALSE;
 
     if (!(image = XGetImage( display, dc->u.x.drawable,
-                             dc->w.DCOrgX + rect.left,
-                             dc->w.DCOrgY + rect.top,
+                             rect.left,
+                             rect.top,
                              rect.right - rect.left,
                              rect.bottom - rect.top,
                              AllPlanes, ZPixmap ))) return FALSE;
@@ -887,10 +888,10 @@
           /* ROP mode is always GXcopy for flood-fill */
         XSetFunction( display, dc->u.x.gc, GXcopy );
         X11DRV_InternalFloodFill(image, dc,
-                                 XLPTODP(dc,params->x) - rect.left,
-                                 YLPTODP(dc,params->y) - rect.top,
-                                 dc->w.DCOrgX + rect.left,
-                                 dc->w.DCOrgY + rect.top,
+                                 XLPTODP(dc,params->x) + dc->w.DCOrgX - rect.left,
+                                 YLPTODP(dc,params->y) + dc->w.DCOrgY - rect.top,
+                                 rect.left,
+                                 rect.top,
                                  COLOR_ToPhysical( dc, params->color ),
                                  params->fillType );
     }
diff --git a/graphics/x11drv/text.c b/graphics/x11drv/text.c
index 0b93e10..068b4cc 100644
--- a/graphics/x11drv/text.c
+++ b/graphics/x11drv/text.c
@@ -28,7 +28,6 @@
                    const RECT32 *lprect, LPCSTR str, UINT32 count,
                    const INT32 *lpDx )
 {
-    HRGN32		hRgnClip = 0;
     int 	        i;
     fontObject*		pfo;
     INT32	 	width, ascent, descent, xwidth, ywidth;
@@ -176,9 +175,9 @@
 
     if (flags & ETO_CLIPPED)
     {
-        hRgnClip = dc->w.hClipRgn;
-        CLIPPING_IntersectClipRect( dc, rect.left, rect.top, rect.right,
-                                    rect.bottom, CLIP_INTERSECT|CLIP_KEEPRGN );
+        SaveVisRgn( dc->hSelf );
+        CLIPPING_IntersectVisRect( dc, rect.left, rect.top, rect.right,
+                                   rect.bottom, FALSE );
     }
 
       /* Draw the text background if necessary */
@@ -331,10 +330,8 @@
     }
 
     if (flags & ETO_CLIPPED) 
-    {
-      SelectClipRgn32( dc->hSelf, hRgnClip );
-      DeleteObject32( hRgnClip );
-    }
+        RestoreVisRgn( dc->hSelf );
+
     return TRUE;
 }
 
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index b200bda..14fdda1 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -160,7 +160,7 @@
 190 pascal16 SetDCHook(word segptr long) THUNK_SetDCHook
 191 pascal   GetDCHook(word ptr) THUNK_GetDCHook
 192 pascal16 SetHookFlags(word word) SetHookFlags
-193 stub SetBoundsRect
+193 pascal16 SetBoundsRect(word ptr word) SetBoundsRect16
 194 pascal16 GetBoundsRect(word ptr word) GetBoundsRect16
 195 stub SelectBitmap
 196 pascal16 SetMetaFileBitsBetter(word) SetMetaFileBitsBetter
diff --git a/include/dc.h b/include/dc.h
index f94e0a2..74eadcd 100644
--- a/include/dc.h
+++ b/include/dc.h
@@ -28,6 +28,8 @@
 /* objects/clipping.c */
 INT32 CLIPPING_IntersectClipRect( DC * dc, INT32 left, INT32 top,
     INT32 right, INT32 bottom, UINT32 flags );
+INT32 CLIPPING_IntersectVisRect( DC * dc, INT32 left, INT32 top,
+    INT32 right, INT32 bottom, BOOL32 exclude );
 extern void CLIPPING_UpdateGCRegion( DC * dc );
 
 #endif /* __WINE_DC_H */
diff --git a/include/windows.h b/include/windows.h
index 2a23cc1..0bc876c 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -6584,6 +6584,7 @@
 VOID        WINAPI ExitProcess(DWORD);
 VOID        WINAPI ExitThread(DWORD);
 BOOL32      WINAPI ExitWindowsEx(UINT32,DWORD);
+INT32       WINAPI ExtSelectClipRgn(HDC32,HRGN32,INT32);
 DWORD       WINAPI ExpandEnvironmentStrings32A(LPCSTR,LPSTR,DWORD);
 DWORD       WINAPI ExpandEnvironmentStrings32W(LPCWSTR,LPWSTR,DWORD);
 #define     ExpandEnvironmentStrings WINELIB_NAME_AW(ExpandEnvironmentStrings)
diff --git a/objects/clipping.c b/objects/clipping.c
index 3f3ad30..1d87410 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -60,27 +60,7 @@
  */
 INT32 WINAPI SelectClipRgn32( HDC32 hdc, HRGN32 hrgn )
 {
-    INT32 retval;
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return ERROR;
-
-    TRACE(clipping, "%04x %04x\n", hdc, hrgn );
-
-    if (hrgn)
-    {
-	if (!dc->w.hClipRgn) dc->w.hClipRgn = CreateRectRgn32(0,0,0,0);
-	retval = CombineRgn32( dc->w.hClipRgn, hrgn, 0, RGN_COPY );
-    }
-    else
-    {
-	if (dc->w.hClipRgn) DeleteObject16( dc->w.hClipRgn );
-	dc->w.hClipRgn = 0;
-	retval = SIMPLEREGION; /* Clip region == whole DC */
-    }
-
-    CLIPPING_UpdateGCRegion( dc );
-    GDI_HEAP_UNLOCK( hdc );
-    return retval;
+    return ExtSelectClipRgn( hdc, hrgn, RGN_COPY );
 }
 
 /******************************************************************************
@@ -88,9 +68,44 @@
  */
 INT32 WINAPI ExtSelectClipRgn( HDC32 hdc, HRGN32 hrgn, INT32 fnMode )
 {
-    if (fnMode != RGN_COPY)
-        FIXME(clipping, "Unimplemented mode: %d\n", fnMode); 
-    return SelectClipRgn32( hdc, hrgn );
+    INT32 retval;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return ERROR;
+
+    TRACE( clipping, "%04x %04x %d\n", hdc, hrgn, fnMode );
+
+    if (!hrgn)
+    {
+        if (fnMode == RGN_COPY)
+        {
+            if (dc->w.hClipRgn) DeleteObject16( dc->w.hClipRgn );
+            dc->w.hClipRgn = 0;
+            retval = SIMPLEREGION; /* Clip region == whole DC */
+        }
+        else
+        {
+            FIXME(clipping, "Unimplemented: hrgn NULL in mode: %d\n", fnMode); 
+            return ERROR;
+        }
+    }
+    else 
+    {
+        if (!dc->w.hClipRgn)
+        {
+            RECT32 rect;
+            GetRgnBox32( dc->w.hVisRgn, &rect );
+            dc->w.hClipRgn = CreateRectRgnIndirect32( &rect );
+        }
+
+        OffsetRgn32( dc->w.hClipRgn, -dc->w.DCOrgX, -dc->w.DCOrgY );
+        retval = CombineRgn32( dc->w.hClipRgn, dc->w.hClipRgn, hrgn, fnMode );
+        OffsetRgn32( dc->w.hClipRgn, dc->w.DCOrgX, dc->w.DCOrgY );
+    }
+
+
+    CLIPPING_UpdateGCRegion( dc );
+    GDI_HEAP_UNLOCK( hdc );
+    return retval;
 }
 
 /***********************************************************************
@@ -180,6 +195,11 @@
     HRGN32 newRgn;
     INT32 ret;
 
+    left   += dc->w.DCOrgX;
+    right  += dc->w.DCOrgX;
+    top    += dc->w.DCOrgY;
+    bottom += dc->w.DCOrgY;
+
     if (!(newRgn = CreateRectRgn32( left, top, right, bottom ))) return ERROR;
     if (!dc->w.hClipRgn)
     {
@@ -293,19 +313,21 @@
 /***********************************************************************
  *           CLIPPING_IntersectVisRect
  *
- * Helper function for {Intersect,Exclude}VisRect
+ * Helper function for {Intersect,Exclude}VisRect, can be called from
+ * elsewhere (like ExtTextOut()) to skip redundant metafile update and
+ * coordinate conversion.
  */
-static INT32 CLIPPING_IntersectVisRect( DC * dc, INT32 left, INT32 top,
-                                        INT32 right, INT32 bottom,
-                                        BOOL32 exclude )
+INT32 CLIPPING_IntersectVisRect( DC * dc, INT32 left, INT32 top,
+                                 INT32 right, INT32 bottom,
+                                 BOOL32 exclude )
 {
     HRGN32 tempRgn, newRgn;
     INT32 ret;
 
-    left   = XLPTODP( dc, left );
-    right  = XLPTODP( dc, right );
-    top    = YLPTODP( dc, top );
-    bottom = YLPTODP( dc, bottom );
+    left   += dc->w.DCOrgX;
+    right  += dc->w.DCOrgX;
+    top    += dc->w.DCOrgY;
+    bottom += dc->w.DCOrgY;
 
     if (!(newRgn = CreateRectRgn32( 0, 0, 0, 0 ))) return ERROR;
     if (!(tempRgn = CreateRectRgn32( left, top, right, bottom )))
@@ -340,6 +362,12 @@
 {
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return ERROR;    
+
+    left   = XLPTODP( dc, left );
+    right  = XLPTODP( dc, right );
+    top    = YLPTODP( dc, top );
+    bottom = YLPTODP( dc, bottom );
+
     TRACE(clipping, "%04x %dx%d,%dx%d\n",
 	    hdc, left, top, right, bottom );
 
@@ -355,6 +383,12 @@
 {
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return ERROR;    
+
+    left   = XLPTODP( dc, left );
+    right  = XLPTODP( dc, right );
+    top    = YLPTODP( dc, top );
+    bottom = YLPTODP( dc, bottom );
+
     TRACE(clipping, "%04x %dx%d,%dx%d\n",
 	    hdc, left, top, right, bottom );
 
@@ -385,7 +419,8 @@
     if( dc->w.flags & DC_DIRTY ) UPDATE_DIRTY_DC(dc);
     dc->w.flags &= ~DC_DIRTY;
 
-    return PtInRegion32( dc->w.hGCClipRgn, XLPTODP(dc,x), YLPTODP(dc,y) );
+    return PtInRegion32( dc->w.hGCClipRgn, XLPTODP(dc,x) + dc->w.DCOrgX, 
+                                           YLPTODP(dc,y) + dc->w.DCOrgY );
 }
 
 
@@ -403,6 +438,7 @@
     /* copy rectangle to avoid overwriting by LPtoDP */
     tmpRect = *rect;
     LPtoDP16( hdc, (LPPOINT16)&tmpRect, 2 );
+    OffsetRect16( &tmpRect, dc->w.DCOrgX, dc->w.DCOrgY );
     return RectInRegion16( dc->w.hGCClipRgn, &tmpRect );
 }
 
@@ -427,6 +463,7 @@
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return ERROR;    
     ret = GetRgnBox16( dc->w.hGCClipRgn, rect );
+    OffsetRect16( rect, -dc->w.DCOrgX, -dc->w.DCOrgY );
     DPtoLP16( hdc, (LPPOINT16)rect, 2 );
     return ret;
 }
@@ -441,6 +478,7 @@
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return ERROR;    
     ret = GetRgnBox32( dc->w.hGCClipRgn, rect );
+    OffsetRect32( rect, -dc->w.DCOrgX, -dc->w.DCOrgY );
     DPtoLP32( hdc, (LPPOINT32)rect, 2 );
     return ret;
 }
@@ -456,10 +494,13 @@
       if( dc->w.hClipRgn )
       { 
 	/* this assumes that dc->w.hClipRgn is in coordinates
-	   relative to the DC origin (not device) */
+	   relative to the device (not DC origin) */
 
 	if( CombineRgn32(hRgn, dc->w.hClipRgn, 0, RGN_COPY) != ERROR )
+        {
+            OffsetRgn32( hRgn, -dc->w.DCOrgX, -dc->w.DCOrgY );
 	    return 1;
+        }
       }
       else return 0;
     return -1;
diff --git a/objects/dc.c b/objects/dc.c
index a787475..230f502 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -546,8 +546,11 @@
     newdc->w.breakRem         = dc->w.breakRem;
     newdc->w.MapMode          = dc->w.MapMode;
     newdc->w.GraphicsMode     = dc->w.GraphicsMode;
+#if 0
+    /* Apparently, the DC origin is not changed by [GS]etDCState */
     newdc->w.DCOrgX           = dc->w.DCOrgX;
     newdc->w.DCOrgY           = dc->w.DCOrgY;
+#endif
     newdc->w.CursPosX         = dc->w.CursPosX;
     newdc->w.CursPosY         = dc->w.CursPosY;
     newdc->w.ArcDirection     = dc->w.ArcDirection;
@@ -627,8 +630,11 @@
     dc->w.breakRem         = dcs->w.breakRem;
     dc->w.MapMode          = dcs->w.MapMode;
     dc->w.GraphicsMode     = dcs->w.GraphicsMode;
+#if 0
+    /* Apparently, the DC origin is not changed by [GS]etDCState */
     dc->w.DCOrgX           = dcs->w.DCOrgX;
     dc->w.DCOrgY           = dcs->w.DCOrgY;
+#endif
     dc->w.CursPosX         = dcs->w.CursPosX;
     dc->w.CursPosY         = dcs->w.CursPosY;
     dc->w.ArcDirection     = dcs->w.ArcDirection;
@@ -647,7 +653,15 @@
     dc->vportExtY          = dcs->vportExtY;
 
     if (!(dc->w.flags & DC_MEMORY)) dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
-    SelectClipRgn32( hdc, dcs->w.hClipRgn );
+
+    if (dcs->w.hClipRgn)
+    {
+        if (!dc->w.hClipRgn) dc->w.hClipRgn = CreateRectRgn32( 0, 0, 0, 0 );
+        CombineRgn32( dc->w.hClipRgn, dcs->w.hClipRgn, 0, RGN_COPY );
+        CLIPPING_UpdateGCRegion( dc );
+    }
+    else
+        dc->w.hClipRgn = 0;
 
     SelectObject32( hdc, dcs->w.hBitmap );
     SelectObject32( hdc, dcs->w.hBrush );
@@ -1516,3 +1530,12 @@
     return DCB_RESET;   /* bounding rectangle always empty */
 }
 
+/***********************************************************************
+ *           SetBoundsRect16    (GDI.193)
+ */
+UINT16 WINAPI SetBoundsRect16(HDC16 hdc, LPRECT16 rect, UINT16 flags)
+{
+    FIXME(dc, "(): stub\n");
+    return DCB_DISABLE;   /* bounding rectangle always empty */
+}
+
diff --git a/objects/dcvalues.c b/objects/dcvalues.c
index df7de09..3abf31a 100644
--- a/objects/dcvalues.c
+++ b/objects/dcvalues.c
@@ -129,6 +129,7 @@
 DC_GET_X_Y( DWORD, GetWindowExt, wndExtX, wndExtY )             /* GDI.96    */
 DC_GET_X_Y( DWORD, GetWindowOrg, wndOrgX, wndOrgY )             /* GDI.97    */
 DC_GET_VAL_16( HRGN16, InquireVisRgn, w.hVisRgn )               /* GDI.131   */
+DC_GET_VAL_16( HRGN16, GetClipRgn16, w.hClipRgn )               /* GDI.173   */
 DC_GET_X_Y( DWORD, GetBrushOrg, w.brushOrgX, w.brushOrgY )      /* GDI.149   */
 DC_GET_VAL_16( UINT16, GetTextAlign16, w.textAlign )            /* GDI.345   */
 DC_GET_VAL_32( UINT32, GetTextAlign32, w.textAlign )            /* GDI32.224 */
@@ -140,9 +141,3 @@
 DC_GET_VAL_EX( GetViewportOrgEx, vportOrgX, vportOrgY ) /* GDI.473 GDI32.240 */
 DC_GET_VAL_EX( GetWindowExtEx, wndExtX, wndExtY )       /* GDI.474 GDI32.242 */
 DC_GET_VAL_EX( GetWindowOrgEx, wndOrgX, wndOrgY )       /* GDI.475 GDI32.243 */
-
-/* this one is wrong - Windows returns region that
-   is relative to the device and not to the DC origin */
-
-DC_GET_VAL_16( HRGN16, GetClipRgn16, w.hClipRgn )              /* GDI.173    */
-
diff --git a/windows/dce.c b/windows/dce.c
index 25145c8..fbb8e09 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -497,6 +497,22 @@
     return hrgnVis;
 }
 
+/***********************************************************************
+ *           DCE_OffsetVisRgn
+ *
+ * Change region from DC-origin relative coordinates to screen coords.
+ */
+
+static void DCE_OffsetVisRgn( HDC32 hDC, HRGN32 hVisRgn )
+{
+    DC *dc;
+    if (!(dc = (DC *) GDI_GetObjPtr( hDC, DC_MAGIC ))) return;
+
+    OffsetRgn32( hVisRgn, dc->w.DCOrgX, dc->w.DCOrgY );
+
+    GDI_HEAP_UNLOCK( hDC );
+}
+
 
 /***********************************************************************
  *           DCE_SetDrawable
@@ -535,6 +551,7 @@
         dc->w.DCOrgY -= wndPtr->rectWindow.top;
         dc->u.x.drawable = wndPtr->window;
 
+#if 0
 	/* This is needed when we reuse a cached DC because
 	 * SetDCState() called by ReleaseDC() screws up DC
 	 * origins for child windows.
@@ -542,6 +559,7 @@
 
 	if( bSetClipOrigin )
 	    TSXSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY );
+#endif
     }
 }
 /***********************************************************************
@@ -552,9 +570,7 @@
  */
 INT16 DCE_ExcludeRgn( HDC32 hDC, WND* wnd, HRGN32 hRgn )
 {
-  INT16	   ret;
   POINT32  pt = {0, 0};
-  HRGN32   hRgnClip = GetClipRgn16( hDC );
   DCE     *dce = firstDCE;
 
   while (dce && (dce->hDC != hDC)) dce = dce->next;
@@ -570,14 +586,8 @@
   }
   else return ERROR;
   OffsetRgn32(hRgn, pt.x, pt.y);
-  if( hRgnClip ) ret = CombineRgn32( hRgnClip, hRgnClip, hRgn, RGN_DIFF );
-  else 
-  {
-      hRgnClip = InquireVisRgn( hDC );
-      ret = CombineRgn32( hRgn, hRgnClip, hRgn, RGN_DIFF );
-      SelectClipRgn32( hDC, hRgn );
-  }
-  return ret;
+
+  return ExtSelectClipRgn( hDC, hRgn, RGN_DIFF );
 }
 
 /***********************************************************************
@@ -755,6 +765,7 @@
 		else
 		    OffsetRgn32( hrgnVisible, -wndPtr->rectClient.left,
 					      -wndPtr->rectClient.top );
+                DCE_OffsetVisRgn( hdc, hrgnVisible );
 	    }
 	    else
 		hrgnVisible = CreateRectRgn32( 0, 0, 0, 0 );
@@ -764,7 +775,11 @@
                 (rootWindow == DefaultRootWindow(display)))
                  hrgnVisible = CreateRectRgn32( 0, 0, SYSMETRICS_CXSCREEN,
 						      SYSMETRICS_CYSCREEN );
-	    else hrgnVisible = DCE_GetVisRgn( hwnd, flags );
+	    else 
+            {
+                hrgnVisible = DCE_GetVisRgn( hwnd, flags );
+                DCE_OffsetVisRgn( hdc, hrgnVisible );
+            }
 
 	dc->w.flags &= ~DC_DIRTY;
 	dce->DCXflags &= ~DCX_DCEDIRTY;
@@ -785,7 +800,9 @@
 	TRACE(dc, "\tsaved VisRgn, clipRgn = %04x\n", hrgnClip);
 
 	SaveVisRgn( hdc );
-        CombineRgn32( hrgnVisible, InquireVisRgn( hdc ), hrgnClip,
+        CombineRgn32( hrgnVisible, hrgnClip, 0, RGN_COPY );
+        DCE_OffsetVisRgn( hdc, hrgnVisible );
+        CombineRgn32( hrgnVisible, InquireVisRgn( hdc ), hrgnVisible,
                       (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
 	SelectVisRgn( hdc, hrgnVisible );
     }
@@ -919,6 +936,7 @@
                                       (dce->DCXflags & DCX_EXCLUDERGN)? RGN_DIFF:RGN_AND);
 	       }
 	       dce->DCXflags &= ~DCX_DCEDIRTY;
+               DCE_OffsetVisRgn( hDC, hVisRgn );
 	       SelectVisRgn(hDC, hVisRgn);
 	       DeleteObject32( hVisRgn );
 	   }
diff --git a/windows/painting.c b/windows/painting.c
index c97dad1..9ddd9f1 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -138,13 +138,11 @@
         return 0;
     }
 
-    GetRgnBox16( InquireVisRgn(lps->hdc), &lps->rcPaint );
+    GetClipBox16( lps->hdc, &lps->rcPaint );
 
 TRACE(win,"box = (%i,%i - %i,%i)\n", lps->rcPaint.left, lps->rcPaint.top,
 		    lps->rcPaint.right, lps->rcPaint.bottom );
 
-    DPtoLP16( lps->hdc, (LPPOINT16)&lps->rcPaint, 2 );
-
     if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
     {
         wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
diff --git a/windows/scroll.c b/windows/scroll.c
index d8b06b3..b67d00a 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -147,9 +147,7 @@
                           const RECT32 *prLClip, HRGN32 hrgnUpdate,
                           LPRECT32 rcUpdate )
 {
-    RECT32 rDClip, rLClip;
-    HRGN32 hrgnClip = 0;
-    HRGN32 hrgnScrollClip = 0;
+    RECT32 rClip;
     POINT32 src, dest;
     INT32  ldx, ldy;
     DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
@@ -171,49 +169,23 @@
     /* compute device clipping region */
 
     if ( rc )
-    {
-	rLClip = *rc;
-	rDClip.left = XLPTODP(dc, rc->left); rDClip.right = XLPTODP(dc, rc->right);
-	rDClip.top = YLPTODP(dc, rc->top); rDClip.bottom = YLPTODP(dc, rc->bottom);
-    }
+	rClip = *rc;
     else /* maybe we should just return FALSE? */
-    {
-	GetClipBox32( hdc, &rDClip );
-	rLClip.left = XDPTOLP(dc, rDClip.left); rLClip.right = XDPTOLP(dc, rDClip.right);
-	rLClip.top = YDPTOLP(dc, rDClip.top); rLClip.bottom = YDPTOLP(dc, rDClip.bottom);
-    }
+	GetClipBox32( hdc, &rClip );
 
     if (prLClip)
-    {
-	RECT32 r;
+	IntersectRect32(&rClip,&rClip,prLClip);
 
-	r.left = XLPTODP(dc, prLClip->left); r.right = XLPTODP(dc, prLClip->right);
-	r.top = YLPTODP(dc, prLClip->top); r.bottom = YLPTODP(dc, prLClip->bottom);
-	IntersectRect32(&rLClip,&rLClip,prLClip);
-	IntersectRect32(&rDClip,&rDClip,&r);
-    }
-
-    if( rDClip.left >= rDClip.right || rDClip.top >= rDClip.bottom )
+    if( rClip.left >= rClip.right || rClip.top >= rClip.bottom )
     {
         GDI_HEAP_UNLOCK( hdc );
 	return FALSE;
     }
-    
-    hrgnClip = GetClipRgn16(hdc);
-    hrgnScrollClip = CreateRectRgnIndirect32(&rDClip);
+   
+    SaveVisRgn( hdc );
+    IntersectVisRect( hdc, rClip.left, rClip.top, 
+                           rClip.right, rClip.bottom ); 
 
-    if( hrgnClip )
-      {
-        /* change device clipping region directly */
-
-        CombineRgn32( hrgnScrollClip, hrgnClip, 0, RGN_COPY );
-        SetRectRgn32( hrgnClip, rDClip.left, rDClip.top,
-                      rDClip.right, rDClip.bottom );
-
-	CLIPPING_UpdateGCRegion( dc );
-      }
-    else
-        SelectClipRgn32( hdc, hrgnScrollClip );
 
     /* translate coordinates */
 
@@ -221,22 +193,22 @@
     ldy = dy * dc->wndExtY / dc->vportExtY;
 
     if (dx > 0)
-	dest.x = (src.x = rLClip.left) + ldx;
+	dest.x = (src.x = rClip.left) + ldx;
     else
-	src.x = (dest.x = rLClip.left) - ldx;
+	src.x = (dest.x = rClip.left) - ldx;
 
     if (dy > 0)
-	dest.y = (src.y = rLClip.top) + ldy;
+	dest.y = (src.y = rClip.top) + ldy;
     else
-	src.y = (dest.y = rLClip.top) - ldy;
+	src.y = (dest.y = rClip.top) - ldy;
 
     /* copy bits */
 
-    if( rDClip.right - rDClip.left > dx &&
-	rDClip.bottom - rDClip.top > dy )
+    if( rClip.right - rClip.left > ldx &&
+	rClip.bottom - rClip.top > ldy )
     {
-	ldx = rLClip.right - rLClip.left - ldx;
-	ldy = rLClip.bottom - rLClip.top - ldy;
+	ldx = rClip.right - rClip.left - ldx;
+	ldy = rClip.bottom - rClip.top - ldy;
 
 	if (!BitBlt32( hdc, dest.x, dest.y, ldx, ldy,
 		       hdc, src.x, src.y, SRCCOPY))
@@ -248,52 +220,32 @@
 
     /* restore clipping region */
 
-    if( hrgnClip )
-    {
-	CombineRgn32( hrgnClip, hrgnScrollClip, 0, RGN_COPY );
-	CLIPPING_UpdateGCRegion( dc );
-	SetRectRgn32( hrgnScrollClip, rDClip.left, rDClip.top, 
-                      rDClip.right, rDClip.bottom );
-    }
-    else
-        SelectClipRgn32( hdc, 0 );
+    RestoreVisRgn( hdc );
+
 
     /* compute update areas */
 
-    if (hrgnUpdate || rcUpdate)
+    if ( (hrgnUpdate || rcUpdate) && dc->w.hVisRgn )
     {
 	HRGN32 hrgn = (hrgnUpdate) ? hrgnUpdate : CreateRectRgn32( 0,0,0,0 );
+        HRGN32 hrgnClip;
 
-	if( dc->w.hVisRgn )
-	{
-	  CombineRgn32( hrgn, dc->w.hVisRgn, hrgnScrollClip, RGN_AND );
-	  OffsetRgn32( hrgn, dx, dy );
-	  CombineRgn32( hrgn, dc->w.hVisRgn, hrgn, RGN_DIFF );
-	  CombineRgn32( hrgn, hrgn, hrgnScrollClip, RGN_AND );
-	}
-	else
-	{
-	  RECT32 rect;
+        LPtoDP32( hdc, (LPPOINT32)&rClip, 2 );
+        OffsetRect32( &rClip, dc->w.DCOrgX, dc->w.DCOrgY );
+        hrgnClip = CreateRectRgnIndirect32( &rClip );
+        
+        CombineRgn32( hrgn, dc->w.hVisRgn, hrgnClip, RGN_AND );
+        OffsetRgn32( hrgn, dx, dy );
+        CombineRgn32( hrgn, dc->w.hVisRgn, hrgn, RGN_DIFF );
+        CombineRgn32( hrgn, hrgn, hrgnClip, RGN_AND );
+        OffsetRgn32( hrgn, -dc->w.DCOrgX, -dc->w.DCOrgY );
 
-          rect = rDClip;				/* vertical band */
-          if (dx > 0) rect.right = rect.left + dx;
-          else if (dx < 0) rect.left = rect.right + dx;
-          else SetRectEmpty32( &rect );
-          SetRectRgn32( hrgn, rect.left, rect.top, rect.right, rect.bottom );
+        if( rcUpdate ) GetRgnBox32( hrgnUpdate, rcUpdate );
 
-          rect = rDClip;				/* horizontal band */
-          if (dy > 0) rect.bottom = rect.top + dy;
-          else if (dy < 0) rect.top = rect.bottom + dy;
-          else SetRectEmpty32( &rect );
-
-          REGION_UnionRectWithRgn( hrgn, &rect );
-	}
-
-	if (rcUpdate) GetRgnBox32( hrgn, rcUpdate );
 	if (!hrgnUpdate) DeleteObject32( hrgn );
+        DeleteObject32( hrgnClip );     
     }
 
-    DeleteObject32( hrgnScrollClip );     
     GDI_HEAP_UNLOCK( hdc );
     return TRUE;
 }
@@ -415,10 +367,12 @@
 
 	    if( dc->w.hVisRgn && bUpdate )
 	    {
+                OffsetRgn32( hrgnClip, dc->w.DCOrgX, dc->w.DCOrgY );
 		CombineRgn32( hrgnUpdate, dc->w.hVisRgn, hrgnClip, RGN_AND );
 		OffsetRgn32( hrgnUpdate, dx, dy );
 		CombineRgn32( hrgnUpdate, dc->w.hVisRgn, hrgnUpdate, RGN_DIFF );
 		CombineRgn32( hrgnUpdate, hrgnUpdate, hrgnClip, RGN_AND );
+                OffsetRgn32( hrgnUpdate, -dc->w.DCOrgX, -dc->w.DCOrgY );
 
 		if( rcUpdate ) GetRgnBox32( hrgnUpdate, rcUpdate );
 	    }