Alexandre Julliard : user32: Add support for setting the window surface visible region.

Alexandre Julliard julliard at winehq.org
Tue Oct 9 13:12:35 CDT 2012


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Oct  9 15:21:21 2012 +0200

user32: Add support for setting the window surface visible region.

---

 dlls/user32/win.c         |    6 +++++
 dlls/user32/winpos.c      |   55 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/winex11.drv/bitblt.c |   23 ++++++++++++++++++
 include/wine/gdi_driver.h |    1 +
 4 files changed, 84 insertions(+), 1 deletions(-)

diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 7da4972..66eaf09 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -539,6 +539,11 @@ static RECT *dummy_surface_get_bounds( struct window_surface *window_surface )
     return &dummy_bounds;
 }
 
+static void dummy_surface_set_region( struct window_surface *window_surface, HRGN region )
+{
+    /* nothing to do */
+}
+
 static void dummy_surface_flush( struct window_surface *window_surface )
 {
     /* nothing to do */
@@ -555,6 +560,7 @@ static const struct window_surface_funcs dummy_surface_funcs =
     dummy_surface_unlock,
     dummy_surface_get_bitmap_info,
     dummy_surface_get_bounds,
+    dummy_surface_set_region,
     dummy_surface_flush,
     dummy_surface_destroy
 };
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index 7a0d8f9..a04bf2c 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -1941,6 +1941,57 @@ static BOOL fixup_flags( WINDOWPOS *winpos )
 
 
 /***********************************************************************
+ *		update_surface_region
+ */
+static void update_surface_region( HWND hwnd )
+{
+    NTSTATUS status;
+    HRGN region = 0;
+    RGNDATA *data;
+    size_t size = 256;
+    WND *win = WIN_GetPtr( hwnd );
+
+    if (!win || win == WND_DESKTOP || win == WND_OTHER_PROCESS) return;
+    if (!win->surface) goto done;
+
+    do
+    {
+        if (!(data = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( RGNDATA, Buffer[size] )))) goto done;
+
+        SERVER_START_REQ( get_surface_region )
+        {
+            req->window = wine_server_user_handle( hwnd );
+            wine_server_set_reply( req, data->Buffer, size );
+            if (!(status = wine_server_call( req )))
+            {
+                size_t reply_size = wine_server_reply_size( reply );
+                if (reply_size)
+                {
+                    data->rdh.dwSize   = sizeof(data->rdh);
+                    data->rdh.iType    = RDH_RECTANGLES;
+                    data->rdh.nCount   = reply_size / sizeof(RECT);
+                    data->rdh.nRgnSize = reply_size;
+                    region = ExtCreateRegion( NULL, size, data );
+                    OffsetRgn( region, -reply->visible_rect.left, -reply->visible_rect.top );
+                }
+            }
+            else size = reply->total_size;
+        }
+        SERVER_END_REQ;
+        HeapFree( GetProcessHeap(), 0, data );
+    } while (status == STATUS_BUFFER_OVERFLOW);
+
+    if (status) goto done;
+
+    win->surface->funcs->set_region( win->surface, region );
+    if (region) DeleteObject( region );
+
+done:
+    WIN_ReleasePtr( win );
+}
+
+
+/***********************************************************************
  *		set_window_pos
  *
  * Backend implementation of SetWindowPos.
@@ -1949,7 +2000,7 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
                      const RECT *window_rect, const RECT *client_rect, const RECT *valid_rects )
 {
     WND *win;
-    HWND parent = GetAncestor( hwnd, GA_PARENT );
+    HWND surface_win = 0, parent = GetAncestor( hwnd, GA_PARENT );
     BOOL ret;
     int old_width;
     RECT visible_rect, old_visible_rect, old_window_rect;
@@ -2005,6 +2056,7 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
             win->visible_rect = visible_rect;
             old_surface       = win->surface;
             win->surface      = new_surface;
+            surface_win       = wine_server_ptr_handle( reply->surface_win );
             if (GetWindowLongW( win->parent, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL)
             {
                 RECT client;
@@ -2022,6 +2074,7 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
 
     if (ret)
     {
+        if (surface_win) update_surface_region( surface_win );
         if (old_surface != new_surface ||
             ((swp_flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) ||
             (swp_flags & (SWP_HIDEWINDOW | SWP_SHOWWINDOW | SWP_STATECHANGED | SWP_FRAMECHANGED)))
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c
index e1812cd..c3cf056 100644
--- a/dlls/winex11.drv/bitblt.c
+++ b/dlls/winex11.drv/bitblt.c
@@ -1848,6 +1848,28 @@ static RECT *x11drv_surface_get_bounds( struct window_surface *window_surface )
 }
 
 /***********************************************************************
+ *           x11drv_surface_set_region
+ */
+static void x11drv_surface_set_region( struct window_surface *window_surface, HRGN region )
+{
+    RGNDATA *data;
+    struct x11drv_window_surface *surface = get_x11_surface( window_surface );
+
+    TRACE( "updating surface %p with %p\n", surface, region );
+
+    if (!region)
+    {
+        XSetClipMask( gdi_display, surface->gc, None );
+    }
+    else if ((data = X11DRV_GetRegionData( region, 0 )))
+    {
+        XSetClipRectangles( gdi_display, surface->gc, 0, 0,
+                            (XRectangle *)data->Buffer, data->rdh.nCount, YXBanded );
+        HeapFree( GetProcessHeap(), 0, data );
+    }
+}
+
+/***********************************************************************
  *           x11drv_surface_flush
  */
 static void x11drv_surface_flush( struct window_surface *window_surface )
@@ -1945,6 +1967,7 @@ static const struct window_surface_funcs x11drv_surface_funcs =
     x11drv_surface_unlock,
     x11drv_surface_get_bitmap_info,
     x11drv_surface_get_bounds,
+    x11drv_surface_set_region,
     x11drv_surface_flush,
     x11drv_surface_destroy
 };
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h
index c58803d..e942ed9 100644
--- a/include/wine/gdi_driver.h
+++ b/include/wine/gdi_driver.h
@@ -233,6 +233,7 @@ struct window_surface_funcs
     void  (*unlock)( struct window_surface *surface );
     void* (*get_info)( struct window_surface *surface, BITMAPINFO *info );
     RECT* (*get_bounds)( struct window_surface *surface );
+    void  (*set_region)( struct window_surface *surface, HRGN region );
     void  (*flush)( struct window_surface *surface );
     void  (*destroy)( struct window_surface *surface );
 };




More information about the wine-cvs mailing list