Commit eea70694 authored by Alexandre Julliard's avatar Alexandre Julliard

The update region passed in WM_NCPAINT and the clipping region passed

to GetDCEx have to be in screen coordinates.
parent 6b10c324
...@@ -80,7 +80,7 @@ static void dump_rdw_flags(UINT flags) ...@@ -80,7 +80,7 @@ static void dump_rdw_flags(UINT flags)
/*********************************************************************** /***********************************************************************
* get_update_region * get_update_region
* *
* Return update region for a window. * Return update region (in screen coordinates) for a window.
*/ */
static HRGN get_update_region( HWND hwnd, UINT *flags, HWND *child ) static HRGN get_update_region( HWND hwnd, UINT *flags, HWND *child )
{ {
...@@ -172,7 +172,7 @@ static BOOL redraw_window_rects( HWND hwnd, UINT flags, const RECT *rects, UINT ...@@ -172,7 +172,7 @@ static BOOL redraw_window_rects( HWND hwnd, UINT flags, const RECT *rects, UINT
/*********************************************************************** /***********************************************************************
* send_ncpaint * send_ncpaint
* *
* Send a WM_NCPAINT message if needed, and return the resulting update region. * Send a WM_NCPAINT message if needed, and return the resulting update region (in screen coords).
* Helper for erase_now and BeginPaint. * Helper for erase_now and BeginPaint.
*/ */
static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags ) static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags )
...@@ -186,18 +186,11 @@ static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags ) ...@@ -186,18 +186,11 @@ static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags )
{ {
RECT client, update; RECT client, update;
INT type; INT type;
WND *win = WIN_GetPtr( hwnd );
if (!win || win == WND_OTHER_PROCESS || win == WND_DESKTOP)
{
DeleteObject( whole_rgn );
return 0;
}
/* check if update rgn overlaps with nonclient area */ /* check if update rgn overlaps with nonclient area */
type = GetRgnBox( whole_rgn, &update ); type = GetRgnBox( whole_rgn, &update );
client = win->rectClient; GetClientRect( hwnd, &client );
OffsetRect( &client, -win->rectWindow.left, -win->rectWindow.top ); MapWindowPoints( hwnd, 0, (POINT *)&client, 2 );
if ((*flags & UPDATE_NONCLIENT) || if ((*flags & UPDATE_NONCLIENT) ||
update.left < client.left || update.top < client.top || update.left < client.left || update.top < client.top ||
...@@ -207,12 +200,15 @@ static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags ) ...@@ -207,12 +200,15 @@ static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags )
CombineRgn( client_rgn, client_rgn, whole_rgn, RGN_AND ); CombineRgn( client_rgn, client_rgn, whole_rgn, RGN_AND );
/* check if update rgn contains complete nonclient area */ /* check if update rgn contains complete nonclient area */
if (type == SIMPLEREGION && update.left == 0 && update.top == 0 && if (type == SIMPLEREGION)
update.right == win->rectWindow.right - win->rectWindow.left &&
update.bottom == win->rectWindow.bottom - win->rectWindow.top)
{ {
DeleteObject( whole_rgn ); RECT window;
whole_rgn = (HRGN)1; GetWindowRect( hwnd, &window );
if (EqualRect( &window, &update ))
{
DeleteObject( whole_rgn );
whole_rgn = (HRGN)1;
}
} }
} }
else else
...@@ -220,10 +216,6 @@ static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags ) ...@@ -220,10 +216,6 @@ static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags )
client_rgn = whole_rgn; client_rgn = whole_rgn;
whole_rgn = 0; whole_rgn = 0;
} }
/* map client region to client coordinates */
OffsetRgn( client_rgn, win->rectWindow.left - win->rectClient.left,
win->rectWindow.top - win->rectClient.top );
WIN_ReleasePtr( win );
if (whole_rgn) /* NOTE: WM_NCPAINT allows wParam to be 1 */ if (whole_rgn) /* NOTE: WM_NCPAINT allows wParam to be 1 */
{ {
...@@ -247,7 +239,9 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn, ...@@ -247,7 +239,9 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn,
{ {
BOOL need_erase = FALSE; BOOL need_erase = FALSE;
HDC hdc; HDC hdc;
RECT dummy;
if (!clip_rect) clip_rect = &dummy;
if (hdc_ret || (flags & UPDATE_ERASE)) if (hdc_ret || (flags & UPDATE_ERASE))
{ {
UINT dcx_flags = DCX_INTERSECTRGN | DCX_USESTYLE; UINT dcx_flags = DCX_INTERSECTRGN | DCX_USESTYLE;
...@@ -266,7 +260,7 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn, ...@@ -266,7 +260,7 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn,
if (!hdc_ret) if (!hdc_ret)
{ {
if (need_erase && hwnd != GetDesktopWindow()) /* FIXME: mark it as needing erase again */ if (need_erase && hwnd != GetDesktopWindow()) /* FIXME: mark it as needing erase again */
RedrawWindow( hwnd, NULL, client_rgn, RDW_INVALIDATE | RDW_ERASE | RDW_NOCHILDREN ); RedrawWindow( hwnd, clip_rect, 0, RDW_INVALIDATE | RDW_ERASE | RDW_NOCHILDREN );
ReleaseDC( hwnd, hdc ); ReleaseDC( hwnd, hdc );
} }
} }
...@@ -290,14 +284,13 @@ static void erase_now( HWND hwnd, UINT rdw_flags ) ...@@ -290,14 +284,13 @@ static void erase_now( HWND hwnd, UINT rdw_flags )
/* loop while we find a child to repaint */ /* loop while we find a child to repaint */
for (;;) for (;;)
{ {
RECT rect;
UINT flags = UPDATE_NONCLIENT | UPDATE_ERASE; UINT flags = UPDATE_NONCLIENT | UPDATE_ERASE;
if (rdw_flags & RDW_NOCHILDREN) flags |= UPDATE_NOCHILDREN; if (rdw_flags & RDW_NOCHILDREN) flags |= UPDATE_NOCHILDREN;
else if (rdw_flags & RDW_ALLCHILDREN) flags |= UPDATE_ALLCHILDREN; else if (rdw_flags & RDW_ALLCHILDREN) flags |= UPDATE_ALLCHILDREN;
if (!(hrgn = send_ncpaint( hwnd, &child, &flags ))) break; if (!(hrgn = send_ncpaint( hwnd, &child, &flags ))) break;
send_erase( child, flags, hrgn, &rect, NULL ); send_erase( child, flags, hrgn, NULL, NULL );
DeleteObject( hrgn ); DeleteObject( hrgn );
if (!flags) break; /* nothing more to do */ if (!flags) break; /* nothing more to do */
...@@ -349,12 +342,11 @@ static void update_now( HWND hwnd, UINT rdw_flags ) ...@@ -349,12 +342,11 @@ static void update_now( HWND hwnd, UINT rdw_flags )
{ {
UINT erase_flags = UPDATE_NONCLIENT | UPDATE_ERASE | UPDATE_NOCHILDREN; UINT erase_flags = UPDATE_NONCLIENT | UPDATE_ERASE | UPDATE_NOCHILDREN;
HRGN hrgn; HRGN hrgn;
RECT rect;
TRACE( "%p not repainted properly, erasing\n", child ); TRACE( "%p not repainted properly, erasing\n", child );
if ((hrgn = send_ncpaint( child, NULL, &erase_flags ))) if ((hrgn = send_ncpaint( child, NULL, &erase_flags )))
{ {
send_erase( child, erase_flags, hrgn, &rect, NULL ); send_erase( child, erase_flags, hrgn, NULL, NULL );
DeleteObject( hrgn ); DeleteObject( hrgn );
} }
prev = 0; prev = 0;
...@@ -529,10 +521,6 @@ BOOL WINAPI RedrawWindow( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags ) ...@@ -529,10 +521,6 @@ BOOL WINAPI RedrawWindow( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags )
if (!hwnd) hwnd = GetDesktopWindow(); if (!hwnd) hwnd = GetDesktopWindow();
/* check if the window or its parents are visible/not minimized */
if (!WIN_IsWindowDrawable( hwnd, !(flags & RDW_FRAME) )) return TRUE;
if (TRACE_ON(win)) if (TRACE_ON(win))
{ {
if (hrgn) if (hrgn)
...@@ -638,8 +626,12 @@ INT WINAPI GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) ...@@ -638,8 +626,12 @@ INT WINAPI GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
if ((update_rgn = send_ncpaint( hwnd, NULL, &flags ))) if ((update_rgn = send_ncpaint( hwnd, NULL, &flags )))
{ {
RECT rect; POINT offset;
send_erase( hwnd, flags, update_rgn, &rect, NULL ); send_erase( hwnd, flags, update_rgn, NULL, NULL );
/* map region to client coordinates */
offset.x = offset.y = 0;
ScreenToClient( hwnd, &offset );
OffsetRgn( update_rgn, offset.x, offset.y );
retval = CombineRgn( hrgn, update_rgn, 0, RGN_COPY ); retval = CombineRgn( hrgn, update_rgn, 0, RGN_COPY );
DeleteObject( update_rgn ); DeleteObject( update_rgn );
} }
...@@ -653,7 +645,6 @@ INT WINAPI GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) ...@@ -653,7 +645,6 @@ INT WINAPI GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase ) BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
{ {
HDC hdc; HDC hdc;
RECT dummy;
UINT flags = UPDATE_NOCHILDREN; UINT flags = UPDATE_NOCHILDREN;
HRGN update_rgn; HRGN update_rgn;
...@@ -661,9 +652,13 @@ BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase ) ...@@ -661,9 +652,13 @@ BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
if (!(update_rgn = send_ncpaint( hwnd, NULL, &flags ))) return FALSE; if (!(update_rgn = send_ncpaint( hwnd, NULL, &flags ))) return FALSE;
if (rect) GetRgnBox( update_rgn, rect ); if (rect)
{
if (GetRgnBox( update_rgn, rect ) != NULLREGION)
MapWindowPoints( 0, hwnd, (LPPOINT)rect, 2 );
}
send_erase( hwnd, flags, update_rgn, &dummy, &hdc ); send_erase( hwnd, flags, update_rgn, NULL, &hdc );
if (hdc) if (hdc)
{ {
if (rect) DPtoLP( hdc, (LPPOINT)rect, 2 ); if (rect) DPtoLP( hdc, (LPPOINT)rect, 2 );
......
...@@ -167,7 +167,7 @@ static void test_dc_visrgn(void) ...@@ -167,7 +167,7 @@ static void test_dc_visrgn(void)
hdc = GetDCEx( hwnd_cache, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE ); hdc = GetDCEx( hwnd_cache, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE );
SetRectEmpty( &rect ); SetRectEmpty( &rect );
GetClipBox( hdc, &rect ); GetClipBox( hdc, &rect );
todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
"invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom );
ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
ReleaseDC( hwnd_cache, hdc ); ReleaseDC( hwnd_cache, hdc );
...@@ -181,7 +181,7 @@ static void test_dc_visrgn(void) ...@@ -181,7 +181,7 @@ static void test_dc_visrgn(void)
hdc = GetDCEx( hwnd_cache, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE | DCX_NORESETATTRS ); hdc = GetDCEx( hwnd_cache, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE | DCX_NORESETATTRS );
SetRectEmpty( &rect ); SetRectEmpty( &rect );
GetClipBox( hdc, &rect ); GetClipBox( hdc, &rect );
todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
"invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom );
ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
ReleaseDC( hwnd_cache, hdc ); ReleaseDC( hwnd_cache, hdc );
...@@ -201,19 +201,19 @@ static void test_dc_visrgn(void) ...@@ -201,19 +201,19 @@ static void test_dc_visrgn(void)
hdc = GetDCEx( hwnd_owndc, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE ); hdc = GetDCEx( hwnd_owndc, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE );
SetRectEmpty( &rect ); SetRectEmpty( &rect );
GetClipBox( hdc, &rect ); GetClipBox( hdc, &rect );
todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
"invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom );
ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
ReleaseDC( hwnd_owndc, hdc ); ReleaseDC( hwnd_owndc, hdc );
ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
SetRectEmpty( &rect ); SetRectEmpty( &rect );
GetClipBox( hdc, &rect ); GetClipBox( hdc, &rect );
todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
"invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom );
hdc = GetDCEx( hwnd_owndc, 0, DCX_USESTYLE ); hdc = GetDCEx( hwnd_owndc, 0, DCX_USESTYLE );
SetRectEmpty( &rect ); SetRectEmpty( &rect );
GetClipBox( hdc, &rect ); GetClipBox( hdc, &rect );
todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
"invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom );
ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
ReleaseDC( hwnd_owndc, hdc ); ReleaseDC( hwnd_owndc, hdc );
...@@ -226,7 +226,7 @@ static void test_dc_visrgn(void) ...@@ -226,7 +226,7 @@ static void test_dc_visrgn(void)
ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" ); ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" );
SetRectEmpty( &rect ); SetRectEmpty( &rect );
GetClipBox( hdc, &rect ); GetClipBox( hdc, &rect );
todo_wine ok( rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30, ok( rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30,
"invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom );
ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" ); ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
ReleaseDC( hwnd_owndc, hdc ); ReleaseDC( hwnd_owndc, hdc );
...@@ -247,20 +247,20 @@ static void test_dc_visrgn(void) ...@@ -247,20 +247,20 @@ static void test_dc_visrgn(void)
hdc = GetDCEx( hwnd_classdc, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE ); hdc = GetDCEx( hwnd_classdc, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE );
SetRectEmpty( &rect ); SetRectEmpty( &rect );
GetClipBox( hdc, &rect ); GetClipBox( hdc, &rect );
todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
"invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom );
ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
ReleaseDC( hwnd_classdc, hdc ); ReleaseDC( hwnd_classdc, hdc );
ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
SetRectEmpty( &rect ); SetRectEmpty( &rect );
GetClipBox( hdc, &rect ); GetClipBox( hdc, &rect );
todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
"invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom );
hdc = GetDCEx( hwnd_classdc, 0, DCX_USESTYLE ); hdc = GetDCEx( hwnd_classdc, 0, DCX_USESTYLE );
SetRectEmpty( &rect ); SetRectEmpty( &rect );
GetClipBox( hdc, &rect ); GetClipBox( hdc, &rect );
todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
"invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom );
ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
ReleaseDC( hwnd_classdc, hdc ); ReleaseDC( hwnd_classdc, hdc );
...@@ -273,7 +273,7 @@ static void test_dc_visrgn(void) ...@@ -273,7 +273,7 @@ static void test_dc_visrgn(void)
ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" ); ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" );
SetRectEmpty( &rect ); SetRectEmpty( &rect );
GetClipBox( hdc, &rect ); GetClipBox( hdc, &rect );
todo_wine ok( rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30, ok( rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30,
"invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom );
ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" ); ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
......
...@@ -224,6 +224,10 @@ static void set_drawable( struct dce *dce, BOOL update_visrgn ) ...@@ -224,6 +224,10 @@ static void set_drawable( struct dce *dce, BOOL update_visrgn )
CombineRgn( visRgn, visRgn, dce->clip_rgn, CombineRgn( visRgn, visRgn, dce->clip_rgn,
(flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF ); (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
/* map region to DC coordinates */
OffsetRgn( visRgn, -(escape.org.x + escape.drawable_org.x),
-(escape.org.y + escape.drawable_org.y) );
SelectVisRgn16( HDC_16(dce->hdc), HRGN_16(visRgn) ); SelectVisRgn16( HDC_16(dce->hdc), HRGN_16(visRgn) );
DeleteObject( visRgn ); DeleteObject( visRgn );
} }
......
...@@ -633,6 +633,21 @@ static struct region *intersect_window_region( struct region *region, struct win ...@@ -633,6 +633,21 @@ static struct region *intersect_window_region( struct region *region, struct win
} }
/* map the region from window to screen coordinates */
static inline void map_win_region_to_screen( struct window *win, struct region *region )
{
int x = win->window_rect.left;
int y = win->window_rect.top;
for (win = win->parent; win; win = win->parent)
{
x += win->client_rect.left;
y += win->client_rect.top;
}
offset_region( region, x, y );
}
/* clip all children of a given window out of the visible region */ /* clip all children of a given window out of the visible region */
static struct region *clip_children( struct window *parent, struct window *last, static struct region *clip_children( struct window *parent, struct window *last,
struct region *region, int offset_x, int offset_y ) struct region *region, int offset_x, int offset_y )
...@@ -690,7 +705,7 @@ static inline struct window *get_top_clipping_window( struct window *win ) ...@@ -690,7 +705,7 @@ static inline struct window *get_top_clipping_window( struct window *win )
} }
/* compute the visible region of a window */ /* compute the visible region of a window, in window coordinates */
static struct region *get_visible_region( struct window *win, unsigned int flags ) static struct region *get_visible_region( struct window *win, unsigned int flags )
{ {
struct region *tmp, *region; struct region *tmp, *region;
...@@ -709,39 +724,32 @@ static struct region *get_visible_region( struct window *win, unsigned int flags ...@@ -709,39 +724,32 @@ static struct region *get_visible_region( struct window *win, unsigned int flags
{ {
set_region_client_rect( region, win->parent ); set_region_client_rect( region, win->parent );
offset_region( region, -win->parent->client_rect.left, -win->parent->client_rect.top ); offset_region( region, -win->parent->client_rect.left, -win->parent->client_rect.top );
offset_x = win->client_rect.left;
offset_y = win->client_rect.top;
} }
else if (flags & DCX_WINDOW) else if (flags & DCX_WINDOW)
{ {
set_region_rect( region, &win->visible_rect ); set_region_rect( region, &win->visible_rect );
if (win->win_region && !intersect_window_region( region, win )) goto error; if (win->win_region && !intersect_window_region( region, win )) goto error;
offset_x = win->window_rect.left;
offset_y = win->window_rect.top;
} }
else else
{ {
set_region_client_rect( region, win ); set_region_client_rect( region, win );
if (win->win_region && !intersect_window_region( region, win )) goto error; if (win->win_region && !intersect_window_region( region, win )) goto error;
offset_x = win->client_rect.left;
offset_y = win->client_rect.top;
} }
offset_region( region, -offset_x, -offset_y ); offset_x = win->window_rect.left;
offset_y = win->window_rect.top;
/* clip children */ /* clip children */
if (flags & DCX_CLIPCHILDREN) if (flags & DCX_CLIPCHILDREN)
{ {
if (!clip_children( win, NULL, region, if (!clip_children( win, NULL, region, win->client_rect.left, win->client_rect.top ))
offset_x - win->client_rect.left, goto error;
offset_y - win->client_rect.top )) goto error;
} }
/* clip siblings of ancestors */ /* clip siblings of ancestors */
if (top && top != win && (tmp = create_empty_region()) != NULL) if (top && top != win && (tmp = create_empty_region()) != NULL)
{ {
offset_region( region, offset_x, offset_y ); /* make it relative to parent */
while (win != top && win->parent) while (win != top && win->parent)
{ {
if (win->style & WS_CLIPSIBLINGS) if (win->style & WS_CLIPSIBLINGS)
...@@ -767,9 +775,9 @@ static struct region *get_visible_region( struct window *win, unsigned int flags ...@@ -767,9 +775,9 @@ static struct region *get_visible_region( struct window *win, unsigned int flags
} }
if (is_region_empty( region )) break; if (is_region_empty( region )) break;
} }
offset_region( region, -offset_x, -offset_y ); /* make it relative to target window again */
free_region( tmp ); free_region( tmp );
} }
offset_region( region, -offset_x, -offset_y ); /* make it relative to target window */
return region; return region;
error: error:
...@@ -1578,7 +1586,9 @@ DECL_HANDLER(get_visible_region) ...@@ -1578,7 +1586,9 @@ DECL_HANDLER(get_visible_region)
if ((region = get_visible_region( win, req->flags ))) if ((region = get_visible_region( win, req->flags )))
{ {
rectangle_t *data = get_region_data_and_free( region, get_reply_max_size(), &reply->total_size ); rectangle_t *data;
map_win_region_to_screen( win, 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 ); if (data) set_reply_data_ptr( data, reply->total_size );
} }
} }
...@@ -1657,8 +1667,18 @@ DECL_HANDLER(get_update_region) ...@@ -1657,8 +1667,18 @@ DECL_HANDLER(get_update_region)
if (win->update_region) if (win->update_region)
{ {
if (!(data = get_region_data( win->update_region, get_reply_max_size(), /* convert update region to screen coordinates */
&reply->total_size ))) return; struct region *region = create_empty_region();
if (!region) return;
if (!copy_region( region, win->update_region ))
{
free_region( region );
return;
}
map_win_region_to_screen( win, region );
if (!(data = get_region_data_and_free( region, get_reply_max_size(),
&reply->total_size ))) return;
set_reply_data_ptr( data, reply->total_size ); set_reply_data_ptr( data, reply->total_size );
} }
......
...@@ -953,7 +953,6 @@ static void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint ) ...@@ -953,7 +953,6 @@ static void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint )
dwStyle = wndPtr->dwStyle; dwStyle = wndPtr->dwStyle;
dwExStyle = wndPtr->dwExStyle; dwExStyle = wndPtr->dwExStyle;
flags = wndPtr->flags; flags = wndPtr->flags;
rectClient = wndPtr->rectClient;
rectWindow = wndPtr->rectWindow; rectWindow = wndPtr->rectWindow;
WIN_ReleasePtr( wndPtr ); WIN_ReleasePtr( wndPtr );
...@@ -971,10 +970,10 @@ static void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint ) ...@@ -971,10 +970,10 @@ static void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint )
Now, how is the "system" supposed to tell what happened? Now, how is the "system" supposed to tell what happened?
*/ */
hrgn = CreateRectRgn( rectClient.left - rectWindow.left, GetClientRect( hwnd, &rectClient );
rectClient.top - rectWindow.top, MapWindowPoints( hwnd, 0, (POINT *)&rectClient, 2 );
rectClient.right - rectWindow.left, hrgn = CreateRectRgnIndirect( &rectClient );
rectClient.bottom - rectWindow.top );
if (clip > (HRGN)1) if (clip > (HRGN)1)
{ {
CombineRgn( hrgn, clip, hrgn, RGN_DIFF ); CombineRgn( hrgn, clip, hrgn, RGN_DIFF );
...@@ -990,14 +989,7 @@ static void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint ) ...@@ -990,14 +989,7 @@ static void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint )
rect.top = rect.left = 0; rect.top = rect.left = 0;
rect.right = rectWindow.right - rectWindow.left; rect.right = rectWindow.right - rectWindow.left;
rect.bottom = rectWindow.bottom - rectWindow.top; rect.bottom = rectWindow.bottom - rectWindow.top;
GetClipBox( hdc, &rectClip );
if( clip > (HRGN)1 )
GetRgnBox( clip, &rectClip );
else
{
clip = 0;
rectClip = rect;
}
SelectObject( hdc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME) ); SelectObject( hdc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME) );
...@@ -1021,7 +1013,7 @@ static void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint ) ...@@ -1021,7 +1013,7 @@ static void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint )
r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION); r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
rect.top += GetSystemMetrics(SM_CYCAPTION); rect.top += GetSystemMetrics(SM_CYCAPTION);
} }
if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) ) if( IntersectRect( &rfuzz, &r, &rectClip ) )
NC_DrawCaption(hdc, &r, hwnd, dwStyle, dwExStyle, active); NC_DrawCaption(hdc, &r, hwnd, dwStyle, dwExStyle, active);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment