Alexandre Julliard : gdi32: Store the object type directly in the GDI handle table.
Alexandre Julliard
julliard at winehq.org
Wed Oct 17 14:32:28 CDT 2012
Module: wine
Branch: master
Commit: 2bdf447744b3d380ed266e7627976612ec58ffe2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2bdf447744b3d380ed266e7627976612ec58ffe2
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Oct 17 12:25:28 2012 +0200
gdi32: Store the object type directly in the GDI handle table.
---
dlls/gdi32/dc.c | 14 +++--
dlls/gdi32/enhmfdrv/init.c | 2 +-
dlls/gdi32/gdi_private.h | 1 -
dlls/gdi32/gdiobj.c | 114 +++++++++++++++++++++++--------------------
dlls/gdi32/mfdrv/init.c | 2 +-
dlls/gdi32/pen.c | 4 +-
6 files changed, 73 insertions(+), 64 deletions(-)
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index 1f089de..5a68aa6 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -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;
}
diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c
index bd4c906..57a4d18 100644
--- a/dlls/gdi32/enhmfdrv/init.c
+++ b/dlls/gdi32/enhmfdrv/init.c
@@ -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;
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 5b79526..9c926d4 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -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 */
diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c
index 9da5533..0cd182a 100644
--- a/dlls/gdi32/gdiobj.c
+++ b/dlls/gdi32/gdiobj.c
@@ -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;
}
diff --git a/dlls/gdi32/mfdrv/init.c b/dlls/gdi32/mfdrv/init.c
index f75637c..03cd22c 100644
--- a/dlls/gdi32/mfdrv/init.c
+++ b/dlls/gdi32/mfdrv/init.c
@@ -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;
diff --git a/dlls/gdi32/pen.c b/dlls/gdi32/pen.c
index 6695ee9..94c3933 100644
--- a/dlls/gdi32/pen.c
+++ b/dlls/gdi32/pen.c
@@ -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:
{
More information about the wine-cvs
mailing list