user32: Add support for setting the window surface visible region.
This commit is contained in:
parent
d0c9d22371
commit
cc7bf355c5
@ -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
|
||||
};
|
||||
|
@ -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)))
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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 );
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user