Module: wine Branch: master Commit: 4396a79edebc381bb5b394c0a1f315efb07da372 URL: http://source.winehq.org/git/wine.git/?a=commit;h=4396a79edebc381bb5b394c0a1...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Oct 24 18:24:03 2012 +0200
gdi32: Add a DC hook flag to reset the DC state.
---
dlls/gdi32/dc.c | 94 ++++++++++++++++++++++++++++++++++++-------- dlls/gdi32/tests/dc.c | 3 - dlls/user32/painting.c | 16 +------- include/wine/gdi_driver.h | 1 + 4 files changed, 80 insertions(+), 34 deletions(-)
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c index 030304c..b59c154 100644 --- a/dlls/gdi32/dc.c +++ b/dlls/gdi32/dc.c @@ -71,28 +71,20 @@ static inline DC *get_dc_obj( HDC hdc )
/*********************************************************************** - * alloc_dc_ptr + * set_initial_dc_state */ -DC *alloc_dc_ptr( WORD magic ) +static void set_initial_dc_state( DC *dc ) { - DC *dc; - - if (!(dc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*dc) ))) return NULL; - - dc->nulldrv.funcs = &null_driver; - dc->physDev = &dc->nulldrv; - dc->module = gdi32_module; - dc->thread = GetCurrentThreadId(); - dc->refcount = 1; + dc->wndOrgX = 0; + dc->wndOrgY = 0; dc->wndExtX = 1; dc->wndExtY = 1; + dc->vportOrgX = 0; + dc->vportOrgY = 0; dc->vportExtX = 1; dc->vportExtY = 1; dc->miterLimit = 10.0f; /* 10.0 is the default, from MSDN */ - dc->hPen = GDI_inc_ref_count( GetStockObject( BLACK_PEN )); - dc->hBrush = GDI_inc_ref_count( GetStockObject( WHITE_BRUSH )); - dc->hFont = GDI_inc_ref_count( GetStockObject( SYSTEM_FONT )); - dc->hPalette = GetStockObject( DEFAULT_PALETTE ); + dc->layout = 0; dc->font_code_page = CP_ACP; dc->ROPmode = R2_COPYPEN; dc->polyFillMode = ALTERNATE; @@ -103,9 +95,17 @@ DC *alloc_dc_ptr( WORD magic ) dc->dcBrushColor = RGB( 255, 255, 255 ); dc->dcPenColor = RGB( 0, 0, 0 ); dc->textColor = RGB( 0, 0, 0 ); + dc->brushOrgX = 0; + dc->brushOrgY = 0; + dc->mapperFlags = 0; dc->textAlign = TA_LEFT | TA_TOP | TA_NOUPDATECP; + dc->charExtra = 0; + dc->breakExtra = 0; + dc->breakRem = 0; dc->MapMode = MM_TEXT; dc->GraphicsMode = GM_COMPATIBLE; + dc->CursPosX = 0; + dc->CursPosY = 0; dc->ArcDirection = AD_COUNTERCLOCKWISE; dc->xformWorld2Wnd.eM11 = 1.0f; dc->xformWorld2Wnd.eM12 = 0.0f; @@ -118,6 +118,28 @@ DC *alloc_dc_ptr( WORD magic ) dc->vport2WorldValid = TRUE;
reset_bounds( &dc->bounds ); +} + +/*********************************************************************** + * alloc_dc_ptr + */ +DC *alloc_dc_ptr( WORD magic ) +{ + DC *dc; + + if (!(dc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*dc) ))) return NULL; + + dc->nulldrv.funcs = &null_driver; + dc->physDev = &dc->nulldrv; + dc->module = gdi32_module; + dc->thread = GetCurrentThreadId(); + dc->refcount = 1; + dc->hPen = GDI_inc_ref_count( GetStockObject( BLACK_PEN )); + dc->hBrush = GDI_inc_ref_count( GetStockObject( WHITE_BRUSH )); + dc->hFont = GDI_inc_ref_count( GetStockObject( SYSTEM_FONT )); + dc->hPalette = GetStockObject( DEFAULT_PALETTE ); + + set_initial_dc_state( dc );
if (!(dc->hSelf = alloc_gdi_handle( dc, magic, &dc_funcs ))) { @@ -520,6 +542,44 @@ BOOL nulldrv_RestoreDC( PHYSDEV dev, INT level )
/*********************************************************************** + * reset_dc_state + */ +static BOOL reset_dc_state( HDC hdc ) +{ + DC *dc, *dcs, *next; + + if (!(dc = get_dc_ptr( hdc ))) return FALSE; + + set_initial_dc_state( dc ); + SetBkColor( hdc, RGB( 255, 255, 255 )); + SetTextColor( hdc, RGB( 0, 0, 0 )); + SelectObject( hdc, GetStockObject( WHITE_BRUSH )); + SelectObject( hdc, GetStockObject( SYSTEM_FONT )); + SelectObject( hdc, GetStockObject( BLACK_PEN )); + SetVirtualResolution( hdc, 0, 0, 0, 0 ); + GDISelectPalette( hdc, GetStockObject( DEFAULT_PALETTE ), FALSE ); + SetBoundsRect( hdc, NULL, DCB_DISABLE ); + AbortPath( hdc ); + + if (dc->hClipRgn) DeleteObject( dc->hClipRgn ); + if (dc->hMetaRgn) DeleteObject( dc->hMetaRgn ); + dc->hClipRgn = 0; + dc->hMetaRgn = 0; + update_dc_clipping( dc ); + + for (dcs = dc->saved_dc; dcs; dcs = next) + { + next = dcs->saved_dc; + free_dc_state( dcs ); + } + dc->saved_dc = NULL; + dc->saveLevel = 0; + release_dc_ptr( dc ); + return TRUE; +} + + +/*********************************************************************** * SaveDC (GDI32.@) */ INT WINAPI SaveDC( HDC hdc ) @@ -1217,8 +1277,6 @@ WORD WINAPI SetHookFlags( HDC hdc, WORD flags )
if (!dc) return 0;
- /* "Undocumented Windows" info is slightly confusing. */ - TRACE("hDC %p, flags %04x\n",hdc,flags);
if (flags & DCHF_INVALIDATEVISRGN) @@ -1227,6 +1285,8 @@ WORD WINAPI SetHookFlags( HDC hdc, WORD flags ) ret = InterlockedExchange( &dc->dirty, 0 );
GDI_ReleaseObj( hdc ); + + if (flags & DCHF_RESETDC) ret = reset_dc_state( hdc ); return ret; }
diff --git a/dlls/gdi32/tests/dc.c b/dlls/gdi32/tests/dc.c index e286044..8baacc2 100644 --- a/dlls/gdi32/tests/dc.c +++ b/dlls/gdi32/tests/dc.c @@ -124,10 +124,7 @@ static void test_savedc_2(void) rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
ret = SaveDC(hdc); -todo_wine -{ ok(ret == 1, "ret = %d\n", ret); -}
ret = IntersectClipRect(hdc, 0, 0, 50, 50); if (ret == COMPLEXREGION) diff --git a/dlls/user32/painting.c b/dlls/user32/painting.c index e9705fe..b2ddfe6 100644 --- a/dlls/user32/painting.c +++ b/dlls/user32/painting.c @@ -178,16 +178,6 @@ static void update_visible_region( struct dce *dce )
/*********************************************************************** - * reset_dce_attrs - */ -static void reset_dce_attrs( struct dce *dce ) -{ - RestoreDC( dce->hdc, 1 ); /* initial save level is always 1 */ - SaveDC( dce->hdc ); /* save the state again for next time */ -} - - -/*********************************************************************** * release_dce */ static void release_dce( struct dce *dce ) @@ -235,8 +225,6 @@ static struct dce *alloc_dce(void) HeapFree( GetProcessHeap(), 0, dce ); return 0; } - SaveDC( dce->hdc ); - dce->hwnd = 0; dce->clip_rgn = 0; dce->flags = 0; @@ -352,7 +340,7 @@ void free_dce( struct dce *dce, HWND hwnd ) if (!--dce->count) { /* turn it into a cache entry */ - reset_dce_attrs( dce ); + SetHookFlags( dce->hdc, DCHF_RESETDC ); release_dce( dce ); dce->flags |= DCX_CACHE; } @@ -470,7 +458,7 @@ static INT release_dc( HWND hwnd, HDC hdc, BOOL end_paint ) dce = (struct dce *)GetDCHook( hdc, NULL ); if (dce && dce->count) { - if (!(dce->flags & DCX_NORESETATTRS)) reset_dce_attrs( dce ); + if (!(dce->flags & DCX_NORESETATTRS)) SetHookFlags( dce->hdc, DCHF_RESETDC ); if (end_paint || (dce->flags & DCX_CACHE)) delete_clip_rgn( dce ); if (dce->flags & DCX_CACHE) dce->count = 0; ret = TRUE; diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 3d4e6c5..1f6376c 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -265,6 +265,7 @@ static inline ULONG window_surface_release( struct window_surface *surface ) #define DCHC_DELETEDC 0x0002 #define DCHF_INVALIDATEVISRGN 0x0001 #define DCHF_VALIDATEVISRGN 0x0002 +#define DCHF_RESETDC 0x0004 /* Wine extension */
typedef BOOL (CALLBACK *DCHOOKPROC)(HDC,WORD,DWORD_PTR,LPARAM);