Alexandre Julliard : gdi32: Add a DC hook flag to reset the DC state.
Alexandre Julliard
julliard at winehq.org
Wed Oct 24 13:39:41 CDT 2012
Module: wine
Branch: master
Commit: 4396a79edebc381bb5b394c0a1f315efb07da372
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4396a79edebc381bb5b394c0a1f315efb07da372
Author: Alexandre Julliard <julliard at 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);
More information about the wine-cvs
mailing list