From 73593cbf5aa080273cba604f85e6f1a130f61e29 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 29 Jan 2009 16:28:57 +0100 Subject: [PATCH] gdi32: Store a separate flag to mark a GDI object for delayed destruction. --- dlls/gdi32/bitmap.c | 2 +- dlls/gdi32/gdi_private.h | 7 ++++--- dlls/gdi32/gdiobj.c | 27 ++++++++++++++------------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c index 8bb21f2ba2c..5ca76a2e928 100644 --- a/dlls/gdi32/bitmap.c +++ b/dlls/gdi32/bitmap.c @@ -586,7 +586,7 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc ) goto done; } - if (bitmap->header.dwCount && (handle != GetStockObject(DEFAULT_BITMAP))) + if (bitmap->header.selcount && (handle != GetStockObject(DEFAULT_BITMAP))) { WARN( "Bitmap already selected in another DC\n" ); GDI_ReleaseObj( handle ); diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index f4c2d029b39..e01f1d0f320 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -59,9 +59,10 @@ struct hdc_list typedef struct tagGDIOBJHDR { - WORD type; - WORD system : 1; - DWORD dwCount; + WORD type; /* object type (one of the OBJ_* constants) */ + WORD system : 1; /* system object flag */ + WORD deleted : 1; /* whether DeleteObject has been called on this object */ + DWORD selcount; /* number of times the object is selected in a DC */ const struct gdi_obj_funcs *funcs; struct hdc_list *hdcs; } GDIOBJHDR; diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index b4ca4d9bbdf..a67ceb32d5d 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -528,7 +528,7 @@ HGDIOBJ GDI_inc_ref_count( HGDIOBJ handle ) if ((header = GDI_GetObjPtr( handle, 0 ))) { - header->dwCount++; + header->selcount++; GDI_ReleaseObj( handle ); } else handle = 0; @@ -548,16 +548,16 @@ BOOL GDI_dec_ref_count( HGDIOBJ handle ) if ((header = GDI_GetObjPtr( handle, 0 ))) { - if (header->dwCount) header->dwCount--; - if (header->dwCount != 0x80000000) GDI_ReleaseObj( handle ); - else + assert( header->selcount ); + if (!--header->selcount && header->deleted) { /* handle delayed DeleteObject*/ - header->dwCount = 0; + header->deleted = 0; GDI_ReleaseObj( handle ); TRACE( "executing delayed DeleteObject for %p\n", handle ); DeleteObject( handle ); } + else GDI_ReleaseObj( handle ); } return header != NULL; } @@ -641,11 +641,12 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs int i; /* initialize the object header */ - obj->type = type; - obj->system = 0; - obj->dwCount = 0; - obj->funcs = funcs; - obj->hdcs = NULL; + obj->type = type; + obj->system = 0; + obj->deleted = 0; + obj->selcount = 0; + obj->funcs = funcs; + obj->hdcs = NULL; _EnterSysLevel( &GDI_level ); for (i = next_large_handle + 1; i < MAX_LARGE_HANDLES; i++) @@ -796,10 +797,10 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj ) if (!header) return FALSE; } - if (header->dwCount) + if (header->selcount) { - TRACE("delayed for %p because object in use, count %d\n", obj, header->dwCount ); - header->dwCount |= 0x80000000; /* mark for delete */ + TRACE("delayed for %p because object in use, count %u\n", obj, header->selcount ); + header->deleted = 1; /* mark for delete */ GDI_ReleaseObj( obj ); return TRUE; }