From cf3cafdc18d1f839f67e0237cfbb608944746b1d Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 17 Oct 2012 12:43:23 +0200 Subject: [PATCH] gdi32: Store the object function table directly in the GDI handle table. --- dlls/gdi32/gdi_private.h | 1 - dlls/gdi32/gdiobj.c | 133 ++++++++++++++++++--------------------- 2 files changed, 60 insertions(+), 74 deletions(-) diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 9c926d420eb..36566b152e8 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -68,7 +68,6 @@ typedef struct tagGDIOBJHDR 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 */ - const struct gdi_obj_funcs *funcs; struct hdc_list *hdcs; } GDIOBJHDR; diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index 0cd182a8665..2e32de92513 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -44,6 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi); struct gdi_handle_entry { GDIOBJHDR *obj; /* pointer to the object-specific data */ + const struct gdi_obj_funcs *funcs; /* type-specific functions */ WORD type; /* object type (one of the OBJ_* constants) */ }; @@ -682,7 +683,6 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs obj->system = 0; obj->deleted = 0; obj->selcount = 0; - obj->funcs = funcs; obj->hdcs = NULL; EnterCriticalSection( &gdi_section ); @@ -699,6 +699,7 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs found: entry = &gdi_handles[i]; entry->obj = obj; + entry->funcs = funcs; entry->type = type; next_gdi_handle = i; ret = entry_to_handle( entry ); @@ -728,11 +729,6 @@ void *free_gdi_handle( HGDIOBJ handle ) entry->type = 0; } LeaveCriticalSection( &gdi_section ); - - if (object) - { - object->funcs = NULL; - } return object; } @@ -805,60 +801,59 @@ void GDI_CheckNotLock(void) */ BOOL WINAPI DeleteObject( HGDIOBJ obj ) { - /* Check if object is valid */ - + struct gdi_handle_entry *entry; struct hdc_list *hdcs_head; const struct gdi_obj_funcs *funcs; - GDIOBJHDR * header; - if (HIWORD(obj)) return FALSE; + EnterCriticalSection( &gdi_section ); + if (!(entry = handle_entry( obj ))) + { + LeaveCriticalSection( &gdi_section ); + return FALSE; + } - if (!(header = GDI_GetObjPtr( obj, 0 ))) return FALSE; - - if (header->system) + if (entry->obj->system) { TRACE("Preserving system object %p\n", obj); - GDI_ReleaseObj( obj ); + LeaveCriticalSection( &gdi_section ); return TRUE; } - while ((hdcs_head = header->hdcs) != NULL) + while ((hdcs_head = entry->obj->hdcs) != NULL) { DC *dc = get_dc_ptr(hdcs_head->hdc); - header->hdcs = hdcs_head->next; + entry->obj->hdcs = hdcs_head->next; TRACE("hdc %p has interest in %p\n", hdcs_head->hdc, obj); if(dc) { PHYSDEV physdev = GET_DC_PHYSDEV( dc, pDeleteObject ); - GDI_ReleaseObj( obj ); /* release the GDI lock */ + LeaveCriticalSection( &gdi_section ); physdev->funcs->pDeleteObject( physdev, obj ); - header = GDI_GetObjPtr( obj, 0 ); /* and grab it again */ + EnterCriticalSection( &gdi_section ); /* and grab it again */ + entry = handle_entry( obj ); release_dc_ptr( dc ); } HeapFree(GetProcessHeap(), 0, hdcs_head); - if (!header) return FALSE; + if (!entry) return FALSE; } - if (header->selcount) + if (entry->obj->selcount) { - TRACE("delayed for %p because object in use, count %u\n", obj, header->selcount ); - header->deleted = 1; /* mark for delete */ - GDI_ReleaseObj( obj ); + TRACE("delayed for %p because object in use, count %u\n", obj, entry->obj->selcount ); + entry->obj->deleted = 1; /* mark for delete */ + LeaveCriticalSection( &gdi_section ); return TRUE; } + funcs = entry->funcs; + LeaveCriticalSection( &gdi_section ); + TRACE("%p\n", obj ); - /* Delete object */ - - funcs = header->funcs; - GDI_ReleaseObj( obj ); - if (funcs && funcs->pDeleteObject) - return funcs->pDeleteObject( obj ); - else - return FALSE; + if (funcs && funcs->pDeleteObject) return funcs->pDeleteObject( obj ); + return FALSE; } /*********************************************************************** @@ -950,26 +945,25 @@ HGDIOBJ WINAPI GetStockObject( INT obj ) */ INT WINAPI GetObjectA( HGDIOBJ handle, INT count, LPVOID buffer ) { - const struct gdi_obj_funcs *funcs; - GDIOBJHDR * ptr; + struct gdi_handle_entry *entry; + const struct gdi_obj_funcs *funcs = NULL; INT result = 0; TRACE("%p %d %p\n", handle, count, buffer ); - if (!(ptr = GDI_GetObjPtr( handle, 0 ))) return 0; - funcs = ptr->funcs; - GDI_ReleaseObj( handle ); + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( handle ))) funcs = entry->funcs; + LeaveCriticalSection( &gdi_section ); - if (funcs && funcs->pGetObjectA) + if (funcs) { - if (buffer && ((ULONG_PTR)buffer >> 16) == 0) /* catch apps getting argument order wrong */ + if (!funcs->pGetObjectA) + SetLastError( ERROR_INVALID_HANDLE ); + else if (buffer && ((ULONG_PTR)buffer >> 16) == 0) /* catch apps getting argument order wrong */ SetLastError( ERROR_NOACCESS ); else result = funcs->pGetObjectA( handle, count, buffer ); } - else - SetLastError( ERROR_INVALID_HANDLE ); - return result; } @@ -978,25 +972,25 @@ INT WINAPI GetObjectA( HGDIOBJ handle, INT count, LPVOID buffer ) */ INT WINAPI GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer ) { - const struct gdi_obj_funcs *funcs; - GDIOBJHDR * ptr; + struct gdi_handle_entry *entry; + const struct gdi_obj_funcs *funcs = NULL; INT result = 0; + TRACE("%p %d %p\n", handle, count, buffer ); - if (!(ptr = GDI_GetObjPtr( handle, 0 ))) return 0; - funcs = ptr->funcs; - GDI_ReleaseObj( handle ); + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( handle ))) funcs = entry->funcs; + LeaveCriticalSection( &gdi_section ); - if (funcs && funcs->pGetObjectW) + if (funcs) { - if (buffer && ((ULONG_PTR)buffer >> 16) == 0) /* catch apps getting argument order wrong */ + if (!funcs->pGetObjectW) + SetLastError( ERROR_INVALID_HANDLE ); + else if (buffer && ((ULONG_PTR)buffer >> 16) == 0) /* catch apps getting argument order wrong */ SetLastError( ERROR_NOACCESS ); else result = funcs->pGetObjectW( handle, count, buffer ); } - else - SetLastError( ERROR_INVALID_HANDLE ); - return result; } @@ -1083,19 +1077,17 @@ HGDIOBJ WINAPI GetCurrentObject(HDC hdc,UINT type) */ HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ hObj ) { - HGDIOBJ ret = 0; - GDIOBJHDR *header; + struct gdi_handle_entry *entry; + const struct gdi_obj_funcs *funcs = NULL; TRACE( "(%p,%p)\n", hdc, hObj ); - header = GDI_GetObjPtr( hObj, 0 ); - if (header) - { - const struct gdi_obj_funcs *funcs = header->funcs; - GDI_ReleaseObj( hObj ); - if (funcs && funcs->pSelectObject) ret = funcs->pSelectObject( hObj, hdc ); - } - return ret; + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( hObj ))) funcs = entry->funcs; + LeaveCriticalSection( &gdi_section ); + + if (funcs && funcs->pSelectObject) return funcs->pSelectObject( hObj, hdc ); + return 0; } @@ -1104,20 +1096,15 @@ HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ hObj ) */ BOOL WINAPI UnrealizeObject( HGDIOBJ obj ) { - BOOL result = FALSE; - GDIOBJHDR * header = GDI_GetObjPtr( obj, 0 ); + struct gdi_handle_entry *entry; + const struct gdi_obj_funcs *funcs = NULL; - if (header) - { - const struct gdi_obj_funcs *funcs = header->funcs; + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( obj ))) funcs = entry->funcs; + LeaveCriticalSection( &gdi_section ); - GDI_ReleaseObj( obj ); - if (funcs && funcs->pUnrealizeObject) - result = header->funcs->pUnrealizeObject( obj ); - else - result = TRUE; - } - return result; + if (funcs && funcs->pUnrealizeObject) return funcs->pUnrealizeObject( obj ); + return funcs != NULL; }