Alexandre Julliard : server: Don' t expose the parent window in areas that are now part of the child visible region .
Alexandre Julliard
julliard at winehq.org
Thu Oct 18 07:59:31 CDT 2007
Module: wine
Branch: master
Commit: a771c53e27a89959d163c8f544467641ecc8a240
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a771c53e27a89959d163c8f544467641ecc8a240
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Oct 17 17:43:06 2007 +0200
server: Don't expose the parent window in areas that are now part of the child visible region.
---
server/window.c | 99 ++++++++++++++++++++++++++++++++++---------------------
1 files changed, 61 insertions(+), 38 deletions(-)
diff --git a/server/window.c b/server/window.c
index 15e4bc0..ce5297c 100644
--- a/server/window.c
+++ b/server/window.c
@@ -1303,23 +1303,51 @@ static unsigned int get_window_update_flags( struct window *win, struct window *
}
-/* expose a region of a window on its parent */
-/* the region is in window coordinates */
-static void expose_window( struct window *win, struct region *region )
+/* expose the areas revealed by a vis region change on the window parent */
+/* returns the region exposed on the window itself (in client coordinates) */
+static struct region *expose_window( struct window *win, const rectangle_t *old_window_rect,
+ struct region *old_vis_rgn )
{
struct window *parent = win;
- int offset_x = win->window_rect.left - win->client_rect.left;
- int offset_y = win->window_rect.top - win->client_rect.top;
+ struct region *new_vis_rgn, *exposed_rgn;
- if (win->parent && !is_desktop_window(win->parent))
+ if (!(new_vis_rgn = get_visible_region( win, DCX_WINDOW ))) return NULL;
+
+ if ((exposed_rgn = create_empty_region()))
{
- offset_x += win->client_rect.left;
- offset_y += win->client_rect.top;
- parent = win->parent;
+ if (subtract_region( exposed_rgn, new_vis_rgn, old_vis_rgn ) && !is_region_empty( exposed_rgn ))
+ {
+ /* make it relative to the new client area */
+ offset_region( exposed_rgn, win->window_rect.left - win->client_rect.left,
+ win->window_rect.top - win->client_rect.top );
+ }
+ else
+ {
+ free_region( exposed_rgn );
+ exposed_rgn = NULL;
+ }
}
- offset_region( region, offset_x, offset_y );
- redraw_window( parent, region, 0, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN );
- offset_region( region, -offset_x, -offset_y );
+
+ /* make it relative to the old window pos for subtracting */
+ offset_region( new_vis_rgn, win->window_rect.left - old_window_rect->left,
+ win->window_rect.top - old_window_rect->top );
+
+ if (subtract_region( new_vis_rgn, old_vis_rgn, new_vis_rgn ) && !is_region_empty( new_vis_rgn ))
+ {
+ /* make it relative to new client rect again */
+ int offset_x = old_window_rect->left - win->client_rect.left;
+ int offset_y = old_window_rect->top - win->client_rect.top;
+ if (win->parent && !is_desktop_window(win->parent))
+ {
+ offset_x += win->client_rect.left;
+ offset_y += win->client_rect.top;
+ parent = win->parent;
+ }
+ offset_region( new_vis_rgn, offset_x, offset_y );
+ redraw_window( parent, new_vis_rgn, 0, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN );
+ }
+ free_region( new_vis_rgn );
+ return exposed_rgn;
}
@@ -1329,7 +1357,7 @@ static void set_window_pos( struct window *win, struct window *previous,
const rectangle_t *client_rect, const rectangle_t *visible_rect,
const rectangle_t *valid_rects )
{
- struct region *old_vis_rgn = NULL, *new_vis_rgn;
+ struct region *old_vis_rgn = NULL, *exposed_rgn = NULL;
const rectangle_t old_window_rect = win->window_rect;
const rectangle_t old_visible_rect = win->visible_rect;
const rectangle_t old_client_rect = win->client_rect;
@@ -1357,23 +1385,10 @@ static void set_window_pos( struct window *win, struct window *previous,
/* if the window is not visible, everything is easy */
if (!visible) return;
- if (!(new_vis_rgn = get_visible_region( win, DCX_WINDOW )))
- {
- free_region( old_vis_rgn );
- clear_error(); /* ignore error since the window info has been modified already */
- return;
- }
-
/* expose anything revealed by the change */
if (!(swp_flags & SWP_NOREDRAW))
- {
- offset_region( old_vis_rgn, old_window_rect.left - window_rect->left,
- old_window_rect.top - window_rect->top );
- if (xor_region( new_vis_rgn, old_vis_rgn, new_vis_rgn ))
- expose_window( win, new_vis_rgn );
- }
- free_region( old_vis_rgn );
+ exposed_rgn = expose_window( win, &old_window_rect, old_vis_rgn );
if (!(win->style & WS_VISIBLE))
{
@@ -1443,19 +1458,28 @@ static void set_window_pos( struct window *win, struct window *previous,
else if (valid_rects)
set_region_rect( tmp, &valid_rects[0] );
- set_region_rect( new_vis_rgn, window_rect );
- if (subtract_region( tmp, new_vis_rgn, tmp ))
+ set_region_rect( old_vis_rgn, window_rect );
+ if (!subtract_region( tmp, old_vis_rgn, tmp )) free_region( tmp );
+ else
{
if (!is_desktop_window(win))
offset_region( tmp, -client_rect->left, -client_rect->top );
- redraw_window( win, tmp, 1, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN );
+ if (exposed_rgn)
+ {
+ union_region( exposed_rgn, exposed_rgn, tmp );
+ free_region( tmp );
+ }
+ else exposed_rgn = tmp;
}
- free_region( tmp );
}
}
+ if (exposed_rgn)
+ redraw_window( win, exposed_rgn, 1, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN );
+
done:
- free_region( new_vis_rgn );
+ free_region( old_vis_rgn );
+ if (exposed_rgn) free_region( exposed_rgn );
clear_error(); /* we ignore out of memory errors once the new rects have been set */
}
@@ -1463,7 +1487,7 @@ done:
/* set the window region, updating the update region if necessary */
static void set_window_region( struct window *win, struct region *region, int redraw )
{
- struct region *old_vis_rgn = NULL, *new_vis_rgn;
+ struct region *old_vis_rgn = NULL, *exposed_rgn;
/* no need to redraw if window is not visible */
if (redraw && !is_visible( win )) redraw = 0;
@@ -1473,12 +1497,11 @@ static void set_window_region( struct window *win, struct region *region, int re
if (win->win_region) free_region( win->win_region );
win->win_region = region;
- if (old_vis_rgn && (new_vis_rgn = get_visible_region( win, DCX_WINDOW )))
+ /* expose anything revealed by the change */
+ if (old_vis_rgn && ((exposed_rgn = expose_window( win, &win->window_rect, old_vis_rgn ))))
{
- /* expose anything revealed by the change */
- if (xor_region( new_vis_rgn, old_vis_rgn, new_vis_rgn ))
- expose_window( win, new_vis_rgn );
- free_region( new_vis_rgn );
+ redraw_window( win, exposed_rgn, 1, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN );
+ free_region( exposed_rgn );
}
if (old_vis_rgn) free_region( old_vis_rgn );
More information about the wine-cvs
mailing list