Commit 7b970a16 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Don't allocate a GDI handle for saved DCs.

parent e6d153bb
...@@ -160,18 +160,27 @@ DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic ) ...@@ -160,18 +160,27 @@ DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic )
/*********************************************************************** /***********************************************************************
* free_dc_ptr * free_dc_state
*/ */
BOOL free_dc_ptr( DC *dc ) static void free_dc_state( DC *dc )
{ {
assert( dc->refcount == 1 );
if (free_gdi_handle( dc->hSelf ) != dc) return FALSE; /* shouldn't happen */
if (dc->hClipRgn) DeleteObject( dc->hClipRgn ); if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
if (dc->hMetaRgn) DeleteObject( dc->hMetaRgn ); if (dc->hMetaRgn) DeleteObject( dc->hMetaRgn );
if (dc->hMetaClipRgn) DeleteObject( dc->hMetaClipRgn ); if (dc->hMetaClipRgn) DeleteObject( dc->hMetaClipRgn );
if (dc->hVisRgn) DeleteObject( dc->hVisRgn ); if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
PATH_DestroyGdiPath( &dc->path ); PATH_DestroyGdiPath( &dc->path );
return HeapFree( GetProcessHeap(), 0, dc ); HeapFree( GetProcessHeap(), 0, dc );
}
/***********************************************************************
* free_dc_ptr
*/
void free_dc_ptr( DC *dc )
{
assert( dc->refcount == 1 );
free_gdi_handle( dc->hSelf );
free_dc_state( dc );
} }
...@@ -373,7 +382,6 @@ void DC_UpdateXforms( DC *dc ) ...@@ -373,7 +382,6 @@ void DC_UpdateXforms( DC *dc )
INT CDECL nulldrv_SaveDC( PHYSDEV dev ) INT CDECL nulldrv_SaveDC( PHYSDEV dev )
{ {
DC *newdc, *dc = get_nulldrv_dc( dev ); DC *newdc, *dc = get_nulldrv_dc( dev );
INT ret;
if (!(newdc = HeapAlloc( GetProcessHeap(), 0, sizeof(*newdc )))) return 0; if (!(newdc = HeapAlloc( GetProcessHeap(), 0, sizeof(*newdc )))) return 0;
newdc->flags = dc->flags | DC_SAVED; newdc->flags = dc->flags | DC_SAVED;
...@@ -422,22 +430,8 @@ INT CDECL nulldrv_SaveDC( PHYSDEV dev ) ...@@ -422,22 +430,8 @@ INT CDECL nulldrv_SaveDC( PHYSDEV dev )
newdc->BoundsRect = dc->BoundsRect; newdc->BoundsRect = dc->BoundsRect;
newdc->gdiFont = dc->gdiFont; newdc->gdiFont = dc->gdiFont;
newdc->thread = GetCurrentThreadId();
newdc->refcount = 1;
newdc->saveLevel = 0;
newdc->saved_dc = 0;
PATH_InitGdiPath( &newdc->path ); PATH_InitGdiPath( &newdc->path );
newdc->pAbortProc = NULL;
newdc->hookProc = NULL;
if (!(newdc->hSelf = alloc_gdi_handle( &newdc->header, dc->header.type, &dc_funcs )))
{
HeapFree( GetProcessHeap(), 0, newdc );
return 0;
}
/* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */ /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
newdc->hVisRgn = 0; newdc->hVisRgn = 0;
...@@ -454,20 +448,19 @@ INT CDECL nulldrv_SaveDC( PHYSDEV dev ) ...@@ -454,20 +448,19 @@ INT CDECL nulldrv_SaveDC( PHYSDEV dev )
newdc->hMetaRgn = CreateRectRgn( 0, 0, 0, 0 ); newdc->hMetaRgn = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( newdc->hMetaRgn, dc->hMetaRgn, 0, RGN_COPY ); CombineRgn( newdc->hMetaRgn, dc->hMetaRgn, 0, RGN_COPY );
} }
/* don't bother recomputing hMetaClipRgn, we'll do that in SetDCState */ /* don't bother recomputing hMetaClipRgn, we'll do that in SetDCState */
if (!PATH_AssignGdiPath( &newdc->path, &dc->path )) if (!PATH_AssignGdiPath( &newdc->path, &dc->path ))
{ {
release_dc_ptr( dc ); release_dc_ptr( dc );
free_dc_ptr( newdc ); free_dc_state( newdc );
return 0; return 0;
} }
newdc->saved_dc = dc->saved_dc; newdc->saved_dc = dc->saved_dc;
dc->saved_dc = newdc->hSelf; dc->saved_dc = newdc;
ret = ++dc->saveLevel; return ++dc->saveLevel;
release_dc_ptr( newdc );
return ret;
} }
...@@ -476,8 +469,7 @@ INT CDECL nulldrv_SaveDC( PHYSDEV dev ) ...@@ -476,8 +469,7 @@ INT CDECL nulldrv_SaveDC( PHYSDEV dev )
*/ */
BOOL CDECL nulldrv_RestoreDC( PHYSDEV dev, INT level ) BOOL CDECL nulldrv_RestoreDC( PHYSDEV dev, INT level )
{ {
DC *dcs, *dc = get_nulldrv_dc( dev ); DC *dcs, *first_dcs, *dc = get_nulldrv_dc( dev );
HDC hdcs, first_dcs;
INT save_level; INT save_level;
/* find the state level to restore */ /* find the state level to restore */
...@@ -485,21 +477,12 @@ BOOL CDECL nulldrv_RestoreDC( PHYSDEV dev, INT level ) ...@@ -485,21 +477,12 @@ BOOL CDECL nulldrv_RestoreDC( PHYSDEV dev, INT level )
if (abs(level) > dc->saveLevel || level == 0) return FALSE; if (abs(level) > dc->saveLevel || level == 0) return FALSE;
if (level < 0) level = dc->saveLevel + level + 1; if (level < 0) level = dc->saveLevel + level + 1;
first_dcs = dc->saved_dc; first_dcs = dc->saved_dc;
for (hdcs = first_dcs, save_level = dc->saveLevel; save_level > level; save_level--) for (dcs = first_dcs, save_level = dc->saveLevel; save_level > level; save_level--)
{ dcs = dcs->saved_dc;
if (!(dcs = get_dc_ptr( hdcs ))) return FALSE;
hdcs = dcs->saved_dc;
release_dc_ptr( dcs );
}
/* restore the state */ /* restore the state */
if (!(dcs = get_dc_ptr( hdcs ))) return FALSE; if (!PATH_AssignGdiPath( &dc->path, &dcs->path )) return FALSE;
if (!PATH_AssignGdiPath( &dc->path, &dcs->path ))
{
release_dc_ptr( dcs );
return FALSE;
}
dc->flags = dcs->flags & ~DC_SAVED; dc->flags = dcs->flags & ~DC_SAVED;
dc->layout = dcs->layout; dc->layout = dcs->layout;
...@@ -577,16 +560,13 @@ BOOL CDECL nulldrv_RestoreDC( PHYSDEV dev, INT level ) ...@@ -577,16 +560,13 @@ BOOL CDECL nulldrv_RestoreDC( PHYSDEV dev, INT level )
dcs->saved_dc = 0; dcs->saved_dc = 0;
dc->saveLevel = save_level - 1; dc->saveLevel = save_level - 1;
release_dc_ptr( dcs );
/* now destroy all the saved DCs */ /* now destroy all the saved DCs */
while (first_dcs) while (first_dcs)
{ {
if (!(dcs = get_dc_ptr( first_dcs ))) break; DC *next = first_dcs->saved_dc;
hdcs = dcs->saved_dc; free_dc_state( first_dcs );
free_dc_ptr( dcs ); first_dcs = next;
first_dcs = hdcs;
} }
return TRUE; return TRUE;
} }
...@@ -841,12 +821,10 @@ BOOL WINAPI DeleteDC( HDC hdc ) ...@@ -841,12 +821,10 @@ BOOL WINAPI DeleteDC( HDC hdc )
while (dc->saveLevel) while (dc->saveLevel)
{ {
DC * dcs; DC *dcs = dc->saved_dc;
HDC hdcs = dc->saved_dc;
if (!(dcs = get_dc_ptr( hdcs ))) break;
dc->saved_dc = dcs->saved_dc; dc->saved_dc = dcs->saved_dc;
dc->saveLevel--; dc->saveLevel--;
free_dc_ptr( dcs ); free_dc_state( dcs );
} }
if (!(dc->flags & DC_SAVED)) if (!(dc->flags & DC_SAVED))
......
...@@ -253,7 +253,7 @@ typedef struct tagDC ...@@ -253,7 +253,7 @@ typedef struct tagDC
LONG refcount; /* thread refcount */ LONG refcount; /* thread refcount */
LONG dirty; /* dirty flag */ LONG dirty; /* dirty flag */
INT saveLevel; INT saveLevel;
HDC saved_dc; struct tagDC *saved_dc;
DWORD_PTR dwHookData; DWORD_PTR dwHookData;
DCHOOKPROC hookProc; /* DC hook */ DCHOOKPROC hookProc; /* DC hook */
...@@ -376,7 +376,7 @@ extern void CLIPPING_UpdateGCRegion( DC * dc ) DECLSPEC_HIDDEN; ...@@ -376,7 +376,7 @@ extern void CLIPPING_UpdateGCRegion( DC * dc ) DECLSPEC_HIDDEN;
/* dc.c */ /* dc.c */
extern DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic ) DECLSPEC_HIDDEN; extern DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic ) DECLSPEC_HIDDEN;
extern BOOL free_dc_ptr( DC *dc ) DECLSPEC_HIDDEN; extern void free_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
extern DC *get_dc_ptr( HDC hdc ) DECLSPEC_HIDDEN; extern DC *get_dc_ptr( HDC hdc ) DECLSPEC_HIDDEN;
extern void release_dc_ptr( DC *dc ) DECLSPEC_HIDDEN; extern void release_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
extern void update_dc( DC *dc ) DECLSPEC_HIDDEN; extern void update_dc( DC *dc ) DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment