gdi32: Release GDI handles before freeing the object.
This makes it unnecessary to hold the GDI lock during destruction.
This commit is contained in:
parent
311c53db4f
commit
de831f334c
|
@ -628,12 +628,16 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc )
|
||||||
*/
|
*/
|
||||||
static BOOL BITMAP_DeleteObject( HGDIOBJ handle )
|
static BOOL BITMAP_DeleteObject( HGDIOBJ handle )
|
||||||
{
|
{
|
||||||
|
const DC_FUNCTIONS *funcs;
|
||||||
BITMAPOBJ *bmp = GDI_GetObjPtr( handle, OBJ_BITMAP );
|
BITMAPOBJ *bmp = GDI_GetObjPtr( handle, OBJ_BITMAP );
|
||||||
|
|
||||||
if (!bmp) return FALSE;
|
if (!bmp) return FALSE;
|
||||||
|
funcs = bmp->funcs;
|
||||||
|
GDI_ReleaseObj( handle );
|
||||||
|
|
||||||
if (bmp->funcs && bmp->funcs->pDeleteBitmap)
|
if (funcs && funcs->pDeleteBitmap) funcs->pDeleteBitmap( handle );
|
||||||
bmp->funcs->pDeleteBitmap( handle );
|
|
||||||
|
if (!(bmp = free_gdi_handle( handle ))) return FALSE;
|
||||||
|
|
||||||
HeapFree( GetProcessHeap(), 0, bmp->bitmap.bmBits );
|
HeapFree( GetProcessHeap(), 0, bmp->bitmap.bmBits );
|
||||||
|
|
||||||
|
@ -665,7 +669,7 @@ static BOOL BITMAP_DeleteObject( HGDIOBJ handle )
|
||||||
}
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, bmp->color_table);
|
HeapFree(GetProcessHeap(), 0, bmp->color_table);
|
||||||
}
|
}
|
||||||
return GDI_FreeObject( handle, bmp );
|
return HeapFree( GetProcessHeap(), 0, bmp );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -416,7 +416,7 @@ static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc )
|
||||||
*/
|
*/
|
||||||
static BOOL BRUSH_DeleteObject( HGDIOBJ handle )
|
static BOOL BRUSH_DeleteObject( HGDIOBJ handle )
|
||||||
{
|
{
|
||||||
BRUSHOBJ *brush = GDI_GetObjPtr( handle, OBJ_BRUSH );
|
BRUSHOBJ *brush = free_gdi_handle( handle );
|
||||||
|
|
||||||
if (!brush) return FALSE;
|
if (!brush) return FALSE;
|
||||||
switch(brush->logbrush.lbStyle)
|
switch(brush->logbrush.lbStyle)
|
||||||
|
@ -428,7 +428,7 @@ static BOOL BRUSH_DeleteObject( HGDIOBJ handle )
|
||||||
GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
|
GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return GDI_FreeObject( handle, brush );
|
return HeapFree( GetProcessHeap(), 0, brush );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -163,9 +163,8 @@ DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic )
|
||||||
BOOL free_dc_ptr( DC *dc )
|
BOOL free_dc_ptr( DC *dc )
|
||||||
{
|
{
|
||||||
assert( dc->refcount == 1 );
|
assert( dc->refcount == 1 );
|
||||||
/* grab the gdi lock again */
|
if (free_gdi_handle( dc->hSelf ) != dc) return FALSE; /* shouldn't happen */
|
||||||
if (!GDI_GetObjPtr( dc->hSelf, 0 )) return FALSE; /* shouldn't happen */
|
return HeapFree( GetProcessHeap(), 0, dc );
|
||||||
return GDI_FreeObject( dc->hSelf, dc );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -276,7 +276,7 @@ HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk )
|
||||||
*/
|
*/
|
||||||
static BOOL EMF_Delete_HENHMETAFILE( HENHMETAFILE hmf )
|
static BOOL EMF_Delete_HENHMETAFILE( HENHMETAFILE hmf )
|
||||||
{
|
{
|
||||||
ENHMETAFILEOBJ *metaObj = GDI_GetObjPtr( hmf, OBJ_ENHMETAFILE );
|
ENHMETAFILEOBJ *metaObj = free_gdi_handle( hmf );
|
||||||
|
|
||||||
if(!metaObj) return FALSE;
|
if(!metaObj) return FALSE;
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ static BOOL EMF_Delete_HENHMETAFILE( HENHMETAFILE hmf )
|
||||||
UnmapViewOfFile( metaObj->emh );
|
UnmapViewOfFile( metaObj->emh );
|
||||||
else
|
else
|
||||||
HeapFree( GetProcessHeap(), 0, metaObj->emh );
|
HeapFree( GetProcessHeap(), 0, metaObj->emh );
|
||||||
return GDI_FreeObject( hmf, metaObj );
|
return HeapFree( GetProcessHeap(), 0, metaObj );
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
|
|
|
@ -559,10 +559,12 @@ static INT FONT_GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer )
|
||||||
*/
|
*/
|
||||||
static BOOL FONT_DeleteObject( HGDIOBJ handle )
|
static BOOL FONT_DeleteObject( HGDIOBJ handle )
|
||||||
{
|
{
|
||||||
FONTOBJ *obj = GDI_GetObjPtr( handle, OBJ_FONT ); /* to grab the GDI lock (FIXME) */
|
FONTOBJ *obj;
|
||||||
if (!obj) return FALSE;
|
|
||||||
WineEngDestroyFontInstance( handle );
|
WineEngDestroyFontInstance( handle );
|
||||||
return GDI_FreeObject( handle, obj );
|
|
||||||
|
if (!(obj = free_gdi_handle( handle ))) return FALSE;
|
||||||
|
return HeapFree( GetProcessHeap(), 0, obj );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -439,7 +439,7 @@ extern BOOL WineEngRemoveFontResourceEx(LPCWSTR, DWORD, PVOID) DECLSPEC_HIDDEN;
|
||||||
extern BOOL GDI_Init(void) DECLSPEC_HIDDEN;
|
extern BOOL GDI_Init(void) DECLSPEC_HIDDEN;
|
||||||
extern HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN;
|
extern HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN;
|
||||||
extern void *GDI_ReallocObject( WORD, HGDIOBJ, void *obj ) DECLSPEC_HIDDEN;
|
extern void *GDI_ReallocObject( WORD, HGDIOBJ, void *obj ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL GDI_FreeObject( HGDIOBJ, void *obj ) DECLSPEC_HIDDEN;
|
extern void *free_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN;
|
||||||
extern void *GDI_GetObjPtr( HGDIOBJ, WORD ) DECLSPEC_HIDDEN;
|
extern void *GDI_GetObjPtr( HGDIOBJ, WORD ) DECLSPEC_HIDDEN;
|
||||||
extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN;
|
extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN;
|
||||||
extern void GDI_CheckNotLock(void) DECLSPEC_HIDDEN;
|
extern void GDI_CheckNotLock(void) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -689,25 +689,29 @@ void *GDI_ReallocObject( WORD size, HGDIOBJ handle, void *object )
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GDI_FreeObject
|
* free_gdi_handle
|
||||||
|
*
|
||||||
|
* Free a GDI handle and return a pointer to the object.
|
||||||
*/
|
*/
|
||||||
BOOL GDI_FreeObject( HGDIOBJ handle, void *ptr )
|
void *free_gdi_handle( HGDIOBJ handle )
|
||||||
{
|
{
|
||||||
GDIOBJHDR *object = ptr;
|
GDIOBJHDR *object = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
object->type = 0; /* Mark it as invalid */
|
|
||||||
object->funcs = NULL;
|
|
||||||
i = ((ULONG_PTR)handle >> 2) - FIRST_LARGE_HANDLE;
|
i = ((ULONG_PTR)handle >> 2) - FIRST_LARGE_HANDLE;
|
||||||
if (i >= 0 && i < MAX_LARGE_HANDLES)
|
if (i >= 0 && i < MAX_LARGE_HANDLES)
|
||||||
{
|
{
|
||||||
HeapFree( GetProcessHeap(), 0, large_handles[i] );
|
_EnterSysLevel( &GDI_level );
|
||||||
|
object = large_handles[i];
|
||||||
large_handles[i] = NULL;
|
large_handles[i] = NULL;
|
||||||
|
_LeaveSysLevel( &GDI_level );
|
||||||
}
|
}
|
||||||
else ERR( "Invalid handle %p\n", handle );
|
if (object)
|
||||||
TRACE("(%p): leave %d\n", handle, GDI_level.crst.RecursionCount);
|
{
|
||||||
_LeaveSysLevel( &GDI_level );
|
object->type = 0; /* mark it as invalid */
|
||||||
return TRUE;
|
object->funcs = NULL;
|
||||||
|
}
|
||||||
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -163,11 +163,10 @@ static POINT *convert_points( UINT count, POINT16 *pt16 )
|
||||||
|
|
||||||
BOOL WINAPI DeleteMetaFile( HMETAFILE hmf )
|
BOOL WINAPI DeleteMetaFile( HMETAFILE hmf )
|
||||||
{
|
{
|
||||||
METAFILEOBJ * metaObj = GDI_GetObjPtr( hmf, OBJ_METAFILE );
|
METAFILEOBJ * metaObj = free_gdi_handle( hmf );
|
||||||
if (!metaObj) return FALSE;
|
if (!metaObj) return FALSE;
|
||||||
HeapFree( GetProcessHeap(), 0, metaObj->mh );
|
HeapFree( GetProcessHeap(), 0, metaObj->mh );
|
||||||
GDI_FreeObject( hmf, metaObj );
|
return HeapFree( GetProcessHeap(), 0, metaObj );
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
|
|
|
@ -679,8 +679,8 @@ static BOOL PALETTE_DeleteObject( HGDIOBJ handle )
|
||||||
PALETTEOBJ *obj;
|
PALETTEOBJ *obj;
|
||||||
|
|
||||||
PALETTE_UnrealizeObject( handle );
|
PALETTE_UnrealizeObject( handle );
|
||||||
if (!(obj = GDI_GetObjPtr( handle, OBJ_PAL ))) return FALSE;
|
if (!(obj = free_gdi_handle( handle ))) return FALSE;
|
||||||
return GDI_FreeObject( handle, obj );
|
return HeapFree( GetProcessHeap(), 0, obj );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -254,10 +254,10 @@ static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc )
|
||||||
*/
|
*/
|
||||||
static BOOL PEN_DeleteObject( HGDIOBJ handle )
|
static BOOL PEN_DeleteObject( HGDIOBJ handle )
|
||||||
{
|
{
|
||||||
PENOBJ *pen = GDI_GetObjPtr( handle, 0 );
|
PENOBJ *pen = free_gdi_handle( handle );
|
||||||
|
|
||||||
if (!pen) return FALSE;
|
if (!pen) return FALSE;
|
||||||
return GDI_FreeObject( handle, pen );
|
return HeapFree( GetProcessHeap(), 0, pen );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -542,11 +542,12 @@ static void REGION_DestroyWineRegion( WINEREGION* pReg )
|
||||||
*/
|
*/
|
||||||
static BOOL REGION_DeleteObject( HGDIOBJ handle )
|
static BOOL REGION_DeleteObject( HGDIOBJ handle )
|
||||||
{
|
{
|
||||||
RGNOBJ *rgn = GDI_GetObjPtr( handle, OBJ_REGION );
|
RGNOBJ *rgn = free_gdi_handle( handle );
|
||||||
|
|
||||||
if (!rgn) return FALSE;
|
if (!rgn) return FALSE;
|
||||||
REGION_DestroyWineRegion( rgn->rgn );
|
REGION_DestroyWineRegion( rgn->rgn );
|
||||||
return GDI_FreeObject( handle, rgn );
|
HeapFree( GetProcessHeap(), 0, rgn );
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -2820,7 +2821,8 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
|
||||||
if (! (pETEs = HeapAlloc( GetProcessHeap(), 0, sizeof(EdgeTableEntry) * total )))
|
if (! (pETEs = HeapAlloc( GetProcessHeap(), 0, sizeof(EdgeTableEntry) * total )))
|
||||||
{
|
{
|
||||||
REGION_DestroyWineRegion( region );
|
REGION_DestroyWineRegion( region );
|
||||||
GDI_FreeObject( hrgn, obj );
|
free_gdi_handle( hrgn );
|
||||||
|
HeapFree( GetProcessHeap(), 0, obj );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pts = FirstPtBlock.pts;
|
pts = FirstPtBlock.pts;
|
||||||
|
@ -2911,8 +2913,8 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
|
||||||
if(!tmpPtBlock) {
|
if(!tmpPtBlock) {
|
||||||
WARN("Can't alloc tPB\n");
|
WARN("Can't alloc tPB\n");
|
||||||
REGION_DestroyWineRegion( region );
|
REGION_DestroyWineRegion( region );
|
||||||
GDI_FreeObject( hrgn, obj );
|
free_gdi_handle( hrgn );
|
||||||
HeapFree( GetProcessHeap(), 0, pETEs );
|
HeapFree( GetProcessHeap(), 0, obj );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
curPtBlock->next = tmpPtBlock;
|
curPtBlock->next = tmpPtBlock;
|
||||||
|
|
Loading…
Reference in New Issue