From 16da76923d90291b2e6dc24e8e886aeb84f398ab Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 17 Nov 2009 12:28:44 +0100 Subject: [PATCH] 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 f7b295ac594..fdfc1005674 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 bd535d1c92e..0712f40fd86 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 ad57b1b692f..bc2d9a7ca8a 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 */