gdi32: Store a separate flag to mark a GDI object for delayed destruction.
This commit is contained in:
parent
827e1f1de3
commit
73593cbf5a
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue