server: Add a request to compute the clipping region of a window surface.

This commit is contained in:
Alexandre Julliard 2012-10-09 11:47:50 +02:00
parent 20768173ba
commit a52ebb158e
5 changed files with 156 additions and 3 deletions

View File

@ -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 */

View File

@ -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 */

View File

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

View File

@ -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",

View File

@ -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)
{