Authors: Alexandre Julliard <julliard@codeweavers.com> (for Corel), Albert den Haan <albertd@corel.com>
Added syslevel locking for GDI operations.
Propagate the changes through the graphics code.

diff --git a/graphics/bitblt.c b/graphics/bitblt.c
index b739aec..c7c0f87 100644
--- a/graphics/bitblt.c
+++ b/graphics/bitblt.c
@@ -7,9 +7,7 @@
 #include "dc.h"
 #include "debugtools.h"
 
-DEFAULT_DEBUG_CHANNEL(bitblt)
-DECLARE_DEBUG_CHANNEL(bitmap)
-DECLARE_DEBUG_CHANNEL(gdi)
+DEFAULT_DEBUG_CHANNEL(bitblt);
 
 
 /***********************************************************************
@@ -18,11 +16,7 @@
 BOOL16 WINAPI PatBlt16( HDC16 hdc, INT16 left, INT16 top,
                         INT16 width, INT16 height, DWORD rop)
 {
-    DC * dc = DC_GetDCPtr( hdc );
-    if (!dc || !dc->funcs->pPatBlt) return FALSE;
-
-    TRACE("%04x %d,%d %dx%d %06lx\n", hdc, left, top, width, height, rop );
-    return dc->funcs->pPatBlt( dc, left, top, width, height, rop );
+    return PatBlt( hdc, left, top, width, height, rop );
 }
 
 
@@ -33,10 +27,17 @@
                         INT width, INT height, DWORD rop)
 {
     DC * dc = DC_GetDCPtr( hdc );
-    if (!dc || !dc->funcs->pPatBlt) return FALSE;
+    BOOL bRet = FALSE;
 
-    TRACE("%04x %d,%d %dx%d %06lx\n", hdc, left, top, width, height, rop );
-    return dc->funcs->pPatBlt( dc, left, top, width, height, rop );
+    if (!dc) return FALSE;
+
+    if (dc->funcs->pPatBlt)
+    {
+        TRACE("%04x %d,%d %dx%d %06lx\n", hdc, left, top, width, height, rop );
+        bRet = dc->funcs->pPatBlt( dc, left, top, width, height, rop );
+    }
+    GDI_ReleaseObj( hdc );
+    return bRet;
 }
 
 
@@ -47,17 +48,7 @@
                         INT16 height, HDC16 hdcSrc, INT16 xSrc, INT16 ySrc,
                         DWORD rop )
 {
-    DC *dcDst, *dcSrc;
-
-    if (!(dcDst = DC_GetDCPtr( hdcDst ))) return FALSE;
-    if (!dcDst->funcs->pBitBlt) return FALSE;
-    dcSrc = DC_GetDCPtr( hdcSrc );
-
-    TRACE("hdcSrc=%04x %d,%d %d bpp->hdcDest=%04x %d,%d %dx%dx%d rop=%06lx\n",
-          hdcSrc, xSrc, ySrc, dcSrc ? dcSrc->w.bitsPerPixel : 0,
-          hdcDst, xDst, yDst, width, height, dcDst->w.bitsPerPixel, rop);
-    return dcDst->funcs->pBitBlt( dcDst, xDst, yDst, width, height,
-                                  dcSrc, xSrc, ySrc, rop );
+    return BitBlt( hdcDst, xDst, yDst, width, height, hdcSrc, xSrc, ySrc, rop );
 }
 
 
@@ -65,20 +56,26 @@
  *           BitBlt    (GDI32.10)
  */
 BOOL WINAPI BitBlt( HDC hdcDst, INT xDst, INT yDst, INT width,
-                        INT height, HDC hdcSrc, INT xSrc, INT ySrc,
-                        DWORD rop )
+                    INT height, HDC hdcSrc, INT xSrc, INT ySrc, DWORD rop )
 {
+    BOOL ret = FALSE;
     DC *dcDst, *dcSrc;
 
-    if (!(dcDst = DC_GetDCPtr( hdcDst ))) return FALSE;
-    if (!dcDst->funcs->pBitBlt) return FALSE;
-    dcSrc = DC_GetDCPtr( hdcSrc );
-
-    TRACE("hdcSrc=%04x %d,%d %d bpp->hdcDest=%04x %d,%d %dx%dx%d rop=%06lx\n",
-          hdcSrc, xSrc, ySrc, dcSrc ? dcSrc->w.bitsPerPixel : 0,
-          hdcDst, xDst, yDst, width, height, dcDst->w.bitsPerPixel, rop);
-    return dcDst->funcs->pBitBlt( dcDst, xDst, yDst, width, height,
-                                  dcSrc, xSrc, ySrc, rop );
+    if ((dcSrc = DC_GetDCUpdate( hdcSrc ))) GDI_ReleaseObj( hdcSrc );
+    /* FIXME: there is a race condition here */
+    if ((dcDst = DC_GetDCUpdate( hdcDst )))
+    {
+        dcSrc = DC_GetDCPtr( hdcSrc );
+        TRACE("hdcSrc=%04x %d,%d %d bpp->hdcDest=%04x %d,%d %dx%dx%d rop=%06lx\n",
+              hdcSrc, xSrc, ySrc, dcSrc ? dcSrc->w.bitsPerPixel : 0,
+              hdcDst, xDst, yDst, width, height, dcDst->w.bitsPerPixel, rop);
+        if (dcDst->funcs->pBitBlt)
+            ret = dcDst->funcs->pBitBlt( dcDst, xDst, yDst, width, height,
+                                         dcSrc, xSrc, ySrc, rop );
+        if (dcSrc) GDI_ReleaseObj( hdcSrc );
+        GDI_ReleaseObj( hdcDst );
+    }
+    return ret;
 }
 
 
@@ -90,19 +87,8 @@
                             HDC16 hdcSrc, INT16 xSrc, INT16 ySrc,
                             INT16 widthSrc, INT16 heightSrc, DWORD rop )
 {
-    DC *dcDst, *dcSrc;
-
-    if (!(dcDst = DC_GetDCPtr( hdcDst ))) return FALSE;
-    if (!dcDst->funcs->pStretchBlt) return FALSE;
-    dcSrc = DC_GetDCPtr( hdcSrc );
-
-    TRACE("%04x %d,%d %dx%dx%d -> %04x %d,%d %dx%dx%d rop=%06lx\n",
-          hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
-          dcSrc ? dcSrc->w.bitsPerPixel : 0, hdcDst, xDst, yDst,
-          widthDst, heightDst, dcDst->w.bitsPerPixel, rop );
-    return dcDst->funcs->pStretchBlt( dcDst, xDst, yDst, widthDst, heightDst,
-                                      dcSrc, xSrc, ySrc, widthSrc, heightSrc,
-                                      rop );
+    return StretchBlt( hdcDst, xDst, yDst, widthDst, heightDst,
+                       hdcSrc, xSrc, ySrc, widthSrc, heightSrc, rop );
 }
 
 
@@ -112,21 +98,32 @@
 BOOL WINAPI StretchBlt( HDC hdcDst, INT xDst, INT yDst,
                             INT widthDst, INT heightDst,
                             HDC hdcSrc, INT xSrc, INT ySrc,
-                            INT widthSrc, INT heightSrc, DWORD rop )
+                            INT widthSrc, INT heightSrc, 
+			DWORD rop )
 {
+    BOOL ret = FALSE;
     DC *dcDst, *dcSrc;
 
-    if (!(dcDst = DC_GetDCPtr( hdcDst ))) return FALSE;
-    if (!dcDst->funcs->pStretchBlt) return FALSE;
-    dcSrc = DC_GetDCPtr( hdcSrc );
+    if ((dcSrc = DC_GetDCUpdate( hdcSrc ))) GDI_ReleaseObj( hdcSrc );
+    /* FIXME: there is a race condition here */
+    if ((dcDst = DC_GetDCUpdate( hdcDst )))
+    {
+        dcSrc = DC_GetDCPtr( hdcSrc );
 
-    TRACE("%04x %d,%d %dx%dx%d -> %04x %d,%d %dx%dx%d rop=%06lx\n",
-          hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
-          dcSrc ? dcSrc->w.bitsPerPixel : 0, hdcDst, xDst, yDst,
-          widthDst, heightDst, dcDst->w.bitsPerPixel, rop );
-    return dcDst->funcs->pStretchBlt( dcDst, xDst, yDst, widthDst, heightDst,
-                                      dcSrc, xSrc, ySrc, widthSrc, heightSrc,
-                                      rop );
+        TRACE("%04x %d,%d %dx%dx%d -> %04x %d,%d %dx%dx%d rop=%06lx\n",
+              hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
+              dcSrc ? dcSrc->w.bitsPerPixel : 0, hdcDst, xDst, yDst,
+              widthDst, heightDst, dcDst->w.bitsPerPixel, rop );
+
+	if (dcSrc) {
+	    if (dcDst->funcs->pStretchBlt)
+		ret = dcDst->funcs->pStretchBlt( dcDst, xDst, yDst, widthDst, heightDst,
+						 dcSrc, xSrc, ySrc, widthSrc, heightSrc, rop );
+	    GDI_ReleaseObj( hdcSrc );
+	}
+        GDI_ReleaseObj( hdcDst );
+    }
+    return ret;
 }
 
 
@@ -147,7 +144,10 @@
               rect->bottom - rect->top - height, rop );
     SelectObject( hdc, hbrush );
     return TRUE;
+
 }
+
+
 /***********************************************************************
  *           MaskBlt [GDI32.252]
  */
@@ -156,7 +156,7 @@
 			INT nXSrc, INT nYSrc, HBITMAP hbmMask,
 			INT xMask, INT yMask, DWORD dwRop)
 {
-    FIXME_(bitmap)("(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%ld): stub\n",
+    FIXME("(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%ld): stub\n",
              hdcDest,nXDest,nYDest,nWidth,nHeight,hdcSource,nXSrc,nYSrc,
              hbmMask,xMask,yMask,dwRop);
     return 1;
@@ -170,7 +170,7 @@
                         HDC hdcSrc, INT nXDest, INT nYDest, INT nWidth,
                         INT nHeight, HBITMAP hbmMask, INT xMask, INT yMask)
 {
-        FIXME_(gdi)("PlgBlt, stub\n");
+    FIXME("PlgBlt, stub\n");
         return 1;
 }
  
diff --git a/graphics/enhmetafiledrv/init.c b/graphics/enhmetafiledrv/init.c
index 07f38bc..82c6e1b 100644
--- a/graphics/enhmetafiledrv/init.c
+++ b/graphics/enhmetafiledrv/init.c
@@ -129,7 +129,7 @@
     if (physDev->emh) HeapFree( GetProcessHeap(), 0, physDev->emh );
     HeapFree( GetProcessHeap(), 0, physDev );
     dc->physDev = NULL;
-    GDI_FreeObject(dc->hSelf);
+    GDI_FreeObject( dc->hSelf, dc );
     return TRUE;
 }
 
@@ -245,6 +245,7 @@
     LPCWSTR       description /* optional description */ 
     )
 {
+    HDC ret;
     DC *dc;
     HDC hRefDC = hdc ? hdc : CreateDCA("DISPLAY",NULL,NULL,NULL); /* If no ref, use current display */
     EMFDRV_PDEVICE *physDev;
@@ -258,7 +259,7 @@
 
     physDev = (EMFDRV_PDEVICE *)HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
     if (!physDev) {
-        GDI_HEAP_FREE( dc->hSelf );
+        GDI_FreeObject( dc->hSelf, dc );
         return 0;
     }
     dc->physDev = physDev;
@@ -273,7 +274,7 @@
 
     if (!(physDev->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size))) {
         HeapFree( GetProcessHeap(), 0, physDev );
-        GDI_HEAP_FREE( dc->hSelf );
+        GDI_FreeObject( dc->hSelf, dc );
         return 0;
     }
 
@@ -337,8 +338,9 @@
       DeleteDC( hRefDC );
 	
     TRACE("returning %04x\n", dc->hSelf);
-    return dc->hSelf;
-
+    ret = dc->hSelf;
+    GDI_ReleaseObj( dc->hSelf );
+    return ret;
 }
 
 /******************************************************************
diff --git a/graphics/enhmetafiledrv/objects.c b/graphics/enhmetafiledrv/objects.c
index 0e0ccd9..2d615c2 100644
--- a/graphics/enhmetafiledrv/objects.c
+++ b/graphics/enhmetafiledrv/objects.c
@@ -89,9 +89,9 @@
         break;
     default:
         FIXME("Unknown style %x\n", brushObj->logbrush.lbStyle);
-	return FALSE;
+	break;
     }
-    GDI_HEAP_UNLOCK( hBrush );
+    GDI_ReleaseObj( hBrush );
     return index;
 }
 
@@ -170,7 +170,7 @@
 
     if(!EMFDRV_WriteRecord( dc, &emr.emr ))
         index = 0;
-    GDI_HEAP_UNLOCK( hFont );
+    GDI_ReleaseObj( hFont );
     return index;
 }
 
@@ -233,7 +233,7 @@
 
     if(!EMFDRV_WriteRecord( dc, &emr.emr ))
         index = 0;
-    GDI_HEAP_UNLOCK( hPen );
+    GDI_ReleaseObj( hPen );
     return index;
 }
 
@@ -303,7 +303,7 @@
 	  ret = EMFDRV_BITMAP_SelectObject( dc, handle );
 	  break;
     }
-    GDI_HEAP_UNLOCK( handle );
+    GDI_ReleaseObj( handle );
     return ret;
 }
 
diff --git a/graphics/escape.c b/graphics/escape.c
index 5e9e2bc..d4dd462 100644
--- a/graphics/escape.c
+++ b/graphics/escape.c
@@ -21,10 +21,18 @@
 INT16 WINAPI Escape16( HDC16 hdc, INT16 nEscape, INT16 cbInput,
                        SEGPTR lpszInData, SEGPTR lpvOutData )
 {
+    INT16 ret = 0;
     DC * dc = DC_GetDCPtr( hdc );
-    if (!dc || !dc->funcs->pEscape) return 0;
-    if(nEscape == SETABORTPROC) SetAbortProc16(hdc, lpszInData);
-    return dc->funcs->pEscape( dc, nEscape, cbInput, lpszInData, lpvOutData );
+    if (dc)
+    {
+        if (dc->funcs->pEscape)
+        {
+            if(nEscape == SETABORTPROC) SetAbortProc16(hdc, lpszInData);
+            ret = dc->funcs->pEscape( dc, nEscape, cbInput, lpszInData, lpvOutData );
+        }
+        GDI_ReleaseObj( hdc );
+    }
+    return ret;
 }
 
 /************************************************************************
@@ -34,9 +42,10 @@
 		   LPCSTR lpszInData, LPVOID lpvOutData )
 {
     SEGPTR	segin,segout;
-    INT	ret;
+    INT	ret = 0;
     DC * dc = DC_GetDCPtr( hdc );
-    if (!dc || !dc->funcs->pEscape) return 0;
+    if (!dc) return 0;
+    if (!dc->funcs->pEscape) goto done;
 
     segin	= (SEGPTR)lpszInData;
     segout	= (SEGPTR)lpvOutData;
@@ -227,6 +236,8 @@
     default:
     	break;
     }
+ done:
+    GDI_ReleaseObj( hdc );
     return ret;
 }
 
diff --git a/graphics/mapping.c b/graphics/mapping.c
index 4cab204..a23ca2f 100644
--- a/graphics/mapping.c
+++ b/graphics/mapping.c
@@ -48,6 +48,7 @@
 	points->y = YDPTOLP( dc, points->y );
         points++;
     }
+    GDI_ReleaseObj( hdc );
     return TRUE;
 }
 
@@ -63,10 +64,11 @@
     while (count--)
     {
         if (!INTERNAL_DPTOLP( dc, points ))
-	    return FALSE;
+	    break;
         points++;
     }
-    return TRUE;
+    GDI_ReleaseObj( hdc );
+    return (count < 0);
 }
 
 
@@ -84,6 +86,7 @@
 	points->y = YLPTODP( dc, points->y );
         points++;
     }
+    GDI_ReleaseObj( hdc );
     return TRUE;
 }
 
@@ -101,6 +104,7 @@
 	INTERNAL_LPTODP( dc, points );
         points++;
     }
+    GDI_ReleaseObj( hdc );
     return TRUE;
 }
 
@@ -122,7 +126,11 @@
     INT prevMode;
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return 0;
-    if (dc->funcs->pSetMapMode) return dc->funcs->pSetMapMode( dc, mode );
+    if (dc->funcs->pSetMapMode)
+    {
+        prevMode = dc->funcs->pSetMapMode( dc, mode );
+        goto done;
+    }
 
     TRACE("%04x %d\n", hdc, mode );
     
@@ -176,10 +184,12 @@
 	  break;
 
       default:
-	  return prevMode;
+	  goto done;
     }
     dc->w.MapMode = mode;
     DC_UpdateXforms( dc );
+ done:
+    GDI_ReleaseObj( hdc );
     return prevMode;
 }
 
@@ -212,23 +222,33 @@
  */
 BOOL WINAPI SetViewportExtEx( HDC hdc, INT x, INT y, LPSIZE size )
 {
+    BOOL ret = TRUE;
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
     if (dc->funcs->pSetViewportExt)
-        return dc->funcs->pSetViewportExt( dc, x, y );
+    {
+        ret = dc->funcs->pSetViewportExt( dc, x, y );
+        goto done;
+    }
     if (size)
     {
 	size->cx = dc->vportExtX;
 	size->cy = dc->vportExtY;
     }
     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
-	return TRUE;
-    if (!x || !y) return FALSE;
+	goto done;
+    if (!x || !y)
+    {
+        ret = FALSE;
+        goto done;
+    }
     dc->vportExtX = x;
     dc->vportExtY = y;
     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
     DC_UpdateXforms( dc );
-    return TRUE;
+ done:
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -260,19 +280,24 @@
  */
 BOOL WINAPI SetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
 {
+    BOOL ret = TRUE;
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
     if (dc->funcs->pSetViewportOrg)
-        return dc->funcs->pSetViewportOrg( dc, x, y );
-    if (pt)
+        ret = dc->funcs->pSetViewportOrg( dc, x, y );
+    else
     {
-	pt->x = dc->vportOrgX;
-	pt->y = dc->vportOrgY;
+        if (pt)
+        {
+            pt->x = dc->vportOrgX;
+            pt->y = dc->vportOrgY;
+        }
+        dc->vportOrgX = x;
+        dc->vportOrgY = y;
+        DC_UpdateXforms( dc );
     }
-    dc->vportOrgX = x;
-    dc->vportOrgY = y;
-    DC_UpdateXforms( dc );
-    return TRUE;
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -304,22 +329,33 @@
  */
 BOOL WINAPI SetWindowExtEx( HDC hdc, INT x, INT y, LPSIZE size )
 {
+    BOOL ret = TRUE;
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
-    if (dc->funcs->pSetWindowExt) return dc->funcs->pSetWindowExt( dc, x, y );
+    if (dc->funcs->pSetWindowExt)
+    {
+        ret = dc->funcs->pSetWindowExt( dc, x, y );
+        goto done;
+    }
     if (size)
     {
 	size->cx = dc->wndExtX;
 	size->cy = dc->wndExtY;
     }
     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
-	return TRUE;
-    if (!x || !y) return FALSE;
+	goto done;
+    if (!x || !y)
+    {
+        ret = FALSE;
+        goto done;
+    }
     dc->wndExtX = x;
     dc->wndExtY = y;
     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
     DC_UpdateXforms( dc );
-    return TRUE;
+ done:
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -351,18 +387,23 @@
  */
 BOOL WINAPI SetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
 {
+    BOOL ret = TRUE;
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
-    if (dc->funcs->pSetWindowOrg) return dc->funcs->pSetWindowOrg( dc, x, y );
-    if (pt)
+    if (dc->funcs->pSetWindowOrg) ret = dc->funcs->pSetWindowOrg( dc, x, y );
+    else
     {
-	pt->x = dc->wndOrgX;
-	pt->y = dc->wndOrgY;
+        if (pt)
+        {
+            pt->x = dc->wndOrgX;
+            pt->y = dc->wndOrgY;
+        }
+        dc->wndOrgX = x;
+        dc->wndOrgY = y;
+        DC_UpdateXforms( dc );
     }
-    dc->wndOrgX = x;
-    dc->wndOrgY = y;
-    DC_UpdateXforms( dc );
-    return TRUE;
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -394,19 +435,24 @@
  */
 BOOL WINAPI OffsetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt)
 {
+    BOOL ret = TRUE;
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
     if (dc->funcs->pOffsetViewportOrg)
-        return dc->funcs->pOffsetViewportOrg( dc, x, y );
-    if (pt)
+        ret = dc->funcs->pOffsetViewportOrg( dc, x, y );
+    else
     {
-	pt->x = dc->vportOrgX;
-	pt->y = dc->vportOrgY;
+        if (pt)
+        {
+            pt->x = dc->vportOrgX;
+            pt->y = dc->vportOrgY;
+        }
+        dc->vportOrgX += x;
+        dc->vportOrgY += y;
+        DC_UpdateXforms( dc );
     }
-    dc->vportOrgX += x;
-    dc->vportOrgY += y;
-    DC_UpdateXforms( dc );
-    return TRUE;
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -438,19 +484,24 @@
  */
 BOOL WINAPI OffsetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
 {
+    BOOL ret = TRUE;
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
     if (dc->funcs->pOffsetWindowOrg)
-        return dc->funcs->pOffsetWindowOrg( dc, x, y );
-    if (pt)
+        ret = dc->funcs->pOffsetWindowOrg( dc, x, y );
+    else
     {
-	pt->x = dc->wndOrgX;
-	pt->y = dc->wndOrgY;
+        if (pt)
+        {
+            pt->x = dc->wndOrgX;
+            pt->y = dc->wndOrgY;
+        }
+        dc->wndOrgX += x;
+        dc->wndOrgY += y;
+        DC_UpdateXforms( dc );
     }
-    dc->wndOrgX += x;
-    dc->wndOrgY += y;
-    DC_UpdateXforms( dc );
-    return TRUE;
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -487,25 +538,35 @@
 BOOL WINAPI ScaleViewportExtEx( HDC hdc, INT xNum, INT xDenom,
                                     INT yNum, INT yDenom, LPSIZE size )
 {
+    BOOL ret = TRUE;
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
     if (dc->funcs->pScaleViewportExt)
-        return dc->funcs->pScaleViewportExt( dc, xNum, xDenom, yNum, yDenom );
+    {
+        ret = dc->funcs->pScaleViewportExt( dc, xNum, xDenom, yNum, yDenom );
+        goto done;
+    }
     if (size)
     {
 	size->cx = dc->vportExtX;
 	size->cy = dc->vportExtY;
     }
     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
-	return TRUE;
-    if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
+	goto done;
+    if (!xNum || !xDenom || !xNum || !yDenom)
+    {
+        ret = FALSE;
+        goto done;
+    }
     dc->vportExtX = (dc->vportExtX * xNum) / xDenom;
     dc->vportExtY = (dc->vportExtY * yNum) / yDenom;
     if (dc->vportExtX == 0) dc->vportExtX = 1;
     if (dc->vportExtY == 0) dc->vportExtY = 1;
     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
     DC_UpdateXforms( dc );
-    return TRUE;
+ done:
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -542,23 +603,33 @@
 BOOL WINAPI ScaleWindowExtEx( HDC hdc, INT xNum, INT xDenom,
                                   INT yNum, INT yDenom, LPSIZE size )
 {
+    BOOL ret = TRUE;
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
     if (dc->funcs->pScaleWindowExt)
-        return dc->funcs->pScaleWindowExt( dc, xNum, xDenom, yNum, yDenom );
+    {
+        ret = dc->funcs->pScaleWindowExt( dc, xNum, xDenom, yNum, yDenom );
+        goto done;
+    }
     if (size)
     {
 	size->cx = dc->wndExtX;
 	size->cy = dc->wndExtY;
     }
     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
-	return TRUE;
-    if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
+	goto done;
+    if (!xNum || !xDenom || !xNum || !yDenom)
+    {
+        ret = FALSE;
+        goto done;
+    }
     dc->wndExtX = (dc->wndExtX * xNum) / xDenom;
     dc->wndExtY = (dc->wndExtY * yNum) / yDenom;
     if (dc->wndExtX == 0) dc->wndExtX = 1;
     if (dc->wndExtY == 0) dc->wndExtY = 1;
     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
     DC_UpdateXforms( dc );
-    return TRUE;
+ done:
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
diff --git a/graphics/metafiledrv/init.c b/graphics/metafiledrv/init.c
index b9c64ff..d155304 100644
--- a/graphics/metafiledrv/init.c
+++ b/graphics/metafiledrv/init.c
@@ -133,7 +133,7 @@
     physDev = (METAFILEDRV_PDEVICE *)HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
     if (!physDev)
     {
-        GDI_HEAP_FREE( dc->hSelf );
+        GDI_FreeObject( dc->hSelf, dc );
         return NULL;
     }
     dc->physDev = physDev;
@@ -141,7 +141,7 @@
     if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
     {
         HeapFree( GetProcessHeap(), 0, physDev );
-        GDI_HEAP_FREE( dc->hSelf );
+        GDI_FreeObject( dc->hSelf, dc );
         return NULL;
     }
 
@@ -169,7 +169,7 @@
     if (physDev->mh) HeapFree( GetProcessHeap(), 0, physDev->mh );
     HeapFree( GetProcessHeap(), 0, physDev );
     dc->physDev = NULL;
-    GDI_FreeObject(dc->hSelf);
+    GDI_FreeObject( dc->hSelf, dc );
     return TRUE;
 }
 
@@ -186,6 +186,7 @@
 			      LPCSTR filename /* Filename of disk metafile */
 )
 {
+    HDC ret;
     DC *dc;
     METAFILEDRV_PDEVICE *physDev;
     HFILE hFile;
@@ -217,7 +218,9 @@
 	physDev->mh->mtType = METAFILE_MEMORY;
 	
     TRACE("returning %04x\n", dc->hSelf);
-    return dc->hSelf;
+    ret = dc->hSelf;
+    GDI_ReleaseObj( dc->hSelf );
+    return ret;
 }
 
 /**********************************************************************
diff --git a/graphics/metafiledrv/objects.c b/graphics/metafiledrv/objects.c
index 88db9b2..e796be0 100644
--- a/graphics/metafiledrv/objects.c
+++ b/graphics/metafiledrv/objects.c
@@ -35,7 +35,7 @@
 
 INT16 MFDRV_CreateBrushIndirect(DC *dc, HBRUSH hBrush )
 {
-    INT16 index;
+    INT16 index = -1;
     DWORD size;
     METARECORD *mr;
     BRUSHOBJ *brushObj = (BRUSHOBJ *)GDI_GetObjPtr( hBrush, BRUSH_MAGIC );
@@ -68,7 +68,7 @@
 	    GetObjectA(brushObj->logbrush.lbHatch, sizeof(bm), &bm);
 	    if(bm.bmBitsPixel != 1 || bm.bmPlanes != 1) {
 	        FIXME("Trying to store a colour pattern brush\n");
-		return FALSE;
+		goto done;
 	    }
 
 	    bmSize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight, 1);
@@ -77,7 +77,7 @@
 	      sizeof(RGBQUAD) + bmSize;
 
 	    mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
-	    if(!mr) return FALSE;
+	    if(!mr) goto done;
 	    mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
 	    mr->rdSize = size / 2;
 	    mr->rdParm[0] = BS_PATTERN;
@@ -114,7 +114,7 @@
 					  LOWORD(brushObj->logbrush.lbColor)); 
 	      size = sizeof(METARECORD) + biSize + bmSize + 2;
 	      mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
-	      if(!mr) return FALSE;
+	      if(!mr) goto done;
 	      mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
 	      mr->rdSize = size / 2;
 	      *(mr->rdParm) = brushObj->logbrush.lbStyle;
@@ -130,7 +130,8 @@
     if(!MFDRV_WriteRecord( dc, mr, mr->rdSize * 2))
         index = -1;
     HeapFree(GetProcessHeap(), 0, mr);
-    GDI_HEAP_UNLOCK( hBrush );
+done:
+    GDI_ReleaseObj( hBrush );
     return index;
 }
 
@@ -260,7 +261,7 @@
 	  ret = (HGDIOBJ16)SelectClipRgn16( dc->hSelf, handle );
 	  break;
     }
-    GDI_HEAP_UNLOCK( handle );
+    GDI_ReleaseObj( handle );
     return ret;
 }
 
diff --git a/graphics/painting.c b/graphics/painting.c
index aacb7fc..050048c 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -34,19 +34,20 @@
  */
 BOOL WINAPI LineTo( HDC hdc, INT x, INT y )
 {
-    DC * dc = DC_GetDCPtr( hdc );
+    DC * dc = DC_GetDCUpdate( hdc );
     BOOL ret;
 
     if(!dc) return FALSE;
 
     if(PATH_IsPathOpen(dc->w.path))
-        ret = PATH_LineTo(hdc, x, y);
+        ret = PATH_LineTo(dc, x, y);
     else
         ret = dc->funcs->pLineTo && dc->funcs->pLineTo(dc,x,y);
     if(ret) {
         dc->w.CursPosX = x;
         dc->w.CursPosY = y;
     }
+    GDI_ReleaseObj( hdc );
     return ret;
 }
 
@@ -83,7 +84,8 @@
  */
 BOOL WINAPI MoveToEx( HDC hdc, INT x, INT y, LPPOINT pt )
 {
-    DC * dc = DC_GetDCPtr( hdc );
+    BOOL ret = TRUE;
+    DC * dc = DC_GetDCUpdate( hdc );
 
     if(!dc) return FALSE;
 
@@ -94,12 +96,10 @@
     dc->w.CursPosX = x;
     dc->w.CursPosY = y;
 
-    if(PATH_IsPathOpen(dc->w.path))
-        return PATH_MoveTo(hdc);
-
-    if(dc->funcs->pMoveToEx)
-        return dc->funcs->pMoveToEx(dc,x,y,pt);
-    return TRUE;
+    if(PATH_IsPathOpen(dc->w.path)) ret = PATH_MoveTo(dc);
+    else if (dc->funcs->pMoveToEx) ret = dc->funcs->pMoveToEx(dc,x,y,pt);
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -123,15 +123,17 @@
                      INT bottom, INT xstart, INT ystart,
                      INT xend, INT yend )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-    if(!dc) return FALSE;
-
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCUpdate( hdc );
+    if (dc)
+    {
     if(PATH_IsPathOpen(dc->w.path))
-        return PATH_Arc(hdc, left, top, right, bottom, xstart, ystart, xend,
-	   yend);
-    
-    return dc->funcs->pArc &&
-    	   dc->funcs->pArc(dc,left,top,right,bottom,xstart,ystart,xend,yend);
+            ret = PATH_Arc(dc, left, top, right, bottom, xstart, ystart, xend, yend);
+        else if (dc->funcs->pArc)
+            ret = dc->funcs->pArc(dc,left,top,right,bottom,xstart,ystart,xend,yend);
+        GDI_ReleaseObj( hdc );
+}
+    return ret;
 }
 
 /***********************************************************************
@@ -144,37 +146,32 @@
                      INT xend,   INT yend )
 {
     BOOL result;
-    DC * dc = DC_GetDCPtr( hdc );
+    DC * dc = DC_GetDCUpdate( hdc );
     if(!dc) return FALSE;
 
     if(dc->funcs->pArcTo)
-        return dc->funcs->pArcTo( dc, left, top, right, bottom,
+    {
+        result = dc->funcs->pArcTo( dc, left, top, right, bottom,
 				  xstart, ystart, xend, yend );
+        GDI_ReleaseObj( hdc );
+        return result;
+    }
+    GDI_ReleaseObj( hdc );
     /* 
      * Else emulate it.
      * According to the documentation, a line is drawn from the current
      * position to the starting point of the arc.
      */
     LineTo(hdc, xstart, ystart);
-
     /*
      * Then the arc is drawn.
      */
-    result = Arc(hdc, 
-                  left, top,
-                  right, bottom,
-                  xstart, ystart,
-                  xend, yend);
-
+    result = Arc(hdc, left, top, right, bottom, xstart, ystart, xend, yend);
     /*
      * If no error occured, the current position is moved to the ending
      * point of the arc.
      */
-    if (result)
-    {
-        MoveToEx(hdc, xend, yend, NULL);
-    }
-
+    if (result) MoveToEx(hdc, xend, yend, NULL);
     return result;
 }
 
@@ -198,16 +195,17 @@
                      INT right, INT bottom, INT xstart, INT ystart,
                      INT xend, INT yend )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-    if(!dc) return FALSE;
-
-    if(PATH_IsPathOpen(dc->w.path)) {
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCUpdate( hdc );
+    if (dc)
+    {
+        if (PATH_IsPathOpen(dc->w.path))
         FIXME("-> Path: stub\n");
-	return FALSE;
+        else if (dc->funcs->pPie)
+            ret = dc->funcs->pPie(dc,left,top,right,bottom,xstart,ystart,xend,yend);
+        GDI_ReleaseObj( hdc );
     }
-
-    return dc->funcs->pPie &&
-    	   dc->funcs->pPie(dc,left,top,right,bottom,xstart,ystart,xend,yend);
+    return ret;
 }
 
 
@@ -229,16 +227,17 @@
                        INT right, INT bottom, INT xstart, INT ystart,
                        INT xend, INT yend )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-    if(!dc) return FALSE;
-
-    if(PATH_IsPathOpen(dc->w.path)) {
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCUpdate( hdc );
+    if (dc)
+    {
+        if(PATH_IsPathOpen(dc->w.path))
         FIXME("-> Path: stub\n");
-	return FALSE;
+        else if (dc->funcs->pChord)
+            ret = dc->funcs->pChord(dc,left,top,right,bottom,xstart,ystart,xend,yend);
+        GDI_ReleaseObj( hdc );
     }
-  
-    return dc->funcs->pChord &&
-    	   dc->funcs->pChord(dc,left,top,right,bottom,xstart,ystart,xend,yend);
+    return ret;
 }
 
 
@@ -258,16 +257,17 @@
 BOOL WINAPI Ellipse( HDC hdc, INT left, INT top,
                          INT right, INT bottom )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-    if(!dc) return FALSE;
-
-    if(PATH_IsPathOpen(dc->w.path)) {
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCUpdate( hdc );
+    if (dc)
+    {
+        if(PATH_IsPathOpen(dc->w.path))
         FIXME("-> Path: stub\n");
-	return FALSE;
+        else if (dc->funcs->pEllipse)
+            ret = dc->funcs->pEllipse(dc,left,top,right,bottom);
+        GDI_ReleaseObj( hdc );
     }
-  
-    return dc->funcs->pEllipse &&
-    	   dc->funcs->pEllipse(dc,left,top,right,bottom);
+    return ret;
 }
 
 
@@ -287,14 +287,17 @@
 BOOL WINAPI Rectangle( HDC hdc, INT left, INT top,
                            INT right, INT bottom )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-    if(!dc) return FALSE;
-
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCUpdate( hdc );
+    if (dc)
+    {  
     if(PATH_IsPathOpen(dc->w.path))
-        return PATH_Rectangle(hdc, left, top, right, bottom);
-
-    return dc->funcs->pRectangle &&
-    	   dc->funcs->pRectangle(dc,left,top,right,bottom);
+            ret = PATH_Rectangle(dc, left, top, right, bottom);
+        else if (dc->funcs->pRectangle)
+            ret = dc->funcs->pRectangle(dc,left,top,right,bottom);
+        GDI_ReleaseObj( hdc );
+}
+    return ret;
 }
 
 
@@ -314,16 +317,18 @@
 BOOL WINAPI RoundRect( HDC hdc, INT left, INT top, INT right,
                            INT bottom, INT ell_width, INT ell_height )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-    if(!dc) return FALSE;
+    BOOL ret = FALSE;
+    DC *dc = DC_GetDCUpdate( hdc );
 
-    if(PATH_IsPathOpen(dc->w.path)) {
+    if (dc)
+    {
+        if(PATH_IsPathOpen(dc->w.path))
         FIXME("-> Path: stub\n");
-	return FALSE;
+        else if (dc->funcs->pRoundRect)
+            ret = dc->funcs->pRoundRect(dc,left,top,right,bottom,ell_width,ell_height);
+        GDI_ReleaseObj( hdc );
     }
-
-    return dc->funcs->pRoundRect &&
-      dc->funcs->pRoundRect(dc,left,top,right,bottom,ell_width,ell_height);
+    return ret;
 }
 
 /***********************************************************************
@@ -340,10 +345,14 @@
  */
 COLORREF WINAPI SetPixel( HDC hdc, INT x, INT y, COLORREF color )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-  
-    if (!dc || !dc->funcs->pSetPixel) return 0;
-    return dc->funcs->pSetPixel(dc,x,y,color);
+    COLORREF ret = 0;
+    DC * dc = DC_GetDCUpdate( hdc );
+    if (dc)
+    {
+        if (dc->funcs->pSetPixel) ret = dc->funcs->pSetPixel(dc,x,y,color);
+        GDI_ReleaseObj( hdc );
+    }
+    return ret;
 }
 
 /***********************************************************************
@@ -351,11 +360,18 @@
  */
 BOOL WINAPI SetPixelV( HDC hdc, INT x, INT y, COLORREF color )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-  
-    if (!dc || !dc->funcs->pSetPixel) return FALSE;
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCUpdate( hdc );
+    if (dc)
+    {
+        if (dc->funcs->pSetPixel)
+        {
     dc->funcs->pSetPixel(dc,x,y,color);
-    return TRUE;
+            ret = TRUE;
+}
+        GDI_ReleaseObj( hdc );
+    }
+    return ret;
 }
 
 /***********************************************************************
@@ -372,17 +388,19 @@
  */
 COLORREF WINAPI GetPixel( HDC hdc, INT x, INT y )
 {
-    DC * dc = DC_GetDCPtr( hdc );
+    COLORREF ret = 0;
+    DC * dc = DC_GetDCUpdate( hdc );
 
-    if (!dc) return 0;
-#ifdef SOLITAIRE_SPEED_HACK
-    return 0;
-#endif
-
+    if (dc)
+    {
     /* FIXME: should this be in the graphics driver? */
-    if (!PtVisible( hdc, x, y )) return 0;
-    if (!dc || !dc->funcs->pGetPixel) return 0;
-    return dc->funcs->pGetPixel(dc,x,y);
+        if (PtVisible( hdc, x, y ))
+        {
+            if (dc->funcs->pGetPixel) ret = dc->funcs->pGetPixel(dc,x,y);
+        }
+        GDI_ReleaseObj( hdc );
+    }
+    return ret;
 }
 
 
@@ -400,17 +418,18 @@
  */
 INT WINAPI ChoosePixelFormat( HDC hdc, const LPPIXELFORMATDESCRIPTOR ppfd )
 {
-  DC * dc = DC_GetDCPtr( hdc );
+    INT ret = 0;
+    DC * dc = DC_GetDCPtr( hdc );
 
-  TRACE("(%08x,%p)\n",hdc,ppfd);
+    TRACE("(%08x,%p)\n",hdc,ppfd);
   
-  if (dc == NULL) return 0;
-  if (dc->funcs->pChoosePixelFormat == NULL) {
-    FIXME(" :stub\n");
-    return 0;
-  }
-  
-  return dc->funcs->pChoosePixelFormat(dc,ppfd);
+    if (!dc) return 0;
+
+    if (!dc->funcs->pChoosePixelFormat) FIXME(" :stub\n");
+    else ret = dc->funcs->pChoosePixelFormat(dc,ppfd);
+
+    GDI_ReleaseObj( hdc );  
+    return ret;
 }
 
 
@@ -428,16 +447,18 @@
 BOOL WINAPI SetPixelFormat( HDC hdc, INT iPixelFormat,
                             const PIXELFORMATDESCRIPTOR *ppfd)
 {
-  DC * dc = DC_GetDCPtr( hdc );
+    INT bRet = FALSE;
+    DC * dc = DC_GetDCPtr( hdc );
 
-  TRACE("(%d,%d,%p)\n",hdc,iPixelFormat,ppfd);
+    TRACE("(%d,%d,%p)\n",hdc,iPixelFormat,ppfd);
 
-  if (dc == NULL) return 0;
-  if (dc->funcs->pSetPixelFormat == NULL) {
-    FIXME(" :stub\n");
-    return 0;
-  }
-  return dc->funcs->pSetPixelFormat(dc,iPixelFormat,ppfd);
+    if (!dc) return 0;
+
+    if (!dc->funcs->pSetPixelFormat) FIXME(" :stub\n");
+    else bRet = dc->funcs->pSetPixelFormat(dc,iPixelFormat,ppfd);
+
+    GDI_ReleaseObj( hdc );  
+    return bRet;
 }
 
 
@@ -454,16 +475,18 @@
  */
 INT WINAPI GetPixelFormat( HDC hdc )
 {
-  DC * dc = DC_GetDCPtr( hdc );
+    INT ret = 0;
+    DC * dc = DC_GetDCPtr( hdc );
 
-  TRACE("(%08x)\n",hdc);
+    TRACE("(%08x)\n",hdc);
 
-  if (dc == NULL) return 0;
-  if (dc->funcs->pGetPixelFormat == NULL) {
-    FIXME(" :stub\n");
-    return 0;
-  }
-  return dc->funcs->pGetPixelFormat(dc);
+    if (!dc) return 0;
+
+    if (!dc->funcs->pGetPixelFormat) FIXME(" :stub\n");
+    else ret = dc->funcs->pGetPixelFormat(dc);
+
+    GDI_ReleaseObj( hdc );  
+    return ret;
 }
 
 
@@ -484,18 +507,24 @@
 INT WINAPI DescribePixelFormat( HDC hdc, INT iPixelFormat, UINT nBytes,
                                 LPPIXELFORMATDESCRIPTOR ppfd )
 {
-  DC * dc = DC_GetDCPtr( hdc );
+    INT ret = 0;
+    DC * dc = DC_GetDCPtr( hdc );
 
-  TRACE("(%08x,%d,%d,%p): stub\n",hdc,iPixelFormat,nBytes,ppfd);
+    TRACE("(%08x,%d,%d,%p): stub\n",hdc,iPixelFormat,nBytes,ppfd);
 
-  if (dc == NULL) return 0;
-  if (dc->funcs->pDescribePixelFormat == NULL) {
-    FIXME(" :stub\n");
-    ppfd->nSize = nBytes;
-    ppfd->nVersion = 1;
-    return 3;
-  }
-  return dc->funcs->pDescribePixelFormat(dc,iPixelFormat,nBytes,ppfd);
+    if (!dc) return 0;
+
+    if (!dc->funcs->pDescribePixelFormat)
+    {
+        FIXME(" :stub\n");
+        ppfd->nSize = nBytes;
+        ppfd->nVersion = 1;
+	ret = 3;
+    }
+    else ret = dc->funcs->pDescribePixelFormat(dc,iPixelFormat,nBytes,ppfd);
+
+    GDI_ReleaseObj( hdc );  
+    return ret;
 }
 
 
@@ -510,16 +539,22 @@
  */
 BOOL WINAPI SwapBuffers( HDC hdc )
 {
-  DC * dc = DC_GetDCPtr( hdc );
+    INT bRet = FALSE;
+    DC * dc = DC_GetDCPtr( hdc );
 
-  TRACE("(%08x)\n",hdc);
+    TRACE("(%08x)\n",hdc);
 
-  if (dc == NULL) return 0;
-  if (dc->funcs->pSwapBuffers == NULL) {
-    FIXME(" :stub\n");
-    return TRUE;
-  }
-  return dc->funcs->pSwapBuffers(dc);
+    if (!dc) return TRUE;
+
+    if (!dc->funcs->pSwapBuffers)
+    {
+        FIXME(" :stub\n");
+	bRet = TRUE;
+    }
+    else bRet = dc->funcs->pSwapBuffers(dc);
+
+    GDI_ReleaseObj( hdc );  
+    return bRet;
 }
 
 
@@ -537,10 +572,14 @@
  */
 BOOL WINAPI PaintRgn( HDC hdc, HRGN hrgn )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-
-    return dc && dc->funcs->pPaintRgn &&
-	   dc->funcs->pPaintRgn(dc,hrgn);
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCUpdate( hdc );
+    if (dc)
+    {
+        if (dc->funcs->pPaintRgn) ret = dc->funcs->pPaintRgn(dc,hrgn);
+        GDI_ReleaseObj( hdc );
+    }
+    return ret;
 }
 
 
@@ -558,18 +597,19 @@
  */
 BOOL WINAPI FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush )
 {
-    BOOL retval;
+    BOOL retval = FALSE;
     HBRUSH prevBrush;
-    DC * dc = DC_GetDCPtr( hdc );
+    DC * dc = DC_GetDCUpdate( hdc );
 
     if (!dc) return FALSE;
     if(dc->funcs->pFillRgn)
-        return dc->funcs->pFillRgn(dc, hrgn, hbrush);
-
-    prevBrush = SelectObject( hdc, hbrush );
-    if (!prevBrush) return FALSE;
+        retval = dc->funcs->pFillRgn(dc, hrgn, hbrush);
+    else if ((prevBrush = SelectObject( hdc, hbrush )))
+    {
     retval = PaintRgn( hdc, hrgn );
     SelectObject( hdc, prevBrush );
+    }
+    GDI_ReleaseObj( hdc );
     return retval;
 }
 
@@ -590,17 +630,27 @@
 BOOL WINAPI FrameRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush,
                           INT nWidth, INT nHeight )
 {
-    HRGN tmp;
-    DC *dc = DC_GetDCPtr( hdc );
+    BOOL ret = FALSE;
+    DC *dc = DC_GetDCUpdate( hdc );
 
+    if (!dc) return FALSE;
     if(dc->funcs->pFrameRgn)
-        return dc->funcs->pFrameRgn( dc, hrgn, hbrush, nWidth, nHeight );
-
-    tmp = CreateRectRgn( 0, 0, 0, 0 );
-    if(!REGION_FrameRgn( tmp, hrgn, nWidth, nHeight )) return FALSE;
+        ret = dc->funcs->pFrameRgn( dc, hrgn, hbrush, nWidth, nHeight );
+    else
+    {
+        HRGN tmp = CreateRectRgn( 0, 0, 0, 0 );
+        if (tmp)
+        {
+            if (REGION_FrameRgn( tmp, hrgn, nWidth, nHeight ))
+            {
     FillRgn( hdc, tmp, hbrush );
+                ret = TRUE;
+            }
     DeleteObject( tmp );
-    return TRUE;
+}
+    }
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -621,16 +671,20 @@
     HBRUSH prevBrush;
     INT prevROP;
     BOOL retval;
-    DC *dc = DC_GetDCPtr( hdc );
+    DC *dc = DC_GetDCUpdate( hdc );
+    if (!dc) return FALSE;
 
     if(dc->funcs->pInvertRgn)
-        return dc->funcs->pInvertRgn( dc, hrgn );
-
+        retval = dc->funcs->pInvertRgn( dc, hrgn );
+    else
+    {
     prevBrush = SelectObject( hdc, GetStockObject(BLACK_BRUSH) );
     prevROP = SetROP2( hdc, R2_NOT );
     retval = PaintRgn( hdc, hrgn );
     SelectObject( hdc, prevBrush );
     SetROP2( hdc, prevROP );
+    }
+    GDI_ReleaseObj( hdc );
     return retval;
 }
 
@@ -657,14 +711,15 @@
  */
 BOOL WINAPI Polyline( HDC hdc, const POINT* pt, INT count )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-    if(!dc) return FALSE;
-
-    if(PATH_IsPathOpen(dc->w.path))
-        return PATH_Polyline(hdc, pt, count);
-
-    return dc->funcs->pPolyline &&
-    	   dc->funcs->pPolyline(dc,pt,count);
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCUpdate( hdc );
+    if (dc)
+    {
+        if (PATH_IsPathOpen(dc->w.path)) ret = PATH_Polyline(dc, pt, count);
+        else if (dc->funcs->pPolyline) ret = dc->funcs->pPolyline(dc,pt,count);
+        GDI_ReleaseObj( hdc );
+    }
+    return ret;
 }
 
 /**********************************************************************
@@ -672,13 +727,13 @@
  */
 BOOL WINAPI PolylineTo( HDC hdc, const POINT* pt, DWORD cCount )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-    BOOL ret;
+    DC * dc = DC_GetDCUpdate( hdc );
+    BOOL ret = FALSE;
 
     if(!dc) return FALSE;
 
     if(PATH_IsPathOpen(dc->w.path))
-        ret = PATH_PolylineTo(hdc, pt, cCount);
+        ret = PATH_PolylineTo(dc, pt, cCount);
 
     else if(dc->funcs->pPolylineTo)
         ret = dc->funcs->pPolylineTo(dc, pt, cCount);
@@ -686,18 +741,20 @@
     else { /* do it using Polyline */
         POINT *pts = HeapAlloc( GetProcessHeap(), 0,
 				sizeof(POINT) * (cCount + 1) );
-	if(!pts) return FALSE;
-
+	if (pts)
+        {
 	pts[0].x = dc->w.CursPosX;
 	pts[0].y = dc->w.CursPosY;
 	memcpy( pts + 1, pt, sizeof(POINT) * cCount );
 	ret = Polyline( hdc, pts, cCount + 1 );
 	HeapFree( GetProcessHeap(), 0, pts );
     }
+    }
     if(ret) {
         dc->w.CursPosX = pt[cCount-1].x;
 	dc->w.CursPosY = pt[cCount-1].y;
     }
+    GDI_ReleaseObj( hdc );
     return ret;
 }
 
@@ -724,14 +781,15 @@
  */
 BOOL WINAPI Polygon( HDC hdc, const POINT* pt, INT count )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-    if(!dc) return FALSE;
-
-    if(PATH_IsPathOpen(dc->w.path))
-	return PATH_Polygon(hdc, pt, count);
-
-    return dc->funcs->pPolygon &&
-    	   dc->funcs->pPolygon(dc,pt,count);
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCUpdate( hdc );
+    if (dc)
+    {
+        if (PATH_IsPathOpen(dc->w.path)) ret = PATH_Polygon(dc, pt, count);
+        else if (dc->funcs->pPolygon) ret = dc->funcs->pPolygon(dc,pt,count);
+        GDI_ReleaseObj( hdc );
+}
+    return ret;
 }
 
 
@@ -772,14 +830,15 @@
 BOOL WINAPI PolyPolygon( HDC hdc, const POINT* pt, const INT* counts,
                              UINT polygons )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-    if(!dc) return FALSE;
-
-    if(PATH_IsPathOpen(dc->w.path))
-        return PATH_PolyPolygon(hdc, pt, counts, polygons);
-
-    return dc->funcs->pPolyPolygon &&
-    	   dc->funcs->pPolyPolygon(dc,pt,counts,polygons);
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCUpdate( hdc );
+    if (dc)
+    {
+        if (PATH_IsPathOpen(dc->w.path)) ret = PATH_PolyPolygon(dc, pt, counts, polygons);
+        else if (dc->funcs->pPolyPolygon) ret = dc->funcs->pPolyPolygon(dc,pt,counts,polygons);
+        GDI_ReleaseObj( hdc );
+    }
+    return ret;
 }
 
 /**********************************************************************
@@ -788,14 +847,15 @@
 BOOL WINAPI PolyPolyline( HDC hdc, const POINT* pt, const DWORD* counts,
                             DWORD polylines )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-    if(!dc) return FALSE;
-
-    if(PATH_IsPathOpen(dc->w.path))
-        return PATH_PolyPolyline(hdc, pt, counts, polylines);
-
-    return dc->funcs->pPolyPolyline &&
-    	   dc->funcs->pPolyPolyline(dc,pt,counts,polylines);
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCUpdate( hdc );
+    if (dc)
+    {
+        if (PATH_IsPathOpen(dc->w.path)) ret = PATH_PolyPolyline(dc, pt, counts, polylines);
+        else if (dc->funcs->pPolyPolyline) ret = dc->funcs->pPolyPolyline(dc,pt,counts,polylines);
+        GDI_ReleaseObj( hdc );
+}
+    return ret;
 }
 
 /**********************************************************************
@@ -814,10 +874,14 @@
 BOOL WINAPI ExtFloodFill( HDC hdc, INT x, INT y, COLORREF color,
                               UINT fillType )
 {
-    DC *dc = DC_GetDCPtr( hdc );
-
-    return dc && dc->funcs->pExtFloodFill &&
-	   dc->funcs->pExtFloodFill(dc,x,y,color,fillType);
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCUpdate( hdc );
+    if (dc)
+    {
+        if (dc->funcs->pExtFloodFill) ret = dc->funcs->pExtFloodFill(dc,x,y,color,fillType);
+        GDI_ReleaseObj( hdc );
+}
+    return ret;
 }
 
 
@@ -884,30 +948,32 @@
  */
 BOOL WINAPI PolyBezier( HDC hdc, const POINT* lppt, DWORD cPoints )
 {
-    DC * dc = DC_GetDCPtr( hdc );
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCUpdate( hdc );
+
     if(!dc) return FALSE;
 
     if(PATH_IsPathOpen(dc->w.path))
-	return PATH_PolyBezier(hdc, lppt, cPoints);
-
-    if(dc->funcs->pPolyBezier)
-        return dc->funcs->pPolyBezier(dc, lppt, cPoints);
-
-    /* We'll convert it into line segments and draw them using Polyline */
+	ret = PATH_PolyBezier(dc, lppt, cPoints);
+    else if (dc->funcs->pPolyBezier)
+        ret = dc->funcs->pPolyBezier(dc, lppt, cPoints);
+    else  /* We'll convert it into line segments and draw them using Polyline */
     {
         POINT *Pts;
 	INT nOut;
-	BOOL ret;
 
-	Pts = GDI_Bezier( lppt, cPoints, &nOut );
-	if(!Pts) return FALSE;
+	if ((Pts = GDI_Bezier( lppt, cPoints, &nOut )))
+        {
 	TRACE("Pts = %p, no = %d\n", Pts, nOut);
 	ret = Polyline( dc->hSelf, Pts, nOut );
 	HeapFree( GetProcessHeap(), 0, Pts );
-	return ret;
     }
 }
 
+    GDI_ReleaseObj( hdc );
+    return ret;
+}
+
 /******************************************************************************
  * PolyBezierTo [GDI32.269]
  * Draws one or more Bezier curves
@@ -921,13 +987,13 @@
  */
 BOOL WINAPI PolyBezierTo( HDC hdc, const POINT* lppt, DWORD cPoints )
 {
-    DC * dc = DC_GetDCPtr( hdc );
+    DC * dc = DC_GetDCUpdate( hdc );
     BOOL ret;
 
     if(!dc) return FALSE;
 
     if(PATH_IsPathOpen(dc->w.path))
-        ret = PATH_PolyBezierTo(hdc, lppt, cPoints);
+        ret = PATH_PolyBezierTo(dc, lppt, cPoints);
     else if(dc->funcs->pPolyBezierTo)
         ret = dc->funcs->pPolyBezierTo(dc, lppt, cPoints);
     else { /* We'll do it using PolyBezier */
@@ -944,6 +1010,7 @@
         dc->w.CursPosX = lppt[cPoints-1].x;
         dc->w.CursPosY = lppt[cPoints-1].y;
     }
+    GDI_ReleaseObj( hdc );
     return ret;
 }
 
diff --git a/graphics/path.c b/graphics/path.c
index 5ae3779..e82925d 100644
--- a/graphics/path.c
+++ b/graphics/path.c
@@ -73,7 +73,6 @@
 static BOOL PATH_AddEntry(GdiPath *pPath, const POINT *pPoint,
    BYTE flags);
 static BOOL PATH_ReserveEntries(GdiPath *pPath, INT numEntries);
-static BOOL PATH_GetPathFromHDC(HDC hdc, GdiPath **ppPath);
 static BOOL PATH_DoArcPart(GdiPath *pPath, FLOAT_POINT corners[],
    double angleStart, double angleEnd, BOOL addMoveTo);
 static void PATH_ScaleNormalizedPoint(FLOAT_POINT corners[], double x,
@@ -96,31 +95,28 @@
  */
 BOOL WINAPI BeginPath(HDC hdc)
 {
-   DC *dc = DC_GetDCPtr( hdc );
-   GdiPath *pPath;
+    BOOL ret = TRUE;
+    DC *dc = DC_GetDCPtr( hdc );
    
-   if(!dc) {
-     SetLastError(ERROR_INVALID_HANDLE);
-     return FALSE;
-   }
+    if(!dc) return FALSE;
 
-   if(dc->funcs->pBeginPath)
-     return dc->funcs->pBeginPath(dc);
+    if(dc->funcs->pBeginPath)
+        ret = dc->funcs->pBeginPath(dc);
+    else
+    {
+        /* If path is already open, do nothing */
+        if(dc->w.path.state != PATH_Open)
+        {
+            /* Make sure that path is empty */
+            PATH_EmptyPath(&dc->w.path);
 
-   pPath = &dc->w.path;
-
-   /* If path is already open, do nothing */
-   if(pPath->state==PATH_Open)
-      return TRUE;
-
-   /* Make sure that path is empty */
-   PATH_EmptyPath(pPath);
-
-   /* Initialize variables for new path */
-   pPath->newStroke=TRUE;
-   pPath->state=PATH_Open;
-   
-   return TRUE;
+            /* Initialize variables for new path */
+            dc->w.path.newStroke=TRUE;
+            dc->w.path.state=PATH_Open;
+        }
+    }
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -138,30 +134,26 @@
  */
 BOOL WINAPI EndPath(HDC hdc)
 {
-   DC *dc = DC_GetDCPtr( hdc );
-   GdiPath *pPath;
+    BOOL ret = TRUE;
+    DC *dc = DC_GetDCPtr( hdc );
    
-   if(!dc) {
-     SetLastError(ERROR_INVALID_HANDLE);
-     return FALSE;
-   }
+    if(!dc) return FALSE;
 
-   if(dc->funcs->pEndPath)
-     return dc->funcs->pEndPath(dc);
-
-   pPath = &dc->w.path;
-
-   /* Check that path is currently being constructed */
-   if(pPath->state!=PATH_Open)
-   {
-      SetLastError(ERROR_CAN_NOT_COMPLETE);
-      return FALSE;
-   }
-   
-   /* Set flag to indicate that path is finished */
-   pPath->state=PATH_Closed;
-   
-   return TRUE;
+    if(dc->funcs->pEndPath)
+        ret = dc->funcs->pEndPath(dc);
+    else
+    {
+        /* Check that path is currently being constructed */
+        if(dc->w.path.state!=PATH_Open)
+        {
+            SetLastError(ERROR_CAN_NOT_COMPLETE);
+            ret = FALSE;
+        }
+        /* Set flag to indicate that path is finished */
+        else dc->w.path.state=PATH_Closed;
+    }
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -188,23 +180,17 @@
  */
 BOOL WINAPI AbortPath( HDC hdc )
 {
-   DC *dc = DC_GetDCPtr( hdc );
-   GdiPath *pPath;
+    BOOL ret = TRUE;
+    DC *dc = DC_GetDCPtr( hdc );
    
-   if(!dc) {
-     SetLastError(ERROR_INVALID_HANDLE);
-     return FALSE;
-   }
+    if(!dc) return FALSE;
 
-   if(dc->funcs->pAbortPath)
-     return dc->funcs->pAbortPath(dc);
-
-   pPath = &dc->w.path;
-   
-   /* Remove all entries from the path */
-   PATH_EmptyPath(pPath);
-
-   return TRUE;
+    if(dc->funcs->pAbortPath)
+        ret = dc->funcs->pAbortPath(dc);
+    else /* Remove all entries from the path */
+        PATH_EmptyPath( &dc->w.path );
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -224,34 +210,35 @@
  */
 BOOL WINAPI CloseFigure(HDC hdc)
 {
-   DC *dc = DC_GetDCPtr( hdc );
-   GdiPath *pPath;
+    BOOL ret = TRUE;
+    DC *dc = DC_GetDCPtr( hdc );
    
-   if(!dc) {
-     SetLastError(ERROR_INVALID_HANDLE);
-     return FALSE;
-   }
+    if(!dc) return FALSE;
 
-   if(dc->funcs->pCloseFigure)
-     return dc->funcs->pCloseFigure(dc);
-
-   pPath = &dc->w.path;
-
-   /* Check that path is open */
-   if(pPath->state!=PATH_Open)
-   {
-      SetLastError(ERROR_CAN_NOT_COMPLETE);
-      return FALSE;
-   }
-   
-   /* Set PT_CLOSEFIGURE on the last entry and start a new stroke */
-   if(pPath->numEntriesUsed)
-   {
-      pPath->pFlags[pPath->numEntriesUsed-1]|=PT_CLOSEFIGURE;
-      pPath->newStroke=TRUE;
-   }
-
-   return TRUE;
+    if(dc->funcs->pCloseFigure)
+        ret = dc->funcs->pCloseFigure(dc);
+    else
+    {
+        /* Check that path is open */
+        if(dc->w.path.state!=PATH_Open)
+        {
+            SetLastError(ERROR_CAN_NOT_COMPLETE);
+            ret = FALSE;
+        }
+        else
+        {
+            /* FIXME: Shouldn't we draw a line to the beginning of the
+               figure? */
+            /* Set PT_CLOSEFIGURE on the last entry and start a new stroke */
+            if(dc->w.path.numEntriesUsed)
+            {
+                dc->w.path.pFlags[dc->w.path.numEntriesUsed-1]|=PT_CLOSEFIGURE;
+                dc->w.path.newStroke=TRUE;
+            }
+        }
+    }
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -273,28 +260,27 @@
 INT WINAPI GetPath(HDC hdc, LPPOINT pPoints, LPBYTE pTypes,
    INT nSize)
 {
+   INT ret = -1;
    GdiPath *pPath;
+   DC *dc = DC_GetDCPtr( hdc );
    
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-   {
-      SetLastError(ERROR_INVALID_PARAMETER);
-      return -1;
-   }
+   if(!dc) return -1;
+   
+   pPath = &dc->w.path;
    
    /* Check that path is closed */
    if(pPath->state!=PATH_Closed)
    {
       SetLastError(ERROR_CAN_NOT_COMPLETE);
-      return -1;
+      goto done;
    }
    
    if(nSize==0)
-      return pPath->numEntriesUsed;
+      ret = pPath->numEntriesUsed;
    else if(nSize<pPath->numEntriesUsed)
    {
       SetLastError(ERROR_INVALID_PARAMETER);
-      return -1;
+      goto done;
    }
    else
    {
@@ -306,11 +292,13 @@
       {
 	 /* FIXME: Is this the correct value? */
          SetLastError(ERROR_CAN_NOT_COMPLETE);
-         return -1;
+	goto done;
       }
-      
-      return pPath->numEntriesUsed;
+     else ret = pPath->numEntriesUsed;
    }
+ done:
+   GDI_ReleaseObj( hdc );
+   return ret;
 }
 
 /***********************************************************************
@@ -333,32 +321,29 @@
 HRGN WINAPI PathToRegion(HDC hdc)
 {
    GdiPath *pPath;
-   HRGN  hrgnRval;
+   HRGN  hrgnRval = 0;
+   DC *dc = DC_GetDCPtr( hdc );
 
    /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-   {
-      SetLastError(ERROR_INVALID_PARAMETER);
-      return 0;
-   }
+   if(!dc) return -1;
+   
+    pPath = &dc->w.path;
    
    /* Check that path is closed */
-   if(pPath->state!=PATH_Closed)
-   {
-      SetLastError(ERROR_CAN_NOT_COMPLETE);
-      return 0;
-   }
-   
-   /* FIXME: Should we empty the path even if conversion failed? */
-   if(PATH_PathToRegion(pPath, GetPolyFillMode(hdc), &hrgnRval))
-      PATH_EmptyPath(pPath);
+   if(pPath->state!=PATH_Closed) SetLastError(ERROR_CAN_NOT_COMPLETE);
    else
-      hrgnRval=0;
-
+   {
+       /* FIXME: Should we empty the path even if conversion failed? */
+       if(PATH_PathToRegion(pPath, GetPolyFillMode(hdc), &hrgnRval))
+           PATH_EmptyPath(pPath);
+       else
+           hrgnRval=0;
+   }
+   GDI_ReleaseObj( hdc );
    return hrgnRval;
 }
 
-static BOOL PATH_FillPath(HDC hdc, GdiPath *pPath)
+static BOOL PATH_FillPath(DC *dc, GdiPath *pPath)
 {
    INT   mapMode, graphicsMode;
    SIZE  ptViewportExt, ptWindowExt;
@@ -366,6 +351,9 @@
    XFORM xform;
    HRGN  hrgn;
 
+   if(dc->funcs->pFillPath)
+       return dc->funcs->pFillPath(dc);
+
    /* Check that path is closed */
    if(pPath->state!=PATH_Closed)
    {
@@ -374,7 +362,7 @@
    }
    
    /* Construct a region from the path and fill it */
-   if(PATH_PathToRegion(pPath, GetPolyFillMode(hdc), &hrgn))
+   if(PATH_PathToRegion(pPath, dc->w.polyFillMode, &hrgn))
    {
       /* Since PaintRgn interprets the region as being in logical coordinates
        * but the points we store for the path are already in device
@@ -385,11 +373,11 @@
        */
        
       /* Save the information about the old mapping mode */
-      mapMode=GetMapMode(hdc);
-      GetViewportExtEx(hdc, &ptViewportExt);
-      GetViewportOrgEx(hdc, &ptViewportOrg);
-      GetWindowExtEx(hdc, &ptWindowExt);
-      GetWindowOrgEx(hdc, &ptWindowOrg);
+      mapMode=GetMapMode(dc->hSelf);
+      GetViewportExtEx(dc->hSelf, &ptViewportExt);
+      GetViewportOrgEx(dc->hSelf, &ptViewportOrg);
+      GetWindowExtEx(dc->hSelf, &ptWindowExt);
+      GetWindowOrgEx(dc->hSelf, &ptWindowOrg);
       
       /* Save world transform
        * NB: The Windows documentation on world transforms would lead one to
@@ -397,28 +385,28 @@
        * tests show that resetting the graphics mode to GM_COMPATIBLE does
        * not reset the world transform.
        */
-      GetWorldTransform(hdc, &xform);
+      GetWorldTransform(dc->hSelf, &xform);
       
       /* Set MM_TEXT */
-      SetMapMode(hdc, MM_TEXT);
-      SetViewportOrgEx(hdc, 0, 0, NULL);
-      SetWindowOrgEx(hdc, 0, 0, NULL);
+      SetMapMode(dc->hSelf, MM_TEXT);
+      SetViewportOrgEx(dc->hSelf, 0, 0, NULL);
+      SetWindowOrgEx(dc->hSelf, 0, 0, NULL);
 
       /* Paint the region */
-      PaintRgn(hdc, hrgn);
+      PaintRgn(dc->hSelf, hrgn);
       DeleteObject(hrgn);
       /* Restore the old mapping mode */
-      SetMapMode(hdc, mapMode);
-      SetViewportExtEx(hdc, ptViewportExt.cx, ptViewportExt.cy, NULL);
-      SetViewportOrgEx(hdc, ptViewportOrg.x, ptViewportOrg.y, NULL);
-      SetWindowExtEx(hdc, ptWindowExt.cx, ptWindowExt.cy, NULL);
-      SetWindowOrgEx(hdc, ptWindowOrg.x, ptWindowOrg.y, NULL);
+      SetMapMode(dc->hSelf, mapMode);
+      SetViewportExtEx(dc->hSelf, ptViewportExt.cx, ptViewportExt.cy, NULL);
+      SetViewportOrgEx(dc->hSelf, ptViewportOrg.x, ptViewportOrg.y, NULL);
+      SetWindowExtEx(dc->hSelf, ptWindowExt.cx, ptWindowExt.cy, NULL);
+      SetWindowOrgEx(dc->hSelf, ptWindowOrg.x, ptWindowOrg.y, NULL);
 
       /* Go to GM_ADVANCED temporarily to restore the world transform */
-      graphicsMode=GetGraphicsMode(hdc);
-      SetGraphicsMode(hdc, GM_ADVANCED);
-      SetWorldTransform(hdc, &xform);
-      SetGraphicsMode(hdc, graphicsMode);
+      graphicsMode=GetGraphicsMode(dc->hSelf);
+      SetGraphicsMode(dc->hSelf, GM_ADVANCED);
+      SetWorldTransform(dc->hSelf, &xform);
+      SetGraphicsMode(dc->hSelf, graphicsMode);
       return TRUE;
    }
    return FALSE;
@@ -440,22 +428,25 @@
  */
 BOOL WINAPI FillPath(HDC hdc)
 {
-   DC *dc = DC_GetDCPtr( hdc );
+    DC *dc = DC_GetDCPtr( hdc );
+    BOOL bRet = FALSE;
    
-   if(!dc) {
-     SetLastError(ERROR_INVALID_HANDLE);
-     return FALSE;
-   }
+    if(!dc) return FALSE;
 
-   if(dc->funcs->pFillPath)
-     return dc->funcs->pFillPath(dc);
-
-   if(!PATH_FillPath(hdc, &dc->w.path))
-      return FALSE;
-
-   /* FIXME: Should the path be emptied even if conversion failed? */
-   PATH_EmptyPath(&dc->w.path);
-   return TRUE;
+    if(dc->funcs->pFillPath)
+        bRet = dc->funcs->pFillPath(dc);
+    else
+    {
+        bRet = PATH_FillPath(dc, &dc->w.path);
+        if(bRet)
+        {
+            /* FIXME: Should the path be emptied even if conversion
+               failed? */
+            PATH_EmptyPath(&dc->w.path);
+        }
+    }
+    GDI_ReleaseObj( hdc );
+    return bRet;
 }
 
 /***********************************************************************
@@ -475,41 +466,34 @@
 {
    GdiPath *pPath;
    HRGN  hrgnPath;
-   BOOL  success;
+   BOOL  success = FALSE;
    DC *dc = DC_GetDCPtr( hdc );
    
-   if(!dc) {
-     SetLastError(ERROR_INVALID_HANDLE);
-     return FALSE;
-   }
+   if(!dc) return FALSE;
 
    if(dc->funcs->pSelectClipPath)
-     return dc->funcs->pSelectClipPath(dc, iMode);
-
-   pPath = &dc->w.path;
-   
-   /* Check that path is closed */
-   if(pPath->state!=PATH_Closed)
-   {
-      SetLastError(ERROR_CAN_NOT_COMPLETE);
-      return FALSE;
-   }
-   
-   /* Construct a region from the path */
-   if(PATH_PathToRegion(pPath, GetPolyFillMode(hdc), &hrgnPath))
-   {
-      success = ExtSelectClipRgn( hdc, hrgnPath, iMode ) != ERROR;
-      DeleteObject(hrgnPath);
-
-      /* Empty the path */
-      if(success)
-         PATH_EmptyPath(pPath);
-      /* FIXME: Should this function delete the path even if it failed? */
-
-      return success;
-   }
+     success = dc->funcs->pSelectClipPath(dc, iMode);
    else
-      return FALSE;
+   {
+       pPath = &dc->w.path;
+   
+       /* Check that path is closed */
+       if(pPath->state!=PATH_Closed)
+           SetLastError(ERROR_CAN_NOT_COMPLETE);
+       /* Construct a region from the path */
+       else if(PATH_PathToRegion(pPath, GetPolyFillMode(hdc), &hrgnPath))
+       {
+           success = ExtSelectClipRgn( hdc, hrgnPath, iMode ) != ERROR;
+           DeleteObject(hrgnPath);
+
+           /* Empty the path */
+           if(success)
+               PATH_EmptyPath(pPath);
+           /* FIXME: Should this function delete the path even if it failed? */
+       }
+   }
+   GDI_ReleaseObj( hdc );
+   return success;
 }
 
 
@@ -581,13 +565,9 @@
  * open path. This starts a new stroke. Returns TRUE if successful, else
  * FALSE.
  */
-BOOL PATH_MoveTo(HDC hdc)
+BOOL PATH_MoveTo(DC *dc)
 {
-   GdiPath *pPath;
-   
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
+   GdiPath *pPath = &dc->w.path;
    
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
@@ -607,15 +587,11 @@
  * a PT_MOVETO entry, if this is the first LineTo in a stroke).
  * Returns TRUE if successful, else FALSE.
  */
-BOOL PATH_LineTo(HDC hdc, INT x, INT y)
+BOOL PATH_LineTo(DC *dc, INT x, INT y)
 {
-   GdiPath *pPath;
+   GdiPath *pPath = &dc->w.path;
    POINT point, pointCurPos;
    
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
-   
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
       return FALSE;
@@ -623,15 +599,16 @@
    /* Convert point to device coordinates */
    point.x=x;
    point.y=y;
-   if(!LPtoDP(hdc, &point, 1))
+   if(!LPtoDP(dc->hSelf, &point, 1))
       return FALSE;
    
    /* Add a PT_MOVETO if necessary */
    if(pPath->newStroke)
    {
       pPath->newStroke=FALSE;
-      if(!GetCurrentPositionEx(hdc, &pointCurPos) ||
-         !LPtoDP(hdc, &pointCurPos, 1))
+      pointCurPos.x = dc->w.CursPosX;
+      pointCurPos.y = dc->w.CursPosY;
+      if(!LPtoDP(dc->hSelf, &pointCurPos, 1))
          return FALSE;
       if(!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO))
          return FALSE;
@@ -646,16 +623,12 @@
  * Should be called when a call to Rectangle is performed on a DC that has
  * an open path. Returns TRUE if successful, else FALSE.
  */
-BOOL PATH_Rectangle(HDC hdc, INT x1, INT y1, INT x2, INT y2)
+BOOL PATH_Rectangle(DC *dc, INT x1, INT y1, INT x2, INT y2)
 {
-   GdiPath *pPath;
+   GdiPath *pPath = &dc->w.path;
    POINT corners[2], pointTemp;
    INT   temp;
 
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
-   
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
       return FALSE;
@@ -665,7 +638,7 @@
    corners[0].y=y1;
    corners[1].x=x2;
    corners[1].y=y2;
-   if(!LPtoDP(hdc, corners, 2))
+   if(!LPtoDP(dc->hSelf, corners, 2))
       return FALSE;
    
    /* Make sure first corner is top left and second corner is bottom right */
@@ -683,14 +656,14 @@
    }
    
    /* In GM_COMPATIBLE, don't include bottom and right edges */
-   if(GetGraphicsMode(hdc)==GM_COMPATIBLE)
+   if(dc->w.GraphicsMode==GM_COMPATIBLE)
    {
       corners[1].x--;
       corners[1].y--;
    }
 
    /* Close any previous figure */
-   if(!CloseFigure(hdc))
+   if(!CloseFigure(dc->hSelf))
    {
       /* The CloseFigure call shouldn't have failed */
       assert(FALSE);
@@ -712,7 +685,7 @@
       return FALSE;
 
    /* Close the rectangle figure */
-   if(!CloseFigure(hdc))
+   if(!CloseFigure(dc->hSelf))
    {
       /* The CloseFigure call shouldn't have failed */
       assert(FALSE);
@@ -728,11 +701,11 @@
  * an open path. This adds four Bezier splines representing the ellipse
  * to the path. Returns TRUE if successful, else FALSE.
  */
-BOOL PATH_Ellipse(HDC hdc, INT x1, INT y1, INT x2, INT y2)
+BOOL PATH_Ellipse(DC *dc, INT x1, INT y1, INT x2, INT y2)
 {
    /* TODO: This should probably be revised to call PATH_AngleArc */
    /* (once it exists) */
-   return PATH_Arc(hdc, x1, y1, x2, y2, x1, (y1+y2)/2, x1, (y1+y2)/2);
+   return PATH_Arc(dc, x1, y1, x2, y2, x1, (y1+y2)/2, x1, (y1+y2)/2);
 }
 
 /* PATH_Arc
@@ -741,11 +714,10 @@
  * an open path. This adds up to five Bezier splines representing the arc
  * to the path. Returns TRUE if successful, else FALSE.
  */
-BOOL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2,
+BOOL PATH_Arc(DC *dc, INT x1, INT y1, INT x2, INT y2,
    INT xStart, INT yStart, INT xEnd, INT yEnd)
 {
-   GdiPath     *pPath;
-   DC          *pDC;
+   GdiPath     *pPath = &dc->w.path;
    double      angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant=0.0;
                /* Initialize angleEndQuadrant to silence gcc's warning */
    double      x, y;
@@ -756,15 +728,6 @@
    /* FIXME: This function should check for all possible error returns */
    /* FIXME: Do we have to respect newStroke? */
    
-   /* Get pointer to DC */
-   pDC=DC_GetDCPtr(hdc);
-   if(pDC==NULL)
-      return FALSE;
-
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
-   
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
       return FALSE;
@@ -785,10 +748,10 @@
    pointStart.y=(FLOAT)yStart;
    pointEnd.x=(FLOAT)xEnd;
    pointEnd.y=(FLOAT)yEnd;
-   INTERNAL_LPTODP_FLOAT(pDC, corners);
-   INTERNAL_LPTODP_FLOAT(pDC, corners+1);
-   INTERNAL_LPTODP_FLOAT(pDC, &pointStart);
-   INTERNAL_LPTODP_FLOAT(pDC, &pointEnd);
+   INTERNAL_LPTODP_FLOAT(dc, corners);
+   INTERNAL_LPTODP_FLOAT(dc, corners+1);
+   INTERNAL_LPTODP_FLOAT(dc, &pointStart);
+   INTERNAL_LPTODP_FLOAT(dc, &pointEnd);
 
    /* Make sure first corner is top left and second corner is bottom right */
    if(corners[0].x>corners[1].x)
@@ -811,7 +774,7 @@
    angleEnd=atan2(y, x);
 
    /* Make sure the end angle is "on the right side" of the start angle */
-   if(GetArcDirection(hdc)==AD_CLOCKWISE)
+   if(dc->w.ArcDirection==AD_CLOCKWISE)
    {
       if(angleEnd<=angleStart)
       {
@@ -829,7 +792,7 @@
    }
 
    /* In GM_COMPATIBLE, don't include bottom and right edges */
-   if(GetGraphicsMode(hdc)==GM_COMPATIBLE)
+   if(dc->w.GraphicsMode==GM_COMPATIBLE)
    {
       corners[1].x--;
       corners[1].y--;
@@ -845,7 +808,7 @@
       if(start)
       {
          angleStartQuadrant=angleStart;
-	 if(GetArcDirection(hdc)==AD_CLOCKWISE)
+	 if(dc->w.ArcDirection==AD_CLOCKWISE)
 	    angleEndQuadrant=(floor(angleStart/M_PI_2)+1.0)*M_PI_2;
 	 else
 	    angleEndQuadrant=(ceil(angleStart/M_PI_2)-1.0)*M_PI_2;
@@ -853,16 +816,16 @@
       else
       {
 	 angleStartQuadrant=angleEndQuadrant;
-	 if(GetArcDirection(hdc)==AD_CLOCKWISE)
+	 if(dc->w.ArcDirection==AD_CLOCKWISE)
 	    angleEndQuadrant+=M_PI_2;
 	 else
 	    angleEndQuadrant-=M_PI_2;
       }
 
       /* Have we reached the last part of the arc? */
-      if((GetArcDirection(hdc)==AD_CLOCKWISE &&
+      if((dc->w.ArcDirection==AD_CLOCKWISE &&
          angleEnd<angleEndQuadrant) ||
-	 (GetArcDirection(hdc)==AD_COUNTERCLOCKWISE &&
+	 (dc->w.ArcDirection==AD_COUNTERCLOCKWISE &&
 	 angleEnd>angleEndQuadrant))
       {
 	 /* Adjust the end angle for this quadrant */
@@ -879,15 +842,12 @@
    return TRUE;
 }
 
-BOOL PATH_PolyBezierTo(HDC hdc, const POINT *pts, DWORD cbPoints)
+BOOL PATH_PolyBezierTo(DC *dc, const POINT *pts, DWORD cbPoints)
 {
-   GdiPath     *pPath;
+   GdiPath     *pPath = &dc->w.path;
    POINT       pt;
    INT         i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
-   
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
       return FALSE;
@@ -896,8 +856,9 @@
    if(pPath->newStroke)
    {
       pPath->newStroke=FALSE;
-      if(!GetCurrentPositionEx(hdc, &pt) ||
-         !LPtoDP(hdc, &pt, 1))
+      pt.x = dc->w.CursPosX;
+      pt.y = dc->w.CursPosY;
+      if(!LPtoDP(dc->hSelf, &pt, 1))
          return FALSE;
       if(!PATH_AddEntry(pPath, &pt, PT_MOVETO))
          return FALSE;
@@ -905,66 +866,57 @@
 
    for(i = 0; i < cbPoints; i++) {
        pt = pts[i];
-       if(!LPtoDP(hdc, &pt, 1))
+       if(!LPtoDP(dc->hSelf, &pt, 1))
 	   return FALSE;
        PATH_AddEntry(pPath, &pt, PT_BEZIERTO);
    }
    return TRUE;
 }
    
-BOOL PATH_PolyBezier(HDC hdc, const POINT *pts, DWORD cbPoints)
+BOOL PATH_PolyBezier(DC *dc, const POINT *pts, DWORD cbPoints)
 {
-   GdiPath     *pPath;
+   GdiPath     *pPath = &dc->w.path;
    POINT       pt;
    INT         i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
-   
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
       return FALSE;
 
    for(i = 0; i < cbPoints; i++) {
        pt = pts[i];
-       if(!LPtoDP(hdc, &pt, 1))
+       if(!LPtoDP(dc->hSelf, &pt, 1))
 	   return FALSE;
        PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO);
    }
    return TRUE;
 }
 
-BOOL PATH_Polyline(HDC hdc, const POINT *pts, DWORD cbPoints)
+BOOL PATH_Polyline(DC *dc, const POINT *pts, DWORD cbPoints)
 {
-   GdiPath     *pPath;
+   GdiPath     *pPath = &dc->w.path;
    POINT       pt;
    INT         i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
-   
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
       return FALSE;
 
    for(i = 0; i < cbPoints; i++) {
        pt = pts[i];
-       if(!LPtoDP(hdc, &pt, 1))
+       if(!LPtoDP(dc->hSelf, &pt, 1))
 	   return FALSE;
        PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_LINETO);
    }
    return TRUE;
 }
    
-BOOL PATH_PolylineTo(HDC hdc, const POINT *pts, DWORD cbPoints)
+BOOL PATH_PolylineTo(DC *dc, const POINT *pts, DWORD cbPoints)
 {
-   GdiPath     *pPath;
+   GdiPath     *pPath = &dc->w.path;
    POINT       pt;
    INT         i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
-   
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
       return FALSE;
@@ -973,8 +925,9 @@
    if(pPath->newStroke)
    {
       pPath->newStroke=FALSE;
-      if(!GetCurrentPositionEx(hdc, &pt) ||
-         !LPtoDP(hdc, &pt, 1))
+      pt.x = dc->w.CursPosX;
+      pt.y = dc->w.CursPosY;
+      if(!LPtoDP(dc->hSelf, &pt, 1))
          return FALSE;
       if(!PATH_AddEntry(pPath, &pt, PT_MOVETO))
          return FALSE;
@@ -982,7 +935,7 @@
 
    for(i = 0; i < cbPoints; i++) {
        pt = pts[i];
-       if(!LPtoDP(hdc, &pt, 1))
+       if(!LPtoDP(dc->hSelf, &pt, 1))
 	   return FALSE;
        PATH_AddEntry(pPath, &pt, PT_LINETO);
    }
@@ -991,22 +944,19 @@
 }
 
 
-BOOL PATH_Polygon(HDC hdc, const POINT *pts, DWORD cbPoints)
+BOOL PATH_Polygon(DC *dc, const POINT *pts, DWORD cbPoints)
 {
-   GdiPath     *pPath;
+   GdiPath     *pPath = &dc->w.path;
    POINT       pt;
    INT         i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
-   
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
       return FALSE;
 
    for(i = 0; i < cbPoints; i++) {
        pt = pts[i];
-       if(!LPtoDP(hdc, &pt, 1))
+       if(!LPtoDP(dc->hSelf, &pt, 1))
 	   return FALSE;
        PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO :
 		     ((i == cbPoints-1) ? PT_LINETO | PT_CLOSEFIGURE :
@@ -1015,16 +965,13 @@
    return TRUE;
 }
 
-BOOL PATH_PolyPolygon( HDC hdc, const POINT* pts, const INT* counts,
+BOOL PATH_PolyPolygon( DC *dc, const POINT* pts, const INT* counts,
 		       UINT polygons )
 {
-   GdiPath     *pPath;
+   GdiPath     *pPath = &dc->w.path;
    POINT       pt, startpt;
    INT         poly, point, i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
-   
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
       return FALSE;
@@ -1032,7 +979,7 @@
    for(i = 0, poly = 0; poly < polygons; poly++) {
        for(point = 0; point < counts[poly]; point++, i++) {
 	   pt = pts[i];
-	   if(!LPtoDP(hdc, &pt, 1))
+	   if(!LPtoDP(dc->hSelf, &pt, 1))
 	       return FALSE;
 	   if(point == 0) startpt = pt;
 	   PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO);
@@ -1043,16 +990,13 @@
    return TRUE;
 }
 
-BOOL PATH_PolyPolyline( HDC hdc, const POINT* pts, const DWORD* counts,
+BOOL PATH_PolyPolyline( DC *dc, const POINT* pts, const DWORD* counts,
 			DWORD polylines )
 {
-   GdiPath     *pPath;
+   GdiPath     *pPath = &dc->w.path;
    POINT       pt;
    INT         poly, point, i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
-   
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
       return FALSE;
@@ -1060,7 +1004,7 @@
    for(i = 0, poly = 0; poly < polylines; poly++) {
        for(point = 0; point < counts[poly]; point++, i++) {
 	   pt = pts[i];
-	   if(!LPtoDP(hdc, &pt, 1))
+	   if(!LPtoDP(dc->hSelf, &pt, 1))
 	       return FALSE;
 	   PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO);
        }
@@ -1306,25 +1250,6 @@
    return TRUE;
 }
 
-/* PATH_GetPathFromHDC
- *
- * Retrieves a pointer to the GdiPath structure contained in an HDC and
- * places it in *ppPath. TRUE is returned if successful, FALSE otherwise.
- */
-static BOOL PATH_GetPathFromHDC(HDC hdc, GdiPath **ppPath)
-{
-   DC *pDC;
-
-   pDC=DC_GetDCPtr(hdc);
-   if(pDC)
-   {
-      *ppPath=&pDC->w.path;
-      return TRUE;
-   }
-   else
-      return FALSE;
-}
-
 /* PATH_DoArcPart
  *
  * Creates a Bezier spline that corresponds to part of an arc and appends the
@@ -1434,50 +1359,51 @@
  */
 BOOL WINAPI FlattenPath(HDC hdc)
 {
-   DC *dc = DC_GetDCPtr( hdc );
-   GdiPath *pPath;
-   TRACE("%08x\n", hdc);
+    BOOL ret = FALSE;
+    DC *dc = DC_GetDCPtr( hdc );
 
-   if(!dc) {
-     SetLastError(ERROR_INVALID_HANDLE);
-     return FALSE;
-   }
+    if(!dc) return FALSE;
 
-   if(dc->funcs->pFlattenPath)
-     return dc->funcs->pFlattenPath(dc);
-
-    pPath = &dc->w.path;
-    if(pPath->state != PATH_Closed)
-        return FALSE;
-   return PATH_FlattenPath(pPath);
+    if(dc->funcs->pFlattenPath) ret = dc->funcs->pFlattenPath(dc);
+    else 
+    {
+	GdiPath *pPath = &dc->w.path;
+        if(pPath->state != PATH_Closed)
+	    ret = PATH_FlattenPath(pPath);
+    }
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
-static BOOL PATH_StrokePath(HDC hdc, GdiPath *pPath)
+static BOOL PATH_StrokePath(DC *dc, GdiPath *pPath)
 {
     INT i;
     POINT ptLastMove = {0,0};
 
+    if(dc->funcs->pStrokePath)
+        return dc->funcs->pStrokePath(dc);
+
     if(pPath->state != PATH_Closed)
         return FALSE;
 
-    SaveDC(hdc);
-    SetMapMode(hdc, MM_TEXT);
-    SetViewportOrgEx(hdc, 0, 0, NULL);
-    SetWindowOrgEx(hdc, 0, 0, NULL);
+    SaveDC(dc->hSelf);
+    SetMapMode(dc->hSelf, MM_TEXT);
+    SetViewportOrgEx(dc->hSelf, 0, 0, NULL);
+    SetWindowOrgEx(dc->hSelf, 0, 0, NULL);
     for(i = 0; i < pPath->numEntriesUsed; i++) {
         switch(pPath->pFlags[i]) {
 	case PT_MOVETO:
 	    TRACE("Got PT_MOVETO (%ld, %ld)\n",
 		  pPath->pPoints[i].x, pPath->pPoints[i].y);
-	    MoveToEx(hdc, pPath->pPoints[i].x, pPath->pPoints[i].y, NULL);
+	    MoveToEx(dc->hSelf, pPath->pPoints[i].x, pPath->pPoints[i].y, NULL);
 	    ptLastMove = pPath->pPoints[i];
 	    break;
 	case PT_LINETO:
 	case (PT_LINETO | PT_CLOSEFIGURE):
 	    TRACE("Got PT_LINETO (%ld, %ld)\n",
 		  pPath->pPoints[i].x, pPath->pPoints[i].y);
-	    LineTo(hdc, pPath->pPoints[i].x, pPath->pPoints[i].y);
+	    LineTo(dc->hSelf, pPath->pPoints[i].x, pPath->pPoints[i].y);
 	    break;
 	case PT_BEZIERTO:
 	    TRACE("Got PT_BEZIERTO\n");
@@ -1486,7 +1412,7 @@
 	        ERR("Path didn't contain 3 successive PT_BEZIERTOs\n");
 		return FALSE;
 	    }
-	    PolyBezierTo(hdc, &pPath->pPoints[i], 3);
+	    PolyBezierTo(dc->hSelf, &pPath->pPoints[i], 3);
 	    i += 2;
 	    break;
 	default:
@@ -1494,9 +1420,9 @@
 	    return FALSE;
 	}
 	if(pPath->pFlags[i] & PT_CLOSEFIGURE)
-	    LineTo(hdc, ptLastMove.x, ptLastMove.y);
+	    LineTo(dc->hSelf, ptLastMove.x, ptLastMove.y);
     }
-    RestoreDC(hdc, -1);
+    RestoreDC(dc->hSelf , -1);
     return TRUE;
 }
 
@@ -1519,19 +1445,19 @@
 BOOL WINAPI StrokeAndFillPath(HDC hdc)
 {
    DC *dc = DC_GetDCPtr( hdc );
-   BOOL bRet;
+   BOOL bRet = FALSE;
 
-   if(!dc) {
-     SetLastError(ERROR_INVALID_HANDLE);
-     return FALSE;
-   }
+   if(!dc) return FALSE;
 
    if(dc->funcs->pStrokeAndFillPath)
-     return dc->funcs->pStrokeAndFillPath(dc);
-
-   bRet = PATH_FillPath(hdc, &dc->w.path);
-   if(bRet) bRet = PATH_StrokePath(hdc, &dc->w.path);
-   if(bRet) PATH_EmptyPath(&dc->w.path);
+       bRet = dc->funcs->pStrokeAndFillPath(dc);
+   else
+   {
+       bRet = PATH_FillPath(dc, &dc->w.path);
+       if(bRet) bRet = PATH_StrokePath(dc, &dc->w.path);
+       if(bRet) PATH_EmptyPath(&dc->w.path);
+   }
+   GDI_ReleaseObj( hdc );
    return bRet;
 }
 
@@ -1554,20 +1480,21 @@
 {
     DC *dc = DC_GetDCPtr( hdc );
     GdiPath *pPath;
+    BOOL bRet = FALSE;
 
     TRACE("(%08x)\n", hdc);
-    if(!dc) {
-        SetLastError(ERROR_INVALID_HANDLE);
-	return FALSE;
-    }
+    if(!dc) return FALSE;
 
     if(dc->funcs->pStrokePath)
-        return dc->funcs->pStrokePath(dc);
-
-    pPath = &dc->w.path;
-    PATH_StrokePath(hdc, pPath);
-    PATH_EmptyPath(pPath);
-    return TRUE;
+        bRet = dc->funcs->pStrokePath(dc);
+    else
+    {
+        pPath = &dc->w.path;
+        bRet = PATH_StrokePath(dc, pPath);
+        PATH_EmptyPath(pPath);
+    }
+    GDI_ReleaseObj( hdc );
+    return bRet;
 }
 
 /*******************************************************************
@@ -1588,15 +1515,14 @@
 BOOL WINAPI WidenPath(HDC hdc)
 {
    DC *dc = DC_GetDCPtr( hdc );
+   BOOL ret = FALSE;
    
-   if(!dc) {
-     SetLastError(ERROR_INVALID_HANDLE);
-     return FALSE;
-   }
+   if(!dc) return FALSE;
 
    if(dc->funcs->pWidenPath)
-     return dc->funcs->pWidenPath(dc);
+     ret = dc->funcs->pWidenPath(dc);
 
    FIXME("stub\n");
-   return 0;
+   GDI_ReleaseObj( hdc );
+   return ret;
 }
diff --git a/graphics/win16drv/font.c b/graphics/win16drv/font.c
index c525e8f..4c9c0bc 100644
--- a/graphics/win16drv/font.c
+++ b/graphics/win16drv/font.c
@@ -11,6 +11,7 @@
 #include "module.h"
 #include "font.h"
 #include "heap.h"
+#include "dc.h"
 #include "debugtools.h"
 
 DEFAULT_DEBUG_CHANNEL(win16drv)
@@ -179,15 +180,21 @@
  *           WIN16DRV_EnumDeviceFonts
  */
 
-BOOL	WIN16DRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf, 
+BOOL	WIN16DRV_EnumDeviceFonts( HDC hdc, LPLOGFONT16 plf, 
 				        DEVICEFONTENUMPROC proc, LPARAM lp )
 {
-    WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
+    WIN16DRV_PDEVICE *physDev;
     WORD wRet;
     WEPFC wepfc;
+    DC *dc;
     /* EnumDFontCallback is GDI.158 */
     FARPROC16 pfnCallback = NE_GetEntryPoint( GetModuleHandle16("GDI"), 158 );
 
+    if (!(dc = DC_GetDCPtr( hdc ))) return 0;
+    physDev = (WIN16DRV_PDEVICE *)dc->physDev;
+    /* FIXME!! */
+    GDI_ReleaseObj( hdc );
+
     wepfc.proc = (int (*)(LPENUMLOGFONT16,LPNEWTEXTMETRIC16,UINT16,LPARAM))proc;
     wepfc.lp = lp;
 
diff --git a/graphics/win16drv/objects.c b/graphics/win16drv/objects.c
index e21fb31..21d77f7 100644
--- a/graphics/win16drv/objects.c
+++ b/graphics/win16drv/objects.c
@@ -54,6 +54,6 @@
 	ret = (HGDIOBJ16)SelectClipRgn16( dc->hSelf, handle );
 	break;
     }
-    GDI_HEAP_UNLOCK( handle );
+    GDI_ReleaseObj( handle );
     return ret;
 }
diff --git a/graphics/x11drv/bitmap.c b/graphics/x11drv/bitmap.c
index 484a7b6..47c9fc6 100644
--- a/graphics/x11drv/bitmap.c
+++ b/graphics/x11drv/bitmap.c
@@ -84,24 +84,20 @@
 	return 0;
     }
 
+    hrgn = CreateRectRgn(0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
+    if (!hrgn) return 0;
+
     dc->w.totalExtent.left   = 0;
     dc->w.totalExtent.top    = 0;
     dc->w.totalExtent.right  = bmp->bitmap.bmWidth;
     dc->w.totalExtent.bottom = bmp->bitmap.bmHeight;
 
-    if (dc->w.hVisRgn)
-       SetRectRgn( dc->w.hVisRgn, 0, 0,
-                     bmp->bitmap.bmWidth, bmp->bitmap.bmHeight );
-    else
-    { 
-       hrgn = CreateRectRgn(0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
-       if (!hrgn) return 0;
-       dc->w.hVisRgn    = hrgn;
-    }
-
     physDev->drawable = (Pixmap)bmp->physBitmap;
     dc->w.hBitmap     = hbitmap;
 
+    SelectVisRgn16( dc->hSelf, hrgn );
+    DeleteObject( hrgn );
+
       /* Change GC depth if needed */
 
     if (dc->w.bitsPerPixel != bmp->bitmap.bmBitsPixel)
@@ -112,7 +108,6 @@
 	dc->w.bitsPerPixel = bmp->bitmap.bmBitsPixel;
         DC_InitDC( dc );
     }
-    else CLIPPING_UpdateGCRegion( dc );  /* Just update GC clip region */
     return prevHandle;
 }
 
@@ -158,13 +153,17 @@
     }
 
       /* Check parameters */
-    if (bmp->bitmap.bmPlanes != 1) return 0;
+    if (bmp->bitmap.bmPlanes != 1)
+    {
+        GDI_ReleaseObj( hbitmap );
+        return 0;
+    }
     if ((bmp->bitmap.bmBitsPixel != 1) && 
 	(bmp->bitmap.bmBitsPixel != X11DRV_GetDepth()))
     {
         ERR("Trying to make bitmap with planes=%d, bpp=%d\n",
 	    bmp->bitmap.bmPlanes, bmp->bitmap.bmBitsPixel);
-        GDI_HEAP_UNLOCK( hbitmap );
+        GDI_ReleaseObj( hbitmap );
 	return FALSE;
     }
 
@@ -177,7 +176,7 @@
                                                     bmp->bitmap.bmBitsPixel)))
     {
         WARN("Can't create Pixmap\n");
-	GDI_HEAP_UNLOCK( hbitmap );
+	GDI_ReleaseObj( hbitmap );
 	return FALSE;
     }
     bmp->funcs = &X11DRV_DC_Funcs;
@@ -187,7 +186,7 @@
 			   bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes,
 			   DDB_SET );
 
-    GDI_HEAP_UNLOCK( hbitmap );
+    GDI_ReleaseObj( hbitmap );
     return TRUE;
 }
 
@@ -476,8 +475,7 @@
         ERR("Unknown flags value %d\n", flags);
 	ret = 0;
     }
-    
-    GDI_HEAP_UNLOCK( hbitmap );
+    GDI_ReleaseObj( hbitmap );
     return ret;
 }
 
@@ -526,6 +524,7 @@
     
     pBmp->funcs = &X11DRV_DC_Funcs;
     pBmp->physBitmap = (void *)pixmap;
+    GDI_ReleaseObj( hBmp );
 
 END:
     TRACE("\tReturning HBITMAP %x\n", hBmp);
@@ -612,7 +611,10 @@
  */
 Pixmap X11DRV_BITMAP_Pixmap(HBITMAP hbitmap)
 {
+    Pixmap pixmap;
     BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
-    return (Pixmap)bmp->physBitmap;
+    pixmap = (Pixmap)bmp->physBitmap;
+    GDI_ReleaseObj( hbitmap );
+    return pixmap;
 }
 
diff --git a/graphics/x11drv/brush.c b/graphics/x11drv/brush.c
index d5a090a..81e2c95 100644
--- a/graphics/x11drv/brush.c
+++ b/graphics/x11drv/brush.c
@@ -172,17 +172,18 @@
  */
 static BOOL BRUSH_SelectPatternBrush( DC * dc, HBITMAP hbitmap )
 {
+    BOOL ret = FALSE;
     X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
     BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
     if (!bmp) return FALSE;
 
    if(!bmp->physBitmap)
         if(!X11DRV_CreateBitmap(hbitmap))
-	    return 0;
+	    goto done;
 
     if(bmp->funcs != dc->funcs) {
         WARN("Trying to select non-X11 DDB into an X11 dc\n");
-	return 0;
+	goto done;
     }
 
     if ((dc->w.bitsPerPixel == 1) && (bmp->bitmap.bmBitsPixel != 1))
@@ -211,8 +212,10 @@
 	physDev->brush.fillStyle = FillOpaqueStippled;
 	physDev->brush.pixel = -1;  /* Special case (see DC_SetupGCForBrush) */
     }
-    GDI_HEAP_UNLOCK( hbitmap );
-    return TRUE;
+    ret = TRUE;
+ done:
+    GDI_ReleaseObj( hbitmap );
+    return ret;
 }
 
 
diff --git a/graphics/x11drv/clipping.c b/graphics/x11drv/clipping.c
index 5905217..1d8dd28 100644
--- a/graphics/x11drv/clipping.c
+++ b/graphics/x11drv/clipping.c
@@ -49,7 +49,7 @@
 	if(!pXrect)
 	{
 	    WARN("Can't alloc buffer\n");
-	    GDI_HEAP_UNLOCK( dc->w.hGCClipRgn );
+	    GDI_ReleaseObj( dc->w.hGCClipRgn );
 	    return;
 	}
 
@@ -70,6 +70,6 @@
     if(pXrect)
         HeapFree( GetProcessHeap(), 0, pXrect );
 
-    GDI_HEAP_UNLOCK( dc->w.hGCClipRgn );
+    GDI_ReleaseObj( dc->w.hGCClipRgn );
 }
 
diff --git a/graphics/x11drv/dib.c b/graphics/x11drv/dib.c
index 22c0dac..3bc0071 100644
--- a/graphics/x11drv/dib.c
+++ b/graphics/x11drv/dib.c
@@ -2595,9 +2595,6 @@
     int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
     XImage *bmpImage;
 
-    if ( descr->dc && descr->dc->w.flags & DC_DIRTY ) 
-        CLIPPING_UpdateGCRegion( descr->dc );
-
     if (descr->image)
         bmpImage = descr->image;
     else {
@@ -2984,11 +2981,18 @@
    */
   if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
 
-  if( startscan >= bmp->bitmap.bmHeight ) return FALSE;
+  if( startscan >= bmp->bitmap.bmHeight )
+  {
+      lines = 0;
+      goto done;
+  }
   
   if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
                         &descr.infoBpp, &descr.compression ) == -1)
-      return FALSE;
+  {
+      lines = 0;
+      goto done;
+  }
 
   switch (descr.infoBpp)
   {
@@ -3060,7 +3064,8 @@
 
   info->bmiHeader.biCompression = 0;
 
-  GDI_HEAP_UNLOCK( dc->w.hPalette );
+done:
+  GDI_ReleaseObj( dc->w.hPalette );
  
   return lines;
 }
@@ -3193,7 +3198,7 @@
 	break;
       }
   
-  GDI_HEAP_UNLOCK( (HBITMAP)res );
+  GDI_ReleaseObj( (HBITMAP)res );
   return handled;
 }
 
@@ -3276,7 +3281,7 @@
 
   X11DRV_DIB_CmnUpdateDIBSection(bmp, toDIB);
 
-  GDI_HEAP_UNLOCK(hbmp);
+  GDI_ReleaseObj(hbmp);
 }
 
 /***********************************************************************
@@ -3325,12 +3330,11 @@
 	  TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
 			 dib->dsBm.bmBits, size, ((X11DRV_DIBSECTION *) bmp->dib)->selector,
 			 PTR_SEG_OFF_TO_SEGPTR(((X11DRV_DIBSECTION *) bmp->dib)->selector, 0));
-	}
-      GDI_HEAP_UNLOCK( res );
-      
       if ( bits ) 
 	*bits = PTR_SEG_OFF_TO_SEGPTR( ((X11DRV_DIBSECTION *) bmp->dib)->selector, 0 );
     }
+      if (bmp) GDI_ReleaseObj( res );
+    }
 
     return res;
 }
@@ -3545,6 +3549,7 @@
       if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
       if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
       if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
+      if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
       if (res) { DeleteObject(res); res = 0; }
     }
   
@@ -3567,7 +3572,7 @@
     }
 
   /* Return BITMAP handle and storage location */
-  if (res) GDI_HEAP_UNLOCK(res);
+  if (bmp) GDI_ReleaseObj(res);
   if (bm.bmBits && bits) *bits = bm.bmBits;
   return res;
 }
@@ -3642,6 +3647,7 @@
         pBmp->physBitmap = NULL;
         pBmp->funcs = NULL;
     }
+    GDI_ReleaseObj( hBmp );
     DeleteObject(hBmp);  
     
 END:
@@ -3695,6 +3701,7 @@
     pBmp->funcs = NULL;
 
     /* Delete the DDB we created earlier now that we have stolen its pixmap */
+    GDI_ReleaseObj( hBmp );
     DeleteObject(hBmp);
     
     TRACE("\tReturning Pixmap %ld\n", pixmap);
diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c
index dcd95e5..3376546 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -99,8 +99,6 @@
         val.background = X11DRV_PALETTE_XPixelToPalette[val.background];
     }
 
-    if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
-
     val.function = X11DRV_XROPfunction[dc->w.ROPmode-1];
     /*
     ** Let's replace GXinvert by GXxor with (black xor white)
@@ -187,8 +185,6 @@
 
     if (physDev->pen.style == PS_NULL) return FALSE;
 
-    if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc); 
-
     switch (dc->w.ROPmode)
     {
     case R2_BLACK :
@@ -275,8 +271,6 @@
     {
 	XGCValues val;
 
-	if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
-
 	val.function   = GXcopy;  /* Text is always GXcopy */
 	val.foreground = physDev->textPixel;
 	val.background = physDev->backgroundPixel;
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index 0fe27ca..399bc8d 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -240,9 +240,13 @@
     dc->w.devCaps      = &X11DRV_DevCaps;
     if (dc->w.flags & DC_MEMORY)
     {
-        BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( dc->w.hBitmap,
-                                                      BITMAP_MAGIC );
-	if (!bmp->physBitmap) X11DRV_CreateBitmap( dc->w.hBitmap );
+        BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( dc->w.hBitmap, BITMAP_MAGIC );
+	if (!bmp) 
+	{
+	    HeapFree( GetProcessHeap(), 0, physDev );
+	    return FALSE;
+        }
+        if (!bmp->physBitmap) X11DRV_CreateBitmap( dc->w.hBitmap );
         physDev->drawable  = (Pixmap)bmp->physBitmap;
         physDev->gc        = TSXCreateGC(display, physDev->drawable, 0, NULL);
         dc->w.bitsPerPixel = bmp->bitmap.bmBitsPixel;
@@ -253,7 +257,7 @@
         dc->w.totalExtent.bottom = bmp->bitmap.bmHeight;
         dc->w.hVisRgn            = CreateRectRgnIndirect( &dc->w.totalExtent );
 
-	GDI_HEAP_UNLOCK( dc->w.hBitmap );
+        GDI_ReleaseObj( dc->w.hBitmap );
     }
     else
     {
@@ -274,6 +278,7 @@
     if (!dc->w.hVisRgn)
     {
         TSXFreeGC( display, physDev->gc );
+	HeapFree( GetProcessHeap(), 0, physDev );
         return FALSE;
     }
 
diff --git a/graphics/x11drv/objects.c b/graphics/x11drv/objects.c
index ec3576f..9645221 100644
--- a/graphics/x11drv/objects.c
+++ b/graphics/x11drv/objects.c
@@ -58,7 +58,7 @@
 	  ret = (HGDIOBJ16)SelectClipRgn16( dc->hSelf, handle );
 	  break;
     }
-    GDI_HEAP_UNLOCK( handle );
+    GDI_ReleaseObj( handle );
     return ret;
 }
 
@@ -83,7 +83,7 @@
 	ret = FALSE;
 	break;
     }
-    GDI_HEAP_UNLOCK( handle );
+    GDI_ReleaseObj( handle );
     return ret;
 }
 
diff --git a/graphics/x11drv/oembitmap.c b/graphics/x11drv/oembitmap.c
index 1908721..2a4add8 100644
--- a/graphics/x11drv/oembitmap.c
+++ b/graphics/x11drv/oembitmap.c
@@ -341,15 +341,12 @@
 static HBITMAP16 OBM_MakeBitmap( WORD width, WORD height,
                                  WORD bpp, Pixmap pixmap )
 {
-    HBITMAP16 hbitmap;
+    HBITMAP hbitmap;
     BITMAPOBJ * bmpObjPtr;
 
     if (!pixmap) return 0;
 
-    hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
-    if (!hbitmap) return 0;
-
-    bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LOCK( hbitmap );
+    if (!(bmpObjPtr = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC, &hbitmap ))) return 0;
     bmpObjPtr->size.cx = width;
     bmpObjPtr->size.cy = height;
     bmpObjPtr->bitmap.bmType       = 0;
@@ -364,7 +361,7 @@
     bmpObjPtr->funcs = &X11DRV_DC_Funcs;
     bmpObjPtr->physBitmap = (void *)pixmap;
 
-    GDI_HEAP_UNLOCK( hbitmap );
+    GDI_ReleaseObj( hbitmap );
     return hbitmap;
 }
 #endif /* defined(HAVE_LIBXXPM) */
@@ -412,8 +409,8 @@
     {
         if (pixmap) XFreePixmap( display, pixmap );
         if (pixmask) XFreePixmap( display, pixmask );
-        if (descr->bitmap) GDI_FreeObject( descr->bitmap );
-        if (descr->need_mask && descr->mask) GDI_FreeObject( descr->mask );
+        if (descr->bitmap) DeleteObject( descr->bitmap );
+        if (descr->need_mask && descr->mask) DeleteObject( descr->mask );
         return FALSE;
     }
     else return TRUE;
@@ -512,11 +509,7 @@
 
     if (!(handle = GlobalAlloc16( GMEM_MOVEABLE,
                                   sizeof(CURSORICONINFO) + sizeXor + sizeAnd)))
-    {
-        DeleteObject( descr.bitmap );
-        DeleteObject( descr.mask );
-        return 0;
-    }
+        goto done;
 
     pInfo = (CURSORICONINFO *)GlobalLock16( handle );
     pInfo->ptHotSpot.x   = descr.hotspot.x;
@@ -554,11 +547,12 @@
     if (descr.mask) GetBitmapBits( descr.mask, sizeAnd, (char *)(pInfo + 1));
     else memset( (char *)(pInfo + 1), 0xff, sizeAnd );
     GetBitmapBits( descr.bitmap, sizeXor, (char *)(pInfo + 1) + sizeAnd );
-
+    if (fCursor) OBM_Cursors[id] = handle;
+ done:
+    GDI_ReleaseObj( descr.mask );
+    GDI_ReleaseObj( descr.bitmap );
     DeleteObject( descr.bitmap );
     DeleteObject( descr.mask );
-
-    if (fCursor) OBM_Cursors[id] = handle;
     return handle;
 }
 
diff --git a/graphics/x11drv/palette.c b/graphics/x11drv/palette.c
index 0878334..bf363d2 100644
--- a/graphics/x11drv/palette.c
+++ b/graphics/x11drv/palette.c
@@ -692,14 +692,15 @@
             if( (idx = color & 0xffff) >= palPtr->logpalette.palNumEntries)
             {
                 WARN("RGB(%lx) : idx %d is out of bounds, assuming black\n", color, idx);
-		GDI_HEAP_UNLOCK( hPal );
+		GDI_ReleaseObj( hPal );
                 return 0;
             }
 
             if( palPtr->mapping ) 
 	    {
-		GDI_HEAP_UNLOCK( hPal );
-		return palPtr->mapping[idx];
+                int ret = palPtr->mapping[idx];
+		GDI_ReleaseObj( hPal );
+		return ret;
 	    }
 	    color = *(COLORREF*)(palPtr->logpalette.palPalEntry + idx);
 	    break;
@@ -711,7 +712,7 @@
 	  case 0: /* RGB */
 	    if( dc && (dc->w.bitsPerPixel == 1) )
 	    {
-		GDI_HEAP_UNLOCK( hPal );
+		GDI_ReleaseObj( hPal );
 		return (((color >> 16) & 0xff) +
 			((color >> 8) & 0xff) + (color & 0xff) > 255*3/2) ? 1 : 0;
 	    }
@@ -723,7 +724,7 @@
 	if (X11DRV_PALETTE_Graymax)
         {
 	    /* grayscale only; return scaled value */
-	    GDI_HEAP_UNLOCK( hPal );
+	    GDI_ReleaseObj( hPal );
             return ( (red * 30 + green * 69 + blue * 11) * X11DRV_PALETTE_Graymax) / 25500;
 	}
 	else
@@ -736,7 +737,7 @@
 	    if (X11DRV_PALETTE_Bluemax != 255)
 		blue = MulDiv(blue, X11DRV_PALETTE_Bluemax, 255);
 
-	    GDI_HEAP_UNLOCK( hPal );
+	    GDI_ReleaseObj( hPal );
 	    return (red << X11DRV_PALETTE_Redshift) | (green << X11DRV_PALETTE_Greenshift) | (blue << X11DRV_PALETTE_Blueshift);
         }
     }
@@ -755,7 +756,7 @@
        	    case 0:  /* RGB */
 		if( dc && (dc->w.bitsPerPixel == 1) )
 		{
-		    GDI_HEAP_UNLOCK( hPal );
+		    GDI_ReleaseObj( hPal );
 		    return (((color >> 16) & 0xff) +
 			    ((color >> 8) & 0xff) + (color & 0xff) > 255*3/2) ? 1 : 0;
 		}
@@ -786,7 +787,7 @@
 	}
     }
 
-    GDI_HEAP_UNLOCK( hPal );
+    GDI_ReleaseObj( hPal );
     return index;
 }
 
diff --git a/graphics/x11drv/xfont.c b/graphics/x11drv/xfont.c
index 8c4050e..19a52fe 100644
--- a/graphics/x11drv/xfont.c
+++ b/graphics/x11drv/xfont.c
@@ -2991,7 +2991,7 @@
  *
  *           X11DRV_EnumDeviceFonts
  */
-BOOL	X11DRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf, 
+BOOL X11DRV_EnumDeviceFonts( HDC hdc, LPLOGFONT16 plf, 
 				        DEVICEFONTENUMPROC proc, LPARAM lp )
 {
     ENUMLOGFONTEX16	lf;