gdi32: Introduce gdi_obj_header and use it to store gdi_obj_funcs.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-06-30 17:36:19 +02:00 committed by Alexandre Julliard
parent 02268cb290
commit a96fcf21b0
12 changed files with 79 additions and 49 deletions

View File

@ -222,7 +222,7 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
return 0;
}
if (!(hbitmap = alloc_gdi_handle( bmpobj, OBJ_BITMAP, &bitmap_funcs )))
if (!(hbitmap = alloc_gdi_handle( &bmpobj->obj, OBJ_BITMAP, &bitmap_funcs )))
{
HeapFree( GetProcessHeap(), 0, bmpobj->dib.dsBm.bmBits );
HeapFree( GetProcessHeap(), 0, bmpobj );

View File

@ -32,6 +32,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi);
/* GDI logical brush object */
typedef struct
{
struct gdi_obj_header obj;
LOGBRUSH logbrush;
struct brush_pattern pattern;
} BRUSHOBJ;
@ -198,7 +199,7 @@ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
ptr->logbrush = *brush;
if (store_brush_pattern( &ptr->logbrush, &ptr->pattern ) &&
(hbrush = alloc_gdi_handle( ptr, OBJ_BRUSH, &brush_funcs )))
(hbrush = alloc_gdi_handle( &ptr->obj, OBJ_BRUSH, &brush_funcs )))
{
TRACE("%p\n", hbrush);
return hbrush;

View File

@ -137,7 +137,7 @@ DC *alloc_dc_ptr( WORD magic )
set_initial_dc_state( dc );
if (!(dc->hSelf = alloc_gdi_handle( dc, magic, &dc_funcs )))
if (!(dc->hSelf = alloc_gdi_handle( &dc->obj, magic, &dc_funcs )))
{
HeapFree( GetProcessHeap(), 0, dc );
return NULL;

View File

@ -1572,7 +1572,7 @@ HBITMAP WINAPI DECLSPEC_HOTPATCH CreateDIBSection(HDC hdc, const BITMAPINFO *bmi
if (!bmp->dib.dsBm.bmBits) goto error;
if (!(ret = alloc_gdi_handle( bmp, OBJ_BITMAP, &dib_funcs ))) goto error;
if (!(ret = alloc_gdi_handle( &bmp->obj, OBJ_BITMAP, &dib_funcs ))) goto error;
if (bits) *bits = bmp->dib.dsBm.bmBits;
return ret;
@ -1684,7 +1684,7 @@ NTSTATUS WINAPI D3DKMTCreateDCFromMemory( D3DKMT_CREATEDCFROMMEMORY *desc )
}
}
if (!(bitmap = alloc_gdi_handle( bmp, OBJ_BITMAP, &dib_funcs ))) goto error;
if (!(bitmap = alloc_gdi_handle( &bmp->obj, OBJ_BITMAP, &dib_funcs ))) goto error;
desc->hDc = dc;
desc->hBitmap = bitmap;

View File

@ -47,8 +47,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
typedef struct
{
ENHMETAHEADER *emh;
BOOL on_disk; /* true if metafile is on disk */
struct gdi_obj_header obj;
ENHMETAHEADER *emh;
BOOL on_disk; /* true if metafile is on disk */
} ENHMETAFILEOBJ;
static const struct emr_name {
@ -276,7 +277,7 @@ HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, DWORD filesize, BOOL on
metaObj->emh = emh;
metaObj->on_disk = on_disk;
if (!(hmf = alloc_gdi_handle( metaObj, OBJ_ENHMETAFILE, NULL )))
if (!(hmf = alloc_gdi_handle( &metaObj->obj, OBJ_ENHMETAFILE, NULL )))
HeapFree( GetProcessHeap(), 0, metaObj );
return hmf;
}

View File

@ -196,7 +196,8 @@ static const struct gdi_obj_funcs fontobj_funcs =
typedef struct
{
LOGFONTW logfont;
struct gdi_obj_header obj;
LOGFONTW logfont;
} FONTOBJ;
struct font_enum
@ -4321,7 +4322,7 @@ HFONT WINAPI CreateFontIndirectExW( const ENUMLOGFONTEXDVW *penumex )
fontPtr->logfont = *plf;
if (!(hFont = alloc_gdi_handle( fontPtr, OBJ_FONT, &fontobj_funcs )))
if (!(hFont = alloc_gdi_handle( &fontPtr->obj, OBJ_FONT, &fontobj_funcs )))
{
HeapFree( GetProcessHeap(), 0, fontPtr );
return 0;

View File

@ -57,8 +57,14 @@ struct gdi_obj_funcs
BOOL (*pDeleteObject)( HGDIOBJ handle );
};
struct gdi_obj_header
{
const struct gdi_obj_funcs *funcs; /* type-specific functions */
};
typedef struct tagDC
{
struct gdi_obj_header obj; /* object header */
HDC hSelf; /* Handle to this DC */
struct gdi_physdev nulldrv; /* physdev for the null driver */
PHYSDEV physDev; /* current top of the physdev stack */
@ -169,9 +175,10 @@ static inline PHYSDEV find_dc_driver( DC *dc, const struct gdi_dc_funcs *funcs )
typedef struct tagBITMAPOBJ
{
DIBSECTION dib;
SIZE size; /* For SetBitmapDimension() */
RGBQUAD *color_table; /* DIB color table if <= 8bpp (always 1 << bpp in size) */
struct gdi_obj_header obj;
DIBSECTION dib;
SIZE size; /* For SetBitmapDimension() */
RGBQUAD *color_table; /* DIB color table if <= 8bpp (always 1 << bpp in size) */
} BITMAPOBJ;
static inline BOOL is_bitmapobj_dib( const BITMAPOBJ *bmp )
@ -443,7 +450,8 @@ extern BOOL opentype_get_properties( const void *data, size_t size, const struct
DWORD *version, FONTSIGNATURE *fs, DWORD *ntm_flags ) DECLSPEC_HIDDEN;
/* gdiobj.c */
extern HGDIOBJ alloc_gdi_handle( void *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN;
extern HGDIOBJ alloc_gdi_handle( struct gdi_obj_header *obj, WORD type,
const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN;
extern void *free_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN;
extern HGDIOBJ get_full_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN;
extern void *GDI_GetObjPtr( HGDIOBJ, WORD ) DECLSPEC_HIDDEN;
@ -515,6 +523,7 @@ extern HRGN create_polypolygon_region( const POINT *pts, const INT *count, INT n
#define RGN_DEFAULT_RECTS 4
typedef struct
{
struct gdi_obj_header obj;
INT size;
INT numRects;
RECT *rects;

View File

@ -48,7 +48,6 @@ struct hdc_list
struct gdi_handle_entry
{
void *obj; /* pointer to the object-specific data */
const struct gdi_obj_funcs *funcs; /* type-specific functions */
struct hdc_list *hdcs; /* list of HDCs interested in this object */
WORD generation; /* generation count for reusing handle values */
WORD type; /* object type (one of the OBJ_* constants) */
@ -82,6 +81,11 @@ static inline struct gdi_handle_entry *handle_entry( HGDIOBJ handle )
return NULL;
}
static inline struct gdi_obj_header *entry_obj( struct gdi_handle_entry *entry )
{
return entry->obj;
}
/***********************************************************************
* GDI stock objects
*/
@ -731,7 +735,7 @@ static void dump_gdi_objects( void )
*
* Allocate a GDI handle for an object, which must have been allocated on the process heap.
*/
HGDIOBJ alloc_gdi_handle( void *obj, WORD type, const struct gdi_obj_funcs *funcs )
HGDIOBJ alloc_gdi_handle( struct gdi_obj_header *obj, WORD type, const struct gdi_obj_funcs *funcs )
{
struct gdi_handle_entry *entry;
HGDIOBJ ret;
@ -752,8 +756,8 @@ HGDIOBJ alloc_gdi_handle( void *obj, WORD type, const struct gdi_obj_funcs *func
if (TRACE_ON(gdi)) dump_gdi_objects();
return 0;
}
obj->funcs = funcs;
entry->obj = obj;
entry->funcs = funcs;
entry->hdcs = NULL;
entry->type = type;
entry->selcount = 0;
@ -921,7 +925,7 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj )
TRACE("delayed for %p because object in use, count %u\n", obj, entry->selcount );
entry->deleted = 1; /* mark for delete */
}
else funcs = entry->funcs;
else funcs = entry_obj( entry )->funcs;
LeaveCriticalSection( &gdi_section );
@ -1035,7 +1039,7 @@ INT WINAPI GetObjectA( HGDIOBJ handle, INT count, LPVOID buffer )
EnterCriticalSection( &gdi_section );
if ((entry = handle_entry( handle )))
{
funcs = entry->funcs;
funcs = entry_obj( entry )->funcs;
handle = entry_to_handle( entry ); /* make it a full handle */
}
LeaveCriticalSection( &gdi_section );
@ -1066,7 +1070,7 @@ INT WINAPI GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer )
EnterCriticalSection( &gdi_section );
if ((entry = handle_entry( handle )))
{
funcs = entry->funcs;
funcs = entry_obj( entry )->funcs;
handle = entry_to_handle( entry ); /* make it a full handle */
}
LeaveCriticalSection( &gdi_section );
@ -1174,7 +1178,7 @@ HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ hObj )
EnterCriticalSection( &gdi_section );
if ((entry = handle_entry( hObj )))
{
funcs = entry->funcs;
funcs = entry_obj( entry )->funcs;
hObj = entry_to_handle( entry ); /* make it a full handle */
}
LeaveCriticalSection( &gdi_section );
@ -1195,7 +1199,7 @@ BOOL WINAPI UnrealizeObject( HGDIOBJ obj )
EnterCriticalSection( &gdi_section );
if ((entry = handle_entry( obj )))
{
funcs = entry->funcs;
funcs = entry_obj( entry )->funcs;
obj = entry_to_handle( entry ); /* make it a full handle */
}
LeaveCriticalSection( &gdi_section );

View File

@ -60,6 +60,11 @@
WINE_DEFAULT_DEBUG_CHANNEL(metafile);
struct metafile
{
struct gdi_obj_header obj;
METAHEADER *data;
};
/******************************************************************
* MF_AddHandle
@ -91,7 +96,13 @@ static int MF_AddHandle(HANDLETABLE *ht, UINT htlen, HGDIOBJ hobj)
*/
HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh)
{
return alloc_gdi_handle( mh, OBJ_METAFILE, NULL );
struct metafile *metafile;
if (!(metafile = HeapAlloc(GetProcessHeap(), 0, sizeof(*metafile))))
return NULL;
metafile->data = mh;
return alloc_gdi_handle( &metafile->obj, OBJ_METAFILE, NULL );
}
/******************************************************************
@ -123,10 +134,11 @@ static POINT *convert_points( UINT count, const POINTS *pts )
BOOL WINAPI DeleteMetaFile( HMETAFILE hmf )
{
METAHEADER *mh = free_gdi_handle( hmf );
struct metafile *metafile = free_gdi_handle( hmf );
if (!mh) return FALSE;
HeapFree( GetProcessHeap(), 0, mh );
if (!metafile) return FALSE;
HeapFree( GetProcessHeap(), 0, metafile->data );
HeapFree( GetProcessHeap(), 0, metafile );
return TRUE;
}
@ -225,12 +237,13 @@ HMETAFILE WINAPI GetMetaFileW( LPCWSTR lpFilename )
/* return a copy of the metafile bits, to be freed with HeapFree */
static METAHEADER *get_metafile_bits( HMETAFILE hmf )
{
METAHEADER *ret, *mh = GDI_GetObjPtr( hmf, OBJ_METAFILE );
struct metafile *metafile = GDI_GetObjPtr( hmf, OBJ_METAFILE );
METAHEADER *ret;
if (!mh) return NULL;
if (!metafile) return NULL;
ret = HeapAlloc( GetProcessHeap(), 0, mh->mtSize * 2 );
if (ret) memcpy( ret, mh, mh->mtSize * 2 );
ret = HeapAlloc( GetProcessHeap(), 0, metafile->data->mtSize * 2 );
if (ret) memcpy( ret, metafile->data, metafile->data->mtSize * 2 );
GDI_ReleaseObj( hmf );
return ret;
}
@ -1022,20 +1035,19 @@ HMETAFILE WINAPI SetMetaFileBitsEx( UINT size, const BYTE *lpData )
*/
UINT WINAPI GetMetaFileBitsEx( HMETAFILE hmf, UINT nSize, LPVOID buf )
{
METAHEADER *mh = GDI_GetObjPtr( hmf, OBJ_METAFILE );
struct metafile *metafile = GDI_GetObjPtr( hmf, OBJ_METAFILE );
UINT mfSize;
BOOL mf_copy = FALSE;
TRACE("(%p,%d,%p)\n", hmf, nSize, buf);
if (!mh) return 0; /* FIXME: error code */
mfSize = mh->mtSize * 2;
if (!metafile) return 0; /* FIXME: error code */
mfSize = metafile->data->mtSize * 2;
if (buf)
{
if(mfSize > nSize) mfSize = nSize;
memmove(buf, mh, mfSize);
memmove(buf, metafile->data, mfSize);
}
if (mf_copy) HeapFree( GetProcessHeap(), 0, mh );
GDI_ReleaseObj( hmf );
TRACE("returning size %d\n", mfSize);
return mfSize;

View File

@ -42,10 +42,11 @@ typedef BOOL (CDECL *unrealize_function)(HPALETTE);
typedef struct tagPALETTEOBJ
{
unrealize_function unrealize;
WORD version; /* palette version */
WORD count; /* count of palette entries */
PALETTEENTRY *entries;
struct gdi_obj_header obj;
unrealize_function unrealize;
WORD version; /* palette version */
WORD count; /* count of palette entries */
PALETTEENTRY *entries;
} PALETTEOBJ;
static INT PALETTE_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
@ -129,7 +130,7 @@ HPALETTE WINAPI CreatePalette(
return 0;
}
memcpy( palettePtr->entries, palette->palPalEntry, size );
if (!(hpalette = alloc_gdi_handle( palettePtr, OBJ_PAL, &palette_funcs )))
if (!(hpalette = alloc_gdi_handle( &palettePtr->obj, OBJ_PAL, &palette_funcs )))
{
HeapFree( GetProcessHeap(), 0, palettePtr->entries );
HeapFree( GetProcessHeap(), 0, palettePtr );

View File

@ -34,8 +34,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi);
/* GDI logical pen object */
typedef struct
{
struct brush_pattern pattern;
EXTLOGPEN logpen;
struct gdi_obj_header obj;
struct brush_pattern pattern;
EXTLOGPEN logpen;
} PENOBJ;
@ -110,7 +111,7 @@ HPEN WINAPI CreatePenIndirect( const LOGPEN * pen )
break;
}
if (!(hpen = alloc_gdi_handle( penPtr, OBJ_PEN, &pen_funcs )))
if (!(hpen = alloc_gdi_handle( &penPtr->obj, OBJ_PEN, &pen_funcs )))
HeapFree( GetProcessHeap(), 0, penPtr );
return hpen;
}
@ -200,7 +201,7 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width,
penPtr->logpen.elpNumEntries = style_count;
memcpy(penPtr->logpen.elpStyleEntry, style_bits, style_count * sizeof(DWORD));
if (!(hpen = alloc_gdi_handle( penPtr, OBJ_EXTPEN, &pen_funcs )))
if (!(hpen = alloc_gdi_handle( &penPtr->obj, OBJ_EXTPEN, &pen_funcs )))
{
free_brush_pattern( &penPtr->pattern );
HeapFree( GetProcessHeap(), 0, penPtr );

View File

@ -622,7 +622,7 @@ HRGN WINAPI CreateRectRgn(INT left, INT top, INT right, INT bottom)
if (!(obj = alloc_region( RGN_DEFAULT_RECTS ))) return 0;
if (!(hrgn = alloc_gdi_handle( obj, OBJ_REGION, &region_funcs )))
if (!(hrgn = alloc_gdi_handle( &obj->obj, OBJ_REGION, &region_funcs )))
{
free_region( obj );
return 0;
@ -799,7 +799,7 @@ HRGN WINAPI CreateRoundRectRgn( INT left, INT top,
}
rects[ellipse_height / 2].top = top + ellipse_height / 2; /* extend to top of rectangle */
hrgn = alloc_gdi_handle( obj, OBJ_REGION, &region_funcs );
hrgn = alloc_gdi_handle( &obj->obj, OBJ_REGION, &region_funcs );
TRACE("(%d,%d-%d,%d %dx%d): ret=%p\n",
left, top, right, bottom, ellipse_width, ellipse_height, hrgn );
@ -1006,7 +1006,7 @@ HRGN WINAPI ExtCreateRegion( const XFORM* lpXform, DWORD dwCount, const RGNDATA*
if (!REGION_UnionRectWithRegion( pCurRect, obj )) goto done;
}
}
hrgn = alloc_gdi_handle( obj, OBJ_REGION, &region_funcs );
hrgn = alloc_gdi_handle( &obj->obj, OBJ_REGION, &region_funcs );
done:
if (!hrgn) free_region( obj );
@ -2746,7 +2746,7 @@ HRGN create_polypolygon_region( const POINT *Pts, const INT *Count, INT nbpolygo
{
if (nb_points) scan_convert( obj, &ET, mode, clip_rect );
if (!(hrgn = alloc_gdi_handle( obj, OBJ_REGION, &region_funcs )))
if (!(hrgn = alloc_gdi_handle( &obj->obj, OBJ_REGION, &region_funcs )))
free_region( obj );
}