Commit 2bdf4477 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Store the object type directly in the GDI handle table.

parent 3c058185
......@@ -55,16 +55,18 @@ static inline DC *get_dc_obj( HDC hdc )
DC *dc = GDI_GetObjPtr( hdc, 0 );
if (!dc) return NULL;
if ((dc->header.type != OBJ_DC) &&
(dc->header.type != OBJ_MEMDC) &&
(dc->header.type != OBJ_METADC) &&
(dc->header.type != OBJ_ENHMETADC))
switch (GetObjectType( hdc ))
{
case OBJ_DC:
case OBJ_MEMDC:
case OBJ_METADC:
case OBJ_ENHMETADC:
return dc;
default:
GDI_ReleaseObj( hdc );
SetLastError( ERROR_INVALID_HANDLE );
dc = NULL;
return NULL;
}
return dc;
}
......
......@@ -435,7 +435,7 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
TRACE("(%p)\n", hdc );
if (!(dc = get_dc_ptr( hdc ))) return NULL;
if (dc->header.type != OBJ_ENHMETADC)
if (GetObjectType( hdc ) != OBJ_ENHMETADC)
{
release_dc_ptr( dc );
return NULL;
......
......@@ -65,7 +65,6 @@ struct hdc_list
typedef struct tagGDIOBJHDR
{
WORD type; /* object type (one of the OBJ_* constants) */
WORD system : 1; /* system object flag */
WORD deleted : 1; /* whether DeleteObject has been called on this object */
DWORD selcount; /* number of times the object is selected in a DC */
......
......@@ -38,12 +38,34 @@
WINE_DEFAULT_DEBUG_CHANNEL(gdi);
#define HGDIOBJ_32(h16) ((HGDIOBJ)(ULONG_PTR)(h16))
#define FIRST_GDI_HANDLE 16
#define MAX_GDI_HANDLES 16384
#define GDI_HEAP_SIZE 0xffe0
struct gdi_handle_entry
{
GDIOBJHDR *obj; /* pointer to the object-specific data */
WORD type; /* object type (one of the OBJ_* constants) */
};
static struct gdi_handle_entry gdi_handles[MAX_GDI_HANDLES];
static int next_gdi_handle;
static LONG debug_count;
HMODULE gdi32_module = 0;
static inline HGDIOBJ entry_to_handle( struct gdi_handle_entry *entry )
{
unsigned int idx = entry - gdi_handles + FIRST_GDI_HANDLE;
return ULongToHandle( idx << 2 );
}
static inline struct gdi_handle_entry *handle_entry( HGDIOBJ handle )
{
unsigned int idx = (HandleToULong(handle) >> 2) - FIRST_GDI_HANDLE;
if (idx < MAX_GDI_HANDLES && gdi_handles[idx].type) return &gdi_handles[idx];
return NULL;
}
/***********************************************************************
* GDI stock objects
*/
......@@ -600,22 +622,6 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
return TRUE;
}
#define FIRST_GDI_HANDLE 16
#define MAX_GDI_HANDLES ((GDI_HEAP_SIZE >> 2) - FIRST_GDI_HANDLE)
static GDIOBJHDR *gdi_handles[MAX_GDI_HANDLES];
static int next_gdi_handle;
static LONG debug_count;
static inline HGDIOBJ index_to_handle( int index )
{
return ULongToHandle( (index + FIRST_GDI_HANDLE) << 2);
}
static inline int handle_to_index( HGDIOBJ handle )
{
return (HandleToULong(handle) >> 2) - FIRST_GDI_HANDLE;
}
static const char *gdi_obj_type( unsigned type )
{
switch ( type )
......@@ -640,21 +646,21 @@ static const char *gdi_obj_type( unsigned type )
static void dump_gdi_objects( void )
{
int i;
struct gdi_handle_entry *entry;
TRACE( "%u objects:\n", MAX_GDI_HANDLES );
EnterCriticalSection( &gdi_section );
for (i = 0; i < MAX_GDI_HANDLES; i++)
for (entry = gdi_handles; entry < gdi_handles + MAX_GDI_HANDLES; entry++)
{
if (!gdi_handles[i])
if (!entry->type)
{
TRACE( "index %d handle %p FREE\n", i, index_to_handle( i ));
TRACE( "handle %p FREE\n", entry_to_handle( entry ));
continue;
}
TRACE( "handle %p obj %p type %s selcount %u deleted %u\n",
index_to_handle( i ), gdi_handles[i], gdi_obj_type( gdi_handles[i]->type ),
gdi_handles[i]->selcount, gdi_handles[i]->deleted );
entry_to_handle( entry ), entry->obj, gdi_obj_type( entry->type ),
entry->obj->selcount, entry->obj->deleted );
}
LeaveCriticalSection( &gdi_section );
}
......@@ -666,10 +672,13 @@ static void dump_gdi_objects( void )
*/
HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs *funcs )
{
struct gdi_handle_entry *entry;
HGDIOBJ ret;
int i;
assert( type ); /* type 0 is reserved to mark free entries */
/* initialize the object header */
obj->type = type;
obj->system = 0;
obj->deleted = 0;
obj->selcount = 0;
......@@ -678,9 +687,9 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs
EnterCriticalSection( &gdi_section );
for (i = next_gdi_handle + 1; i < MAX_GDI_HANDLES; i++)
if (!gdi_handles[i]) goto found;
if (!gdi_handles[i].type) goto found;
for (i = 0; i <= next_gdi_handle; i++)
if (!gdi_handles[i]) goto found;
if (!gdi_handles[i].type) goto found;
LeaveCriticalSection( &gdi_section );
ERR( "out of GDI object handles, expect a crash\n" );
......@@ -688,13 +697,15 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs
return 0;
found:
gdi_handles[i] = obj;
entry = &gdi_handles[i];
entry->obj = obj;
entry->type = type;
next_gdi_handle = i;
ret = entry_to_handle( entry );
LeaveCriticalSection( &gdi_section );
TRACE( "allocated %s %p %u/%u\n",
gdi_obj_type(type), index_to_handle( i ),
TRACE( "allocated %s %p %u/%u\n", gdi_obj_type(type), ret,
InterlockedIncrement( &debug_count ), MAX_GDI_HANDLES );
return index_to_handle( i );
return ret;
}
......@@ -706,20 +717,20 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs
void *free_gdi_handle( HGDIOBJ handle )
{
GDIOBJHDR *object = NULL;
int i = handle_to_index( handle );
struct gdi_handle_entry *entry;
if (i >= 0 && i < MAX_GDI_HANDLES)
EnterCriticalSection( &gdi_section );
if ((entry = handle_entry( handle )))
{
EnterCriticalSection( &gdi_section );
object = gdi_handles[i];
gdi_handles[i] = NULL;
LeaveCriticalSection( &gdi_section );
TRACE( "freed %s %p %u/%u\n", gdi_obj_type( entry->type ), handle,
InterlockedDecrement( &debug_count ) + 1, MAX_GDI_HANDLES );
object = entry->obj;
entry->type = 0;
}
LeaveCriticalSection( &gdi_section );
if (object)
{
TRACE( "freed %s %p %u/%u\n", gdi_obj_type( object->type ), handle,
InterlockedDecrement( &debug_count ) + 1, MAX_GDI_HANDLES );
object->type = 0; /* mark it as invalid */
object->funcs = NULL;
}
return object;
......@@ -736,14 +747,13 @@ void *free_gdi_handle( HGDIOBJ handle )
void *GDI_GetObjPtr( HGDIOBJ handle, WORD type )
{
GDIOBJHDR *ptr = NULL;
int i = handle_to_index( handle );
struct gdi_handle_entry *entry;
EnterCriticalSection( &gdi_section );
if (i >= 0 && i < MAX_GDI_HANDLES)
if ((entry = handle_entry( handle )))
{
ptr = gdi_handles[i];
if (ptr && type && ptr->type != type) ptr = NULL;
if (!type || entry->type == type) ptr = entry->obj;
}
if (!ptr)
......@@ -995,17 +1005,15 @@ INT WINAPI GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer )
*/
DWORD WINAPI GetObjectType( HGDIOBJ handle )
{
GDIOBJHDR * ptr;
DWORD result;
struct gdi_handle_entry *entry;
DWORD result = 0;
EnterCriticalSection( &gdi_section );
if ((entry = handle_entry( handle ))) result = entry->type;
LeaveCriticalSection( &gdi_section );
if (!(ptr = GDI_GetObjPtr( handle, 0 )))
{
SetLastError( ERROR_INVALID_HANDLE );
return 0;
}
result = ptr->type;
GDI_ReleaseObj( handle );
TRACE("%p -> %u\n", handle, result );
if (!result) SetLastError( ERROR_INVALID_HANDLE );
return result;
}
......
......@@ -390,7 +390,7 @@ static DC *MFDRV_CloseMetaFile( HDC hdc )
TRACE("(%p)\n", hdc );
if (!(dc = get_dc_ptr( hdc ))) return NULL;
if (dc->header.type != OBJ_METADC)
if (GetObjectType( hdc ) != OBJ_METADC)
{
release_dc_ptr( dc );
return NULL;
......
......@@ -236,7 +236,7 @@ static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc )
struct brush_pattern *pattern;
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSelectPen );
switch (pen->header.type)
switch (GetObjectType( handle ))
{
case OBJ_PEN:
pattern = NULL;
......@@ -293,7 +293,7 @@ static INT PEN_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
if (!pen) return 0;
switch (pen->header.type)
switch (GetObjectType( handle ))
{
case OBJ_PEN:
{
......
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