Authors: Alexandre Julliard <julliard@codeweavers.com> (for Corel), Albert den Haan <albertd@corel.com> Added syslevel locking for GDI operations. Propagate the changes through the graphics code.
diff --git a/objects/bitmap.c b/objects/bitmap.c index cc1aa5c..aea222e 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c
@@ -122,14 +122,11 @@ if (width < 0) width = -width; /* Create the BITMAPOBJ */ - hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC ); - if (!hbitmap) return 0; + if (!(bmp = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC, &hbitmap ))) return 0; TRACE("%dx%d, %d colors returning %08x\n", width, height, 1 << (planes*bpp), hbitmap); - bmp = (BITMAPOBJ *) GDI_HEAP_LOCK( hbitmap ); - bmp->size.cx = 0; bmp->size.cy = 0; bmp->bitmap.bmType = 0; @@ -147,7 +144,7 @@ if (bits) /* Set bitmap bits */ SetBitmapBits( hbitmap, height * bmp->bitmap.bmWidthBytes, bits ); - GDI_HEAP_UNLOCK( hbitmap ); + GDI_ReleaseObj( hbitmap ); return hbitmap; } @@ -193,7 +190,7 @@ dc->funcs->pCreateBitmap( hbmpRet ); } TRACE("\t\t%04x\n", hbmpRet); - GDI_HEAP_UNLOCK(hdc); + GDI_ReleaseObj(hdc); return hbmpRet; } @@ -251,7 +248,10 @@ /* If the bits vector is null, the function should return the read size */ if(bits == NULL) - return bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight; + { + ret = bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight; + goto done; + } if (count < 0) { WARN("(%ld): Negative number of bytes passed???\n", count ); @@ -265,8 +265,8 @@ if (count == 0) { WARN("Less then one entire line requested\n"); - GDI_HEAP_UNLOCK( hbitmap ); - return 0; + ret = 0; + goto done; } @@ -295,8 +295,8 @@ } } - - GDI_HEAP_UNLOCK( hbitmap ); + done: + GDI_ReleaseObj( hbitmap ); return ret; } @@ -365,7 +365,7 @@ } } - GDI_HEAP_UNLOCK( hbitmap ); + GDI_ReleaseObj( hbitmap ); return ret; } @@ -393,7 +393,7 @@ HeapFree( GetProcessHeap(), 0, buf ); } - GDI_HEAP_UNLOCK( hbitmap ); + GDI_ReleaseObj( hbitmap ); return res; } @@ -410,7 +410,7 @@ DIB_DeleteDIBSection( bmp ); - return GDI_FreeObject( hbitmap ); + return GDI_FreeObject( hbitmap, bmp ); } @@ -523,7 +523,7 @@ BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); if (!bmp) return FALSE; CONV_SIZE32TO16( &bmp->size, size ); - GDI_HEAP_UNLOCK( hbitmap ); + GDI_ReleaseObj( hbitmap ); return TRUE; } @@ -542,7 +542,7 @@ BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); if (!bmp) return FALSE; *size = bmp->size; - GDI_HEAP_UNLOCK( hbitmap ); + GDI_ReleaseObj( hbitmap ); return TRUE; } @@ -569,7 +569,7 @@ if (prevSize) CONV_SIZE32TO16( &bmp->size, prevSize ); bmp->size.cx = x; bmp->size.cy = y; - GDI_HEAP_UNLOCK( hbitmap ); + GDI_ReleaseObj( hbitmap ); return TRUE; } @@ -592,7 +592,7 @@ if (prevSize) *prevSize = bmp->size; bmp->size.cx = x; bmp->size.cy = y; - GDI_HEAP_UNLOCK( hbitmap ); + GDI_ReleaseObj( hbitmap ); return TRUE; }
diff --git a/objects/brush.c b/objects/brush.c index 068f4e5..080da3c 100644 --- a/objects/brush.c +++ b/objects/brush.c
@@ -105,19 +105,19 @@ { BOOL success; BRUSHOBJ * brushPtr; - HBRUSH16 hbrush = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC ); - if (!hbrush) return 0; - brushPtr = (BRUSHOBJ *) GDI_HEAP_LOCK( hbrush ); + HBRUSH hbrush; + + if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush ))) return 0; brushPtr->logbrush.lbStyle = brush->lbStyle; brushPtr->logbrush.lbColor = brush->lbColor; brushPtr->logbrush.lbHatch = brush->lbHatch; success = create_brush_indirect(brushPtr, TRUE); - GDI_HEAP_UNLOCK( hbrush ); if(!success) { - GDI_FreeObject(hbrush); + GDI_FreeObject( hbrush, brushPtr ); hbrush = 0; } + else GDI_ReleaseObj( hbrush ); TRACE("%04x\n", hbrush); return hbrush; } @@ -136,19 +136,18 @@ { BOOL success; BRUSHOBJ * brushPtr; - HBRUSH hbrush = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC ); - if (!hbrush) return 0; - brushPtr = (BRUSHOBJ *) GDI_HEAP_LOCK( hbrush ); + HBRUSH hbrush; + if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush ))) return 0; brushPtr->logbrush.lbStyle = brush->lbStyle; brushPtr->logbrush.lbColor = brush->lbColor; brushPtr->logbrush.lbHatch = brush->lbHatch; success = create_brush_indirect(brushPtr, FALSE); - GDI_HEAP_UNLOCK( hbrush ); if(!success) { - GDI_FreeObject(hbrush); + GDI_FreeObject( hbrush, brushPtr ); hbrush = 0; } + else GDI_ReleaseObj( hbrush ); TRACE("%08x\n", hbrush); return hbrush; } @@ -319,6 +318,7 @@ retval = dc->w.brushOrgX | (dc->w.brushOrgY << 16); dc->w.brushOrgX = x; dc->w.brushOrgY = y; + GDI_ReleaseObj( hdc ); return retval; } @@ -338,6 +338,7 @@ } dc->w.brushOrgX = x; dc->w.brushOrgY = y; + GDI_ReleaseObj( hdc ); return TRUE; } @@ -365,7 +366,7 @@ GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch ); break; } - return GDI_FreeObject( hbrush ); + return GDI_FreeObject( hbrush, brush ); }
diff --git a/objects/clipping.c b/objects/clipping.c index 3f83d32..e7ac965 100644 --- a/objects/clipping.c +++ b/objects/clipping.c
@@ -12,15 +12,7 @@ #include "wingdi.h" #include "wine/winuser16.h" -DEFAULT_DEBUG_CHANNEL(clipping) -DECLARE_DEBUG_CHANNEL(region) - -#define UPDATE_DIRTY_DC(dc) \ - do { \ - if ((dc)->hookThunk && !((dc)->w.flags & (DC_SAVED | DC_MEMORY))) \ - (dc)->hookThunk( (dc)->hSelf, DCHC_INVALIDVISRGN, (dc)->dwHookData, 0 ); \ - } while(0) - +DEFAULT_DEBUG_CHANNEL(clipping); /*********************************************************************** @@ -34,15 +26,11 @@ if (!dc->w.hVisRgn) { - ERR_(region)("hVisRgn is zero. Please report this.\n" ); + ERR("hVisRgn is zero. Please report this.\n" ); exit(1); } - if (dc->w.flags & DC_DIRTY) - { - UPDATE_DIRTY_DC(dc); - dc->w.flags &= ~DC_DIRTY; - } + if (dc->w.flags & DC_DIRTY) ERR( "DC is dirty. Please report this.\n" ); if (!dc->w.hClipRgn) CombineRgn( dc->w.hGCClipRgn, dc->w.hVisRgn, 0, RGN_COPY ); @@ -83,7 +71,7 @@ INT WINAPI ExtSelectClipRgn( HDC hdc, HRGN hrgn, INT fnMode ) { INT retval; - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); + DC * dc = DC_GetDCUpdate( hdc ); if (!dc) return ERROR; TRACE("%04x %04x %d\n", hdc, hrgn, fnMode ); @@ -99,6 +87,7 @@ else { FIXME("Unimplemented: hrgn NULL in mode: %d\n", fnMode); + GDI_ReleaseObj( hdc ); return ERROR; } } @@ -119,9 +108,8 @@ OffsetRgn( dc->w.hClipRgn, dc->w.DCOrgX, dc->w.DCOrgY ); } - CLIPPING_UpdateGCRegion( dc ); - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return retval; } @@ -131,8 +119,10 @@ INT16 WINAPI SelectVisRgn16( HDC16 hdc, HRGN16 hrgn ) { int retval; - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc || !hrgn) return ERROR; + DC * dc; + + if (!hrgn) return ERROR; + if (!(dc = DC_GetDCPtr( hdc ))) return ERROR; TRACE("%04x %04x\n", hdc, hrgn ); @@ -140,7 +130,7 @@ retval = CombineRgn16( dc->w.hVisRgn, hrgn, 0, RGN_COPY ); CLIPPING_UpdateGCRegion( dc ); - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return retval; } @@ -160,7 +150,7 @@ INT WINAPI OffsetClipRgn( HDC hdc, INT x, INT y ) { INT ret = SIMPLEREGION; - DC *dc = DC_GetDCPtr( hdc ); + DC *dc = DC_GetDCUpdate( hdc ); if (!dc) return ERROR; TRACE("%04x %d,%d\n", hdc, x, y ); @@ -171,7 +161,7 @@ ret = OffsetRgn( dc->w.hClipRgn, XLSTODS(dc,x), YLSTODS(dc,y)); CLIPPING_UpdateGCRegion( dc ); } - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return ret; } @@ -182,12 +172,12 @@ INT16 WINAPI OffsetVisRgn16( HDC16 hdc, INT16 x, INT16 y ) { INT16 retval; - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); + DC * dc = DC_GetDCUpdate( hdc ); if (!dc) return ERROR; TRACE("%04x %d,%d\n", hdc, x, y ); retval = OffsetRgn( dc->w.hVisRgn, x, y ); CLIPPING_UpdateGCRegion( dc ); - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return retval; } @@ -257,7 +247,7 @@ INT right, INT bottom ) { INT ret; - DC *dc = DC_GetDCPtr( hdc ); + DC *dc = DC_GetDCUpdate( hdc ); if (!dc) return ERROR; TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom ); @@ -272,7 +262,7 @@ ret = CLIPPING_IntersectClipRect( dc, left, top, right, bottom, CLIP_EXCLUDE ); } - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return ret; } @@ -294,7 +284,7 @@ INT right, INT bottom ) { INT ret; - DC *dc = DC_GetDCPtr( hdc ); + DC *dc = DC_GetDCUpdate( hdc ); if (!dc) return ERROR; TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom ); @@ -309,7 +299,7 @@ ret = CLIPPING_IntersectClipRect( dc, left, top, right, bottom, CLIP_INTERSECT ); } - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return ret; } @@ -346,12 +336,19 @@ if (ret != ERROR) { RGNOBJ *newObj = (RGNOBJ*)GDI_GetObjPtr( newRgn, REGION_MAGIC); - RGNOBJ *prevObj = (RGNOBJ*)GDI_GetObjPtr( dc->w.hVisRgn, REGION_MAGIC); - if (newObj && prevObj) newObj->header.hNext = prevObj->header.hNext; + if (newObj) + { + RGNOBJ *prevObj = (RGNOBJ*)GDI_GetObjPtr( dc->w.hVisRgn, REGION_MAGIC); + if (prevObj) + { + newObj->header.hNext = prevObj->header.hNext; + GDI_ReleaseObj( dc->w.hVisRgn ); + } + GDI_ReleaseObj( newRgn ); + } DeleteObject( dc->w.hVisRgn ); dc->w.hVisRgn = newRgn; CLIPPING_UpdateGCRegion( dc ); - GDI_HEAP_UNLOCK( newRgn ); } else DeleteObject( newRgn ); return ret; @@ -364,7 +361,8 @@ INT16 WINAPI ExcludeVisRect16( HDC16 hdc, INT16 left, INT16 top, INT16 right, INT16 bottom ) { - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); + INT16 ret; + DC * dc = DC_GetDCUpdate( hdc ); if (!dc) return ERROR; left = XLPTODP( dc, left ); @@ -374,7 +372,9 @@ TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom ); - return CLIPPING_IntersectVisRect( dc, left, top, right, bottom, TRUE ); + ret = CLIPPING_IntersectVisRect( dc, left, top, right, bottom, TRUE ); + GDI_ReleaseObj( hdc ); + return ret; } @@ -384,6 +384,7 @@ INT16 WINAPI IntersectVisRect16( HDC16 hdc, INT16 left, INT16 top, INT16 right, INT16 bottom ) { + INT16 ret; DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); if (!dc) return ERROR; @@ -394,7 +395,9 @@ TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom ); - return CLIPPING_IntersectVisRect( dc, left, top, right, bottom, FALSE ); + ret = CLIPPING_IntersectVisRect( dc, left, top, right, bottom, FALSE ); + GDI_ReleaseObj( hdc ); + return ret; } @@ -412,18 +415,19 @@ */ BOOL WINAPI PtVisible( HDC hdc, INT x, INT y ) { - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) return ERROR; + BOOL ret = FALSE; + DC *dc = DC_GetDCUpdate( hdc ); TRACE("%04x %d,%d\n", hdc, x, y ); - if (!dc->w.hGCClipRgn) return FALSE; - - if( dc->w.flags & DC_DIRTY ) UPDATE_DIRTY_DC(dc); - dc->w.flags &= ~DC_DIRTY; - - return PtInRegion( dc->w.hGCClipRgn, XLPTODP(dc,x) + dc->w.DCOrgX, + if (!dc) return FALSE; + if (dc->w.hGCClipRgn) + { + ret = PtInRegion( dc->w.hGCClipRgn, XLPTODP(dc,x) + dc->w.DCOrgX, YLPTODP(dc,y) + dc->w.DCOrgY ); } + GDI_ReleaseObj( hdc ); + return ret; +} /*********************************************************************** @@ -431,20 +435,25 @@ */ BOOL16 WINAPI RectVisible16( HDC16 hdc, const RECT16* rect ) { + BOOL ret = FALSE; RECT16 tmpRect; DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); if (!dc) return FALSE; TRACE("%04x %d,%dx%d,%d\n", hdc, rect->left, rect->top, rect->right, rect->bottom ); - if (!dc->w.hGCClipRgn) return FALSE; - /* copy rectangle to avoid overwriting by LPtoDP */ - tmpRect = *rect; - LPtoDP16( hdc, (LPPOINT16)&tmpRect, 2 ); - tmpRect.left += dc->w.DCOrgX; - tmpRect.right += dc->w.DCOrgX; - tmpRect.top += dc->w.DCOrgY; - tmpRect.bottom += dc->w.DCOrgY; - return RectInRegion16( dc->w.hGCClipRgn, &tmpRect ); + if (dc->w.hGCClipRgn) + { + /* copy rectangle to avoid overwriting by LPtoDP */ + tmpRect = *rect; + LPtoDP16( hdc, (LPPOINT16)&tmpRect, 2 ); + tmpRect.left += dc->w.DCOrgX; + tmpRect.right += dc->w.DCOrgX; + tmpRect.top += dc->w.DCOrgY; + tmpRect.bottom += dc->w.DCOrgY; + ret = RectInRegion16( dc->w.hGCClipRgn, &tmpRect ); + } + GDI_ReleaseObj( hdc ); + return ret; } @@ -474,6 +483,7 @@ rect->bottom -= dc->w.DCOrgY; DPtoLP16( hdc, (LPPOINT16)rect, 2 ); TRACE("%d,%d-%d,%d\n", rect->left,rect->top,rect->right,rect->bottom ); + GDI_ReleaseObj( hdc ); return ret; } @@ -492,6 +502,7 @@ rect->top -= dc->w.DCOrgY; rect->bottom -= dc->w.DCOrgY; DPtoLP( hdc, (LPPOINT)rect, 2 ); + GDI_ReleaseObj( hdc ); return ret; } @@ -501,8 +512,9 @@ */ INT WINAPI GetClipRgn( HDC hdc, HRGN hRgn ) { - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if( dc && hRgn ) + INT ret = -1; + DC * dc; + if (hRgn && (dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) { if( dc->w.hClipRgn ) { @@ -512,12 +524,13 @@ if( CombineRgn(hRgn, dc->w.hClipRgn, 0, RGN_COPY) != ERROR ) { OffsetRgn( hRgn, -dc->w.DCOrgX, -dc->w.DCOrgY ); - return 1; + ret = 1; } } - else return 0; + else ret = 0; + GDI_ReleaseObj( hdc ); } - return -1; + return ret; } /*********************************************************************** @@ -527,40 +540,35 @@ { HRGN copy; RGNOBJ *obj, *copyObj; - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); + DC *dc = DC_GetDCUpdate( hdc ); + if (!dc) return 0; TRACE("%04x\n", hdc ); - if (!dc->w.hVisRgn) - { - ERR_(region)("hVisRgn is zero. Please report this.\n" ); - exit(1); - } - if( dc->w.flags & DC_DIRTY ) UPDATE_DIRTY_DC(dc); - dc->w.flags &= ~DC_DIRTY; if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->w.hVisRgn, REGION_MAGIC ))) { - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return 0; } if (!(copy = CreateRectRgn( 0, 0, 0, 0 ))) { - GDI_HEAP_UNLOCK( dc->w.hVisRgn ); - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( dc->w.hVisRgn ); + GDI_ReleaseObj( hdc ); return 0; } CombineRgn( copy, dc->w.hVisRgn, 0, RGN_COPY ); if (!(copyObj = (RGNOBJ *) GDI_GetObjPtr( copy, REGION_MAGIC ))) { - GDI_HEAP_UNLOCK( dc->w.hVisRgn ); - GDI_HEAP_UNLOCK( hdc ); + DeleteObject( copy ); + GDI_ReleaseObj( dc->w.hVisRgn ); + GDI_ReleaseObj( hdc ); return 0; } copyObj->header.hNext = obj->header.hNext; obj->header.hNext = copy; - GDI_HEAP_UNLOCK( dc->w.hVisRgn ); - GDI_HEAP_UNLOCK( hdc ); - GDI_HEAP_UNLOCK( copy ); + GDI_ReleaseObj( copy ); + GDI_ReleaseObj( dc->w.hVisRgn ); + GDI_ReleaseObj( hdc ); return copy; } @@ -573,37 +581,24 @@ HRGN saved; RGNOBJ *obj, *savedObj; DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - INT16 ret; + INT16 ret = ERROR; if (!dc) return ERROR; - if (!dc->w.hVisRgn) - { - GDI_HEAP_UNLOCK( hdc ); - return ERROR; - } + if (!dc->w.hVisRgn) goto done; TRACE("%04x\n", hdc ); - if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->w.hVisRgn, REGION_MAGIC ))) - { - GDI_HEAP_UNLOCK( hdc ); - return ERROR; - } - if (!(saved = obj->header.hNext)) - { - GDI_HEAP_UNLOCK( dc->w.hVisRgn ); - GDI_HEAP_UNLOCK( hdc ); - return ERROR; - } - if (!(savedObj = (RGNOBJ *) GDI_GetObjPtr( saved, REGION_MAGIC ))) - { - GDI_HEAP_UNLOCK( dc->w.hVisRgn ); - GDI_HEAP_UNLOCK( hdc ); - return ERROR; - } + if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->w.hVisRgn, REGION_MAGIC ))) goto done; + + saved = obj->header.hNext; + GDI_ReleaseObj( dc->w.hVisRgn ); + if (!saved || !(savedObj = (RGNOBJ *) GDI_GetObjPtr( saved, REGION_MAGIC ))) goto done; + DeleteObject( dc->w.hVisRgn ); dc->w.hVisRgn = saved; + dc->w.flags &= ~DC_DIRTY; CLIPPING_UpdateGCRegion( dc ); - GDI_HEAP_UNLOCK( hdc ); ret = savedObj->rgn->type; /* FIXME */ - GDI_HEAP_UNLOCK( saved ); + GDI_ReleaseObj( saved ); + done: + GDI_ReleaseObj( hdc ); return ret; }
diff --git a/objects/dc.c b/objects/dc.c index 4307e1a..5a9e3d2 100644 --- a/objects/dc.c +++ b/objects/dc.c
@@ -83,12 +83,10 @@ */ DC *DC_AllocDC( const DC_FUNCTIONS *funcs ) { - HDC16 hdc; + HDC hdc; DC *dc; - if (!(hdc = GDI_AllocObject( sizeof(DC), DC_MAGIC ))) return NULL; - dc = (DC *) GDI_HEAP_LOCK( hdc ); - + if (!(dc = GDI_AllocObject( sizeof(DC), DC_MAGIC, &hdc ))) return NULL; dc->hSelf = hdc; dc->funcs = funcs; dc->physDev = NULL; @@ -117,16 +115,45 @@ */ DC *DC_GetDCPtr( HDC hdc ) { - GDIOBJHDR *ptr = (GDIOBJHDR *)GDI_HEAP_LOCK( hdc ); + GDIOBJHDR *ptr = GDI_GetObjPtr( hdc, MAGIC_DONTCARE ); if (!ptr) return NULL; if ((ptr->wMagic == DC_MAGIC) || (ptr->wMagic == METAFILE_DC_MAGIC) || (ptr->wMagic == ENHMETAFILE_DC_MAGIC)) return (DC *)ptr; - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); SetLastError( ERROR_INVALID_HANDLE ); return NULL; } +/*********************************************************************** + * DC_GetDCUpdate + * + * Retrieve a DC ptr while making sure the visRgn is updated. + * This function may call up to USER so the GDI lock should _not_ + * be held when calling it. + */ +DC *DC_GetDCUpdate( HDC hdc ) +{ + DC *dc = DC_GetDCPtr( hdc ); + if (!dc) return NULL; + while (dc->w.flags & DC_DIRTY) + { + dc->w.flags &= ~DC_DIRTY; + if (!(dc->w.flags & (DC_SAVED | DC_MEMORY))) + { + DCHOOKPROC proc = dc->hookThunk; + if (proc) + { + DWORD data = dc->dwHookData; + GDI_ReleaseObj( hdc ); + proc( 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; +} /*********************************************************************** * DC_InitDC @@ -217,16 +244,14 @@ HDC16 WINAPI GetDCState16( HDC16 hdc ) { DC * newdc, * dc; - HGDIOBJ16 handle; + HGDIOBJ handle; - if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; - if (!(handle = GDI_AllocObject( sizeof(DC), DC_MAGIC ))) + if (!(dc = DC_GetDCUpdate( hdc ))) return 0; + if (!(newdc = GDI_AllocObject( sizeof(DC), DC_MAGIC, &handle ))) { - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return 0; } - newdc = (DC *) GDI_HEAP_LOCK( handle ); - TRACE("(%04x): returning %04x\n", hdc, handle ); newdc->w.flags = dc->w.flags | DC_SAVED; @@ -295,8 +320,8 @@ } else newdc->w.hClipRgn = 0; - GDI_HEAP_UNLOCK( handle ); - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( handle ); + GDI_ReleaseObj( hdc ); return handle; } @@ -311,13 +336,13 @@ if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return; if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) { - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return; } if (!dcs->w.flags & DC_SAVED) { - GDI_HEAP_UNLOCK( hdc ); - GDI_HEAP_UNLOCK( hdcs ); + GDI_ReleaseObj( hdc ); + GDI_ReleaseObj( hdcs ); return; } TRACE("%04x %04x\n", hdc, hdcs ); @@ -386,8 +411,8 @@ SetBkColor( hdc, dcs->w.backgroundColor); SetTextColor( hdc, dcs->w.textColor); GDISelectPalette16( hdc, dcs->w.hPalette, FALSE ); - GDI_HEAP_UNLOCK( hdc ); - GDI_HEAP_UNLOCK( hdcs ); + GDI_ReleaseObj( hdcs ); + GDI_ReleaseObj( hdc ); } @@ -409,18 +434,22 @@ DC * dc, * dcs; INT ret; - dc = DC_GetDCPtr( hdc ); + dc = DC_GetDCUpdate( hdc ); if (!dc) return 0; if(dc->funcs->pSaveDC) - return dc->funcs->pSaveDC( dc ); + { + ret = dc->funcs->pSaveDC( dc ); + GDI_ReleaseObj( hdc ); + return ret; + } if (!(hdcs = GetDCState16( hdc ))) { - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return 0; } - dcs = (DC *) GDI_HEAP_LOCK( hdcs ); + dcs = GDI_GetObjPtr( hdcs, DC_MAGIC ); /* Copy path. The reason why path saving / restoring is in SaveDC/ * RestoreDC and not in GetDCState/SetDCState is that the ...DCState @@ -430,8 +459,8 @@ */ if (!PATH_AssignGdiPath( &dcs->w.path, &dc->w.path )) { - GDI_HEAP_UNLOCK( hdc ); - GDI_HEAP_UNLOCK( hdcs ); + GDI_ReleaseObj( hdc ); + GDI_ReleaseObj( hdcs ); DeleteDC( hdcs ); return 0; } @@ -440,8 +469,8 @@ dc->header.hNext = hdcs; TRACE("(%04x): returning %d\n", hdc, dc->saveLevel+1 ); ret = ++dc->saveLevel; - GDI_HEAP_UNLOCK( hdcs ); - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdcs ); + GDI_ReleaseObj( hdc ); return ret; } @@ -467,13 +496,23 @@ dc = DC_GetDCPtr( hdc ); if(!dc) return FALSE; if(dc->funcs->pRestoreDC) - return dc->funcs->pRestoreDC( dc, level ); + { + success = dc->funcs->pRestoreDC( dc, level ); + GDI_ReleaseObj( hdc ); + return success; + } if (level == -1) level = dc->saveLevel; - if ((level < 1) || (level > dc->saveLevel)) + if ((level < 1) + /* This pair of checks disagrees with MSDN "Platform SDK: + Windows GDI" July 2000 which says all negative values + for level will be interpreted as an instance relative + to the current state. Restricting it to just -1 does + not satisfy this */ + || (level > dc->saveLevel)) { - GDI_HEAP_UNLOCK( hdc ); - return FALSE; + GDI_ReleaseObj( hdc ); + return FALSE; } success=TRUE; @@ -482,7 +521,7 @@ HDC16 hdcs = dc->header.hNext; if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) { - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return FALSE; } dc->header.hNext = dcs->header.hNext; @@ -494,9 +533,10 @@ * returning FALSE but still destroying the saved DC state */ success=FALSE; } + GDI_ReleaseObj( hdcs ); DeleteDC( hdcs ); } - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return success; } @@ -507,6 +547,7 @@ HDC16 WINAPI CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output, const DEVMODEA *initData ) { + HDC hdc; DC * dc; const DC_FUNCTIONS *funcs; char buf[300]; @@ -525,13 +566,14 @@ !dc->funcs->pCreateDC( dc, buf, device, output, initData )) { WARN("creation aborted by device\n" ); - GDI_HEAP_FREE( dc->hSelf ); + GDI_FreeObject( dc->hSelf, dc ); return 0; } DC_InitDC( dc ); - GDI_HEAP_UNLOCK( dc->hSelf ); - return dc->hSelf; + hdc = dc->hSelf; + GDI_ReleaseObj( hdc ); + return hdc; } @@ -615,9 +657,12 @@ if ((origDC = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC ))) funcs = origDC->funcs; else funcs = DRIVER_FindDriver( "DISPLAY" ); - if (!funcs) return 0; - if (!(dc = DC_AllocDC( funcs ))) return 0; + if (!funcs || !(dc = DC_AllocDC( funcs ))) + { + if (origDC) GDI_ReleaseObj( hdc ); + return 0; + } TRACE("(%04x): returning %04x\n", hdc, dc->hSelf ); @@ -636,12 +681,14 @@ !dc->funcs->pCreateDC( dc, NULL, NULL, NULL, NULL )) { WARN("creation aborted by device\n"); - GDI_HEAP_FREE( dc->hSelf ); + GDI_FreeObject( dc->hSelf, dc ); + if (origDC) GDI_ReleaseObj( hdc ); return 0; } DC_InitDC( dc ); - GDI_HEAP_UNLOCK( dc->hSelf ); + GDI_ReleaseObj( dc->hSelf ); + if (origDC) GDI_ReleaseObj( hdc ); return dc->hSelf; } @@ -666,11 +713,16 @@ TRACE("%04x\n", hdc ); /* Call hook procedure to check whether is it OK to delete this DC */ - if ( dc->hookThunk && !(dc->w.flags & (DC_SAVED | DC_MEMORY)) - && dc->hookThunk( hdc, DCHC_DELETEDC, dc->dwHookData, 0 ) == FALSE ) + if (dc->hookThunk && !(dc->w.flags & (DC_SAVED | DC_MEMORY))) { - GDI_HEAP_UNLOCK( hdc ); - return FALSE; + DCHOOKPROC proc = dc->hookThunk; + if (proc) + { + DWORD data = dc->dwHookData; + GDI_ReleaseObj( hdc ); + if (!proc( hdc, DCHC_DELETEDC, data, 0 )) return FALSE; + if (!(dc = DC_GetDCPtr( hdc ))) return FALSE; + } } while (dc->saveLevel) @@ -680,6 +732,7 @@ if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) break; dc->header.hNext = dcs->header.hNext; dc->saveLevel--; + GDI_ReleaseObj( hdcs ); DeleteDC( hdcs ); } @@ -698,7 +751,7 @@ if (dc->hookThunk) THUNK_Free( (FARPROC)dc->hookThunk ); PATH_DestroyGdiPath(&dc->w.path); - return GDI_FreeObject( hdc ); + return GDI_FreeObject( hdc, dc ); } @@ -747,7 +800,7 @@ INT WINAPI GetDeviceCaps( HDC hdc, INT cap ) { DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - INT ret; + INT ret = 0; POINT pt; if (!dc) return 0; @@ -777,7 +830,7 @@ if ((cap < 0) || (cap > sizeof(DeviceCaps)-sizeof(WORD))) { - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return 0; } @@ -788,7 +841,7 @@ TRACE("(%04x,%d): returning %d\n", hdc, cap, *(WORD *)(((char *)dc->w.devCaps) + cap) ); ret = *(WORD *)(((char *)dc->w.devCaps) + cap); - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return ret; } @@ -817,7 +870,7 @@ oldColor = dc->w.backgroundColor; dc->w.backgroundColor = color; } - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return oldColor; } @@ -846,7 +899,7 @@ oldColor = dc->w.textColor; dc->w.textColor = color; } - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return oldColor; } @@ -873,7 +926,7 @@ prevAlign = dc->w.textAlign; dc->w.textAlign = align; } - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return prevAlign; } @@ -891,7 +944,7 @@ if (dc->funcs->pGetDCOrgEx) dc->funcs->pGetDCOrgEx( dc, lpp ); lpp->x += dc->w.DCOrgX; lpp->y += dc->w.DCOrgY; - GDI_HEAP_UNLOCK( hDC ); + GDI_ReleaseObj( hDC ); return TRUE; } @@ -919,28 +972,17 @@ prevOrg = dc->w.DCOrgX | (dc->w.DCOrgY << 16); dc->w.DCOrgX = x; dc->w.DCOrgY = y; - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return prevOrg; } /*********************************************************************** - * GetGraphicsMode (GDI32.188) - */ -INT WINAPI GetGraphicsMode( HDC hdc ) -{ - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) return 0; - return dc->w.GraphicsMode; -} - - -/*********************************************************************** * SetGraphicsMode (GDI32.317) */ INT WINAPI SetGraphicsMode( HDC hdc, INT mode ) { - INT ret; + INT ret = 0; DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); /* One would think that setting the graphics mode to GM_COMPATIBLE @@ -950,37 +992,17 @@ */ if (!dc) return 0; - if ((mode <= 0) || (mode > GM_LAST)) return 0; + if ((mode > 0) || (mode <= GM_LAST)) + { ret = dc->w.GraphicsMode; dc->w.GraphicsMode = mode; +} + GDI_ReleaseObj( hdc ); return ret; } /*********************************************************************** - * GetArcDirection16 (GDI.524) - */ -INT16 WINAPI GetArcDirection16( HDC16 hdc ) -{ - return GetArcDirection( (HDC)hdc ); -} - - -/*********************************************************************** - * GetArcDirection (GDI32.141) - */ -INT WINAPI GetArcDirection( HDC hdc ) -{ - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - - if (!dc) - return 0; - - return dc->w.ArcDirection; -} - - -/*********************************************************************** * SetArcDirection16 (GDI.525) */ INT16 WINAPI SetArcDirection16( HDC16 hdc, INT16 nDirection ) @@ -994,11 +1016,8 @@ */ INT WINAPI SetArcDirection( HDC hdc, INT nDirection ) { - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - INT nOldDirection; - - if (!dc) - return 0; + DC * dc; + INT nOldDirection = 0; if (nDirection!=AD_COUNTERCLOCKWISE && nDirection!=AD_CLOCKWISE) { @@ -1006,9 +1025,12 @@ return 0; } + if ((dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) + { nOldDirection = dc->w.ArcDirection; dc->w.ArcDirection = nDirection; - + GDI_ReleaseObj( hdc ); + } return nOldDirection; } @@ -1018,15 +1040,11 @@ */ BOOL WINAPI GetWorldTransform( HDC hdc, LPXFORM xform ) { - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - - if (!dc) - return FALSE; - if (!xform) - return FALSE; - + DC * dc; + if (!xform) return FALSE; + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE; *xform = dc->w.xformWorld2Wnd; - + GDI_ReleaseObj( hdc ); return TRUE; } @@ -1036,6 +1054,7 @@ */ BOOL WINAPI SetWorldTransform( HDC hdc, const XFORM *xform ) { + BOOL ret = FALSE; DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); if (!dc) @@ -1044,18 +1063,17 @@ return FALSE; } - if (!xform) - return FALSE; + if (!xform) goto done; /* Check that graphics mode is GM_ADVANCED */ - if (dc->w.GraphicsMode!=GM_ADVANCED) - return FALSE; + if (dc->w.GraphicsMode!=GM_ADVANCED) goto done; dc->w.xformWorld2Wnd = *xform; - DC_UpdateXforms( dc ); - - return TRUE; + ret = TRUE; + done: + GDI_ReleaseObj( hdc ); + return ret; } @@ -1084,6 +1102,7 @@ BOOL WINAPI ModifyWorldTransform( HDC hdc, const XFORM *xform, DWORD iMode ) { + BOOL ret = FALSE; DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); /* Check for illegal parameters */ @@ -1092,12 +1111,10 @@ SetLastError( ERROR_INVALID_HANDLE ); return FALSE; } - if (!xform) - return FALSE; + if (!xform) goto done; /* Check that graphics mode is GM_ADVANCED */ - if (dc->w.GraphicsMode!=GM_ADVANCED) - return FALSE; + if (dc->w.GraphicsMode!=GM_ADVANCED) goto done; switch (iMode) { @@ -1118,12 +1135,14 @@ xform ); break; default: - return FALSE; + goto done; } DC_UpdateXforms( dc ); - - return TRUE; + ret = TRUE; + done: + GDI_ReleaseObj( hdc ); + return ret; } @@ -1206,7 +1225,7 @@ dc->hookThunk = (DCHOOKPROC) THUNK_Alloc( hookProc, (RELAY)GDI_CallTo16_word_wwll ); - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return TRUE; } @@ -1219,7 +1238,7 @@ DC *dc = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC ); if (!dc) return 0; *phookProc = dc->hookProc; - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return dc->dwHookData; } @@ -1244,7 +1263,7 @@ dc->w.flags |= DC_DIRTY; else if( flags & DCHF_VALIDATEVISRGN || !flags ) dc->w.flags &= ~DC_DIRTY; - GDI_HEAP_UNLOCK( hDC ); + GDI_ReleaseObj( hDC ); return wRet; } return 0;
diff --git a/objects/dcvalues.c b/objects/dcvalues.c index 9afd47a..0b23150 100644 --- a/objects/dcvalues.c +++ b/objects/dcvalues.c
@@ -5,31 +5,55 @@ * */ +#include "winbase.h" +#include "winerror.h" #include "gdi.h" #include "dc.h" +#define COLORREF16 COLORREF /*hack*/ + #define DC_GET_VAL_16( func_type, func_name, dc_field ) \ func_type WINAPI func_name( HDC16 hdc ) \ { \ + func_type ret = 0; \ DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \ - if (!dc) return 0; \ - return dc->dc_field; \ + if (dc) \ + { \ + ret = dc->dc_field; \ + GDI_ReleaseObj( hdc ); \ + } \ + return ret; \ } -#define DC_GET_VAL_32( func_type, func_name, dc_field ) \ +#define DC_GET_VAL( func_type, func_name, dc_field ) \ +func_type##16 WINAPI func_name##16( HDC16 hdc ) \ +{ \ + return func_name( hdc ); \ +} \ + \ func_type WINAPI func_name( HDC hdc ) \ { \ + func_type ret = 0; \ DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \ - if (!dc) return 0; \ - return dc->dc_field; \ + if (dc) \ + { \ + ret = dc->dc_field; \ + GDI_ReleaseObj( hdc ); \ + } \ + return ret; \ } #define DC_GET_X_Y( func_type, func_name, ret_x, ret_y ) \ func_type WINAPI func_name( HDC16 hdc ) \ { \ + func_type ret = 0; \ DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \ - if (!dc) return 0; \ - return MAKELONG( dc->ret_x, dc->ret_y ); \ + if (dc) \ + { \ + ret = MAKELONG( dc->ret_x, dc->ret_y ); \ + GDI_ReleaseObj( hdc ); \ + } \ + return ret; \ } /* DC_GET_VAL_EX is used to define functions returning a POINT or a SIZE. It is @@ -43,15 +67,17 @@ if (!dc) return FALSE; \ ((LPPOINT16)pt)->x = dc->ret_x; \ ((LPPOINT16)pt)->y = dc->ret_y; \ + GDI_ReleaseObj( hdc ); \ return TRUE; \ } \ \ BOOL WINAPI func_name( HDC hdc, LP##type pt ) \ { \ - DC * dc = (DC *) GDI_GetObjPtr( (HDC16)hdc, DC_MAGIC ); \ + DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \ if (!dc) return FALSE; \ ((LPPOINT)pt)->x = dc->ret_x; \ ((LPPOINT)pt)->y = dc->ret_y; \ + GDI_ReleaseObj( hdc ); \ return TRUE; \ } @@ -64,16 +90,19 @@ INT WINAPI func_name( HDC hdc, INT mode ) \ { \ INT prevMode; \ - DC *dc = DC_GetDCPtr( hdc ); \ - if(!dc) return 0; \ - if ((mode < min_val) || (mode > max_val)) return 0; \ + DC *dc; \ + if ((mode < min_val) || (mode > max_val)) { \ + SetLastError(ERROR_INVALID_PARAMETER); \ + return 0; \ + } \ + if (!(dc = DC_GetDCPtr( hdc ))) return 0; \ if (dc->funcs->p##func_name) { \ prevMode = dc->funcs->p##func_name( dc, mode ); \ } else { \ prevMode = dc->dc_field; \ dc->dc_field = mode; \ } \ - GDI_HEAP_UNLOCK( hdc ); \ + GDI_ReleaseObj( hdc ); \ return prevMode; \ } @@ -104,24 +133,14 @@ DC_SET_MODE( SetStretchBltMode, w.stretchBltMode, BLACKONWHITE, HALFTONE ) /*********************************************************************** - * GetBkColor16 (GDI.75) + * GetBkColor (GDI.75) (GDI32.145) */ -DC_GET_VAL_16( COLORREF, GetBkColor16, w.backgroundColor ) +DC_GET_VAL( COLORREF, GetBkColor, w.backgroundColor ) /*********************************************************************** - * GetBkColor (GDI32.145) + * GetBkMode (GDI.76) (GDI32.146) */ -DC_GET_VAL_32( COLORREF, GetBkColor, w.backgroundColor ) - -/*********************************************************************** - * GetBkMode16 (GDI.76) - */ -DC_GET_VAL_16( INT16, GetBkMode16, w.backgroundMode ) - -/*********************************************************************** - * GetBkMode (GDI32.146) - */ -DC_GET_VAL_32( INT, GetBkMode, w.backgroundMode ) +DC_GET_VAL( INT, GetBkMode, w.backgroundMode ) /*********************************************************************** * GetCurrentPosition16 (GDI.78) @@ -129,34 +148,19 @@ DC_GET_X_Y( DWORD, GetCurrentPosition16, w.CursPosX, w.CursPosY ) /*********************************************************************** - * GetMapMode16 (GDI.81) + * GetMapMode (GDI.81) (GDI32.196) */ -DC_GET_VAL_16( INT16, GetMapMode16, w.MapMode ) +DC_GET_VAL( INT, GetMapMode, w.MapMode ) /*********************************************************************** - * GetMapMode (GDI32.196) + * GetPolyFillMode (GDI.84) (GDI32.213) */ -DC_GET_VAL_32( INT, GetMapMode, w.MapMode ) +DC_GET_VAL( INT, GetPolyFillMode, w.polyFillMode ) /*********************************************************************** - * GetPolyFillMode16 (GDI.84) + * GetROP2 (GDI.85) (GDI32.214) */ -DC_GET_VAL_16( INT16, GetPolyFillMode16, w.polyFillMode ) - -/*********************************************************************** - * GetPolyFillMode (GDI32.213) - */ -DC_GET_VAL_32( INT, GetPolyFillMode, w.polyFillMode ) - -/*********************************************************************** - * GetROP216 (GDI.85) - */ -DC_GET_VAL_16( INT16, GetROP216, w.ROPmode ) - -/*********************************************************************** - * GetROP2 (GDI32.214) - */ -DC_GET_VAL_32( INT, GetROP2, w.ROPmode ) +DC_GET_VAL( INT, GetROP2, w.ROPmode ) /*********************************************************************** * GetRelAbs16 (GDI.86) @@ -164,24 +168,14 @@ DC_GET_VAL_16( INT16, GetRelAbs16, w.relAbsMode ) /*********************************************************************** - * GetStretchBltMode16 (GDI.88) + * GetStretchBltMode (GDI.88) (GDI32.221) */ -DC_GET_VAL_16( INT16, GetStretchBltMode16, w.stretchBltMode ) +DC_GET_VAL( INT, GetStretchBltMode, w.stretchBltMode ) /*********************************************************************** - * GetStretchBltMode (GDI32.221) + * GetTextColor (GDI.90) (GDI32.227) */ -DC_GET_VAL_32( INT, GetStretchBltMode, w.stretchBltMode ) - -/*********************************************************************** - * GetTextColor16 (GDI.90) - */ -DC_GET_VAL_16( COLORREF, GetTextColor16, w.textColor ) - -/*********************************************************************** - * GetTextColor (GDI32.227) - */ -DC_GET_VAL_32( COLORREF, GetTextColor, w.textColor ) +DC_GET_VAL( COLORREF, GetTextColor, w.textColor ) /*********************************************************************** * GetViewportExt16 (GDI.94) @@ -219,14 +213,9 @@ DC_GET_X_Y( DWORD, GetBrushOrg16, w.brushOrgX, w.brushOrgY ) /*********************************************************************** - * GetTextAlign16 (GDI.345) + * GetTextAlign (GDI.345) (GDI32,224) */ -DC_GET_VAL_16( UINT16, GetTextAlign16, w.textAlign ) - -/*********************************************************************** - * GetTextAlign (GDI32.224) - */ -DC_GET_VAL_32( UINT, GetTextAlign, w.textAlign ) +DC_GET_VAL( UINT, GetTextAlign, w.textAlign ) /*********************************************************************** * GetCurLogFont16 (GDI.411) @@ -234,6 +223,16 @@ DC_GET_VAL_16( HFONT16, GetCurLogFont16, w.hFont ) /*********************************************************************** + * GetArcDirection (GDI.524) (GDI32.141) + */ +DC_GET_VAL( INT, GetArcDirection, w.ArcDirection ) + +/*********************************************************************** + * GetGraphicsMode (GDI32.188) + */ +DC_GET_VAL( INT, GetGraphicsMode, w.GraphicsMode) + +/*********************************************************************** * GetBrushOrgEx (GDI.469) (GDI32.148) */ DC_GET_VAL_EX( GetBrushOrgEx, w.brushOrgX, w.brushOrgY, POINT ) /* */
diff --git a/objects/dib.c b/objects/dib.c index 4947f12..8d5dcc8 100644 --- a/objects/dib.c +++ b/objects/dib.c
@@ -133,11 +133,11 @@ INT heightSrc, const void *bits, const BITMAPINFO *info, UINT wUsage, DWORD dwRop ) { - DC *dc = DC_GetDCPtr( hdc ); + DC *dc = DC_GetDCUpdate( hdc ); if(!dc) return FALSE; if(dc->funcs->pStretchDIBits) - return dc->funcs->pStretchDIBits(dc, xDst, yDst, widthDst, + heightSrc = dc->funcs->pStretchDIBits(dc, xDst, yDst, widthDst, heightDst, xSrc, ySrc, widthSrc, heightSrc, bits, info, wUsage, dwRop); @@ -157,8 +157,9 @@ SelectObject( hdcMem, hOldBitmap ); DeleteDC( hdcMem ); DeleteObject( hBitmap ); - return heightSrc; } + GDI_ReleaseObj( hdc ); + return heightSrc; } @@ -198,16 +199,11 @@ INT result; /* Check parameters */ - dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) - { - dc = (DC *) GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC); - if (!dc) return 0; - } + if (!(dc = DC_GetDCUpdate( hdc ))) return 0; if (!(bitmap = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) { - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return 0; } @@ -215,8 +211,8 @@ lines, bits, info, coloruse, hbitmap); - GDI_HEAP_UNLOCK( hdc ); - GDI_HEAP_UNLOCK( hbitmap ); + GDI_ReleaseObj( hbitmap ); + GDI_ReleaseObj( hdc ); return result; } @@ -246,7 +242,7 @@ INT ret; DC *dc; - if (!(dc = DC_GetDCPtr( hdc ))) return 0; + if (!(dc = DC_GetDCUpdate( hdc ))) return 0; if(dc->funcs->pSetDIBitsToDevice) ret = dc->funcs->pSetDIBitsToDevice( dc, xDest, yDest, cx, cy, xSrc, @@ -257,7 +253,7 @@ ret = 0; } - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return ret; } @@ -281,15 +277,11 @@ PALETTEOBJ * palette; RGBQUAD *end; - dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) - { - dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC); - if (!dc) return 0; - } + if (!(dc = DC_GetDCUpdate( hdc ))) return 0; if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC ))) { + GDI_ReleaseObj( hdc ); return 0; } @@ -312,7 +304,8 @@ } else { entries = 0; } - GDI_HEAP_UNLOCK( dc->w.hPalette ); + GDI_ReleaseObj( dc->w.hPalette ); + GDI_ReleaseObj( hdc ); return entries; } @@ -336,15 +329,11 @@ PALETTEOBJ * palette; RGBQUAD *end; - dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) - { - dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC); - if (!dc) return 0; - } + if (!(dc = DC_GetDCUpdate( hdc ))) return 0; if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC ))) { + GDI_ReleaseObj( hdc ); return 0; } @@ -365,7 +354,8 @@ } else { entries = 0; } - GDI_HEAP_UNLOCK( dc->w.hPalette ); + GDI_ReleaseObj( dc->w.hPalette ); + GDI_ReleaseObj( hdc ); return entries; } @@ -456,21 +446,16 @@ int i; if (!info) return 0; - dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) - { - dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC); - if (!dc) return 0; - } + if (!(dc = DC_GetDCUpdate( hdc ))) return 0; if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) { - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); return 0; } if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC ))) { - GDI_HEAP_UNLOCK( hdc ); - GDI_HEAP_UNLOCK( hbitmap ); + GDI_ReleaseObj( hdc ); + GDI_ReleaseObj( hbitmap ); return 0; } @@ -530,7 +515,7 @@ } } - GDI_HEAP_UNLOCK( dc->w.hPalette ); + GDI_ReleaseObj( dc->w.hPalette ); if (bits && lines) { @@ -728,10 +713,10 @@ /* Otherwise, get bits from the XImage */ else if(!BITMAP_Driver->pGetDIBits(bmp, dc, startscan, lines, bits, info, coloruse, hbitmap)) { - GDI_HEAP_UNLOCK( hdc ); - GDI_HEAP_UNLOCK( hbitmap ); + GDI_ReleaseObj( hdc ); + GDI_ReleaseObj( hbitmap ); - return FALSE; + return 0; } } else if( info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) ) @@ -763,8 +748,8 @@ info->bmiHeader.biSizeImage, info->bmiHeader.biWidth, info->bmiHeader.biHeight); - GDI_HEAP_UNLOCK( hdc ); - GDI_HEAP_UNLOCK( hbitmap ); + GDI_ReleaseObj( hdc ); + GDI_ReleaseObj( hbitmap ); return lines; } @@ -870,7 +855,7 @@ SEGPTR *bits, HANDLE section, DWORD offset) { - HBITMAP16 hbitmap; + HBITMAP16 hbitmap = 0; DC *dc; BOOL bDesktopDC = FALSE; @@ -881,13 +866,11 @@ bDesktopDC = TRUE; } - dc = (DC *) GDI_GetObjPtr(hdc, DC_MAGIC); - if(!dc) dc = (DC *) GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC); - if(!dc) return (HBITMAP16) NULL; - - hbitmap = dc->funcs->pCreateDIBSection16(dc, bmi, usage, bits, section, offset, 0); - - GDI_HEAP_UNLOCK(hdc); + if ((dc = DC_GetDCPtr( hdc ))) + { + hbitmap = dc->funcs->pCreateDIBSection16(dc, bmi, usage, bits, section, offset, 0); + GDI_ReleaseObj(hdc); + } if (bDesktopDC) DeleteDC(hdc); @@ -902,7 +885,7 @@ LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch) { - HBITMAP hbitmap; + HBITMAP hbitmap = 0; DC *dc; BOOL bDesktopDC = FALSE; @@ -913,13 +896,11 @@ bDesktopDC = TRUE; } - dc = (DC *) GDI_GetObjPtr(hdc, DC_MAGIC); - if(!dc) dc = (DC *) GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC); - if(!dc) return (HBITMAP) NULL; - - hbitmap = dc->funcs->pCreateDIBSection(dc, bmi, usage, bits, section, offset, ovr_pitch); - - GDI_HEAP_UNLOCK(hdc); + if ((dc = DC_GetDCPtr( hdc ))) + { + hbitmap = dc->funcs->pCreateDIBSection(dc, bmi, usage, bits, section, offset, ovr_pitch); + GDI_ReleaseObj(hdc); + } if (bDesktopDC) DeleteDC(hdc); @@ -976,6 +957,7 @@ /* Get a pointer to the BITMAPOBJ structure */ pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC ); + if (!pBmp) return hPackedDIB; /* Get the bitmap dimensions */ width = pBmp->bitmap.bmWidth; @@ -1042,5 +1024,6 @@ } END: + GDI_ReleaseObj( hBmp ); return hPackedDIB; }
diff --git a/objects/enhmetafile.c b/objects/enhmetafile.c index 6828837..60000a0 100644 --- a/objects/enhmetafile.c +++ b/objects/enhmetafile.c
@@ -35,13 +35,16 @@ HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, HFILE hFile, HANDLE hMapping ) { - HENHMETAFILE hmf = GDI_AllocObject( sizeof(ENHMETAFILEOBJ), - ENHMETAFILE_MAGIC ); - ENHMETAFILEOBJ *metaObj = (ENHMETAFILEOBJ *)GDI_HEAP_LOCK( hmf ); + HENHMETAFILE hmf = 0; + ENHMETAFILEOBJ *metaObj = GDI_AllocObject( sizeof(ENHMETAFILEOBJ), + ENHMETAFILE_MAGIC, &hmf ); + if (metaObj) + { metaObj->emh = emh; metaObj->hFile = hFile; metaObj->hMapping = hMapping; - GDI_HEAP_UNLOCK( hmf ); + GDI_ReleaseObj( hmf ); + } return hmf; } @@ -59,7 +62,7 @@ CloseHandle( metaObj->hFile ); } else HeapFree( GetProcessHeap(), 0, metaObj->emh ); - return GDI_FreeObject( hmf ); + return GDI_FreeObject( hmf, metaObj ); } /****************************************************************** @@ -81,9 +84,9 @@ * * Releases ENHMETAHEADER associated with HENHMETAFILE */ -static BOOL EMF_ReleaseEnhMetaHeader( HENHMETAFILE hmf ) +static void EMF_ReleaseEnhMetaHeader( HENHMETAFILE hmf ) { - return GDI_HEAP_UNLOCK( hmf ); + GDI_ReleaseObj( hmf ); } /*****************************************************************************
diff --git a/objects/font.c b/objects/font.c index 03f1827..66423fe 100644 --- a/objects/font.c +++ b/objects/font.c
@@ -309,15 +309,13 @@ */ HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *font ) { - HFONT16 hFont = 0; + HFONT hFont = 0; if (font) { - hFont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC ); - if( hFont ) - { FONTOBJ* fontPtr; - fontPtr = (FONTOBJ *) GDI_HEAP_LOCK( hFont ); + if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont ))) + { memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) ); TRACE("(%i %i %i %i) '%s' %s %s => %04x\n", @@ -334,7 +332,7 @@ "escapement angle %f for new font %04x\n", font->lfOrientation/10., font->lfEscapement/10., hFont); } - GDI_HEAP_UNLOCK( hFont ); + GDI_ReleaseObj( hFont ); } } else WARN("(NULL) => NULL\n"); @@ -535,10 +533,15 @@ FONTENUMPROCEX16 efproc, LPARAM lParam, DWORD dwFlags) { + BOOL (*enum_func)(HDC,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM); INT16 retVal = 0; - DC* dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC ); + DC* dc = DC_GetDCPtr( hDC ); - if( dc && dc->funcs->pEnumDeviceFonts ) + if (!dc) return 0; + enum_func = dc->funcs->pEnumDeviceFonts; + GDI_ReleaseObj( hDC ); + + if (enum_func) { LPNEWTEXTMETRICEX16 lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) ); if( lptm16 ) @@ -557,8 +560,7 @@ fe16.segTextMetric = SEGPTR_GET(lptm16); fe16.segLogFont = SEGPTR_GET(lplf16); - retVal = dc->funcs->pEnumDeviceFonts( dc, plf, FONT_EnumInstance16, (LPARAM)&fe16 ); - + retVal = enum_func( hDC, plf, FONT_EnumInstance16, (LPARAM)&fe16 ); SEGPTR_FREE(lplf16); } SEGPTR_FREE(lptm16); @@ -573,9 +575,15 @@ static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf, FONTENUMPROCEXW efproc, LPARAM lParam, DWORD dwUnicode) { - DC* dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC ); + BOOL (*enum_func)(HDC,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM); + INT ret = 0; + DC *dc = DC_GetDCPtr( hDC ); - if( dc && dc->funcs->pEnumDeviceFonts ) + if (!dc) return 0; + enum_func = dc->funcs->pEnumDeviceFonts; + GDI_ReleaseObj( hDC ); + + if (enum_func) { LOGFONT16 lf16; NEWTEXTMETRICEXW tm32w; @@ -602,9 +610,9 @@ else lf16.lfFaceName[0] = '\0'; lf16.lfCharSet = plf->lfCharSet; - return dc->funcs->pEnumDeviceFonts( dc, &lf16, FONT_EnumInstance, (LPARAM)&fe32 ); + ret = enum_func( hDC, &lf16, FONT_EnumInstance, (LPARAM)&fe32 ); } - return 0; + return ret; } /*********************************************************************** @@ -708,10 +716,7 @@ */ INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc ) { - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) return 0; - return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2) - / dc->vportExtX ); + return (INT16)GetTextCharacterExtra( hdc ); } @@ -720,10 +725,13 @@ */ INT WINAPI GetTextCharacterExtra( HDC hdc ) { + INT ret; DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); if (!dc) return 0; - return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2) + ret = abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX ); + GDI_ReleaseObj( hdc ); + return ret; } @@ -745,11 +753,15 @@ DC * dc = DC_GetDCPtr( hdc ); if (!dc) return 0; if (dc->funcs->pSetTextCharacterExtra) - return dc->funcs->pSetTextCharacterExtra( dc, extra ); - extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX; - prev = dc->w.charExtra; - dc->w.charExtra = abs(extra); - return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX; + prev = dc->funcs->pSetTextCharacterExtra( dc, extra ); + else + { + extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX; + prev = (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX; + dc->w.charExtra = abs(extra); + } + GDI_ReleaseObj( hdc ); + return prev; } @@ -767,26 +779,30 @@ */ BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks ) { + BOOL ret = TRUE; DC * dc = DC_GetDCPtr( hdc ); - if (!dc) return 0; + if (!dc) return FALSE; if (dc->funcs->pSetTextJustification) - return dc->funcs->pSetTextJustification( dc, extra, breaks ); - - extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX); - if (!extra) breaks = 0; - dc->w.breakTotalExtra = extra; - dc->w.breakCount = breaks; - if (breaks) - { - dc->w.breakExtra = extra / breaks; - dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra); - } + ret = dc->funcs->pSetTextJustification( dc, extra, breaks ); else { - dc->w.breakExtra = 0; - dc->w.breakRem = 0; + extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX); + if (!extra) breaks = 0; + dc->w.breakTotalExtra = extra; + dc->w.breakCount = breaks; + if (breaks) + { + dc->w.breakExtra = extra / breaks; + dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra); + } + else + { + dc->w.breakExtra = 0; + dc->w.breakRem = 0; + } } - return 1; + GDI_ReleaseObj( hdc ); + return ret; } @@ -804,18 +820,23 @@ INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name ) { FONTOBJ *font; + INT ret = 0; - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); + DC * dc = (DC *) DC_GetDCPtr( hdc ); if (!dc) return 0; - if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC ))) - return 0; - if (name) - lstrcpynA( name, font->logfont.lfFaceName, count ); - GDI_HEAP_UNLOCK( dc->w.hFont ); - if (name) - return strlen(name); - else - return strlen(font->logfont.lfFaceName) + 1; + + if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC ))) + { + if (name) + { + lstrcpynA( name, font->logfont.lfFaceName, count ); + ret = strlen(name); + } + else ret = strlen(font->logfont.lfFaceName) + 1; + GDI_ReleaseObj( dc->w.hFont ); + } + GDI_ReleaseObj( hdc ); + return ret; } /*********************************************************************** @@ -825,7 +846,7 @@ { LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count ); INT res = GetTextFaceA(hdc,count,nameA); - lstrcpyAtoW( name, nameA ); + if (name) lstrcpyAtoW( name, nameA ); HeapFree( GetProcessHeap(), 0, nameA ); return res; } @@ -903,14 +924,17 @@ INT count, /* [in] Number of characters in string */ LPSIZE size) /* [out] Address of structure for string size */ { + BOOL ret = FALSE; DC * dc = DC_GetDCPtr( hdc ); - if (!dc || !dc->funcs->pGetTextExtentPoint || - !dc->funcs->pGetTextExtentPoint( dc, str, count, size )) - return FALSE; - + if (dc) + { + if(dc->funcs->pGetTextExtentPoint) + ret = dc->funcs->pGetTextExtentPoint( dc, str, count, size ); + GDI_ReleaseObj( hdc ); + } TRACE("(%08x %s %d %p): returning %d,%d\n", hdc, debugstr_wn (str, count), count, size, size->cx, size->cy ); - return TRUE; + return ret; } @@ -966,14 +990,16 @@ { int index, nFit, extent; SIZE tSize; + BOOL ret = FALSE; DC * dc = DC_GetDCPtr( hdc ); + if (!dc) return FALSE; - if (!dc || !dc->funcs->pGetTextExtentPoint) return FALSE; + if (!dc->funcs->pGetTextExtentPoint) goto done; size->cx = size->cy = nFit = extent = 0; for(index = 0; index < count; index++) { - if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE; + if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) goto done; if( extent+tSize.cx < maxExt ) { extent+=tSize.cx; @@ -986,10 +1012,13 @@ } size->cx = extent; *lpnFit = nFit; + ret = TRUE; TRACE("(%08x %s %d) returning %d %d %d\n", hdc,debugstr_wn(str,count),maxExt,nFit, size->cx,size->cy); - return TRUE; +done: + GDI_ReleaseObj( hdc ); + return ret; } /*********************************************************************** @@ -1009,18 +1038,13 @@ * GetTextMetricsA (GDI32.236) */ BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics ) -{ - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) { - if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ))) - return FALSE; - } + BOOL ret = FALSE; + DC * dc = DC_GetDCPtr( hdc ); + if (!dc) return FALSE; - if (!dc->funcs->pGetTextMetrics || - !dc->funcs->pGetTextMetrics( dc, metrics )) - return FALSE; - + if (dc->funcs->pGetTextMetrics && dc->funcs->pGetTextMetrics( dc, metrics )) + { /* device layer returns values in device units * therefore we have to convert them to logical */ @@ -1039,6 +1063,7 @@ metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth); metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth); metrics->tmOverhang = WDPTOLP(metrics->tmOverhang); + ret = TRUE; TRACE("text metrics:\n" " Weight = %03li\t FirstChar = %03i\t AveCharWidth = %li\n" @@ -1060,7 +1085,9 @@ metrics->tmAscent, metrics->tmDescent, metrics->tmHeight ); - return TRUE; + } + GDI_ReleaseObj( hdc ); + return ret; } @@ -1221,24 +1248,21 @@ LPINT buffer ) { UINT i, extra; - DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) + BOOL ret = FALSE; + DC * dc = DC_GetDCPtr( hdc ); + if (!dc) return FALSE; + + if (dc->funcs->pGetCharWidth && dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer)) { - if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ))) - return FALSE; + /* convert device units to logical */ + + extra = dc->vportExtX >> 1; + for( i = firstChar; i <= lastChar; i++, buffer++ ) + *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX; + ret = TRUE; } - - if (!dc->funcs->pGetCharWidth || - !dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer)) - return FALSE; - - /* convert device units to logical */ - - extra = dc->vportExtX >> 1; - for( i = firstChar; i <= lastChar; i++, buffer++ ) - *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX; - - return TRUE; + GDI_ReleaseObj( hdc ); + return ret; } @@ -1276,7 +1300,7 @@ ret = dc->funcs->pSetMapperFlags( dc, dwFlag ); else FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag); - GDI_HEAP_UNLOCK( hDC ); + GDI_ReleaseObj( hDC ); return ret; }
diff --git a/objects/gdiobj.c b/objects/gdiobj.c index b08f395..a94cd15 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c
@@ -6,9 +6,15 @@ #include "config.h" +#include <assert.h> #include <stdlib.h> #include <stdio.h> +#include "windef.h" +#include "wingdi.h" +#include "winerror.h" +#include "wine/winbase16.h" + #include "bitmap.h" #include "brush.h" #include "dc.h" @@ -21,8 +27,7 @@ #include "debugtools.h" #include "gdi.h" #include "tweak.h" -#include "windef.h" -#include "wingdi.h" +#include "syslevel.h" DEFAULT_DEBUG_CHANNEL(gdi); @@ -177,6 +182,10 @@ HBITMAP hPseudoStockBitmap; /* 1x1 bitmap for memory DCs */ +static SYSLEVEL GDI_level; +static WORD GDI_HeapSel; + + /****************************************************************************** * * void ReadFontInformation( @@ -308,7 +317,8 @@ */ #define FixStockFontSizeW FixStockFontSizeA - +#define TRACE_SEC(handle,text) \ + TRACE("(%04x): " text " %ld\n", (handle), GDI_level.crst.RecursionCount) /*********************************************************************** * GDI_Init @@ -318,6 +328,14 @@ BOOL GDI_Init(void) { BOOL systemIsBold = (TWEAK_WineLook == WIN31_LOOK); + HPALETTE16 hpalette; + HINSTANCE16 instance; + + _CreateSysLevel( &GDI_level, 3 ); + + /* create GDI heap */ + if ((instance = LoadLibrary16( "GDI.EXE" )) < 32) return FALSE; + GDI_HeapSel = GlobalHandleToSel16( instance ); /* Kill some warnings. */ (void)align_OEMFixedFont; @@ -340,12 +358,9 @@ /* Create default palette */ /* DR well *this* palette can't be moveable (?) */ - { - HPALETTE16 hpalette = PALETTE_Init(); - if( !hpalette ) - return FALSE; - StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LOCK( hpalette ); - } + hpalette = PALETTE_Init(); + if( !hpalette ) return FALSE; + StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, hpalette ); hPseudoStockBitmap = CreateBitmap( 1, 1, 1, 1, NULL ); return TRUE; @@ -355,75 +370,121 @@ /*********************************************************************** * GDI_AllocObject */ -HGDIOBJ GDI_AllocObject( WORD size, WORD magic ) +void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle ) { static DWORD count = 0; - GDIOBJHDR * obj; - HGDIOBJ16 handle; - if ( magic == DC_MAGIC || magic == METAFILE_DC_MAGIC ) - handle = GDI_HEAP_ALLOC( size ); - else - handle = GDI_HEAP_ALLOC_MOVEABLE( size ); - if (!handle) return 0; - obj = (GDIOBJHDR *) GDI_HEAP_LOCK( handle ); + GDIOBJHDR *obj; + + _EnterSysLevel( &GDI_level ); + if (!(*handle = LOCAL_Alloc( GDI_HeapSel, LMEM_MOVEABLE, size ))) + { + _LeaveSysLevel( &GDI_level ); + return NULL; + } + obj = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, *handle ); obj->hNext = 0; obj->wMagic = magic; obj->dwCount = ++count; - GDI_HEAP_UNLOCK( handle ); - return handle; + + TRACE_SEC( *handle, "enter" ); + return obj; } /*********************************************************************** + * GDI_ReallocObject + * + * The object ptr must have been obtained with GDI_GetObjPtr. + * The new pointer must be released with GDI_ReleaseObj. + */ +void *GDI_ReallocObject( WORD size, HGDIOBJ handle, void *object ) +{ + HGDIOBJ new_handle; + + LOCAL_Unlock( GDI_HeapSel, handle ); + if (!(new_handle = LOCAL_ReAlloc( GDI_HeapSel, handle, size, LMEM_MOVEABLE ))) + { + TRACE_SEC( handle, "leave" ); + _LeaveSysLevel( &GDI_level ); + return NULL; + } + assert( new_handle == handle ); /* moveable handle cannot change */ + return LOCAL_Lock( GDI_HeapSel, handle ); +} + + +/*********************************************************************** * GDI_FreeObject */ -BOOL GDI_FreeObject( HGDIOBJ handle ) +BOOL GDI_FreeObject( HGDIOBJ handle, void *ptr ) { - GDIOBJHDR * object; + GDIOBJHDR *object = ptr; - /* Can't free stock objects */ - if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE)) - return TRUE; - - object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle ); - if (!object) return FALSE; - object->wMagic = 0; /* Mark it as invalid */ - - /* Free object */ - - GDI_HEAP_FREE( handle ); + /* can't free stock objects */ + if (handle < FIRST_STOCK_HANDLE) + { + object->wMagic = 0; /* Mark it as invalid */ + LOCAL_Unlock( GDI_HeapSel, handle ); + LOCAL_Free( GDI_HeapSel, handle ); + } + TRACE_SEC( handle, "leave" ); + _LeaveSysLevel( &GDI_level ); return TRUE; } + /*********************************************************************** * GDI_GetObjPtr * * Return a pointer to the GDI object associated to the handle. * Return NULL if the object has the wrong magic number. - * Movable GDI objects are locked in memory: it is up to the caller to unlock - * it after the caller is done with the pointer. + * The object must be released with GDI_ReleaseObj. */ -GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ handle, WORD magic ) +void *GDI_GetObjPtr( HGDIOBJ handle, WORD magic ) { - GDIOBJHDR * ptr = NULL; + GDIOBJHDR *ptr = NULL; + + _EnterSysLevel( &GDI_level ); if (handle >= FIRST_STOCK_HANDLE) { if (handle <= LAST_STOCK_HANDLE) ptr = StockObjects[handle - FIRST_STOCK_HANDLE]; + if (ptr && (magic != MAGIC_DONTCARE) && (ptr->wMagic != magic)) ptr = NULL; } - else - ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle ); - if (!ptr) return NULL; - if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic)) + else { - GDI_HEAP_UNLOCK( handle ); - return NULL; + ptr = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, handle ); + if (ptr && (magic != MAGIC_DONTCARE) && (ptr->wMagic != magic)) + { + LOCAL_Unlock( GDI_HeapSel, handle ); + ptr = NULL; + } } + + if (!ptr) + { + _LeaveSysLevel( &GDI_level ); + SetLastError( ERROR_INVALID_HANDLE ); + } + else TRACE_SEC( handle, "enter" ); + return ptr; } /*********************************************************************** + * GDI_ReleaseObj + * + */ +void GDI_ReleaseObj( HGDIOBJ handle ) +{ + if (handle < FIRST_STOCK_HANDLE) LOCAL_Unlock( GDI_HeapSel, handle ); + TRACE_SEC( handle, "leave" ); + _LeaveSysLevel( &GDI_level ); +} + + +/*********************************************************************** * DeleteObject16 (GDI.69) */ BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj ) @@ -441,10 +502,12 @@ GDIOBJHDR * header; if (HIWORD(obj)) return FALSE; - if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE)) + if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE)) { + TRACE("Preserving Stock object %04x\n", obj ); + /* NOTE: No GDI_Release is necessary */ return TRUE; - if (obj == hPseudoStockBitmap) return TRUE; - if (!(header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ))) return FALSE; + } + if (!(header = GDI_GetObjPtr( obj, MAGIC_DONTCARE ))) return FALSE; TRACE("%04x\n", obj ); @@ -452,19 +515,22 @@ switch(header->wMagic) { - case PEN_MAGIC: return GDI_FreeObject( obj ); + case PEN_MAGIC: return GDI_FreeObject( obj, header ); case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header ); - case FONT_MAGIC: return GDI_FreeObject( obj ); + case FONT_MAGIC: return GDI_FreeObject( obj, header ); case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header); case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header); case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header ); - case DC_MAGIC: return DeleteDC(obj); + case DC_MAGIC: + GDI_ReleaseObj( obj ); + return DeleteDC(obj); case 0 : WARN("Already deleted\n"); break; default: WARN("Unknown magic number (%d)\n",header->wMagic); } + GDI_ReleaseObj( obj ); return FALSE; } @@ -482,11 +548,12 @@ */ HGDIOBJ WINAPI GetStockObject( INT obj ) { + HGDIOBJ ret; if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0; if (!StockObjects[obj]) return 0; - TRACE("returning %d\n", - FIRST_STOCK_HANDLE + obj ); - return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj); + ret = (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj); + TRACE("returning %4x\n", ret ); + return ret; } @@ -527,7 +594,7 @@ result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer ); break; } - GDI_HEAP_UNLOCK( handle ); + GDI_ReleaseObj( handle ); return result; } @@ -585,7 +652,7 @@ ERR("Invalid GDI Magic %04x\n", ptr->wMagic); return 0; } - GDI_HEAP_UNLOCK( handle ); + GDI_ReleaseObj( handle ); return result; } @@ -630,7 +697,7 @@ ptr->wMagic ); break; } - GDI_HEAP_UNLOCK( handle ); + GDI_ReleaseObj( handle ); return result; } @@ -688,7 +755,7 @@ ptr->wMagic ); break; } - GDI_HEAP_UNLOCK( handle ); + GDI_ReleaseObj( handle ); return result; } @@ -697,21 +764,25 @@ */ HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type) { + HANDLE ret = 0; DC * dc = DC_GetDCPtr( hdc ); - if (!dc) - return 0; + if (dc) + { switch (type) { - case OBJ_PEN: return dc->w.hPen; - case OBJ_BRUSH: return dc->w.hBrush; - case OBJ_PAL: return dc->w.hPalette; - case OBJ_FONT: return dc->w.hFont; - case OBJ_BITMAP: return dc->w.hBitmap; + case OBJ_PEN: ret = dc->w.hPen; break; + case OBJ_BRUSH: ret = dc->w.hBrush; break; + case OBJ_PAL: ret = dc->w.hPalette; break; + case OBJ_FONT: ret = dc->w.hFont; break; + case OBJ_BITMAP: ret = dc->w.hBitmap; break; default: /* the SDK only mentions those above */ WARN("(%08x,%d): unknown type.\n",hdc,type); - return 0; + break; + } + GDI_ReleaseObj( hdc ); } + return ret; } @@ -729,10 +800,14 @@ */ HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle ) { - DC * dc = DC_GetDCPtr( hdc ); - if (!dc || !dc->funcs->pSelectObject) return 0; + HGDIOBJ ret = 0; + DC * dc = DC_GetDCUpdate( hdc ); + if (!dc) return 0; TRACE("hdc=%04x %04x\n", hdc, handle ); - return dc->funcs->pSelectObject( dc, handle ); + if (dc->funcs->pSelectObject) + ret = dc->funcs->pSelectObject( dc, handle ); + GDI_ReleaseObj( hdc ); + return ret; } @@ -753,7 +828,7 @@ BOOL result = TRUE; /* Check if object is valid */ - GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ); + GDIOBJHDR * header = GDI_GetObjPtr( obj, MAGIC_DONTCARE ); if (!header) return FALSE; TRACE("%04x\n", obj ); @@ -770,7 +845,7 @@ /* Windows resets the brush origin. We don't need to. */ break; } - GDI_HEAP_UNLOCK( obj ); + GDI_ReleaseObj( obj ); return result; } @@ -939,54 +1014,13 @@ { UINT16 magic = 0; - if (handle >= FIRST_STOCK_HANDLE ) + GDIOBJHDR *object = GDI_GetObjPtr( handle, MAGIC_DONTCARE ); + if (object) { - switch (handle) - { - case STOCK_WHITE_BRUSH: - case STOCK_LTGRAY_BRUSH: - case STOCK_GRAY_BRUSH: - case STOCK_DKGRAY_BRUSH: - case STOCK_BLACK_BRUSH: - case STOCK_HOLLOW_BRUSH: - magic = BRUSH_MAGIC; - break; - - case STOCK_WHITE_PEN: - case STOCK_BLACK_PEN: - case STOCK_NULL_PEN : - magic = PEN_MAGIC; - break; - - case STOCK_OEM_FIXED_FONT: - case STOCK_ANSI_FIXED_FONT: - case STOCK_ANSI_VAR_FONT: - case STOCK_SYSTEM_FONT: - case STOCK_DEVICE_DEFAULT_FONT: - case STOCK_SYSTEM_FIXED_FONT: - case STOCK_DEFAULT_GUI_FONT: - magic = FONT_MAGIC; - break; - - case STOCK_DEFAULT_PALETTE: - magic = PALETTE_MAGIC; - break; - } + magic = object->wMagic - PEN_MAGIC + 1; + GDI_ReleaseObj( handle ); } - else - { - GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle ); - if (object) - { - magic = object->wMagic; - GDI_HEAP_UNLOCK( handle ); - } - } - - if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC) - return magic - PEN_MAGIC + 1; - else - return FALSE; + return magic; }
diff --git a/objects/metafile.c b/objects/metafile.c index 036144d..172c578 100644 --- a/objects/metafile.c +++ b/objects/metafile.c
@@ -73,10 +73,13 @@ */ HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh) { - HMETAFILE hmf = GDI_AllocObject( sizeof(METAFILEOBJ), METAFILE_MAGIC ); - METAFILEOBJ *metaObj = (METAFILEOBJ *)GDI_HEAP_LOCK( hmf ); + HMETAFILE hmf = 0; + METAFILEOBJ *metaObj = GDI_AllocObject( sizeof(METAFILEOBJ), METAFILE_MAGIC, &hmf ); + if (metaObj) + { metaObj->mh = mh; - GDI_HEAP_UNLOCK( hmf ); + GDI_ReleaseObj( hmf ); + } return hmf; } @@ -130,9 +133,9 @@ * * Releases METAHEADER associated with HMETAFILE */ -static BOOL MF_ReleaseMetaHeader( HMETAFILE hmf ) +static void MF_ReleaseMetaHeader( HMETAFILE hmf ) { - return GDI_HEAP_UNLOCK( hmf ); + GDI_ReleaseObj( hmf ); } /****************************************************************** @@ -162,11 +165,10 @@ BOOL WINAPI DeleteMetaFile( HMETAFILE hmf ) { - METAHEADER *mh = MF_GetMetaHeader( hmf ); - - if(!mh) return FALSE; - HeapFree( GetProcessHeap(), 0, mh ); - GDI_FreeObject( hmf ); + METAFILEOBJ * metaObj = (METAFILEOBJ *)GDI_GetObjPtr( hmf, METAFILE_MAGIC ); + if (!metaObj) return FALSE; + HeapFree( GetProcessHeap(), 0, metaObj->mh ); + GDI_FreeObject( hmf, metaObj ); return TRUE; } @@ -475,7 +477,7 @@ BOOL loaded = FALSE; if (!mh) return FALSE; - if(mh->mtType == METAFILE_DISK) { /* Create a memoery-based copy */ + if(mh->mtType == METAFILE_DISK) { /* Create a memory-based copy */ mh = MF_LoadDiskBasedMetaFile(mh); if(!mh) return FALSE; loaded = TRUE; @@ -580,7 +582,7 @@ if(!mh) return FALSE; - if(mh->mtType == METAFILE_DISK) { /* Create a memoery-based copy */ + if(mh->mtType == METAFILE_DISK) { /* Create a memory-based copy */ mh = MF_LoadDiskBasedMetaFile(mh); if(!mh) return FALSE; loaded = TRUE; @@ -668,7 +670,7 @@ TRACE("(%08x,%08x,%p,%p)\n", hdc, hmf, lpEnumFunc, (void*)lpData); if (!mh) return 0; - if(mh->mtType == METAFILE_DISK) { /* Create a memoery-based copy */ + if(mh->mtType == METAFILE_DISK) { /* Create a memory-based copy */ mh = MF_LoadDiskBasedMetaFile(mh); if(!mh) return 0; loaded = TRUE;
diff --git a/objects/palette.c b/objects/palette.c index d8e995c..6b1c2ee 100644 --- a/objects/palette.c +++ b/objects/palette.c
@@ -17,6 +17,7 @@ #include "wine/winuser16.h" #include "gdi.h" #include "color.h" +#include "dc.h" #include "palette.h" #include "debugtools.h" #include "callback.h" @@ -71,9 +72,8 @@ { if (!(palObj->mapping = HeapAlloc( GetProcessHeap(), 0, sizeof(int) * 20 ))) ERR("Can not create palette mapping -- out of memory!"); - GDI_HEAP_UNLOCK( hpalette ); + GDI_ReleaseObj( hpalette ); } - return hpalette; } @@ -116,15 +116,13 @@ size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY); - hpalette = GDI_AllocObject( size + sizeof(int*) +sizeof(GDIOBJHDR) , PALETTE_MAGIC ); - if (!hpalette) return 0; - - palettePtr = (PALETTEOBJ *) GDI_HEAP_LOCK( hpalette ); + if (!(palettePtr = GDI_AllocObject( size + sizeof(int*) +sizeof(GDIOBJHDR), + PALETTE_MAGIC, &hpalette ))) return 0; memcpy( &palettePtr->logpalette, palette, size ); PALETTE_ValidateFlags(palettePtr->logpalette.palPalEntry, palettePtr->logpalette.palNumEntries); palettePtr->mapping = NULL; - GDI_HEAP_UNLOCK( hpalette ); + GDI_ReleaseObj( hpalette ); TRACE(" returning %04x\n", hpalette); return hpalette; @@ -228,7 +226,7 @@ { if (start >= numEntries) { - GDI_HEAP_UNLOCK( hpalette ); + GDI_ReleaseObj( hpalette ); return 0; } memcpy( entries, &palPtr->logpalette.palPalEntry[start], @@ -236,9 +234,9 @@ for( numEntries = 0; numEntries < count ; numEntries++ ) if (entries[numEntries].peFlags & 0xF0) entries[numEntries].peFlags = 0; - GDI_HEAP_UNLOCK( hpalette ); } + GDI_ReleaseObj( hpalette ); return count; } @@ -277,7 +275,7 @@ numEntries = palPtr->logpalette.palNumEntries; if (start >= numEntries) { - GDI_HEAP_UNLOCK( hpalette ); + GDI_ReleaseObj( hpalette ); return 0; } if (start+count > numEntries) count = numEntries - start; @@ -287,7 +285,7 @@ palPtr->logpalette.palNumEntries); HeapFree( GetProcessHeap(), 0, palPtr->mapping ); palPtr->mapping = NULL; - GDI_HEAP_UNLOCK( hpalette ); + GDI_ReleaseObj( hpalette ); return count; } @@ -328,11 +326,7 @@ size += sizeof(int*) + sizeof(GDIOBJHDR); mapping = palPtr->mapping; - GDI_HEAP_UNLOCK( hPal ); - - hPal = GDI_HEAP_REALLOC( hPal, size ); - palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hPal, PALETTE_MAGIC ); - if( !palPtr ) return FALSE; + if (!(palPtr = GDI_ReallocObject( size, hPal, palPtr ))) return FALSE; if( mapping ) { @@ -341,7 +335,7 @@ if(newMap == NULL) { ERR("Can not resize mapping -- out of memory!"); - GDI_HEAP_UNLOCK( hPal ); + GDI_ReleaseObj( hPal ); return FALSE; } palPtr->mapping = newMap; @@ -357,7 +351,7 @@ } palPtr->logpalette.palNumEntries = cEntries; palPtr->logpalette.palVersion = prevVer; - GDI_HEAP_UNLOCK( hPal ); + GDI_ReleaseObj( hPal ); return TRUE; } @@ -403,9 +397,10 @@ PALETTE_Driver-> pSetMapping(palPtr, StartIndex, NumEntries, hPal != hPrimaryPalette ); - GDI_HEAP_UNLOCK( hPal ); + GDI_ReleaseObj( hPal ); return TRUE; } + GDI_ReleaseObj( hPal ); } return FALSE; } @@ -489,12 +484,19 @@ TRACE("hdc=%04x,start=%i,count=%i\n", hdc,start,count); if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; - if (!entries) return dc->w.devCaps->sizePalette; + + if (!entries) + { + count = dc->w.devCaps->sizePalette; + goto done; + } + if (start >= dc->w.devCaps->sizePalette) { - GDI_HEAP_UNLOCK( hdc ); - return 0; + count = 0; + goto done; } + if (start+count >= dc->w.devCaps->sizePalette) count = dc->w.devCaps->sizePalette - start; for (i = 0; i < count; i++) @@ -504,7 +506,8 @@ TRACE("\tidx(%02x) -> RGB(%08lx)\n", start + i, *(COLORREF*)(entries + i) ); } - GDI_HEAP_UNLOCK( hdc ); + done: + GDI_ReleaseObj( hdc ); return count; } @@ -536,12 +539,14 @@ UINT index = 0; if( palObj ) + { index = COLOR_PaletteLookupPixel(palObj->logpalette.palPalEntry, palObj->logpalette.palNumEntries, NULL, color, FALSE ); + GDI_ReleaseObj( hpalette ); + } TRACE("(%04x,%06lx): returning %d\n", hpalette, color, index ); - GDI_HEAP_UNLOCK( hpalette ); return index; } @@ -558,9 +563,6 @@ /*********************************************************************** * GetNearestColor [GDI32.202] Gets a system color to match * - * NOTES - * Should this return CLR_INVALID instead of FadeCafe? - * * RETURNS * Success: Color from system palette that corresponds to given color * Failure: CLR_INVALID @@ -569,24 +571,26 @@ HDC hdc, /* [in] Handle of device context */ COLORREF color) /* [in] Color to be matched */ { - COLORREF nearest = 0xFADECAFE; + COLORREF nearest = CLR_INVALID; DC *dc; PALETTEOBJ *palObj; if ( (dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC )) ) { - palObj = (PALETTEOBJ*) - GDI_GetObjPtr( (dc->w.hPalette)? dc->w.hPalette - : STOCK_DEFAULT_PALETTE, PALETTE_MAGIC ); - if (!palObj) return nearest; + HPALETTE hpal = (dc->w.hPalette)? dc->w.hPalette : STOCK_DEFAULT_PALETTE; + palObj = GDI_GetObjPtr( hpal, PALETTE_MAGIC ); + if (!palObj) { + GDI_ReleaseObj( hdc ); + return nearest; + } - nearest = COLOR_LookupNearestColor( palObj->logpalette.palPalEntry, - palObj->logpalette.palNumEntries, color ); - GDI_HEAP_UNLOCK( dc->w.hPalette ); + nearest = COLOR_LookupNearestColor( palObj->logpalette.palPalEntry, + palObj->logpalette.palNumEntries, color ); + GDI_ReleaseObj( hpal ); + GDI_ReleaseObj( hdc ); } TRACE("(%06lx): returning %06lx\n", color, nearest ); - GDI_HEAP_UNLOCK( hdc ); return nearest; } @@ -624,7 +628,7 @@ { HeapFree( GetProcessHeap(), 0, palette->mapping ); if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0; - return GDI_FreeObject( hpalette ); + return GDI_FreeObject( hpalette, palette ); } @@ -638,15 +642,10 @@ TRACE("%04x %04x\n", hdc, hpal ); - dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) - { - dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC); - if (!dc) return 0; - } + if (!(dc = DC_GetDCPtr( hdc ))) return 0; prev = dc->w.hPalette; dc->w.hPalette = hpal; - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); if (!wBkg) hPrimaryPalette = hpal; return prev; } @@ -659,37 +658,39 @@ { PALETTEOBJ* palPtr; int realized = 0; - DC* dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) - { - dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC); - if (!dc) return 0; - } + DC* dc = DC_GetDCPtr( hdc ); + + if (!dc) return 0; TRACE("%04x...\n", hdc ); - if( dc && dc->w.hPalette != hLastRealizedPalette ) + if(dc->w.hPalette != hLastRealizedPalette ) { - if( dc->w.hPalette == STOCK_DEFAULT_PALETTE ) - return RealizeDefaultPalette16( hdc ); + if( dc->w.hPalette == STOCK_DEFAULT_PALETTE ) { + realized = RealizeDefaultPalette16( hdc ); + GDI_ReleaseObj( hdc ); + return (UINT16)realized; + } + palPtr = (PALETTEOBJ *) GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC ); if (!palPtr) { - FIXME("invalid selected palette %04x\n",dc->w.hPalette); - return 0; + GDI_ReleaseObj( hdc ); + FIXME("invalid selected palette %04x\n",dc->w.hPalette); + return 0; } realized = PALETTE_Driver-> pSetMapping(palPtr,0,palPtr->logpalette.palNumEntries, (dc->w.hPalette != hPrimaryPalette) || (dc->w.hPalette == STOCK_DEFAULT_PALETTE)); - GDI_HEAP_UNLOCK( dc->w.hPalette ); hLastRealizedPalette = dc->w.hPalette; + GDI_ReleaseObj( dc->w.hPalette ); } else TRACE(" skipping (hLastRealizedPalette = %04x)\n", hLastRealizedPalette); - GDI_HEAP_UNLOCK( hdc ); + GDI_ReleaseObj( hdc ); TRACE(" realized %i colors.\n", realized ); return (UINT16)realized; @@ -701,33 +702,26 @@ */ UINT16 WINAPI RealizeDefaultPalette16( HDC16 hdc ) { + UINT16 ret = 0; DC *dc; PALETTEOBJ* palPtr; TRACE("%04x\n", hdc ); - dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) + if (!(dc = DC_GetDCPtr( hdc ))) return 0; + + if (!(dc->w.flags & DC_MEMORY)) { - dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC); - if (!dc) return 0; + palPtr = (PALETTEOBJ*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE, PALETTE_MAGIC ); + if (palPtr) + { + /* lookup is needed to account for SetSystemPaletteUse() stuff */ + ret = PALETTE_Driver->pUpdateMapping(palPtr); + GDI_ReleaseObj( STOCK_DEFAULT_PALETTE ); + } } - - if ( dc->w.flags & DC_MEMORY ) - { - GDI_HEAP_UNLOCK( hdc ); - return 0; - } - - hPrimaryPalette = STOCK_DEFAULT_PALETTE; - hLastRealizedPalette = STOCK_DEFAULT_PALETTE; - - palPtr = (PALETTEOBJ*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE, PALETTE_MAGIC ); - if (!palPtr) return 0; - - /* lookup is needed to account for SetSystemPaletteUse() stuff */ - - return PALETTE_Driver->pUpdateMapping(palPtr); + GDI_ReleaseObj( hdc ); + return ret; } /*********************************************************************** @@ -738,8 +732,9 @@ DC* dc = (DC *)GDI_GetObjPtr( hDC, DC_MAGIC ); if (dc) { - GDI_HEAP_UNLOCK( hDC ); - return dc->w.hPalette == hPrimaryPalette; + BOOL bRet = dc->w.hPalette == hPrimaryPalette; + GDI_ReleaseObj( hDC ); + return bRet; } return FALSE; } @@ -798,11 +793,12 @@ /* Send palette change notification */ HWND hWnd; + GDI_ReleaseObj( hDC ); if( (hWnd = Callout.WindowFromDC( hDC )) ) Callout.SendMessageA( HWND_BROADCAST, WM_PALETTECHANGED, hWnd, 0L); } + else GDI_ReleaseObj( hDC ); - GDI_HEAP_UNLOCK( hDC ); return realized; } @@ -814,19 +810,19 @@ { DC *dc; HWND hWnd; + int size; if (!(dc = (DC *) GDI_GetObjPtr( hDC, DC_MAGIC ))) return 0; - + size = dc->w.devCaps->sizePalette; + GDI_ReleaseObj( hDC ); hWnd = Callout.WindowFromDC( hDC ); /* Docs say that we have to remap current drawable pixel by pixel * but it would take forever given the speed of XGet/PutPixel. */ - if (hWnd && dc->w.devCaps->sizePalette ) + if (hWnd && size) Callout.RedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE ); - GDI_HEAP_UNLOCK( hDC ); - return 0x666; }
diff --git a/objects/pen.c b/objects/pen.c index 5fb6f08..09fcf66 100644 --- a/objects/pen.c +++ b/objects/pen.c
@@ -54,16 +54,14 @@ HPEN16 WINAPI CreatePenIndirect16( const LOGPEN16 * pen ) { PENOBJ * penPtr; - HPEN16 hpen; + HPEN hpen; if (pen->lopnStyle > PS_INSIDEFRAME) return 0; - hpen = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC ); - if (!hpen) return 0; - penPtr = (PENOBJ *)GDI_HEAP_LOCK( hpen ); + if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC, &hpen ))) return 0; penPtr->logpen.lopnStyle = pen->lopnStyle; penPtr->logpen.lopnColor = pen->lopnColor; CONV_POINT16TO32( &pen->lopnWidth, &penPtr->logpen.lopnWidth ); - GDI_HEAP_UNLOCK( hpen ); + GDI_ReleaseObj( hpen ); return hpen; } @@ -77,13 +75,11 @@ HPEN hpen; if (pen->lopnStyle > PS_INSIDEFRAME) return 0; - hpen = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC ); - if (!hpen) return 0; - penPtr = (PENOBJ *)GDI_HEAP_LOCK( hpen ); + if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC, &hpen ))) return 0; penPtr->logpen.lopnStyle = pen->lopnStyle; penPtr->logpen.lopnWidth = pen->lopnWidth; penPtr->logpen.lopnColor = pen->lopnColor; - GDI_HEAP_UNLOCK( hpen ); + GDI_ReleaseObj( hpen ); return hpen; } @@ -106,9 +102,7 @@ if (brush->lbHatch) FIXME("Hatches not implemented\n"); - hpen = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC ); - if (!hpen) return 0; - penPtr = (PENOBJ *)GDI_HEAP_LOCK( hpen ); + if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC, &hpen ))) return 0; penPtr->logpen.lopnStyle = style & ~PS_TYPE_MASK; /* PS_USERSTYLE and PS_ALTERNATE workaround */ @@ -119,7 +113,7 @@ penPtr->logpen.lopnWidth.x = (style & PS_GEOMETRIC) ? width : 1; penPtr->logpen.lopnWidth.y = 0; penPtr->logpen.lopnColor = brush->lbColor; - GDI_HEAP_UNLOCK( hpen ); + GDI_ReleaseObj( hpen ); return hpen; }
diff --git a/objects/region.c b/objects/region.c index e644a88..d4d28f7 100644 --- a/objects/region.c +++ b/objects/region.c
@@ -457,14 +457,12 @@ HRGN hrgn; RGNOBJ *obj; - if(!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) - return 0; - obj = (RGNOBJ *) GDI_HEAP_LOCK( hrgn ); + if(!(obj = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC, &hrgn ))) return 0; if(!(obj->rgn = REGION_AllocWineRegion(n))) { - GDI_FreeObject( hrgn ); + GDI_FreeObject( hrgn, obj ); return 0; } - GDI_HEAP_UNLOCK( hrgn ); + GDI_ReleaseObj( hrgn ); return hrgn; } @@ -487,7 +485,7 @@ TRACE(" %04x\n", hrgn ); REGION_DestroyWineRegion( obj->rgn ); - return GDI_FreeObject( hrgn ); + return GDI_FreeObject( hrgn, obj ); } /*********************************************************************** @@ -530,7 +528,7 @@ } } ret = obj->rgn->type; - GDI_HEAP_UNLOCK( hrgn ); + GDI_ReleaseObj( hrgn ); return ret; } @@ -561,7 +559,7 @@ rect->right = obj->rgn->extents.right; rect->bottom = obj->rgn->extents.bottom; ret = obj->rgn->type; - GDI_HEAP_UNLOCK(hrgn); + GDI_ReleaseObj(hrgn); return ret; } return ERROR; @@ -664,7 +662,7 @@ else EMPTY_REGION(obj->rgn); - GDI_HEAP_UNLOCK( hrgn ); + GDI_ReleaseObj( hrgn ); return TRUE; } @@ -717,7 +715,7 @@ d = (ellipse_height < 128) ? ((3 * ellipse_height) >> 2) : 64; if (!(hrgn = REGION_CreateRegion(d))) return 0; - obj = (RGNOBJ *) GDI_HEAP_LOCK( hrgn ); + if (!(obj = GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return 0; TRACE("(%d,%d-%d,%d %dx%d): ret=%04x\n", left, top, right, bottom, ellipse_width, ellipse_height, hrgn ); @@ -792,7 +790,7 @@ REGION_UnionRectWithRegion( &rect, obj->rgn ); } obj->rgn->type = SIMPLEREGION; /* FIXME? */ - GDI_HEAP_UNLOCK( hrgn ); + GDI_ReleaseObj( hrgn ); return hrgn; } @@ -857,7 +855,7 @@ size = obj->rgn->numRects * sizeof(RECT); if(count < (size + sizeof(RGNDATAHEADER)) || rgndata == NULL) { - GDI_HEAP_UNLOCK( hrgn ); + GDI_ReleaseObj( hrgn ); return size + sizeof(RGNDATAHEADER); } @@ -872,7 +870,7 @@ memcpy( rgndata->Buffer, obj->rgn->rects, size ); - GDI_HEAP_UNLOCK( hrgn ); + GDI_ReleaseObj( hrgn ); return 1; } @@ -912,13 +910,16 @@ RECT *pCurRect, *pEndRect; RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ); - pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount; - for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++) - REGION_UnionRectWithRegion( pCurRect, obj->rgn ); - GDI_HEAP_UNLOCK( hrgn ); + if (obj) { + pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount; + for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++) + REGION_UnionRectWithRegion( pCurRect, obj->rgn ); + GDI_ReleaseObj( hrgn ); - TRACE("%04x\n", hrgn ); - return hrgn; + TRACE("%04x\n", hrgn ); + return hrgn; + } + else ERR("Could not get pointer to newborn Region!"); } fail: WARN("Failed\n"); @@ -940,20 +941,22 @@ BOOL WINAPI PtInRegion( HRGN hrgn, INT x, INT y ) { RGNOBJ * obj; + BOOL ret = FALSE; if ((obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) { - BOOL ret = FALSE; int i; if (obj->rgn->numRects > 0 && INRECT(obj->rgn->extents, x, y)) for (i = 0; i < obj->rgn->numRects; i++) if (INRECT (obj->rgn->rects[i], x, y)) + { ret = TRUE; - GDI_HEAP_UNLOCK( hrgn ); - return ret; + break; + } + GDI_ReleaseObj( hrgn ); } - return FALSE; + return ret; } @@ -977,11 +980,11 @@ BOOL WINAPI RectInRegion( HRGN hrgn, const RECT *rect ) { RGNOBJ * obj; + BOOL ret = FALSE; if ((obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) { RECT *pCurRect, *pRectEnd; - BOOL ret = FALSE; /* this is (just) a useful optimization */ if ((obj->rgn->numRects > 0) && EXTENTCHECK(&obj->rgn->extents, @@ -993,10 +996,8 @@ if (pCurRect->bottom <= rect->top) continue; /* not far enough down yet */ - if (pCurRect->top >= rect->bottom) { - ret = FALSE; /* too far down */ - break; - } + if (pCurRect->top >= rect->bottom) + break; /* too far down */ if (pCurRect->right <= rect->left) continue; /* not far enough over yet */ @@ -1009,10 +1010,9 @@ break; } } - GDI_HEAP_UNLOCK(hrgn); - return ret; + GDI_ReleaseObj(hrgn); } - return FALSE; + return ret; } /*********************************************************************** @@ -1058,9 +1058,9 @@ } ret = TRUE; done: - GDI_HEAP_UNLOCK(hrgn2); + GDI_ReleaseObj(hrgn2); } - GDI_HEAP_UNLOCK(hrgn1); + GDI_ReleaseObj(hrgn1); } return ret; } @@ -1093,7 +1093,7 @@ if(!obj) return FALSE; REGION_UnionRectWithRegion( lpRect, obj->rgn ); - GDI_HEAP_UNLOCK(hrgn); + GDI_ReleaseObj(hrgn); return TRUE; } @@ -1108,6 +1108,7 @@ BOOL bRet; RGNOBJ *srcObj = (RGNOBJ*) GDI_GetObjPtr( hSrc, REGION_MAGIC ); + if (!srcObj) return FALSE; if (srcObj->rgn->numRects != 0) { RGNOBJ* destObj = (RGNOBJ*) GDI_GetObjPtr( hDest, REGION_MAGIC ); @@ -1126,12 +1127,12 @@ REGION_UnionRectWithRegion( &tempRect, destObj->rgn ); } REGION_SubtractRegion( destObj->rgn, destObj->rgn, srcObj->rgn ); - GDI_HEAP_UNLOCK ( hDest ); + GDI_ReleaseObj ( hDest ); bRet = TRUE; } else bRet = FALSE; - GDI_HEAP_UNLOCK( hSrc ); + GDI_ReleaseObj( hSrc ); return bRet; } @@ -1146,24 +1147,27 @@ RGNOBJ *srcObj, *destObj; DC * dc = DC_GetDCPtr( hdc ); RECT tmpRect; + BOOL ret = FALSE; TRACE(" hdc=%04x dest=%04x src=%04x\n", hdc, hDest, hSrc) ; + if (!dc) return ret; if (dc->w.MapMode == MM_TEXT) /* Requires only a translation */ { - if( CombineRgn( hDest, hSrc, 0, RGN_COPY ) == ERROR ) return FALSE; + if( CombineRgn( hDest, hSrc, 0, RGN_COPY ) == ERROR ) goto done; OffsetRgn( hDest, dc->vportOrgX - dc->wndOrgX, dc->vportOrgY - dc->wndOrgY ); - return TRUE; + ret = TRUE; + goto done; } if(!( srcObj = (RGNOBJ *) GDI_GetObjPtr( hSrc, REGION_MAGIC) )) - return FALSE; + goto done; if(!( destObj = (RGNOBJ *) GDI_GetObjPtr( hDest, REGION_MAGIC) )) { - GDI_HEAP_UNLOCK( hSrc ); - return FALSE; + GDI_ReleaseObj( hSrc ); + goto done; } EMPTY_REGION( destObj->rgn ); @@ -1178,9 +1182,11 @@ REGION_UnionRectWithRegion( &tmpRect, destObj->rgn ); } - GDI_HEAP_UNLOCK( hDest ); - GDI_HEAP_UNLOCK( hSrc ); - return TRUE; + GDI_ReleaseObj( hDest ); + GDI_ReleaseObj( hSrc ); + done: + GDI_ReleaseObj( hdc ); + return ret; } /*********************************************************************** @@ -1243,16 +1249,16 @@ break; } result = destObj->rgn->type; - GDI_HEAP_UNLOCK( hSrc2 ); + GDI_ReleaseObj( hSrc2 ); } } - GDI_HEAP_UNLOCK( hSrc1 ); + GDI_ReleaseObj( hSrc1 ); } TRACE("dump:\n"); if(TRACE_ON(region)) REGION_DumpRegion(destObj->rgn); - GDI_HEAP_UNLOCK( hDest ); + GDI_ReleaseObj( hDest ); } else { ERR("Invalid rgn=%04x\n", hDest); } @@ -2714,7 +2720,7 @@ { SetRectRgn( hrgn, min(Pts[0].x, Pts[2].x), min(Pts[0].y, Pts[2].y), max(Pts[0].x, Pts[2].x), max(Pts[0].y, Pts[2].y) ); - GDI_HEAP_UNLOCK( hrgn ); + GDI_ReleaseObj( hrgn ); return hrgn; } @@ -2811,6 +2817,7 @@ sizeof(POINTBLOCK) ); if(!tmpPtBlock) { WARN("Can't alloc tPB\n"); + REGION_DeleteObject( hrgn, obj ); return 0; } curPtBlock->next = tmpPtBlock; @@ -2845,7 +2852,7 @@ curPtBlock = tmpPtBlock; } HeapFree( GetProcessHeap(), 0, pETEs ); - GDI_HEAP_UNLOCK( hrgn ); + GDI_ReleaseObj( hrgn ); return hrgn; } @@ -2910,6 +2917,8 @@ DC *dc = DC_GetDCPtr (hDC); OSVERSIONINFOA vi; POINT org; + + if (!dc) return -1; CombineRgn (hRgn, dc->w.hVisRgn, 0, RGN_COPY); /* * On Windows NT/2000, @@ -2925,7 +2934,7 @@ org.x -= dc->w.DCOrgX; org.y -= dc->w.DCOrgY; OffsetRgn (hRgn, org.x, org.y); - + GDI_ReleaseObj( hDC ); return 1; } /* case 1: @@ -3167,7 +3176,7 @@ { if( hDst ) /* existing rgn */ { - GDI_HEAP_UNLOCK(hDst); + GDI_ReleaseObj(hDst); hDst = 0; goto done; } @@ -3175,7 +3184,7 @@ } else if( hDst == 0 ) { - if(!(hDst = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) + if (!(objDst = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC, &hDst ))) { fail: if( rgnDst->rects ) @@ -3183,16 +3192,14 @@ HeapFree( GetProcessHeap(), 0, rgnDst ); goto done; } - - objDst = (RGNOBJ *) GDI_HEAP_LOCK( hDst ); objDst->rgn = rgnDst; } - GDI_HEAP_UNLOCK(hDst); + GDI_ReleaseObj(hDst); } else hDst = 0; done: - GDI_HEAP_UNLOCK(hSrc); + GDI_ReleaseObj(hSrc); return hDst; } return 0;
diff --git a/objects/text.c b/objects/text.c index b5b7cdf..99b9e23 100644 --- a/objects/text.c +++ b/objects/text.c
@@ -92,9 +92,15 @@ const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx ) { - DC * dc = DC_GetDCPtr( hdc ); - return dc && dc->funcs->pExtTextOut && - dc->funcs->pExtTextOut(dc,x,y,flags,lprect,str,count,lpDx); + BOOL ret = FALSE; + DC * dc = DC_GetDCUpdate( hdc ); + if (dc) + { + if(dc->funcs->pExtTextOut) + ret = dc->funcs->pExtTextOut(dc,x,y,flags,lprect,str,count,lpDx); + GDI_ReleaseObj( hdc ); + } + return ret; }