Alexandre Julliard : gdi32: Move the object refcount handling to the SelectObject backend functions.

Alexandre Julliard julliard at winehq.org
Thu Sep 27 14:48:51 CDT 2007


Module: wine
Branch: master
Commit: af6c0a09c56770c903f21b65a637d6645502afca
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=af6c0a09c56770c903f21b65a637d6645502afca

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Sep 27 20:57:02 2007 +0200

gdi32: Move the object refcount handling to the SelectObject backend functions.

---

 dlls/gdi32/bitmap.c      |    2 ++
 dlls/gdi32/brush.c       |   10 +++++++---
 dlls/gdi32/font.c        |    2 ++
 dlls/gdi32/gdi_private.h |    2 ++
 dlls/gdi32/gdiobj.c      |   25 +++++++++++++------------
 dlls/gdi32/pen.c         |   13 +++++++++----
 6 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c
index 0aa7dd5..e882442 100644
--- a/dlls/gdi32/bitmap.c
+++ b/dlls/gdi32/bitmap.c
@@ -593,9 +593,11 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc )
     if (handle)
     {
         dc->hBitmap = handle;
+        GDI_inc_ref_count( handle );
         dc->dirty = 0;
         SetRectRgn( dc->hVisRgn, 0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight);
         DC_InitDC( dc );
+        GDI_dec_ref_count( ret );
     }
     else ret = 0;
 
diff --git a/dlls/gdi32/brush.c b/dlls/gdi32/brush.c
index 4b13bc0..ac5ae77 100644
--- a/dlls/gdi32/brush.c
+++ b/dlls/gdi32/brush.c
@@ -381,10 +381,14 @@ static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc )
         if (brush->logbrush.lbStyle == BS_PATTERN)
             BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, dc );
 
-        ret = dc->hBrush;
         if (dc->funcs->pSelectBrush) handle = dc->funcs->pSelectBrush( dc->physDev, handle );
-        if (handle) dc->hBrush = handle;
-        else ret = 0;
+        if (handle)
+        {
+            ret = dc->hBrush;
+            dc->hBrush = handle;
+            GDI_inc_ref_count( handle );
+            GDI_dec_ref_count( ret );
+        }
         GDI_ReleaseObj( handle );
     }
     release_dc_ptr( dc );
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index f76af22..826e331 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -608,6 +608,8 @@ static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, HDC hdc )
     {
         ret = dc->hFont;
         dc->hFont = handle;
+        GDI_inc_ref_count( handle );
+        GDI_dec_ref_count( ret );
     }
     DC_ReleaseDCPtr( dc );
     return ret;
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 6ef0b66..421e7c5 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -456,6 +456,8 @@ extern BOOL GDI_FreeObject( HGDIOBJ, void *obj );
 extern void *GDI_GetObjPtr( HGDIOBJ, WORD );
 extern void GDI_ReleaseObj( HGDIOBJ );
 extern void GDI_CheckNotLock(void);
+extern BOOL GDI_inc_ref_count( HGDIOBJ handle );
+extern BOOL GDI_dec_ref_count( HGDIOBJ handle );
 extern BOOL GDI_hdc_using_object(HGDIOBJ obj, HDC hdc);
 extern BOOL GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc);
 
diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c
index 25f072c..9539d61 100644
--- a/dlls/gdi32/gdiobj.c
+++ b/dlls/gdi32/gdiobj.c
@@ -524,22 +524,29 @@ static DWORD get_dpi( void )
 
 
 /***********************************************************************
- *           inc_ref_count
+ *           GDI_inc_ref_count
  *
  * Increment the reference count of a GDI object.
  */
-static inline void inc_ref_count( GDIOBJHDR *header )
+BOOL GDI_inc_ref_count( HGDIOBJ handle )
 {
-    header->dwCount++;
+    GDIOBJHDR *header;
+
+    if ((header = GDI_GetObjPtr( handle, MAGIC_DONTCARE )))
+    {
+        header->dwCount++;
+        GDI_ReleaseObj( handle );
+    }
+    return header != NULL;
 }
 
 
 /***********************************************************************
- *           dec_ref_count
+ *           GDI_dec_ref_count
  *
  * Decrement the reference count of a GDI object.
  */
-static inline void dec_ref_count( HGDIOBJ handle )
+BOOL GDI_dec_ref_count( HGDIOBJ handle )
 {
     GDIOBJHDR *header;
 
@@ -556,6 +563,7 @@ static inline void dec_ref_count( HGDIOBJ handle )
             DeleteObject( handle );
         }
     }
+    return header != NULL;
 }
 
 
@@ -1149,14 +1157,7 @@ HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ hObj )
         if (header)
         {
             if (header->funcs && header->funcs->pSelectObject)
-            {
                 ret = header->funcs->pSelectObject( hObj, hdc );
-                if (ret && ret != hObj && HandleToULong(ret) > COMPLEXREGION)
-                {
-                    inc_ref_count( header );
-                    dec_ref_count( ret );
-                }
-            }
 	    GDI_ReleaseObj( hObj );
         }
     }
diff --git a/dlls/gdi32/pen.c b/dlls/gdi32/pen.c
index 1c4381e..5647d7e 100644
--- a/dlls/gdi32/pen.c
+++ b/dlls/gdi32/pen.c
@@ -217,14 +217,19 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width,
  */
 static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc )
 {
-    HGDIOBJ ret;
+    HGDIOBJ ret = 0;
     DC *dc = DC_GetDCPtr( hdc );
 
     if (!dc) return 0;
-    ret = dc->hPen;
+
     if (dc->funcs->pSelectPen) handle = dc->funcs->pSelectPen( dc->physDev, handle );
-    if (handle) dc->hPen = handle;
-    else ret = 0;
+    if (handle)
+    {
+        ret = dc->hPen;
+        dc->hPen = handle;
+        GDI_inc_ref_count( handle );
+        GDI_dec_ref_count( ret );
+    }
     DC_ReleaseDCPtr( dc );
     return ret;
 }




More information about the wine-cvs mailing list