Added reference counting and delayed destruction of GDI objects.
This commit is contained in:
parent
d44e495aa4
commit
8e5e003f09
|
@ -757,6 +757,7 @@ BOOL WINAPI DeleteDC( HDC hdc )
|
||||||
SelectObject( hdc, GetStockObject(BLACK_PEN) );
|
SelectObject( hdc, GetStockObject(BLACK_PEN) );
|
||||||
SelectObject( hdc, GetStockObject(WHITE_BRUSH) );
|
SelectObject( hdc, GetStockObject(WHITE_BRUSH) );
|
||||||
SelectObject( hdc, GetStockObject(SYSTEM_FONT) );
|
SelectObject( hdc, GetStockObject(SYSTEM_FONT) );
|
||||||
|
SelectObject( hdc, GetStockObject(DEFAULT_BITMAP) );
|
||||||
funcs = dc->funcs;
|
funcs = dc->funcs;
|
||||||
if (dc->funcs->pDeleteDC) dc->funcs->pDeleteDC(dc);
|
if (dc->funcs->pDeleteDC) dc->funcs->pDeleteDC(dc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,6 +144,48 @@ static HFONT create_stock_font( char const *fontName, const LOGFONTW *font, HKEY
|
||||||
TRACE("(%04x): " text " %ld\n", (handle), GDI_level.crst.RecursionCount)
|
TRACE("(%04x): " text " %ld\n", (handle), GDI_level.crst.RecursionCount)
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* inc_ref_count
|
||||||
|
*
|
||||||
|
* Increment the reference count of a GDI object.
|
||||||
|
*/
|
||||||
|
inline static void inc_ref_count( HGDIOBJ handle )
|
||||||
|
{
|
||||||
|
GDIOBJHDR *header;
|
||||||
|
|
||||||
|
if ((header = GDI_GetObjPtr( handle, MAGIC_DONTCARE )))
|
||||||
|
{
|
||||||
|
header->dwCount++;
|
||||||
|
GDI_ReleaseObj( handle );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* dec_ref_count
|
||||||
|
*
|
||||||
|
* Decrement the reference count of a GDI object.
|
||||||
|
*/
|
||||||
|
inline static void dec_ref_count( HGDIOBJ handle )
|
||||||
|
{
|
||||||
|
GDIOBJHDR *header;
|
||||||
|
|
||||||
|
if ((header = GDI_GetObjPtr( handle, MAGIC_DONTCARE )))
|
||||||
|
{
|
||||||
|
if (header->dwCount) header->dwCount--;
|
||||||
|
if (header->dwCount != 0x80000000) GDI_ReleaseObj( handle );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* handle delayed DeleteObject*/
|
||||||
|
header->dwCount = 0;
|
||||||
|
GDI_ReleaseObj( handle );
|
||||||
|
TRACE( "executing delayed DeleteObject for %04x\n", handle );
|
||||||
|
DeleteObject( handle );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GDI_Init
|
* GDI_Init
|
||||||
*
|
*
|
||||||
|
@ -243,7 +285,6 @@ inline static GDIOBJHDR *alloc_large_heap( WORD size, HGDIOBJ *handle )
|
||||||
*/
|
*/
|
||||||
void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle )
|
void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle )
|
||||||
{
|
{
|
||||||
static DWORD count = 0;
|
|
||||||
GDIOBJHDR *obj;
|
GDIOBJHDR *obj;
|
||||||
|
|
||||||
_EnterSysLevel( &GDI_level );
|
_EnterSysLevel( &GDI_level );
|
||||||
|
@ -269,7 +310,7 @@ void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle )
|
||||||
|
|
||||||
obj->hNext = 0;
|
obj->hNext = 0;
|
||||||
obj->wMagic = magic|OBJECT_NOSYSTEM;
|
obj->wMagic = magic|OBJECT_NOSYSTEM;
|
||||||
obj->dwCount = ++count;
|
obj->dwCount = 0;
|
||||||
|
|
||||||
TRACE_SEC( *handle, "enter" );
|
TRACE_SEC( *handle, "enter" );
|
||||||
return obj;
|
return obj;
|
||||||
|
@ -427,7 +468,15 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj )
|
||||||
GDI_ReleaseObj( obj );
|
GDI_ReleaseObj( obj );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (header->dwCount)
|
||||||
|
{
|
||||||
|
TRACE("delayed for %04x because object in use, count %ld\n", obj, header->dwCount );
|
||||||
|
header->dwCount |= 0x80000000; /* mark for delete */
|
||||||
|
GDI_ReleaseObj( obj );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("%04x\n", obj );
|
TRACE("%04x\n", obj );
|
||||||
|
|
||||||
/* Delete object */
|
/* Delete object */
|
||||||
|
@ -701,6 +750,12 @@ HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
|
||||||
if (dc->funcs->pSelectObject)
|
if (dc->funcs->pSelectObject)
|
||||||
ret = dc->funcs->pSelectObject( dc, handle );
|
ret = dc->funcs->pSelectObject( dc, handle );
|
||||||
GDI_ReleaseObj( hdc );
|
GDI_ReleaseObj( hdc );
|
||||||
|
|
||||||
|
if (ret && ret != handle)
|
||||||
|
{
|
||||||
|
inc_ref_count( handle );
|
||||||
|
dec_ref_count( ret );
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue