Alexandre Julliard : gdi32: Store a separate flag to mark a GDI object for delayed destruction.
Alexandre Julliard
julliard at winehq.org
Fri Jan 30 07:58:01 CST 2009
Module: wine
Branch: master
Commit: 73593cbf5aa080273cba604f85e6f1a130f61e29
URL: http://source.winehq.org/git/wine.git/?a=commit;h=73593cbf5aa080273cba604f85e6f1a130f61e29
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Jan 29 16:28:57 2009 +0100
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 8bb21f2..5ca76a2 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 f4c2d02..e01f1d0 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 b4ca4d9..a67ceb3 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;
}
More information about the wine-cvs
mailing list