Use a different magic for memory DCs and get rid of the DC_MEMORY
flag.
diff --git a/objects/bitmap.c b/objects/bitmap.c
index a78d192..e617c81 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -407,7 +407,7 @@
DC *dc = DC_GetDCPtr( hdc );
if (!dc) return 0;
- if (!(dc->flags & DC_MEMORY))
+ if (GetObjectType( hdc ) != OBJ_MEMDC)
{
GDI_ReleaseObj( hdc );
return 0;
diff --git a/objects/dc.c b/objects/dc.c
index f352c46..d8bc999 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -48,12 +48,12 @@
/***********************************************************************
* DC_AllocDC
*/
-DC *DC_AllocDC( const DC_FUNCTIONS *funcs )
+DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic )
{
HDC hdc;
DC *dc;
- if (!(dc = GDI_AllocObject( sizeof(*dc), DC_MAGIC, (HGDIOBJ*)&hdc, &dc_funcs ))) return NULL;
+ if (!(dc = GDI_AllocObject( sizeof(*dc), magic, (HGDIOBJ*)&hdc, &dc_funcs ))) return NULL;
dc->hSelf = hdc;
dc->funcs = funcs;
@@ -130,8 +130,9 @@
GDIOBJHDR *ptr = GDI_GetObjPtr( hdc, MAGIC_DONTCARE );
if (!ptr) return NULL;
if ((GDIMAGIC(ptr->wMagic) == DC_MAGIC) ||
- (GDIMAGIC(ptr->wMagic) == METAFILE_DC_MAGIC) ||
- (GDIMAGIC(ptr->wMagic) == ENHMETAFILE_DC_MAGIC))
+ (GDIMAGIC(ptr->wMagic) == MEMORY_DC_MAGIC) ||
+ (GDIMAGIC(ptr->wMagic) == METAFILE_DC_MAGIC) ||
+ (GDIMAGIC(ptr->wMagic) == ENHMETAFILE_DC_MAGIC))
return (DC *)ptr;
GDI_ReleaseObj( hdc );
SetLastError( ERROR_INVALID_HANDLE );
@@ -151,18 +152,15 @@
if (!dc) return NULL;
while (dc->flags & DC_DIRTY)
{
+ DCHOOKPROC proc = dc->hookThunk;
dc->flags &= ~DC_DIRTY;
- if (!(dc->flags & (DC_SAVED | DC_MEMORY)))
+ if (proc)
{
- DCHOOKPROC proc = dc->hookThunk;
- if (proc)
- {
- DWORD data = dc->dwHookData;
- GDI_ReleaseObj( hdc );
- proc( HDC_16(hdc), DCHC_INVALIDVISRGN, data, 0 );
- if (!(dc = DC_GetDCPtr( hdc ))) break;
- /* otherwise restart the loop in case it became dirty again in the meantime */
- }
+ DWORD data = dc->dwHookData;
+ GDI_ReleaseObj( hdc );
+ proc( HDC_16(hdc), DCHC_INVALIDVISRGN, data, 0 );
+ if (!(dc = DC_GetDCPtr( hdc ))) break;
+ /* otherwise restart the loop in case it became dirty again in the meantime */
}
}
return dc;
@@ -271,7 +269,7 @@
HGDIOBJ handle;
if (!(dc = DC_GetDCPtr( hdc ))) return 0;
- if (!(newdc = GDI_AllocObject( sizeof(DC), DC_MAGIC, &handle, &dc_funcs )))
+ if (!(newdc = GDI_AllocObject( sizeof(DC), GDIMAGIC(dc->header.wMagic), &handle, &dc_funcs )))
{
GDI_ReleaseObj( hdc );
return 0;
@@ -409,7 +407,7 @@
dc->vportExtX = dcs->vportExtX;
dc->vportExtY = dcs->vportExtY;
- if (!(dc->flags & DC_MEMORY)) dc->bitsPerPixel = dcs->bitsPerPixel;
+ if (GDIMAGIC(dc->header.wMagic) != MEMORY_DC_MAGIC) dc->bitsPerPixel = dcs->bitsPerPixel;
if (dcs->hClipRgn)
{
@@ -586,13 +584,12 @@
ERR( "no driver found for %s\n", buf );
return 0;
}
- if (!(dc = DC_AllocDC( funcs )))
+ if (!(dc = DC_AllocDC( funcs, DC_MAGIC )))
{
DRIVER_release_driver( funcs );
return 0;
}
- dc->flags = 0;
dc->hBitmap = GetStockObject( DEFAULT_BITMAP );
TRACE("(driver=%s, device=%s, output=%s): returning %p\n",
@@ -667,20 +664,26 @@
{
DC *dc, *origDC;
const DC_FUNCTIONS *funcs;
+ PHYSDEV physDev;
GDI_CheckNotLock();
if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC )))
{
funcs = origDC->funcs;
+ physDev = origDC->physDev;
GDI_ReleaseObj( hdc ); /* can't hold the lock while loading the driver */
funcs = DRIVER_get_driver( funcs );
}
- else funcs = DRIVER_load_driver( "DISPLAY" );
+ else
+ {
+ funcs = DRIVER_load_driver( "DISPLAY" );
+ physDev = NULL;
+ }
if (!funcs) return 0;
- if (!(dc = DC_AllocDC( funcs )))
+ if (!(dc = DC_AllocDC( funcs, MEMORY_DC_MAGIC )))
{
DRIVER_release_driver( funcs );
return 0;
@@ -688,21 +691,19 @@
TRACE("(%p): returning %p\n", hdc, dc->hSelf );
- dc->flags = DC_MEMORY;
dc->bitsPerPixel = 1;
dc->hBitmap = GetStockObject( DEFAULT_BITMAP );
/* Copy the driver-specific physical device info into
* the new DC. The driver may use this read-only info
* while creating the compatible DC below. */
- if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC ))) dc->physDev = origDC->physDev;
+ dc->physDev = physDev;
if (dc->funcs->pCreateDC &&
!dc->funcs->pCreateDC( dc, &dc->physDev, NULL, NULL, NULL, NULL ))
{
WARN("creation aborted by device\n");
GDI_FreeObject( dc->hSelf, dc );
- if (origDC) GDI_ReleaseObj( hdc );
DRIVER_release_driver( funcs );
return 0;
}
@@ -715,7 +716,6 @@
DC_InitDC( dc );
GDI_ReleaseObj( dc->hSelf );
- if (origDC) GDI_ReleaseObj( hdc );
return dc->hSelf;
}
@@ -732,19 +732,16 @@
GDI_CheckNotLock();
- if (!(dc = GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE;
+ if (!(dc = DC_GetDCPtr( hdc ))) return FALSE;
/* Call hook procedure to check whether is it OK to delete this DC */
- if (dc->hookThunk && !(dc->flags & (DC_SAVED | DC_MEMORY)))
+ if (dc->hookThunk)
{
DCHOOKPROC proc = dc->hookThunk;
- if (proc)
- {
- DWORD data = dc->dwHookData;
- GDI_ReleaseObj( hdc );
- if (!proc( HDC_16(hdc), DCHC_DELETEDC, data, 0 )) return FALSE;
- if (!(dc = DC_GetDCPtr( hdc ))) return TRUE; /* deleted by the hook */
- }
+ DWORD data = dc->dwHookData;
+ GDI_ReleaseObj( hdc );
+ if (!proc( HDC_16(hdc), DCHC_DELETEDC, data, 0 )) return FALSE;
+ if (!(dc = DC_GetDCPtr( hdc ))) return TRUE; /* deleted by the hook */
}
while (dc->saveLevel)
@@ -1141,11 +1138,15 @@
*/
BOOL WINAPI SetDCHook( HDC hdc, DCHOOKPROC hookProc, DWORD dwHookData )
{
- DC *dc = DC_GetDCPtr( hdc );
+ DC *dc = GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return FALSE;
- dc->dwHookData = dwHookData;
- dc->hookThunk = hookProc;
+
+ if (!(dc->flags & DC_SAVED))
+ {
+ dc->dwHookData = dwHookData;
+ dc->hookThunk = hookProc;
+ }
GDI_ReleaseObj( hdc );
return TRUE;
}
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 85d6779..6e2d483 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -692,6 +692,7 @@
case METAFILE_DC_MAGIC:
case ENHMETAFILE_MAGIC:
case ENHMETAFILE_DC_MAGIC:
+ case MEMORY_DC_MAGIC:
case BITMAP_MAGIC:
case PALETTE_MAGIC:
if (!(obj = alloc_large_heap( size, handle ))) goto error;
@@ -1023,6 +1024,9 @@
case ENHMETAFILE_DC_MAGIC:
result = OBJ_ENHMETADC;
break;
+ case MEMORY_DC_MAGIC:
+ result = OBJ_MEMDC;
+ break;
default:
FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
break;