Skip to content

Commit

Permalink
server: Add support for a layered window region. (v3)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitry Timoshkov authored and Guy1524 committed Apr 6, 2020
1 parent aa5eee9 commit 1642fc3
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 3 deletions.
2 changes: 0 additions & 2 deletions dlls/user32/tests/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -2882,13 +2882,11 @@ static void test_Input_mouse(void)

if (msg.message == WM_LBUTTONDOWN)
{
todo_wine
ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
got_button_down = TRUE;
}
else if (msg.message == WM_LBUTTONUP)
{
todo_wine
ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
got_button_up = TRUE;
break;
Expand Down
45 changes: 45 additions & 0 deletions dlls/winex11.drv/bitblt.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "winuser.h"
#include "x11drv.h"
#include "winternl.h"
#include "wine/server.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(bitblt);
Expand Down Expand Up @@ -1613,6 +1614,48 @@ static inline void add_row( HRGN rgn, RGNDATA *data, int x, int y, int len )
}
#endif

static void set_layer_region( struct x11drv_window_surface *surface, HRGN hrgn )
{
static const RECT empty_rect;
RGNDATA *data;
DWORD size;
HWND hwnd;

if (XFindContext( thread_init_display(), surface->window, winContext, (char **)&hwnd ))
return;

if (hrgn)
{
if (!(size = GetRegionData( hrgn, 0, NULL ))) return;
if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return;
if (!GetRegionData( hrgn, size, data ))
{
HeapFree( GetProcessHeap(), 0, data );
return;
}
SERVER_START_REQ( set_layer_region )
{
req->window = wine_server_user_handle( hwnd );
if (data->rdh.nCount)
wine_server_add_data( req, data->Buffer, data->rdh.nCount * sizeof(RECT) );
else
wine_server_add_data( req, &empty_rect, sizeof(empty_rect) );
wine_server_call( req );
}
SERVER_END_REQ;
HeapFree( GetProcessHeap(), 0, data );
}
else /* clear existing region */
{
SERVER_START_REQ( set_layer_region )
{
req->window = wine_server_user_handle( hwnd );
wine_server_call( req );
}
SERVER_END_REQ;
}
}

/***********************************************************************
* update_surface_region
*/
Expand All @@ -1631,6 +1674,7 @@ static void update_surface_region( struct x11drv_window_surface *surface )
if (!surface->is_argb && surface->color_key == CLR_INVALID)
{
XShapeCombineMask( gdi_display, surface->window, ShapeBounding, 0, 0, None, ShapeSet );
set_layer_region( surface, NULL );
return;
}

Expand Down Expand Up @@ -1741,6 +1785,7 @@ static void update_surface_region( struct x11drv_window_surface *surface )
HeapFree( GetProcessHeap(), 0, data );
}

set_layer_region( surface, rgn );
DeleteObject( rgn );
#endif
}
Expand Down
18 changes: 17 additions & 1 deletion include/wine/server_protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -3922,6 +3922,19 @@ struct set_window_region_reply



struct set_layer_region_request
{
struct request_header __header;
user_handle_t window;
/* VARARG(region,rectangles); */
};
struct set_layer_region_reply
{
struct reply_header __header;
};



struct get_update_region_request
{
struct request_header __header;
Expand Down Expand Up @@ -6251,6 +6264,7 @@ enum request
REQ_get_surface_region,
REQ_get_window_region,
REQ_set_window_region,
REQ_set_layer_region,
REQ_get_update_region,
REQ_update_window_zorder,
REQ_redraw_window,
Expand Down Expand Up @@ -6572,6 +6586,7 @@ union generic_request
struct get_surface_region_request get_surface_region_request;
struct get_window_region_request get_window_region_request;
struct set_window_region_request set_window_region_request;
struct set_layer_region_request set_layer_region_request;
struct get_update_region_request get_update_region_request;
struct update_window_zorder_request update_window_zorder_request;
struct redraw_window_request redraw_window_request;
Expand Down Expand Up @@ -6891,6 +6906,7 @@ union generic_reply
struct get_surface_region_reply get_surface_region_reply;
struct get_window_region_reply get_window_region_reply;
struct set_window_region_reply set_window_region_reply;
struct set_layer_region_reply set_layer_region_reply;
struct get_update_region_reply get_update_region_reply;
struct update_window_zorder_reply update_window_zorder_reply;
struct redraw_window_reply redraw_window_reply;
Expand Down Expand Up @@ -7028,7 +7044,7 @@ union generic_reply

/* ### protocol_version begin ### */

#define SERVER_PROTOCOL_VERSION 632
#define SERVER_PROTOCOL_VERSION 633

/* ### protocol_version end ### */

Expand Down
7 changes: 7 additions & 0 deletions server/protocol.def
Original file line number Diff line number Diff line change
Expand Up @@ -2817,6 +2817,13 @@ enum coords_relative
@END


/* Set the layer region */
@REQ(set_layer_region)
user_handle_t window; /* handle to the window */
VARARG(region,rectangles); /* list of rectangles for the region (in window coords) */
@END


/* Get the window update region */
@REQ(get_update_region)
user_handle_t window; /* handle to the window */
Expand Down
4 changes: 4 additions & 0 deletions server/request.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ DECL_HANDLER(get_visible_region);
DECL_HANDLER(get_surface_region);
DECL_HANDLER(get_window_region);
DECL_HANDLER(set_window_region);
DECL_HANDLER(set_layer_region);
DECL_HANDLER(get_update_region);
DECL_HANDLER(update_window_zorder);
DECL_HANDLER(redraw_window);
Expand Down Expand Up @@ -614,6 +615,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_surface_region,
(req_handler)req_get_window_region,
(req_handler)req_set_window_region,
(req_handler)req_set_layer_region,
(req_handler)req_get_update_region,
(req_handler)req_update_window_zorder,
(req_handler)req_redraw_window,
Expand Down Expand Up @@ -1870,6 +1872,8 @@ C_ASSERT( sizeof(struct get_window_region_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct set_window_region_request, window) == 12 );
C_ASSERT( FIELD_OFFSET(struct set_window_region_request, redraw) == 16 );
C_ASSERT( sizeof(struct set_window_region_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct set_layer_region_request, window) == 12 );
C_ASSERT( sizeof(struct set_layer_region_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_update_region_request, window) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_update_region_request, from_child) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_update_region_request, flags) == 20 );
Expand Down
9 changes: 9 additions & 0 deletions server/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -3351,6 +3351,12 @@ static void dump_set_window_region_request( const struct set_window_region_reque
dump_varargs_rectangles( ", region=", cur_size );
}

static void dump_set_layer_region_request( const struct set_layer_region_request *req )
{
fprintf( stderr, " window=%08x", req->window );
dump_varargs_rectangles( ", region=", cur_size );
}

static void dump_get_update_region_request( const struct get_update_region_request *req )
{
fprintf( stderr, " window=%08x", req->window );
Expand Down Expand Up @@ -4957,6 +4963,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_surface_region_request,
(dump_func)dump_get_window_region_request,
(dump_func)dump_set_window_region_request,
(dump_func)dump_set_layer_region_request,
(dump_func)dump_get_update_region_request,
(dump_func)dump_update_window_zorder_request,
(dump_func)dump_redraw_window_request,
Expand Down Expand Up @@ -5274,6 +5281,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_surface_region_reply,
(dump_func)dump_get_window_region_reply,
NULL,
NULL,
(dump_func)dump_get_update_region_reply,
NULL,
NULL,
Expand Down Expand Up @@ -5591,6 +5599,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_surface_region",
"get_window_region",
"set_window_region",
"set_layer_region",
"get_update_region",
"update_window_zorder",
"redraw_window",
Expand Down
32 changes: 32 additions & 0 deletions server/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ struct window
rectangle_t surface_rect; /* window surface rectangle (relative to parent client area) */
rectangle_t client_rect; /* client rectangle (relative to parent client area) */
struct region *win_region; /* region for shaped windows (relative to window rect) */
struct region *layer_region; /* region for layered windows (relative to window rect) */
struct region *update_region; /* update region (relative to window rect) */
unsigned int style; /* window style */
unsigned int ex_style; /* window extended style */
Expand Down Expand Up @@ -495,6 +496,7 @@ static struct window *create_window( struct window *parent, struct window *owner
win->atom = atom;
win->last_active = win->handle;
win->win_region = NULL;
win->layer_region = NULL;
win->update_region = NULL;
win->style = 0;
win->ex_style = 0;
Expand Down Expand Up @@ -725,6 +727,9 @@ static int is_point_in_window( struct window *win, int *x, int *y, unsigned int
if (win->win_region &&
!point_in_region( win->win_region, *x - win->window_rect.left, *y - win->window_rect.top ))
return 0; /* not in window region */
if (win->layer_region &&
!point_in_region( win->layer_region, *x - win->window_rect.left, *y - win->window_rect.top ))
return 0; /* not in layer mask region */
return 1;
}

Expand Down Expand Up @@ -1870,6 +1875,14 @@ static void set_window_region( struct window *win, struct region *region, int re
}


/* set the layer region */
static void set_layer_region( struct window *win, struct region *region )
{
if (win->layer_region) free_region( win->layer_region );
win->layer_region = region;
}


/* destroy a window */
void destroy_window( struct window *win )
{
Expand Down Expand Up @@ -1918,6 +1931,7 @@ void destroy_window( struct window *win )

detach_window_thread( win );
if (win->win_region) free_region( win->win_region );
if (win->layer_region) free_region( win->layer_region );
if (win->update_region) free_region( win->update_region );
if (win->class) release_class( win->class );
free( win->text );
Expand Down Expand Up @@ -2566,6 +2580,24 @@ DECL_HANDLER(set_window_region)
}


/* set the layer region */
DECL_HANDLER(set_layer_region)
{
struct region *region = NULL;
struct window *win = get_window( req->window );

if (!win) return;

if (get_req_data_size()) /* no data means remove the region completely */
{
if (!(region = create_region_from_req_data( get_req_data(), get_req_data_size() )))
return;
if (win->ex_style & WS_EX_LAYOUTRTL) mirror_region( &win->window_rect, region );
}
set_layer_region( win, region );
}


/* get a window update region */
DECL_HANDLER(get_update_region)
{
Expand Down

0 comments on commit 1642fc3

Please sign in to comment.