Alexandre Julliard : gdi32: Store the HDC list 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: 2e693d00c9bc38009d305b04b6425ce7b67ceffd
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2e693d00c9bc38009d305b04b6425ce7b67ceffd

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Oct 17 13:03:18 2012 +0200

gdi32: Store the HDC list directly in the GDI handle table.

---

 dlls/gdi32/gdi_private.h |   11 +-----
 dlls/gdi32/gdiobj.c      |   87 ++++++++++++++++++++-------------------------
 2 files changed, 41 insertions(+), 57 deletions(-)

diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 36566b1..5dadbc2 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -57,18 +57,11 @@ struct gdi_obj_funcs
     BOOL    (*pDeleteObject)( HGDIOBJ handle );
 };
 
-struct hdc_list
-{
-    HDC hdc;
-    struct hdc_list *next;
-};
-
 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 */
-    struct hdc_list *hdcs;
 } GDIOBJHDR;
 
 typedef struct tagGdiFont GdiFont;
@@ -325,8 +318,8 @@ extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN;
 extern void GDI_CheckNotLock(void) DECLSPEC_HIDDEN;
 extern HGDIOBJ GDI_inc_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN;
 extern BOOL GDI_dec_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN;
-extern BOOL GDI_hdc_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN;
-extern BOOL GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN;
+extern void GDI_hdc_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN;
+extern void GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN;
 
 /* metafile.c */
 extern HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh) DECLSPEC_HIDDEN;
diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c
index 2e32de9..750e95b 100644
--- a/dlls/gdi32/gdiobj.c
+++ b/dlls/gdi32/gdiobj.c
@@ -41,10 +41,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi);
 #define FIRST_GDI_HANDLE 16
 #define MAX_GDI_HANDLES  16384
 
+struct hdc_list
+{
+    HDC hdc;
+    struct hdc_list *next;
+};
+
 struct gdi_handle_entry
 {
     GDIOBJHDR                  *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                        type;        /* object type (one of the OBJ_* constants) */
 };
 
@@ -683,7 +690,6 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs
     obj->system   = 0;
     obj->deleted  = 0;
     obj->selcount = 0;
-    obj->hdcs     = NULL;
 
     EnterCriticalSection( &gdi_section );
     for (i = next_gdi_handle + 1; i < MAX_GDI_HANDLES; i++)
@@ -700,6 +706,7 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs
     entry = &gdi_handles[i];
     entry->obj      = obj;
     entry->funcs    = funcs;
+    entry->hdcs     = NULL;
     entry->type     = type;
     next_gdi_handle = i;
     ret = entry_to_handle( entry );
@@ -819,11 +826,11 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj )
 	return TRUE;
     }
 
-    while ((hdcs_head = entry->obj->hdcs) != NULL)
+    while ((hdcs_head = entry->hdcs) != NULL)
     {
         DC *dc = get_dc_ptr(hdcs_head->hdc);
 
-        entry->obj->hdcs = hdcs_head->next;
+        entry->hdcs = hdcs_head->next;
         TRACE("hdc %p has interest in %p\n", hdcs_head->hdc, obj);
 
         if(dc)
@@ -861,70 +868,54 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj )
  *
  * Call this if the dc requires DeleteObject notification
  */
-BOOL GDI_hdc_using_object(HGDIOBJ obj, HDC hdc)
+void GDI_hdc_using_object(HGDIOBJ obj, HDC hdc)
 {
-    GDIOBJHDR * header;
-    struct hdc_list **pphdc;
+    struct gdi_handle_entry *entry;
+    struct hdc_list *phdc;
 
     TRACE("obj %p hdc %p\n", obj, hdc);
 
-    if (!(header = GDI_GetObjPtr( obj, 0 ))) return FALSE;
-
-    if (header->system)
+    EnterCriticalSection( &gdi_section );
+    if ((entry = handle_entry( obj )) && !entry->obj->system)
     {
-        GDI_ReleaseObj(obj);
-        return FALSE;
-    }
-
-    for(pphdc = &header->hdcs; *pphdc; pphdc = &(*pphdc)->next)
-        if((*pphdc)->hdc == hdc)
-            break;
+        for (phdc = entry->hdcs; phdc; phdc = phdc->next)
+            if (phdc->hdc == hdc) break;
 
-    if(!*pphdc) {
-        *pphdc = HeapAlloc(GetProcessHeap(), 0, sizeof(**pphdc));
-        (*pphdc)->hdc = hdc;
-        (*pphdc)->next = NULL;
+        if (!phdc)
+        {
+            phdc = HeapAlloc(GetProcessHeap(), 0, sizeof(*phdc));
+            phdc->hdc = hdc;
+            phdc->next = entry->hdcs;
+            entry->hdcs = phdc;
+        }
     }
-
-    GDI_ReleaseObj(obj);
-    return TRUE;
+    LeaveCriticalSection( &gdi_section );
 }
 
 /***********************************************************************
  *           GDI_hdc_not_using_object
  *
  */
-BOOL GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc)
+void GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc)
 {
-    GDIOBJHDR * header;
-    struct hdc_list *phdc, **prev;
+    struct gdi_handle_entry *entry;
+    struct hdc_list **pphdc;
 
     TRACE("obj %p hdc %p\n", obj, hdc);
 
-    if (!(header = GDI_GetObjPtr( obj, 0 ))) return FALSE;
-
-    if (header->system)
+    EnterCriticalSection( &gdi_section );
+    if ((entry = handle_entry( obj )) && !entry->obj->system)
     {
-        GDI_ReleaseObj(obj);
-        return FALSE;
+        for (pphdc = &entry->hdcs; *pphdc; pphdc = &(*pphdc)->next)
+            if ((*pphdc)->hdc == hdc)
+            {
+                struct hdc_list *phdc = *pphdc;
+                *pphdc = phdc->next;
+                HeapFree(GetProcessHeap(), 0, phdc);
+                break;
+            }
     }
-
-    phdc = header->hdcs;
-    prev = &header->hdcs;
-
-    while(phdc) {
-        if(phdc->hdc == hdc) {
-            *prev = phdc->next;
-            HeapFree(GetProcessHeap(), 0, phdc);
-            phdc = *prev;
-        } else {
-            prev = &phdc->next;
-            phdc = phdc->next;
-        }
-    }
-
-    GDI_ReleaseObj(obj);
-    return TRUE;
+    LeaveCriticalSection( &gdi_section );
 }
 
 /***********************************************************************




More information about the wine-cvs mailing list