mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 16:47:17 +00:00
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;
|
struct reply_header __header;
|
||||||
unsigned int new_style;
|
unsigned int new_style;
|
||||||
unsigned int new_ex_style;
|
unsigned int new_ex_style;
|
||||||
|
user_handle_t surface_win;
|
||||||
|
char __pad_20[4];
|
||||||
};
|
};
|
||||||
#define SET_WINPOS_PAINT_SURFACE 0x01
|
#define SET_WINPOS_PAINT_SURFACE 0x01
|
||||||
#define SET_WINPOS_PIXEL_FORMAT 0x02
|
#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 get_window_region_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
|
@ -5092,6 +5110,7 @@ enum request
|
||||||
REQ_set_window_text,
|
REQ_set_window_text,
|
||||||
REQ_get_windows_offset,
|
REQ_get_windows_offset,
|
||||||
REQ_get_visible_region,
|
REQ_get_visible_region,
|
||||||
|
REQ_get_surface_region,
|
||||||
REQ_get_window_region,
|
REQ_get_window_region,
|
||||||
REQ_set_window_region,
|
REQ_set_window_region,
|
||||||
REQ_get_update_region,
|
REQ_get_update_region,
|
||||||
|
@ -5347,6 +5366,7 @@ union generic_request
|
||||||
struct set_window_text_request set_window_text_request;
|
struct set_window_text_request set_window_text_request;
|
||||||
struct get_windows_offset_request get_windows_offset_request;
|
struct get_windows_offset_request get_windows_offset_request;
|
||||||
struct get_visible_region_request get_visible_region_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 get_window_region_request get_window_region_request;
|
||||||
struct set_window_region_request set_window_region_request;
|
struct set_window_region_request set_window_region_request;
|
||||||
struct get_update_region_request get_update_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 set_window_text_reply set_window_text_reply;
|
||||||
struct get_windows_offset_reply get_windows_offset_reply;
|
struct get_windows_offset_reply get_windows_offset_reply;
|
||||||
struct get_visible_region_reply get_visible_region_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 get_window_region_reply get_window_region_reply;
|
||||||
struct set_window_region_reply set_window_region_reply;
|
struct set_window_region_reply set_window_region_reply;
|
||||||
struct get_update_region_reply get_update_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;
|
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 */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -2401,6 +2401,7 @@ enum message_type
|
||||||
@REPLY
|
@REPLY
|
||||||
unsigned int new_style; /* new window style */
|
unsigned int new_style; /* new window style */
|
||||||
unsigned int new_ex_style; /* new window extended style */
|
unsigned int new_ex_style; /* new window extended style */
|
||||||
|
user_handle_t surface_win; /* window that needs a surface update */
|
||||||
@END
|
@END
|
||||||
#define SET_WINPOS_PAINT_SURFACE 0x01 /* window has a paintable surface */
|
#define SET_WINPOS_PAINT_SURFACE 0x01 /* window has a paintable surface */
|
||||||
#define SET_WINPOS_PIXEL_FORMAT 0x02 /* window has a custom pixel format */
|
#define SET_WINPOS_PIXEL_FORMAT 0x02 /* window has a custom pixel format */
|
||||||
|
@ -2462,6 +2463,16 @@ enum coords_relative
|
||||||
@END
|
@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 */
|
/* Get the window region */
|
||||||
@REQ(get_window_region)
|
@REQ(get_window_region)
|
||||||
user_handle_t window; /* handle to the window */
|
user_handle_t window; /* handle to the window */
|
||||||
|
|
|
@ -269,6 +269,7 @@ DECL_HANDLER(get_window_text);
|
||||||
DECL_HANDLER(set_window_text);
|
DECL_HANDLER(set_window_text);
|
||||||
DECL_HANDLER(get_windows_offset);
|
DECL_HANDLER(get_windows_offset);
|
||||||
DECL_HANDLER(get_visible_region);
|
DECL_HANDLER(get_visible_region);
|
||||||
|
DECL_HANDLER(get_surface_region);
|
||||||
DECL_HANDLER(get_window_region);
|
DECL_HANDLER(get_window_region);
|
||||||
DECL_HANDLER(set_window_region);
|
DECL_HANDLER(set_window_region);
|
||||||
DECL_HANDLER(get_update_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_set_window_text,
|
||||||
(req_handler)req_get_windows_offset,
|
(req_handler)req_get_windows_offset,
|
||||||
(req_handler)req_get_visible_region,
|
(req_handler)req_get_visible_region,
|
||||||
|
(req_handler)req_get_surface_region,
|
||||||
(req_handler)req_get_window_region,
|
(req_handler)req_get_window_region,
|
||||||
(req_handler)req_set_window_region,
|
(req_handler)req_set_window_region,
|
||||||
(req_handler)req_get_update_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( 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_style) == 8 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct set_window_pos_reply, new_ex_style) == 12 );
|
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, handle) == 12 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_request, relative) == 16 );
|
C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_request, relative) == 16 );
|
||||||
C_ASSERT( sizeof(struct get_window_rectangles_request) == 24 );
|
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, win_rect) == 28 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_visible_region_reply, total_size) == 44 );
|
C_ASSERT( FIELD_OFFSET(struct get_visible_region_reply, total_size) == 44 );
|
||||||
C_ASSERT( sizeof(struct get_visible_region_reply) == 48 );
|
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( FIELD_OFFSET(struct get_window_region_request, window) == 12 );
|
||||||
C_ASSERT( sizeof(struct get_window_region_request) == 16 );
|
C_ASSERT( sizeof(struct get_window_region_request) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_window_region_reply, total_size) == 8 );
|
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_style=%08x", req->new_style );
|
||||||
fprintf( stderr, ", new_ex_style=%08x", req->new_ex_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 )
|
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 );
|
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 )
|
static void dump_get_window_region_request( const struct get_window_region_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " window=%08x", req->window );
|
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_set_window_text_request,
|
||||||
(dump_func)dump_get_windows_offset_request,
|
(dump_func)dump_get_windows_offset_request,
|
||||||
(dump_func)dump_get_visible_region_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_get_window_region_request,
|
||||||
(dump_func)dump_set_window_region_request,
|
(dump_func)dump_set_window_region_request,
|
||||||
(dump_func)dump_get_update_region_request,
|
(dump_func)dump_get_update_region_request,
|
||||||
|
@ -4347,6 +4361,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||||
NULL,
|
NULL,
|
||||||
(dump_func)dump_get_windows_offset_reply,
|
(dump_func)dump_get_windows_offset_reply,
|
||||||
(dump_func)dump_get_visible_region_reply,
|
(dump_func)dump_get_visible_region_reply,
|
||||||
|
(dump_func)dump_get_surface_region_reply,
|
||||||
(dump_func)dump_get_window_region_reply,
|
(dump_func)dump_get_window_region_reply,
|
||||||
NULL,
|
NULL,
|
||||||
(dump_func)dump_get_update_region_reply,
|
(dump_func)dump_get_update_region_reply,
|
||||||
|
@ -4598,6 +4613,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||||
"set_window_text",
|
"set_window_text",
|
||||||
"get_windows_offset",
|
"get_windows_offset",
|
||||||
"get_visible_region",
|
"get_visible_region",
|
||||||
|
"get_surface_region",
|
||||||
"get_window_region",
|
"get_window_region",
|
||||||
"set_window_region",
|
"set_window_region",
|
||||||
"get_update_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 */
|
/* get the window class of a window */
|
||||||
struct window_class* get_window_class( user_handle_t 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;
|
rectangle_t window_rect, client_rect, visible_rect;
|
||||||
struct window *previous = NULL;
|
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;
|
unsigned int flags = req->swp_flags;
|
||||||
|
|
||||||
if (!win) return;
|
if (!win) return;
|
||||||
|
@ -2180,6 +2254,9 @@ DECL_HANDLER(set_window_pos)
|
||||||
|
|
||||||
reply->new_style = win->style;
|
reply->new_style = win->style;
|
||||||
reply->new_ex_style = win->ex_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 */
|
/* get the window region */
|
||||||
DECL_HANDLER(get_window_region)
|
DECL_HANDLER(get_window_region)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue