Alexandre Julliard : winex11: Fall back to normal expose processing for areas outside of the surface region .

Alexandre Julliard julliard at winehq.org
Mon Dec 3 13:33:56 CST 2012


Module: wine
Branch: master
Commit: 8e6548573233ecdb85a01ac8f6f48456fd259147
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8e6548573233ecdb85a01ac8f6f48456fd259147

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Dec  3 15:27:04 2012 +0100

winex11: Fall back to normal expose processing for areas outside of the surface region.

---

 dlls/winex11.drv/bitblt.c |   23 +++++++++++++++++++++++
 dlls/winex11.drv/event.c  |   23 +++++++++++++----------
 dlls/winex11.drv/x11drv.h |    1 +
 3 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c
index c5a6bd0..161fa73 100644
--- a/dlls/winex11.drv/bitblt.c
+++ b/dlls/winex11.drv/bitblt.c
@@ -2062,3 +2062,26 @@ void set_surface_color_key( struct window_surface *window_surface, COLORREF colo
     if (surface->color_key != prev) update_surface_region( surface );
     window_surface->funcs->unlock( window_surface );
 }
+
+/***********************************************************************
+ *           expose_surface
+ */
+HRGN expose_surface( struct window_surface *window_surface, const RECT *rect )
+{
+    struct x11drv_window_surface *surface = get_x11_surface( window_surface );
+    HRGN region = 0;
+
+    window_surface->funcs->lock( window_surface );
+    add_bounds_rect( &surface->bounds, rect );
+    if (surface->region)
+    {
+        region = CreateRectRgnIndirect( rect );
+        if (CombineRgn( region, region, surface->region, RGN_DIFF ) <= NULLREGION)
+        {
+            DeleteObject( region );
+            region = 0;
+        }
+    }
+    window_surface->funcs->unlock( window_surface );
+    return region;
+}
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index f908413..90b2068 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -816,7 +816,8 @@ static void X11DRV_Expose( HWND hwnd, XEvent *xev )
     XExposeEvent *event = &xev->xexpose;
     RECT rect;
     struct x11drv_win_data *data;
-    int flags = RDW_INVALIDATE | RDW_ERASE | RDW_FRAME;
+    HRGN surface_region = 0;
+    UINT flags = RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN;
 
     TRACE( "win %p (%lx) %d,%d %dx%d\n",
            hwnd, event->window, event->x, event->y, event->width, event->height );
@@ -830,9 +831,8 @@ static void X11DRV_Expose( HWND hwnd, XEvent *xev )
 
     if (data->surface)
     {
-        data->surface->funcs->lock( data->surface );
-        add_bounds_rect( data->surface->funcs->get_bounds( data->surface ), &rect );
-        data->surface->funcs->unlock( data->surface );
+        surface_region = expose_surface( data->surface, &rect );
+        if (!surface_region) flags = 0;
         if (data->vis.visualid != default_visual.visualid)
             data->surface->funcs->flush( data->surface );
     }
@@ -841,6 +841,8 @@ static void X11DRV_Expose( HWND hwnd, XEvent *xev )
     {
         OffsetRect( &rect, data->whole_rect.left - data->client_rect.left,
                     data->whole_rect.top - data->client_rect.top );
+        if (surface_region) OffsetRgn( surface_region, data->whole_rect.left - data->client_rect.left,
+                                       data->whole_rect.top - data->client_rect.top );
 
         if (GetWindowLongW( data->hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL)
             mirror_rect( &data->client_rect, &rect );
@@ -855,15 +857,16 @@ static void X11DRV_Expose( HWND hwnd, XEvent *xev )
             wine_server_call( req );
         }
         SERVER_END_REQ;
-
-        flags |= RDW_ALLCHILDREN;
     }
-    else OffsetRect( &rect, virtual_screen_rect.left, virtual_screen_rect.top );
-
-    if (data->surface) flags = 0;
+    else
+    {
+        OffsetRect( &rect, virtual_screen_rect.left, virtual_screen_rect.top );
+        flags &= ~RDW_ALLCHILDREN;
+    }
     release_win_data( data );
 
-    if (flags) RedrawWindow( hwnd, &rect, 0, flags );
+    if (flags) RedrawWindow( hwnd, &rect, surface_region, flags );
+    if (surface_region) DeleteObject( surface_region );
 }
 
 
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 314a438..0c462d6 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -200,6 +200,7 @@ extern DWORD get_pixmap_image( Pixmap pixmap, int width, int height, const XVisu
 extern struct window_surface *create_surface( Window window, const XVisualInfo *vis, const RECT *rect,
                                               COLORREF color_key, BOOL use_alpha ) DECLSPEC_HIDDEN;
 extern void set_surface_color_key( struct window_surface *window_surface, COLORREF color_key ) DECLSPEC_HIDDEN;
+extern HRGN expose_surface( struct window_surface *window_surface, const RECT *rect ) DECLSPEC_HIDDEN;
 
 extern RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) DECLSPEC_HIDDEN;
 extern BOOL add_extra_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn ) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list