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

This commit is contained in:
Alexandre Julliard 2012-10-09 15:21:21 +02:00
parent d0c9d22371
commit cc7bf355c5
4 changed files with 84 additions and 1 deletions

View File

@ -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
};

View File

@ -1940,6 +1940,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
*
@ -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)))

View File

@ -1847,6 +1847,28 @@ static RECT *x11drv_surface_get_bounds( struct window_surface *window_surface )
return &surface->bounds;
}
/***********************************************************************
* 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
*/
@ -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
};

View File

@ -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 );
};