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