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/objects/font.c b/objects/font.c
index 03f1827..66423fe 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -309,15 +309,13 @@
  */
 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *font )
 {
-    HFONT16 hFont = 0;
+    HFONT hFont = 0;
 
     if (font)
     {
-	hFont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
-	if( hFont )
-	{
 	    FONTOBJ* fontPtr;
-	    fontPtr = (FONTOBJ *) GDI_HEAP_LOCK( hFont );
+	if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont )))
+	{
 	    memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
 
 	    TRACE("(%i %i %i %i) '%s' %s %s => %04x\n",
@@ -334,7 +332,7 @@
                    "escapement angle %f for new font %04x\n", 
                    font->lfOrientation/10., font->lfEscapement/10., hFont);
 	    }
-	    GDI_HEAP_UNLOCK( hFont );
+	    GDI_ReleaseObj( hFont );
 	}
     }
     else WARN("(NULL) => NULL\n");
@@ -535,10 +533,15 @@
                                    FONTENUMPROCEX16 efproc, LPARAM lParam,
                                    DWORD dwFlags)
 {
+    BOOL (*enum_func)(HDC,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM);
     INT16	retVal = 0;
-    DC* 	dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
+    DC* 	dc = DC_GetDCPtr( hDC );
 
-    if( dc && dc->funcs->pEnumDeviceFonts )
+    if (!dc) return 0;
+    enum_func = dc->funcs->pEnumDeviceFonts;
+    GDI_ReleaseObj( hDC );
+
+    if (enum_func)
     {
 	LPNEWTEXTMETRICEX16	lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
 	if( lptm16 )
@@ -557,8 +560,7 @@
 		fe16.segTextMetric = SEGPTR_GET(lptm16);
 		fe16.segLogFont = SEGPTR_GET(lplf16);
 
-		retVal = dc->funcs->pEnumDeviceFonts( dc, plf, FONT_EnumInstance16, (LPARAM)&fe16 );
-
+		retVal = enum_func( hDC, plf, FONT_EnumInstance16, (LPARAM)&fe16 );
 		SEGPTR_FREE(lplf16);
 	    }
 	    SEGPTR_FREE(lptm16);
@@ -573,9 +575,15 @@
 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf, FONTENUMPROCEXW efproc, 
 					           LPARAM lParam, DWORD dwUnicode)
 {
-    DC*		dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
+    BOOL (*enum_func)(HDC,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM);
+    INT ret = 0;
+    DC *dc = DC_GetDCPtr( hDC );
 
-    if( dc && dc->funcs->pEnumDeviceFonts )
+    if (!dc) return 0;
+    enum_func = dc->funcs->pEnumDeviceFonts;
+    GDI_ReleaseObj( hDC );
+
+    if (enum_func)
     {
 	LOGFONT16		lf16;
 	NEWTEXTMETRICEXW 	tm32w;
@@ -602,9 +610,9 @@
 	else lf16.lfFaceName[0] = '\0';
 	lf16.lfCharSet = plf->lfCharSet;
 
-	return dc->funcs->pEnumDeviceFonts( dc, &lf16, FONT_EnumInstance, (LPARAM)&fe32 );
+	ret = enum_func( hDC, &lf16, FONT_EnumInstance, (LPARAM)&fe32 );
     }
-    return 0;
+    return ret;
 }
 
 /***********************************************************************
@@ -708,10 +716,7 @@
  */
 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
 {
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return 0;
-    return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
-                 / dc->vportExtX );
+    return (INT16)GetTextCharacterExtra( hdc );
 }
 
 
@@ -720,10 +725,13 @@
  */
 INT WINAPI GetTextCharacterExtra( HDC hdc )
 {
+    INT ret;
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return 0;
-    return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
+    ret = abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
                  / dc->vportExtX );
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -745,11 +753,15 @@
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return 0;
     if (dc->funcs->pSetTextCharacterExtra)
-        return dc->funcs->pSetTextCharacterExtra( dc, extra );
-    extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
-    prev = dc->w.charExtra;
-    dc->w.charExtra = abs(extra);
-    return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
+        prev = dc->funcs->pSetTextCharacterExtra( dc, extra );
+    else
+    {
+        extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
+        prev = (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
+        dc->w.charExtra = abs(extra);
+    }
+    GDI_ReleaseObj( hdc );
+    return prev;
 }
 
 
@@ -767,26 +779,30 @@
  */
 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
 {
+    BOOL ret = TRUE;
     DC * dc = DC_GetDCPtr( hdc );
-    if (!dc) return 0;
+    if (!dc) return FALSE;
     if (dc->funcs->pSetTextJustification)
-        return dc->funcs->pSetTextJustification( dc, extra, breaks );
-
-    extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
-    if (!extra) breaks = 0;
-    dc->w.breakTotalExtra = extra;
-    dc->w.breakCount = breaks;
-    if (breaks)
-    {
-        dc->w.breakExtra = extra / breaks;
-        dc->w.breakRem   = extra - (dc->w.breakCount * dc->w.breakExtra);
-    }
+        ret = dc->funcs->pSetTextJustification( dc, extra, breaks );
     else
     {
-        dc->w.breakExtra = 0;
-        dc->w.breakRem   = 0;
+        extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
+        if (!extra) breaks = 0;
+        dc->w.breakTotalExtra = extra;
+        dc->w.breakCount = breaks;
+        if (breaks)
+        {
+            dc->w.breakExtra = extra / breaks;
+            dc->w.breakRem   = extra - (dc->w.breakCount * dc->w.breakExtra);
+        }
+        else
+        {
+            dc->w.breakExtra = 0;
+            dc->w.breakRem   = 0;
+        }
     }
-    return 1;
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -804,18 +820,23 @@
 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
 {
     FONTOBJ *font;
+    INT     ret = 0;
 
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    DC * dc = (DC *) DC_GetDCPtr( hdc );
     if (!dc) return 0;
-    if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
-        return 0;
-    if (name) 
-        lstrcpynA( name, font->logfont.lfFaceName, count );
-    GDI_HEAP_UNLOCK( dc->w.hFont );
-    if (name)
-        return strlen(name);
-    else
-        return strlen(font->logfont.lfFaceName) + 1;
+
+    if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
+    {
+        if (name)
+        {
+            lstrcpynA( name, font->logfont.lfFaceName, count );
+            ret = strlen(name);
+        }
+        else ret = strlen(font->logfont.lfFaceName) + 1;
+        GDI_ReleaseObj( dc->w.hFont );
+    }
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 /***********************************************************************
@@ -825,7 +846,7 @@
 {
     LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
     INT res = GetTextFaceA(hdc,count,nameA);
-    lstrcpyAtoW( name, nameA );
+    if (name) lstrcpyAtoW( name, nameA );
     HeapFree( GetProcessHeap(), 0, nameA );
     return res;
 }
@@ -903,14 +924,17 @@
     INT count,   /* [in]  Number of characters in string */
     LPSIZE size) /* [out] Address of structure for string size */
 {
+    BOOL ret = FALSE;
     DC * dc = DC_GetDCPtr( hdc );
-    if (!dc || !dc->funcs->pGetTextExtentPoint ||
-        !dc->funcs->pGetTextExtentPoint( dc, str, count, size ))
-        return FALSE;
-
+    if (dc)
+    {
+	if(dc->funcs->pGetTextExtentPoint)
+	    ret = dc->funcs->pGetTextExtentPoint( dc, str, count, size );
+        GDI_ReleaseObj( hdc );
+    }
     TRACE("(%08x %s %d %p): returning %d,%d\n",
           hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
-    return TRUE;
+    return ret;
 }
 
 
@@ -966,14 +990,16 @@
 {
     int index, nFit, extent;
     SIZE tSize;
+    BOOL ret = FALSE;
     DC * dc = DC_GetDCPtr( hdc );
+    if (!dc) return FALSE;
 
-    if (!dc || !dc->funcs->pGetTextExtentPoint) return FALSE;
+    if (!dc->funcs->pGetTextExtentPoint) goto done;
 
     size->cx = size->cy = nFit = extent = 0;
     for(index = 0; index < count; index++)
     {
- 	if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
+ 	if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) goto done;
 	if( extent+tSize.cx < maxExt )
         {
 	    extent+=tSize.cx;
@@ -986,10 +1012,13 @@
     }
     size->cx = extent;
     *lpnFit = nFit;
+    ret = TRUE;
 
     TRACE("(%08x %s %d) returning %d %d %d\n",
           hdc,debugstr_wn(str,count),maxExt,nFit, size->cx,size->cy);
-    return TRUE;
+done:
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 /***********************************************************************
@@ -1009,18 +1038,13 @@
  *           GetTextMetricsA    (GDI32.236)
  */
 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
-{
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc)
     {
-        if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
-            return FALSE;
-    }
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCPtr( hdc );
+    if (!dc) return FALSE;
 
-    if (!dc->funcs->pGetTextMetrics ||
-        !dc->funcs->pGetTextMetrics( dc, metrics ))
-        return FALSE;
-
+    if (dc->funcs->pGetTextMetrics && dc->funcs->pGetTextMetrics( dc, metrics ))
+    {
     /* device layer returns values in device units
      * therefore we have to convert them to logical */
 
@@ -1039,6 +1063,7 @@
     metrics->tmAveCharWidth     = WDPTOLP(metrics->tmAveCharWidth);
     metrics->tmMaxCharWidth     = WDPTOLP(metrics->tmMaxCharWidth);
     metrics->tmOverhang         = WDPTOLP(metrics->tmOverhang);
+        ret = TRUE;
 
     TRACE("text metrics:\n"
           "    Weight = %03li\t FirstChar = %03i\t AveCharWidth = %li\n"
@@ -1060,7 +1085,9 @@
           metrics->tmAscent,
           metrics->tmDescent,
           metrics->tmHeight );
-    return TRUE;
+    }
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -1221,24 +1248,21 @@
                                LPINT buffer )
 {
     UINT i, extra;
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc)
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCPtr( hdc );
+    if (!dc) return FALSE;
+
+    if (dc->funcs->pGetCharWidth && dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
     {
-        if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
-            return FALSE;
+        /* convert device units to logical */
+
+        extra = dc->vportExtX >> 1;
+        for( i = firstChar; i <= lastChar; i++, buffer++ )
+            *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
+        ret = TRUE;
     }
-
-    if (!dc->funcs->pGetCharWidth ||
-        !dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
-        return FALSE;
-
-    /* convert device units to logical */
-
-    extra = dc->vportExtX >> 1;
-    for( i = firstChar; i <= lastChar; i++, buffer++ )
-         *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
-
-    return TRUE;
+    GDI_ReleaseObj( hdc );
+    return ret;
 }
 
 
@@ -1276,7 +1300,7 @@
         ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
     else
         FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
-    GDI_HEAP_UNLOCK( hDC );
+    GDI_ReleaseObj( hDC );
     return ret;
 }