Alexandre Julliard : gdi32: Store the object function table 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: cf3cafdc18d1f839f67e0237cfbb608944746b1d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=cf3cafdc18d1f839f67e0237cfbb608944746b1d
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Oct 17 12:43:23 2012 +0200
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 9c926d4..36566b1 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 0cd182a..2e32de9 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;
- if (!(header = GDI_GetObjPtr( obj, 0 ))) return FALSE;
+ EnterCriticalSection( &gdi_section );
+ if (!(entry = handle_entry( obj )))
+ {
+ LeaveCriticalSection( &gdi_section );
+ 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;
}
- TRACE("%p\n", obj );
+ funcs = entry->funcs;
+ LeaveCriticalSection( &gdi_section );
- /* Delete object */
+ TRACE("%p\n", obj );
- 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;
}
More information about the wine-cvs
mailing list