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