gdi32: Reimplement SaveVisRgn16/RestoreVisRgn16 to avoid accessing the DC internals.
This commit is contained in:
parent
61925b7e89
commit
16da76923d
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue