Alexandre Julliard : gdi32: Reimplement SaveVisRgn16/ RestoreVisRgn16 to avoid accessing the DC internals.

Alexandre Julliard julliard at winehq.org
Tue Nov 17 09:28:19 CST 2009


Module: wine
Branch: master
Commit: 16da76923d90291b2e6dc24e8e886aeb84f398ab
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=16da76923d90291b2e6dc24e8e886aeb84f398ab

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Nov 17 12:28:44 2009 +0100

gdi32: Reimplement SaveVisRgn16/RestoreVisRgn16 to avoid accessing the DC internals.

---

 dlls/gdi32/dc.c          |   10 -------
 dlls/gdi32/gdi16.c       |   66 ++++++++++++++++++++++++++-------------------
 dlls/gdi32/gdi_private.h |    8 -----
 3 files changed, 38 insertions(+), 46 deletions(-)

diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index f7b295a..fdfc100 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -144,7 +144,6 @@ DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic )
     dc->BoundsRect.top      = 0;
     dc->BoundsRect.right    = 0;
     dc->BoundsRect.bottom   = 0;
-    dc->saved_visrgn        = NULL;
     PATH_InitGdiPath(&dc->path);
 
     if (!(dc->hSelf = alloc_gdi_handle( &dc->header, magic, &dc_funcs )))
@@ -403,7 +402,6 @@ INT save_dc_state( HDC hdc )
 
     newdc->pAbortProc = NULL;
     newdc->hookProc   = NULL;
-    newdc->saved_visrgn = NULL;
 
     if (!(newdc->hSelf = alloc_gdi_handle( &newdc->header, dc->header.type, &dc_funcs )))
     {
@@ -845,14 +843,6 @@ BOOL WINAPI DeleteDC( HDC hdc )
         dc->physDev = NULL;
     }
 
-    while (dc->saved_visrgn)
-    {
-        struct saved_visrgn *next = dc->saved_visrgn->next;
-        DeleteObject( dc->saved_visrgn->hrgn );
-        HeapFree( GetProcessHeap(), 0, dc->saved_visrgn );
-        dc->saved_visrgn = next;
-    }
-
     free_dc_ptr( dc );
     if (funcs) DRIVER_release_driver( funcs );  /* do that after releasing the GDI lock */
     return TRUE;
diff --git a/dlls/gdi32/gdi16.c b/dlls/gdi32/gdi16.c
index bd535d1..0712f40 100644
--- a/dlls/gdi32/gdi16.c
+++ b/dlls/gdi32/gdi16.c
@@ -34,6 +34,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi);
 #define HGDIOBJ_32(handle16)    ((HGDIOBJ)(ULONG_PTR)(handle16))
 #define HGDIOBJ_16(handle32)    ((HGDIOBJ16)(ULONG_PTR)(handle32))
 
+struct saved_visrgn
+{
+    struct list entry;
+    HDC         hdc;
+    HRGN        hrgn;
+};
+
+static struct list saved_regions = LIST_INIT( saved_regions );
+
 /*
  * ############################################################################
  */
@@ -1312,9 +1321,18 @@ BOOL16 WINAPI DeleteDC16( HDC16 hdc )
 {
     if (DeleteDC( HDC_32(hdc) ))
     {
+        struct saved_visrgn *saved, *next;
         struct gdi_thunk* thunk;
-        if ((thunk = GDI_FindThunk(hdc)))
-            GDI_DeleteThunk(thunk);
+
+        if ((thunk = GDI_FindThunk(hdc))) GDI_DeleteThunk(thunk);
+
+        LIST_FOR_EACH_ENTRY_SAFE( saved, next, &saved_regions, struct saved_visrgn, entry )
+        {
+            if (saved->hdc != HDC_32(hdc)) continue;
+            list_remove( &saved->entry );
+            DeleteObject( saved->hrgn );
+            HeapFree( GetProcessHeap(), 0, saved );
+        }
         return TRUE;
     }
     return FALSE;
@@ -3704,24 +3722,19 @@ HRGN16 WINAPI SaveVisRgn16( HDC16 hdc16 )
 {
     struct saved_visrgn *saved;
     HDC hdc = HDC_32( hdc16 );
-    DC *dc = get_dc_ptr( hdc );
 
-    if (!dc) return 0;
     TRACE("%p\n", hdc );
 
-    update_dc( dc );
-    if (!(saved = HeapAlloc( GetProcessHeap(), 0, sizeof(*saved) ))) goto error;
-    if (!(saved->hrgn = CreateRectRgn( 0, 0, 0, 0 ))) goto error;
-    CombineRgn( saved->hrgn, dc->hVisRgn, 0, RGN_COPY );
-    saved->next = dc->saved_visrgn;
-    dc->saved_visrgn = saved;
-    release_dc_ptr( dc );
+    if (!(saved = HeapAlloc( GetProcessHeap(), 0, sizeof(*saved) ))) return 0;
+    if (!(saved->hrgn = CreateRectRgn( 0, 0, 0, 0 )))
+    {
+        HeapFree( GetProcessHeap(), 0, saved );
+        return 0;
+    }
+    saved->hdc = hdc;
+    GetRandomRgn( hdc, saved->hrgn, SYSRGN );
+    list_add_head( &saved_regions, &saved->entry );
     return HRGN_16(saved->hrgn);
-
-error:
-    release_dc_ptr( dc );
-    HeapFree( GetProcessHeap(), 0, saved );
-    return 0;
 }
 
 
@@ -3732,22 +3745,19 @@ INT16 WINAPI RestoreVisRgn16( HDC16 hdc16 )
 {
     struct saved_visrgn *saved;
     HDC hdc = HDC_32( hdc16 );
-    DC *dc = get_dc_ptr( hdc );
     INT16 ret = ERROR;
 
-    if (!dc) return ERROR;
-
     TRACE("%p\n", hdc );
 
-    if (!(saved = dc->saved_visrgn)) goto done;
-
-    ret = CombineRgn( dc->hVisRgn, saved->hrgn, 0, RGN_COPY );
-    dc->saved_visrgn = saved->next;
-    DeleteObject( saved->hrgn );
-    HeapFree( GetProcessHeap(), 0, saved );
-    CLIPPING_UpdateGCRegion( dc );
- done:
-    release_dc_ptr( dc );
+    LIST_FOR_EACH_ENTRY( saved, &saved_regions, struct saved_visrgn, entry )
+    {
+        if (saved->hdc != hdc) continue;
+        ret = SelectVisRgn( hdc, saved->hrgn );
+        list_remove( &saved->entry );
+        DeleteObject( saved->hrgn );
+        HeapFree( GetProcessHeap(), 0, saved );
+        break;
+    }
     return ret;
 }
 
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index ad57b1b..bc2d9a7 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -234,12 +234,6 @@ typedef struct tagGdiPath
 
 typedef struct tagGdiFont GdiFont;
 
-struct saved_visrgn
-{
-    struct saved_visrgn *next;
-    HRGN                 hrgn;
-};
-
 typedef struct tagDC
 {
     GDIOBJHDR    header;
@@ -310,8 +304,6 @@ typedef struct tagDC
     XFORM         xformVport2World;  /* Inverse of the above transformation */
     BOOL          vport2WorldValid;  /* Is xformVport2World valid? */
     RECT          BoundsRect;        /* Current bounding rect */
-
-    struct saved_visrgn *saved_visrgn;
 } DC;
 
   /* DC flags */




More information about the wine-cvs mailing list