server: Add a couple of rectangle helper functions.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2018-07-05 12:46:18 +02:00
parent dbfc4ab5ed
commit d3876ca84e
3 changed files with 33 additions and 47 deletions

View File

@ -129,7 +129,7 @@ static inline int validate_rectangles( const rectangle_t *rects, unsigned int nb
for (ptr = rects, end = rects + nb_rects; ptr < end; ptr++)
{
if (ptr->left >= ptr->right || ptr->top >= ptr->bottom) return 0; /* empty rectangle */
if (is_rect_empty( ptr )) return 0; /* empty rectangle */
if (ptr == end - 1) break;
if (ptr[0].top == ptr[1].top) /* same band */
{
@ -623,7 +623,7 @@ void free_region( struct region *region )
/* set region to a simple rectangle */
void set_region_rect( struct region *region, const rectangle_t *rect )
{
if (rect->left < rect->right && rect->top < rect->bottom)
if (!is_rect_empty( rect ))
{
region->num_rects = 1;
region->rects[0] = region->extents = *rect;
@ -631,10 +631,7 @@ void set_region_rect( struct region *region, const rectangle_t *rect )
else
{
region->num_rects = 0;
region->extents.left = 0;
region->extents.top = 0;
region->extents.right = 0;
region->extents.bottom = 0;
region->extents = empty_rect;
}
}
@ -700,16 +697,8 @@ void offset_region( struct region *region, int x, int y )
if (!region->num_rects) return;
for (rect = region->rects, end = rect + region->num_rects; rect < end; rect++)
{
rect->left += x;
rect->right += x;
rect->top += y;
rect->bottom += y;
}
region->extents.left += x;
region->extents.right += x;
region->extents.top += y;
region->extents.bottom += y;
offset_rect( rect, x, y );
offset_rect( &region->extents, x, y );
}
/* mirror a region relative to a window client rect */

View File

@ -188,6 +188,25 @@ extern void set_process_default_desktop( struct process *process, struct desktop
extern void close_process_desktop( struct process *process );
extern void close_thread_desktop( struct thread *thread );
static inline int is_rect_empty( const rectangle_t *rect )
{
return (rect->left >= rect->right || rect->top >= rect->bottom);
}
static inline int point_in_rect( const rectangle_t *rect, int x, int y )
{
return (x >= rect->left && x < rect->right && y >= rect->top && y < rect->bottom);
}
/* offset the coordinates of a rectangle */
static inline void offset_rect( rectangle_t *rect, int offset_x, int offset_y )
{
rect->left += offset_x;
rect->top += offset_y;
rect->right += offset_x;
rect->bottom += offset_y;
}
/* mirror a rectangle respective to the window client area */
static inline void mirror_rect( const rectangle_t *client_rect, rectangle_t *rect )
{
@ -204,7 +223,7 @@ static inline int intersect_rect( rectangle_t *dst, const rectangle_t *src1, con
dst->top = max( src1->top, src2->top );
dst->right = min( src1->right, src2->right );
dst->bottom = min( src1->bottom, src2->bottom );
return (dst->left < dst->right && dst->top < dst->bottom);
return !is_rect_empty( dst );
}
/* validate a window handle and return the full handle */

View File

@ -114,6 +114,8 @@ struct user_handle_array
int total;
};
static const rectangle_t empty_rect;
/* global window pointers */
static struct window *shell_window;
static struct window *shell_listview;
@ -431,8 +433,7 @@ struct process *get_top_window_owner( struct desktop *desktop )
void get_top_window_rectangle( struct desktop *desktop, rectangle_t *rect )
{
struct window *win = desktop->top_window;
if (!win) rect->left = rect->top = rect->right = rect->bottom = 0;
else *rect = win->window_rect;
*rect = win ? win->window_rect : empty_rect;
}
/* post a message to the desktop window */
@ -447,7 +448,6 @@ void post_desktop_message( struct desktop *desktop, unsigned int message,
static struct window *create_window( struct window *parent, struct window *owner,
atom_t atom, mod_handle_t instance )
{
static const rectangle_t empty_rect;
int extra_bytes;
struct window *win = NULL;
struct desktop *desktop;
@ -665,8 +665,7 @@ static inline int is_point_in_window( struct window *win, int x, int y )
return 0; /* disabled child */
if ((win->ex_style & (WS_EX_LAYERED|WS_EX_TRANSPARENT)) == (WS_EX_LAYERED|WS_EX_TRANSPARENT))
return 0; /* transparent */
if (x < win->visible_rect.left || x >= win->visible_rect.right ||
y < win->visible_rect.top || y >= win->visible_rect.bottom)
if (!point_in_rect( &win->visible_rect, x, y ))
return 0; /* not in window */
if (win->win_region &&
!point_in_region( win->win_region, x - win->window_rect.left, y - win->window_rect.top ))
@ -710,9 +709,7 @@ static struct window *child_window_from_point( struct window *parent, int x, int
if (ptr->style & (WS_MINIMIZE|WS_DISABLED)) return ptr;
/* if point is not in client area, return at once */
if (x < ptr->client_rect.left || x >= ptr->client_rect.right ||
y < ptr->client_rect.top || y >= ptr->client_rect.bottom)
return ptr;
if (!point_in_rect( &ptr->client_rect, x, y )) return ptr;
return child_window_from_point( ptr, x - ptr->client_rect.left, y - ptr->client_rect.top );
}
@ -730,9 +727,7 @@ static int get_window_children_from_point( struct window *parent, int x, int y,
if (!is_point_in_window( ptr, x, y )) continue; /* skip it */
/* if point is in client area, and window is not minimized or disabled, check children */
if (!(ptr->style & (WS_MINIMIZE|WS_DISABLED)) &&
x >= ptr->client_rect.left && x < ptr->client_rect.right &&
y >= ptr->client_rect.top && y < ptr->client_rect.bottom)
if (!(ptr->style & (WS_MINIMIZE|WS_DISABLED)) && point_in_rect( &ptr->client_rect, x, y ))
{
if (!get_window_children_from_point( ptr, x - ptr->client_rect.left,
y - ptr->client_rect.top, array ))
@ -794,9 +789,7 @@ static int all_windows_from_point( struct window *top, int x, int y, struct user
if (!is_point_in_window( top, x, y )) return 1;
/* if point is in client area, and window is not minimized or disabled, check children */
if (!(top->style & (WS_MINIMIZE|WS_DISABLED)) &&
x >= top->client_rect.left && x < top->client_rect.right &&
y >= top->client_rect.top && y < top->client_rect.bottom)
if (!(top->style & (WS_MINIMIZE|WS_DISABLED)) && point_in_rect( &top->client_rect, x, y ))
{
if (!is_desktop_window(top))
{
@ -907,12 +900,7 @@ static inline void client_to_screen( struct window *win, int *x, int *y )
static inline void client_to_screen_rect( struct window *win, rectangle_t *rect )
{
for ( ; win && !is_desktop_window(win); win = win->parent)
{
rect->left += win->client_rect.left;
rect->right += win->client_rect.left;
rect->top += win->client_rect.top;
rect->bottom += win->client_rect.top;
}
offset_rect( rect, win->client_rect.left, win->client_rect.top );
}
/* map the region from window to screen coordinates */
@ -956,16 +944,6 @@ static struct region *clip_children( struct window *parent, struct window *last,
}
/* offset the coordinates of a rectangle */
static inline void offset_rect( rectangle_t *rect, int offset_x, int offset_y )
{
rect->left += offset_x;
rect->top += offset_y;
rect->right += offset_x;
rect->bottom += offset_y;
}
/* set the region to the client rect clipped by the window rect, in parent-relative coordinates */
static void set_region_client_rect( struct region *region, struct window *win )
{