Commit 311c53db authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Allocate and initialize GDI objects before giving them a handle.

This makes it unnecessary to hold the GDI lock since the object cannot be accessed before it has a handle.
parent 5811a2cc
......@@ -280,18 +280,13 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
return 0;
}
/* Create the BITMAPOBJ */
bmpobj = GDI_AllocObject( sizeof(BITMAPOBJ), OBJ_BITMAP, (HGDIOBJ *)&hbitmap, &bitmap_funcs );
if (!bmpobj)
/* Create the BITMAPOBJ */
if (!(bmpobj = HeapAlloc( GetProcessHeap(), 0, sizeof(*bmpobj) )))
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return NULL;
return 0;
}
TRACE("%dx%d, %d colors returning %p\n", bm.bmWidth, bm.bmHeight,
1 << (bm.bmPlanes * bm.bmBitsPixel), hbitmap);
bmpobj->size.cx = 0;
bmpobj->size.cy = 0;
bmpobj->bitmap = bm;
......@@ -302,10 +297,18 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
bmpobj->color_table = NULL;
bmpobj->nb_colors = 0;
if (!(hbitmap = alloc_gdi_handle( &bmpobj->header, OBJ_BITMAP, &bitmap_funcs )))
{
HeapFree( GetProcessHeap(), 0, bmpobj );
return 0;
}
if (bm.bmBits)
SetBitmapBits( hbitmap, bm.bmHeight * bm.bmWidthBytes, bm.bmBits );
GDI_ReleaseObj( hbitmap );
TRACE("%dx%d, %d colors returning %p\n", bm.bmWidth, bm.bmHeight,
1 << (bm.bmPlanes * bm.bmBitsPixel), hbitmap);
return hbitmap;
}
......
......@@ -104,8 +104,8 @@ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
BRUSHOBJ * ptr;
HBRUSH hbrush;
if (!(ptr = GDI_AllocObject( sizeof(BRUSHOBJ), OBJ_BRUSH, (HGDIOBJ *)&hbrush, &brush_funcs )))
return 0;
if (!(ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(*ptr) ))) return 0;
ptr->logbrush.lbStyle = brush->lbStyle;
ptr->logbrush.lbColor = brush->lbColor;
ptr->logbrush.lbHatch = brush->lbHatch;
......@@ -146,12 +146,21 @@ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
break;
}
GDI_ReleaseObj( hbrush );
TRACE("%p\n", hbrush);
return hbrush;
if ((hbrush = alloc_gdi_handle( &ptr->header, OBJ_BRUSH, &brush_funcs )))
{
TRACE("%p\n", hbrush);
return hbrush;
}
error:
GDI_FreeObject( hbrush, ptr );
if (ptr->logbrush.lbHatch)
{
if (ptr->logbrush.lbStyle == BS_PATTERN)
DeleteObject( (HGDIOBJ)ptr->logbrush.lbHatch );
else if (ptr->logbrush.lbStyle == BS_DIBPATTERN)
GlobalFree16( (HGLOBAL16)ptr->logbrush.lbHatch );
}
HeapFree( GetProcessHeap(), 0, ptr );
return 0;
}
......
......@@ -74,12 +74,10 @@ static inline DC *get_dc_obj( HDC hdc )
*/
DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic )
{
HDC hdc;
DC *dc;
if (!(dc = GDI_AllocObject( sizeof(*dc), magic, (HGDIOBJ*)&hdc, &dc_funcs ))) return NULL;
if (!(dc = HeapAlloc( GetProcessHeap(), 0, sizeof(*dc) ))) return NULL;
dc->hSelf = hdc;
dc->funcs = funcs;
dc->physDev = NULL;
dc->thread = GetCurrentThreadId();
......@@ -148,7 +146,12 @@ DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic )
dc->BoundsRect.bottom = 0;
dc->saved_visrgn = NULL;
PATH_InitGdiPath(&dc->path);
GDI_ReleaseObj( dc->hSelf );
if (!(dc->hSelf = alloc_gdi_handle( &dc->header, magic, &dc_funcs )))
{
HeapFree( GetProcessHeap(), 0, dc );
dc = NULL;
}
return dc;
}
......@@ -332,12 +335,11 @@ static HDC GetDCState( HDC hdc )
HGDIOBJ handle;
if (!(dc = get_dc_ptr( hdc ))) return 0;
if (!(newdc = GDI_AllocObject( sizeof(DC), dc->header.type, &handle, &dc_funcs )))
if (!(newdc = HeapAlloc( GetProcessHeap(), 0, sizeof(*newdc ))))
{
release_dc_ptr( dc );
return 0;
}
TRACE("(%p): returning %p\n", hdc, handle );
newdc->flags = dc->flags | DC_SAVED;
newdc->layout = dc->layout;
......@@ -380,13 +382,12 @@ static HDC GetDCState( HDC hdc )
newdc->vportExtX = dc->vportExtX;
newdc->vportExtY = dc->vportExtY;
newdc->BoundsRect = dc->BoundsRect;
newdc->gdiFont = dc->gdiFont;
newdc->hSelf = handle;
newdc->thread = GetCurrentThreadId();
newdc->refcount = 1;
newdc->saveLevel = 0;
newdc->saved_dc = 0;
GDI_ReleaseObj( handle );
PATH_InitGdiPath( &newdc->path );
......@@ -395,6 +396,15 @@ static HDC GetDCState( HDC hdc )
newdc->hookProc = 0;
newdc->saved_visrgn = NULL;
if (!(newdc->hSelf = alloc_gdi_handle( &newdc->header, dc->header.type, &dc_funcs )))
{
HeapFree( GetProcessHeap(), 0, newdc );
release_dc_ptr( dc );
return 0;
}
handle = newdc->hSelf;
TRACE("(%p): returning %p\n", hdc, handle );
/* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
newdc->hVisRgn = 0;
......@@ -413,11 +423,6 @@ static HDC GetDCState( HDC hdc )
}
/* don't bother recomputing hMetaClipRgn, we'll do that in SetDCState */
if(dc->gdiFont) {
newdc->gdiFont = dc->gdiFont;
} else
newdc->gdiFont = 0;
release_dc_ptr( newdc );
release_dc_ptr( dc );
return handle;
......
......@@ -249,7 +249,7 @@ static inline BOOL is_dib_monochrome( const BITMAPINFO* info )
*/
HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk )
{
HENHMETAFILE hmf = 0;
HENHMETAFILE hmf;
ENHMETAFILEOBJ *metaObj;
if (emh->iType != EMR_HEADER || emh->dSignature != ENHMETA_SIGNATURE ||
......@@ -261,13 +261,13 @@ HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk )
return 0;
}
metaObj = GDI_AllocObject( sizeof(ENHMETAFILEOBJ), OBJ_ENHMETAFILE, (HGDIOBJ *)&hmf, NULL );
if (metaObj)
{
metaObj->emh = emh;
metaObj->on_disk = on_disk;
GDI_ReleaseObj( hmf );
}
if (!(metaObj = HeapAlloc( GetProcessHeap(), 0, sizeof(*metaObj) ))) return 0;
metaObj->emh = emh;
metaObj->on_disk = on_disk;
if (!(hmf = alloc_gdi_handle( &metaObj->header, OBJ_ENHMETAFILE, NULL )))
HeapFree( GetProcessHeap(), 0, metaObj );
return hmf;
}
......
......@@ -345,29 +345,17 @@ HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
if (!plf) return 0;
if (!(fontPtr = GDI_AllocObject( sizeof(FONTOBJ), OBJ_FONT, (HGDIOBJ *)&hFont, &font_funcs )))
return 0;
if (!(fontPtr = HeapAlloc( GetProcessHeap(), 0, sizeof(*fontPtr) ))) return 0;
fontPtr->logfont = *plf;
TRACE("(%d %d %d %d %x %d %x %d %d) %s %s %s %s => %p\n",
plf->lfHeight, plf->lfWidth,
plf->lfEscapement, plf->lfOrientation,
plf->lfPitchAndFamily,
plf->lfOutPrecision, plf->lfClipPrecision,
plf->lfQuality, plf->lfCharSet,
debugstr_w(plf->lfFaceName),
plf->lfWeight > 400 ? "Bold" : "",
plf->lfItalic ? "Italic" : "",
plf->lfUnderline ? "Underline" : "", hFont);
if (plf->lfEscapement != plf->lfOrientation)
{
/* this should really depend on whether GM_ADVANCED is set */
fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
WARN("orientation angle %f set to "
"escapement angle %f for new font %p\n",
plf->lfOrientation/10., plf->lfEscapement/10., hFont);
plf->lfOrientation/10., plf->lfEscapement/10., fontPtr);
}
pFaceNameItalicSuffix = strstrW(fontPtr->logfont.lfFaceName, ItalicW);
......@@ -388,7 +376,23 @@ HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
if (pFaceNameSuffix) *pFaceNameSuffix = 0;
GDI_ReleaseObj( hFont );
if (!(hFont = alloc_gdi_handle( &fontPtr->header, OBJ_FONT, &font_funcs )))
{
HeapFree( GetProcessHeap(), 0, fontPtr );
return 0;
}
TRACE("(%d %d %d %d %x %d %x %d %d) %s %s %s %s => %p\n",
plf->lfHeight, plf->lfWidth,
plf->lfEscapement, plf->lfOrientation,
plf->lfPitchAndFamily,
plf->lfOutPrecision, plf->lfClipPrecision,
plf->lfQuality, plf->lfCharSet,
debugstr_w(plf->lfFaceName),
plf->lfWeight > 400 ? "Bold" : "",
plf->lfItalic ? "Italic" : "",
plf->lfUnderline ? "Underline" : "", hFont);
return hFont;
}
......
......@@ -437,7 +437,7 @@ extern BOOL WineEngRemoveFontResourceEx(LPCWSTR, DWORD, PVOID) DECLSPEC_HIDDEN;
/* gdiobj.c */
extern BOOL GDI_Init(void) DECLSPEC_HIDDEN;
extern void *GDI_AllocObject( WORD, WORD, HGDIOBJ *, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN;
extern HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN;
extern void *GDI_ReallocObject( WORD, HGDIOBJ, void *obj ) DECLSPEC_HIDDEN;
extern BOOL GDI_FreeObject( HGDIOBJ, void *obj ) DECLSPEC_HIDDEN;
extern void *GDI_GetObjPtr( HGDIOBJ, WORD ) DECLSPEC_HIDDEN;
......
......@@ -630,56 +630,34 @@ static GDIOBJHDR *large_handles[MAX_LARGE_HANDLES];
static int next_large_handle;
/***********************************************************************
* alloc_large_heap
* alloc_gdi_handle
*
* Allocate a GDI handle from the large heap. Helper for GDI_AllocObject
* Allocate a GDI handle for an object, which must have been allocated on the process heap.
*/
static inline GDIOBJHDR *alloc_large_heap( WORD size, HGDIOBJ *handle )
HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs *funcs )
{
int i;
GDIOBJHDR *obj;
for (i = next_large_handle + 1; i < MAX_LARGE_HANDLES; i++)
if (!large_handles[i]) goto found;
for (i = 0; i <= next_large_handle; i++)
if (!large_handles[i]) goto found;
*handle = 0;
return NULL;
found:
if ((obj = HeapAlloc( GetProcessHeap(), 0, size )))
{
large_handles[i] = obj;
*handle = (HGDIOBJ)(ULONG_PTR)((i + FIRST_LARGE_HANDLE) << 2);
next_large_handle = i;
}
return obj;
}
/***********************************************************************
* GDI_AllocObject
*/
void *GDI_AllocObject( WORD size, WORD type, HGDIOBJ *handle, const struct gdi_obj_funcs *funcs )
{
GDIOBJHDR *obj = NULL;
_EnterSysLevel( &GDI_level );
if (!(obj = alloc_large_heap( size, handle ))) goto error;
/* initialize the object header */
obj->type = type;
obj->system = 0;
obj->dwCount = 0;
obj->funcs = funcs;
obj->hdcs = NULL;
TRACE("(%p): enter %d\n", *handle, GDI_level.crst.RecursionCount);
return obj;
_EnterSysLevel( &GDI_level );
for (i = next_large_handle + 1; i < MAX_LARGE_HANDLES; i++)
if (!large_handles[i]) goto found;
for (i = 0; i <= next_large_handle; i++)
if (!large_handles[i]) goto found;
_LeaveSysLevel( &GDI_level );
return 0;
error:
found:
large_handles[i] = obj;
next_large_handle = i;
_LeaveSysLevel( &GDI_level );
*handle = 0;
return NULL;
return (HGDIOBJ)(ULONG_PTR)((i + FIRST_LARGE_HANDLE) << 2);
}
......
......@@ -107,13 +107,13 @@ static int MF_AddHandle(HANDLETABLE *ht, UINT htlen, HGDIOBJ hobj)
*/
HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh)
{
HMETAFILE hmf = 0;
METAFILEOBJ *metaObj = GDI_AllocObject( sizeof(METAFILEOBJ), OBJ_METAFILE, (HGDIOBJ *)&hmf, NULL );
if (metaObj)
{
metaObj->mh = mh;
GDI_ReleaseObj( hmf );
}
HMETAFILE hmf;
METAFILEOBJ *metaObj;
if (!(metaObj = HeapAlloc( GetProcessHeap(), 0, sizeof(*metaObj) ))) return 0;
metaObj->mh = mh;
if (!(hmf = alloc_gdi_handle( &metaObj->header, OBJ_METAFILE, NULL )))
HeapFree( GetProcessHeap(), 0, metaObj );
return hmf;
}
......
......@@ -149,11 +149,14 @@ HPALETTE WINAPI CreatePalette(
size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
if (!(palettePtr = GDI_AllocObject( size + sizeof(int*) +sizeof(GDIOBJHDR),
OBJ_PAL, (HGDIOBJ *)&hpalette, &palette_funcs ))) return 0;
if (!(palettePtr = HeapAlloc( GetProcessHeap(), 0,
FIELD_OFFSET( PALETTEOBJ, logpalette.palPalEntry[palette->palNumEntries] ))))
return 0;
memcpy( &palettePtr->logpalette, palette, size );
palettePtr->funcs = NULL;
GDI_ReleaseObj( hpalette );
if (!(hpalette = alloc_gdi_handle( &palettePtr->header, OBJ_PAL, &palette_funcs )))
HeapFree( GetProcessHeap(), 0, palettePtr );
TRACE(" returning %p\n", hpalette);
return hpalette;
......
......@@ -87,7 +87,8 @@ HPEN WINAPI CreatePenIndirect( const LOGPEN * pen )
if (hpen) return hpen;
}
if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ), OBJ_PEN, (HGDIOBJ *)&hpen, &pen_funcs ))) return 0;
if (!(penPtr = HeapAlloc( GetProcessHeap(), 0, sizeof(*penPtr) ))) return 0;
if (pen->lopnStyle == PS_USERSTYLE || pen->lopnStyle == PS_ALTERNATE)
penPtr->logpen.elpPenStyle = PS_SOLID;
else
......@@ -107,7 +108,8 @@ HPEN WINAPI CreatePenIndirect( const LOGPEN * pen )
penPtr->logpen.elpNumEntries = 0;
penPtr->logpen.elpStyleEntry[0] = 0;
GDI_ReleaseObj( hpen );
if (!(hpen = alloc_gdi_handle( &penPtr->header, OBJ_PEN, &pen_funcs )))
HeapFree( GetProcessHeap(), 0, penPtr );
return hpen;
}
......@@ -196,9 +198,8 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width,
}
}
if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ) +
style_count * sizeof(DWORD) - sizeof(penPtr->logpen.elpStyleEntry),
OBJ_EXTPEN, (HGDIOBJ *)&hpen, &pen_funcs ))) return 0;
if (!(penPtr = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(PENOBJ,logpen.elpStyleEntry[style_count]))))
return 0;
penPtr->logpen.elpPenStyle = style;
penPtr->logpen.elpWidth = abs(width);
......@@ -207,13 +208,12 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width,
penPtr->logpen.elpHatch = brush->lbHatch;
penPtr->logpen.elpNumEntries = style_count;
memcpy(penPtr->logpen.elpStyleEntry, style_bits, style_count * sizeof(DWORD));
GDI_ReleaseObj( hpen );
if (!(hpen = alloc_gdi_handle( &penPtr->header, OBJ_EXTPEN, &pen_funcs )))
HeapFree( GetProcessHeap(), 0, penPtr );
return hpen;
}
/***********************************************************************
* PEN_SelectObject
*/
......
......@@ -513,12 +513,18 @@ static HRGN REGION_CreateRegion( INT n )
HRGN hrgn;
RGNOBJ *obj;
if(!(obj = GDI_AllocObject( sizeof(RGNOBJ), OBJ_REGION, (HGDIOBJ *)&hrgn, &region_funcs ))) return 0;
if(!(obj->rgn = REGION_AllocWineRegion(n))) {
GDI_FreeObject( hrgn, obj );
if (!(obj = HeapAlloc( GetProcessHeap(), 0, sizeof(*obj) ))) return 0;
if (!(obj->rgn = REGION_AllocWineRegion(n)))
{
HeapFree( GetProcessHeap(), 0, obj );
return 0;
}
GDI_ReleaseObj( hrgn );
if (!(hrgn = alloc_gdi_handle( &obj->header, OBJ_REGION, &region_funcs )))
{
HeapFree( GetProcessHeap(), 0, obj->rgn->rects );
HeapFree( GetProcessHeap(), 0, obj->rgn );
HeapFree( GetProcessHeap(), 0, obj );
}
return hrgn;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment