gdi32: Don't hold the gdi lock while creating a DC.
This commit is contained in:
parent
fa5230fb54
commit
7480bd3204
|
@ -71,9 +71,9 @@ static inline DC *get_dc_obj( HDC hdc )
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* DC_AllocDC
|
* alloc_dc_ptr
|
||||||
*/
|
*/
|
||||||
DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic )
|
DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic )
|
||||||
{
|
{
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
DC *dc;
|
DC *dc;
|
||||||
|
@ -149,6 +149,7 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic )
|
||||||
dc->BoundsRect.bottom = 0;
|
dc->BoundsRect.bottom = 0;
|
||||||
dc->saved_visrgn = NULL;
|
dc->saved_visrgn = NULL;
|
||||||
PATH_InitGdiPath(&dc->path);
|
PATH_InitGdiPath(&dc->path);
|
||||||
|
GDI_ReleaseObj( dc->hSelf );
|
||||||
return dc;
|
return dc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,11 +190,13 @@ void DC_ReleaseDCPtr( DC *dc )
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* DC_FreeDCPtr
|
* free_dc_ptr
|
||||||
*/
|
*/
|
||||||
BOOL DC_FreeDCPtr( DC *dc )
|
BOOL free_dc_ptr( DC *dc )
|
||||||
{
|
{
|
||||||
assert( dc->refcount == 1 );
|
assert( dc->refcount == 1 );
|
||||||
|
/* grab the gdi lock again */
|
||||||
|
if (!GDI_GetObjPtr( dc->hSelf, MAGIC_DONTCARE )) return FALSE; /* shouldn't happen */
|
||||||
return GDI_FreeObject( dc->hSelf, dc );
|
return GDI_FreeObject( dc->hSelf, dc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,7 +707,7 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
|
||||||
ERR( "no driver found for %s\n", debugstr_w(buf) );
|
ERR( "no driver found for %s\n", debugstr_w(buf) );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!(dc = DC_AllocDC( funcs, DC_MAGIC ))) goto error;
|
if (!(dc = alloc_dc_ptr( funcs, DC_MAGIC ))) goto error;
|
||||||
hdc = dc->hSelf;
|
hdc = dc->hSelf;
|
||||||
|
|
||||||
dc->hBitmap = GetStockObject( DEFAULT_BITMAP );
|
dc->hBitmap = GetStockObject( DEFAULT_BITMAP );
|
||||||
|
@ -724,12 +727,12 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
|
||||||
GetDeviceCaps( hdc, DESKTOPHORZRES ), GetDeviceCaps( hdc, DESKTOPVERTRES ) );
|
GetDeviceCaps( hdc, DESKTOPHORZRES ), GetDeviceCaps( hdc, DESKTOPVERTRES ) );
|
||||||
|
|
||||||
DC_InitDC( dc );
|
DC_InitDC( dc );
|
||||||
DC_ReleaseDCPtr( dc );
|
release_dc_ptr( dc );
|
||||||
return hdc;
|
return hdc;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (dc && dc->hVisRgn) DeleteObject( dc->hVisRgn );
|
if (dc && dc->hVisRgn) DeleteObject( dc->hVisRgn );
|
||||||
if (dc) DC_FreeDCPtr( dc );
|
if (dc) free_dc_ptr( dc );
|
||||||
DRIVER_release_driver( funcs );
|
DRIVER_release_driver( funcs );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -805,20 +808,20 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
|
||||||
|
|
||||||
GDI_CheckNotLock();
|
GDI_CheckNotLock();
|
||||||
|
|
||||||
if ((origDC = DC_GetDCPtr( hdc )))
|
if ((origDC = get_dc_ptr( hdc )))
|
||||||
{
|
{
|
||||||
if (GetObjectType( hdc ) == OBJ_DC)
|
if (GetObjectType( hdc ) == OBJ_DC)
|
||||||
{
|
{
|
||||||
funcs = origDC->funcs;
|
funcs = origDC->funcs;
|
||||||
physDev = origDC->physDev;
|
physDev = origDC->physDev;
|
||||||
}
|
}
|
||||||
DC_ReleaseDCPtr( origDC ); /* can't hold the lock while loading the driver */
|
release_dc_ptr( origDC );
|
||||||
if (funcs) funcs = DRIVER_get_driver( funcs );
|
if (funcs) funcs = DRIVER_get_driver( funcs );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!funcs && !(funcs = DRIVER_load_driver( displayW ))) return 0;
|
if (!funcs && !(funcs = DRIVER_load_driver( displayW ))) return 0;
|
||||||
|
|
||||||
if (!(dc = DC_AllocDC( funcs, MEMORY_DC_MAGIC ))) goto error;
|
if (!(dc = alloc_dc_ptr( funcs, MEMORY_DC_MAGIC ))) goto error;
|
||||||
|
|
||||||
TRACE("(%p): returning %p\n", hdc, dc->hSelf );
|
TRACE("(%p): returning %p\n", hdc, dc->hSelf );
|
||||||
|
|
||||||
|
@ -838,12 +841,12 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
|
||||||
}
|
}
|
||||||
|
|
||||||
DC_InitDC( dc );
|
DC_InitDC( dc );
|
||||||
DC_ReleaseDCPtr( dc );
|
release_dc_ptr( dc );
|
||||||
return dc->hSelf;
|
return dc->hSelf;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (dc && dc->hVisRgn) DeleteObject( dc->hVisRgn );
|
if (dc && dc->hVisRgn) DeleteObject( dc->hVisRgn );
|
||||||
if (dc) DC_FreeDCPtr( dc );
|
if (dc) free_dc_ptr( dc );
|
||||||
DRIVER_release_driver( funcs );
|
DRIVER_release_driver( funcs );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -861,29 +864,26 @@ BOOL WINAPI DeleteDC( HDC hdc )
|
||||||
|
|
||||||
GDI_CheckNotLock();
|
GDI_CheckNotLock();
|
||||||
|
|
||||||
if (!(dc = DC_GetDCPtr( hdc ))) return FALSE;
|
if (!(dc = get_dc_ptr( hdc ))) return FALSE;
|
||||||
if (dc->refcount != 1)
|
if (dc->refcount != 1)
|
||||||
{
|
{
|
||||||
FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
|
FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
|
||||||
DC_ReleaseDCPtr( dc );
|
release_dc_ptr( dc );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call hook procedure to check whether is it OK to delete this DC */
|
/* Call hook procedure to check whether is it OK to delete this DC */
|
||||||
if (dc->hookThunk)
|
if (dc->hookThunk && !dc->hookThunk( hdc, DCHC_DELETEDC, dc->dwHookData, 0 ))
|
||||||
{
|
{
|
||||||
DCHOOKPROC proc = dc->hookThunk;
|
release_dc_ptr( dc );
|
||||||
DWORD_PTR data = dc->dwHookData;
|
return FALSE;
|
||||||
DC_ReleaseDCPtr( dc );
|
|
||||||
if (!proc( hdc, DCHC_DELETEDC, data, 0 )) return FALSE;
|
|
||||||
if (!(dc = DC_GetDCPtr( hdc ))) return TRUE; /* deleted by the hook */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (dc->saveLevel)
|
while (dc->saveLevel)
|
||||||
{
|
{
|
||||||
DC * dcs;
|
DC * dcs;
|
||||||
HDC hdcs = dc->saved_dc;
|
HDC hdcs = dc->saved_dc;
|
||||||
if (!(dcs = DC_GetDCPtr( hdcs ))) break;
|
if (!(dcs = get_dc_ptr( hdcs ))) break;
|
||||||
dc->saved_dc = dcs->saved_dc;
|
dc->saved_dc = dcs->saved_dc;
|
||||||
dc->saveLevel--;
|
dc->saveLevel--;
|
||||||
if (dcs->hClipRgn) DeleteObject( dcs->hClipRgn );
|
if (dcs->hClipRgn) DeleteObject( dcs->hClipRgn );
|
||||||
|
@ -891,7 +891,7 @@ BOOL WINAPI DeleteDC( HDC hdc )
|
||||||
if (dcs->hMetaClipRgn) DeleteObject( dcs->hMetaClipRgn );
|
if (dcs->hMetaClipRgn) DeleteObject( dcs->hMetaClipRgn );
|
||||||
if (dcs->hVisRgn) DeleteObject( dcs->hVisRgn );
|
if (dcs->hVisRgn) DeleteObject( dcs->hVisRgn );
|
||||||
PATH_DestroyGdiPath(&dcs->path);
|
PATH_DestroyGdiPath(&dcs->path);
|
||||||
DC_FreeDCPtr( dcs );
|
free_dc_ptr( dcs );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(dc->flags & DC_SAVED))
|
if (!(dc->flags & DC_SAVED))
|
||||||
|
@ -918,7 +918,7 @@ BOOL WINAPI DeleteDC( HDC hdc )
|
||||||
if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
|
if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
|
||||||
PATH_DestroyGdiPath(&dc->path);
|
PATH_DestroyGdiPath(&dc->path);
|
||||||
|
|
||||||
DC_FreeDCPtr( dc );
|
free_dc_ptr( dc );
|
||||||
if (funcs) DRIVER_release_driver( funcs ); /* do that after releasing the GDI lock */
|
if (funcs) DRIVER_release_driver( funcs ); /* do that after releasing the GDI lock */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,7 @@ static BOOL EMFDRV_DeleteDC( DC *dc )
|
||||||
HeapFree( GetProcessHeap(), 0, physDev->handles );
|
HeapFree( GetProcessHeap(), 0, physDev->handles );
|
||||||
HeapFree( GetProcessHeap(), 0, physDev );
|
HeapFree( GetProcessHeap(), 0, physDev );
|
||||||
dc->physDev = NULL;
|
dc->physDev = NULL;
|
||||||
DC_FreeDCPtr( dc );
|
free_dc_ptr( dc );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,11 +314,11 @@ HDC WINAPI CreateEnhMetaFileW(
|
||||||
|
|
||||||
TRACE("%s\n", debugstr_w(filename) );
|
TRACE("%s\n", debugstr_w(filename) );
|
||||||
|
|
||||||
if (!(dc = DC_AllocDC( &EMFDRV_Funcs, ENHMETAFILE_DC_MAGIC ))) return 0;
|
if (!(dc = alloc_dc_ptr( &EMFDRV_Funcs, ENHMETAFILE_DC_MAGIC ))) return 0;
|
||||||
|
|
||||||
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
|
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
|
||||||
if (!physDev) {
|
if (!physDev) {
|
||||||
DC_FreeDCPtr( dc );
|
free_dc_ptr( dc );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dc->physDev = (PHYSDEV)physDev;
|
dc->physDev = (PHYSDEV)physDev;
|
||||||
|
@ -334,7 +334,7 @@ HDC WINAPI CreateEnhMetaFileW(
|
||||||
|
|
||||||
if (!(physDev->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size))) {
|
if (!(physDev->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size))) {
|
||||||
HeapFree( GetProcessHeap(), 0, physDev );
|
HeapFree( GetProcessHeap(), 0, physDev );
|
||||||
DC_FreeDCPtr( dc );
|
free_dc_ptr( dc );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +415,7 @@ HDC WINAPI CreateEnhMetaFileW(
|
||||||
|
|
||||||
TRACE("returning %p\n", dc->hSelf);
|
TRACE("returning %p\n", dc->hSelf);
|
||||||
ret = dc->hSelf;
|
ret = dc->hSelf;
|
||||||
DC_ReleaseDCPtr( dc );
|
release_dc_ptr( dc );
|
||||||
|
|
||||||
if( !hdc )
|
if( !hdc )
|
||||||
DeleteDC( hRefDC );
|
DeleteDC( hRefDC );
|
||||||
|
@ -436,16 +436,16 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
|
||||||
|
|
||||||
TRACE("(%p)\n", hdc );
|
TRACE("(%p)\n", hdc );
|
||||||
|
|
||||||
if (!(dc = DC_GetDCPtr( hdc ))) return NULL;
|
if (!(dc = get_dc_ptr( hdc ))) return NULL;
|
||||||
if (GDIMAGIC(dc->header.wMagic) != ENHMETAFILE_DC_MAGIC)
|
if (GDIMAGIC(dc->header.wMagic) != ENHMETAFILE_DC_MAGIC)
|
||||||
{
|
{
|
||||||
DC_ReleaseDCPtr( dc );
|
release_dc_ptr( dc );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (dc->refcount != 1)
|
if (dc->refcount != 1)
|
||||||
{
|
{
|
||||||
FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
|
FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
|
||||||
DC_ReleaseDCPtr( dc );
|
release_dc_ptr( dc );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
physDev = (EMFDRV_PDEVICE *)dc->physDev;
|
physDev = (EMFDRV_PDEVICE *)dc->physDev;
|
||||||
|
|
|
@ -393,11 +393,11 @@ extern INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp );
|
||||||
extern void CLIPPING_UpdateGCRegion( DC * dc );
|
extern void CLIPPING_UpdateGCRegion( DC * dc );
|
||||||
|
|
||||||
/* dc.c */
|
/* dc.c */
|
||||||
extern DC * DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic );
|
extern DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic );
|
||||||
extern DC * DC_GetDCUpdate( HDC hdc );
|
extern DC * DC_GetDCUpdate( HDC hdc );
|
||||||
extern DC * DC_GetDCPtr( HDC hdc );
|
extern DC * DC_GetDCPtr( HDC hdc );
|
||||||
extern void DC_ReleaseDCPtr( DC *dc );
|
extern void DC_ReleaseDCPtr( DC *dc );
|
||||||
extern BOOL DC_FreeDCPtr( DC *dc );
|
extern BOOL free_dc_ptr( DC *dc );
|
||||||
extern DC *get_dc_ptr( HDC hdc );
|
extern DC *get_dc_ptr( HDC hdc );
|
||||||
extern void release_dc_ptr( DC *dc );
|
extern void release_dc_ptr( DC *dc );
|
||||||
extern void update_dc( DC *dc );
|
extern void update_dc( DC *dc );
|
||||||
|
|
|
@ -165,12 +165,12 @@ static DC *MFDRV_AllocMetaFile(void)
|
||||||
DC *dc;
|
DC *dc;
|
||||||
METAFILEDRV_PDEVICE *physDev;
|
METAFILEDRV_PDEVICE *physDev;
|
||||||
|
|
||||||
if (!(dc = DC_AllocDC( &MFDRV_Funcs, METAFILE_DC_MAGIC ))) return NULL;
|
if (!(dc = alloc_dc_ptr( &MFDRV_Funcs, METAFILE_DC_MAGIC ))) return NULL;
|
||||||
|
|
||||||
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
|
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
|
||||||
if (!physDev)
|
if (!physDev)
|
||||||
{
|
{
|
||||||
DC_FreeDCPtr( dc );
|
free_dc_ptr( dc );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
dc->physDev = (PHYSDEV)physDev;
|
dc->physDev = (PHYSDEV)physDev;
|
||||||
|
@ -179,7 +179,7 @@ static DC *MFDRV_AllocMetaFile(void)
|
||||||
if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
|
if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
|
||||||
{
|
{
|
||||||
HeapFree( GetProcessHeap(), 0, physDev );
|
HeapFree( GetProcessHeap(), 0, physDev );
|
||||||
DC_FreeDCPtr( dc );
|
free_dc_ptr( dc );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ static BOOL MFDRV_DeleteDC( DC *dc )
|
||||||
HeapFree( GetProcessHeap(), 0, physDev->handles );
|
HeapFree( GetProcessHeap(), 0, physDev->handles );
|
||||||
HeapFree( GetProcessHeap(), 0, physDev );
|
HeapFree( GetProcessHeap(), 0, physDev );
|
||||||
dc->physDev = NULL;
|
dc->physDev = NULL;
|
||||||
DC_FreeDCPtr( dc );
|
free_dc_ptr( dc );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ HDC WINAPI CreateMetaFileW( LPCWSTR filename )
|
||||||
|
|
||||||
TRACE("returning %p\n", dc->hSelf);
|
TRACE("returning %p\n", dc->hSelf);
|
||||||
ret = dc->hSelf;
|
ret = dc->hSelf;
|
||||||
DC_ReleaseDCPtr( dc );
|
release_dc_ptr( dc );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,16 +306,16 @@ static DC *MFDRV_CloseMetaFile( HDC hdc )
|
||||||
|
|
||||||
TRACE("(%p)\n", hdc );
|
TRACE("(%p)\n", hdc );
|
||||||
|
|
||||||
if (!(dc = DC_GetDCPtr( hdc ))) return NULL;
|
if (!(dc = get_dc_ptr( hdc ))) return NULL;
|
||||||
if (GDIMAGIC(dc->header.wMagic) != METAFILE_DC_MAGIC)
|
if (GDIMAGIC(dc->header.wMagic) != METAFILE_DC_MAGIC)
|
||||||
{
|
{
|
||||||
DC_ReleaseDCPtr( dc );
|
release_dc_ptr( dc );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (dc->refcount != 1)
|
if (dc->refcount != 1)
|
||||||
{
|
{
|
||||||
FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
|
FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
|
||||||
DC_ReleaseDCPtr( dc );
|
release_dc_ptr( dc );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
|
physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
|
||||||
|
|
Loading…
Reference in New Issue