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