server: Add a request to compute the clipping region of a window surface.
This commit is contained in:
parent
20768173ba
commit
a52ebb158e
|
@ -3325,6 +3325,8 @@ struct set_window_pos_reply
|
|||
struct reply_header __header;
|
||||
unsigned int new_style;
|
||||
unsigned int new_ex_style;
|
||||
user_handle_t surface_win;
|
||||
char __pad_20[4];
|
||||
};
|
||||
#define SET_WINPOS_PAINT_SURFACE 0x01
|
||||
#define SET_WINPOS_PIXEL_FORMAT 0x02
|
||||
|
@ -3417,6 +3419,22 @@ struct get_visible_region_reply
|
|||
|
||||
|
||||
|
||||
struct get_surface_region_request
|
||||
{
|
||||
struct request_header __header;
|
||||
user_handle_t window;
|
||||
};
|
||||
struct get_surface_region_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
rectangle_t visible_rect;
|
||||
data_size_t total_size;
|
||||
/* VARARG(region,rectangles); */
|
||||
char __pad_28[4];
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct get_window_region_request
|
||||
{
|
||||
struct request_header __header;
|
||||
|
@ -5092,6 +5110,7 @@ enum request
|
|||
REQ_set_window_text,
|
||||
REQ_get_windows_offset,
|
||||
REQ_get_visible_region,
|
||||
REQ_get_surface_region,
|
||||
REQ_get_window_region,
|
||||
REQ_set_window_region,
|
||||
REQ_get_update_region,
|
||||
|
@ -5347,6 +5366,7 @@ union generic_request
|
|||
struct set_window_text_request set_window_text_request;
|
||||
struct get_windows_offset_request get_windows_offset_request;
|
||||
struct get_visible_region_request get_visible_region_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 get_update_region_request get_update_region_request;
|
||||
|
@ -5600,6 +5620,7 @@ union generic_reply
|
|||
struct set_window_text_reply set_window_text_reply;
|
||||
struct get_windows_offset_reply get_windows_offset_reply;
|
||||
struct get_visible_region_reply get_visible_region_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 get_update_region_reply get_update_region_reply;
|
||||
|
@ -5692,6 +5713,6 @@ union generic_reply
|
|||
struct set_suspend_context_reply set_suspend_context_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 436
|
||||
#define SERVER_PROTOCOL_VERSION 437
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -2401,6 +2401,7 @@ enum message_type
|
|||
@REPLY
|
||||
unsigned int new_style; /* new window style */
|
||||
unsigned int new_ex_style; /* new window extended style */
|
||||
user_handle_t surface_win; /* window that needs a surface update */
|
||||
@END
|
||||
#define SET_WINPOS_PAINT_SURFACE 0x01 /* window has a paintable surface */
|
||||
#define SET_WINPOS_PIXEL_FORMAT 0x02 /* window has a custom pixel format */
|
||||
|
@ -2462,6 +2463,16 @@ enum coords_relative
|
|||
@END
|
||||
|
||||
|
||||
/* Get the visible surface region of a window */
|
||||
@REQ(get_surface_region)
|
||||
user_handle_t window; /* handle to the window */
|
||||
@REPLY
|
||||
rectangle_t visible_rect; /* window visible rect in screen coords */
|
||||
data_size_t total_size; /* total size of the resulting region */
|
||||
VARARG(region,rectangles); /* list of rectangles for the region (in screen coords) */
|
||||
@END
|
||||
|
||||
|
||||
/* Get the window region */
|
||||
@REQ(get_window_region)
|
||||
user_handle_t window; /* handle to the window */
|
||||
|
|
|
@ -269,6 +269,7 @@ DECL_HANDLER(get_window_text);
|
|||
DECL_HANDLER(set_window_text);
|
||||
DECL_HANDLER(get_windows_offset);
|
||||
DECL_HANDLER(get_visible_region);
|
||||
DECL_HANDLER(get_surface_region);
|
||||
DECL_HANDLER(get_window_region);
|
||||
DECL_HANDLER(set_window_region);
|
||||
DECL_HANDLER(get_update_region);
|
||||
|
@ -523,6 +524,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||
(req_handler)req_set_window_text,
|
||||
(req_handler)req_get_windows_offset,
|
||||
(req_handler)req_get_visible_region,
|
||||
(req_handler)req_get_surface_region,
|
||||
(req_handler)req_get_window_region,
|
||||
(req_handler)req_set_window_region,
|
||||
(req_handler)req_get_update_region,
|
||||
|
@ -1597,7 +1599,8 @@ C_ASSERT( FIELD_OFFSET(struct set_window_pos_request, client) == 40 );
|
|||
C_ASSERT( sizeof(struct set_window_pos_request) == 56 );
|
||||
C_ASSERT( FIELD_OFFSET(struct set_window_pos_reply, new_style) == 8 );
|
||||
C_ASSERT( FIELD_OFFSET(struct set_window_pos_reply, new_ex_style) == 12 );
|
||||
C_ASSERT( sizeof(struct set_window_pos_reply) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct set_window_pos_reply, surface_win) == 16 );
|
||||
C_ASSERT( sizeof(struct set_window_pos_reply) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_request, handle) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_request, relative) == 16 );
|
||||
C_ASSERT( sizeof(struct get_window_rectangles_request) == 24 );
|
||||
|
@ -1625,6 +1628,11 @@ C_ASSERT( FIELD_OFFSET(struct get_visible_region_reply, top_rect) == 12 );
|
|||
C_ASSERT( FIELD_OFFSET(struct get_visible_region_reply, win_rect) == 28 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_visible_region_reply, total_size) == 44 );
|
||||
C_ASSERT( sizeof(struct get_visible_region_reply) == 48 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_surface_region_request, window) == 12 );
|
||||
C_ASSERT( sizeof(struct get_surface_region_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_surface_region_reply, visible_rect) == 8 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_surface_region_reply, total_size) == 24 );
|
||||
C_ASSERT( sizeof(struct get_surface_region_reply) == 32 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_window_region_request, window) == 12 );
|
||||
C_ASSERT( sizeof(struct get_window_region_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_window_region_reply, total_size) == 8 );
|
||||
|
|
|
@ -2828,6 +2828,7 @@ static void dump_set_window_pos_reply( const struct set_window_pos_reply *req )
|
|||
{
|
||||
fprintf( stderr, " new_style=%08x", req->new_style );
|
||||
fprintf( stderr, ", new_ex_style=%08x", req->new_ex_style );
|
||||
fprintf( stderr, ", surface_win=%08x", req->surface_win );
|
||||
}
|
||||
|
||||
static void dump_get_window_rectangles_request( const struct get_window_rectangles_request *req )
|
||||
|
@ -2887,6 +2888,18 @@ static void dump_get_visible_region_reply( const struct get_visible_region_reply
|
|||
dump_varargs_rectangles( ", region=", cur_size );
|
||||
}
|
||||
|
||||
static void dump_get_surface_region_request( const struct get_surface_region_request *req )
|
||||
{
|
||||
fprintf( stderr, " window=%08x", req->window );
|
||||
}
|
||||
|
||||
static void dump_get_surface_region_reply( const struct get_surface_region_reply *req )
|
||||
{
|
||||
dump_rectangle( " visible_rect=", &req->visible_rect );
|
||||
fprintf( stderr, ", total_size=%u", req->total_size );
|
||||
dump_varargs_rectangles( ", region=", cur_size );
|
||||
}
|
||||
|
||||
static void dump_get_window_region_request( const struct get_window_region_request *req )
|
||||
{
|
||||
fprintf( stderr, " window=%08x", req->window );
|
||||
|
@ -4096,6 +4109,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_set_window_text_request,
|
||||
(dump_func)dump_get_windows_offset_request,
|
||||
(dump_func)dump_get_visible_region_request,
|
||||
(dump_func)dump_get_surface_region_request,
|
||||
(dump_func)dump_get_window_region_request,
|
||||
(dump_func)dump_set_window_region_request,
|
||||
(dump_func)dump_get_update_region_request,
|
||||
|
@ -4347,6 +4361,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
NULL,
|
||||
(dump_func)dump_get_windows_offset_reply,
|
||||
(dump_func)dump_get_visible_region_reply,
|
||||
(dump_func)dump_get_surface_region_reply,
|
||||
(dump_func)dump_get_window_region_reply,
|
||||
NULL,
|
||||
(dump_func)dump_get_update_region_reply,
|
||||
|
@ -4598,6 +4613,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"set_window_text",
|
||||
"get_windows_offset",
|
||||
"get_visible_region",
|
||||
"get_surface_region",
|
||||
"get_window_region",
|
||||
"set_window_region",
|
||||
"get_update_region",
|
||||
|
|
|
@ -1018,6 +1018,80 @@ error:
|
|||
}
|
||||
|
||||
|
||||
/* clip all children with a custom pixel format out of the visible region */
|
||||
static struct region *clip_pixel_format_children( struct window *parent, struct region *parent_clip,
|
||||
struct region *region, int offset_x, int offset_y )
|
||||
{
|
||||
struct window *ptr;
|
||||
struct region *clip = create_empty_region();
|
||||
|
||||
if (!clip) return NULL;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_REV( ptr, &parent->children, struct window, entry )
|
||||
{
|
||||
if (!(ptr->style & WS_VISIBLE)) continue;
|
||||
if (ptr->ex_style & WS_EX_TRANSPARENT) continue;
|
||||
|
||||
/* add the visible rect */
|
||||
set_region_rect( clip, &ptr->visible_rect );
|
||||
if (ptr->win_region && !intersect_window_region( clip, ptr )) break;
|
||||
offset_region( clip, offset_x, offset_y );
|
||||
if (!intersect_region( clip, clip, parent_clip )) break;
|
||||
if (!union_region( region, region, clip )) break;
|
||||
|
||||
/* subtract the client rect if it uses a custom pixel format */
|
||||
set_region_rect( clip, &ptr->client_rect );
|
||||
if (ptr->win_region && !intersect_window_region( clip, ptr )) break;
|
||||
offset_region( clip, offset_x, offset_y );
|
||||
if (!intersect_region( clip, clip, parent_clip )) break;
|
||||
if ((ptr->paint_flags & PAINT_HAS_PIXEL_FORMAT) && !subtract_region( region, region, clip ))
|
||||
break;
|
||||
|
||||
if (!clip_pixel_format_children( ptr, clip, region, offset_x + ptr->client_rect.left,
|
||||
offset_y + ptr->client_rect.top ))
|
||||
break;
|
||||
}
|
||||
free_region( clip );
|
||||
return region;
|
||||
}
|
||||
|
||||
|
||||
/* compute the visible surface region of a window, in parent coordinates */
|
||||
static struct region *get_surface_region( struct window *win )
|
||||
{
|
||||
struct region *region, *clip;
|
||||
int offset_x, offset_y;
|
||||
|
||||
/* create a region relative to the window itself */
|
||||
|
||||
if (!(region = create_empty_region())) return NULL;
|
||||
if (!(clip = create_empty_region())) goto error;
|
||||
set_region_rect( region, &win->visible_rect );
|
||||
if (win->win_region && !intersect_window_region( region, win )) goto error;
|
||||
set_region_rect( clip, &win->client_rect );
|
||||
if (win->win_region && !intersect_window_region( clip, win )) goto error;
|
||||
|
||||
/* clip children */
|
||||
|
||||
if (!is_desktop_window(win))
|
||||
{
|
||||
offset_x = win->client_rect.left;
|
||||
offset_y = win->client_rect.top;
|
||||
}
|
||||
else offset_x = offset_y = 0;
|
||||
|
||||
if (!clip_pixel_format_children( win, clip, region, offset_x, offset_y )) goto error;
|
||||
|
||||
free_region( clip );
|
||||
return region;
|
||||
|
||||
error:
|
||||
if (clip) free_region( clip );
|
||||
free_region( region );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* get the window class of a window */
|
||||
struct window_class* get_window_class( user_handle_t window )
|
||||
{
|
||||
|
@ -2107,7 +2181,7 @@ DECL_HANDLER(set_window_pos)
|
|||
{
|
||||
rectangle_t window_rect, client_rect, visible_rect;
|
||||
struct window *previous = NULL;
|
||||
struct window *win = get_window( req->handle );
|
||||
struct window *top, *win = get_window( req->handle );
|
||||
unsigned int flags = req->swp_flags;
|
||||
|
||||
if (!win) return;
|
||||
|
@ -2180,6 +2254,9 @@ DECL_HANDLER(set_window_pos)
|
|||
|
||||
reply->new_style = win->style;
|
||||
reply->new_ex_style = win->ex_style;
|
||||
|
||||
top = get_top_clipping_window( win );
|
||||
if (is_visible( top ) && (top->paint_flags & PAINT_HAS_SURFACE)) reply->surface_win = top->handle;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2348,6 +2425,26 @@ DECL_HANDLER(get_visible_region)
|
|||
}
|
||||
|
||||
|
||||
/* get the surface visible region of a window */
|
||||
DECL_HANDLER(get_surface_region)
|
||||
{
|
||||
struct region *region;
|
||||
struct window *win = get_window( req->window );
|
||||
|
||||
if (!win || !is_visible( win )) return;
|
||||
|
||||
if ((region = get_surface_region( win )))
|
||||
{
|
||||
rectangle_t *data;
|
||||
if (win->parent) map_win_region_to_screen( win->parent, region );
|
||||
data = get_region_data_and_free( region, get_reply_max_size(), &reply->total_size );
|
||||
if (data) set_reply_data_ptr( data, reply->total_size );
|
||||
}
|
||||
reply->visible_rect = win->visible_rect;
|
||||
if (win->parent) client_to_screen_rect( win->parent, &reply->visible_rect );
|
||||
}
|
||||
|
||||
|
||||
/* get the window region */
|
||||
DECL_HANDLER(get_window_region)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue