mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 04:39:45 +00:00
server: Store a separate flag for windows that need to be erased in WM_PAINT.
This avoids the need to invalidate the window after WM_ERASEBKGND.
This commit is contained in:
parent
5bd497f3ca
commit
df13cee288
@ -243,7 +243,7 @@ static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags )
|
||||
static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn,
|
||||
RECT *clip_rect, HDC *hdc_ret )
|
||||
{
|
||||
BOOL need_erase = FALSE;
|
||||
BOOL need_erase = (flags & UPDATE_DELAYED_ERASE) != 0;
|
||||
HDC hdc = 0;
|
||||
RECT dummy;
|
||||
|
||||
@ -263,12 +263,7 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn,
|
||||
if (type != NULLREGION)
|
||||
need_erase = !SendMessageW( hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0 );
|
||||
}
|
||||
if (!hdc_ret)
|
||||
{
|
||||
if (need_erase && hwnd != GetDesktopWindow()) /* FIXME: mark it as needing erase again */
|
||||
RedrawWindow( hwnd, clip_rect, 0, RDW_INVALIDATE | RDW_ERASE | RDW_NOCHILDREN );
|
||||
USER_Driver->pReleaseDC( hwnd, hdc, TRUE );
|
||||
}
|
||||
if (!hdc_ret) USER_Driver->pReleaseDC( hwnd, hdc, TRUE );
|
||||
}
|
||||
|
||||
if (hdc_ret) *hdc_ret = hdc;
|
||||
@ -287,6 +282,7 @@ void erase_now( HWND hwnd, UINT rdw_flags )
|
||||
{
|
||||
HWND child = 0;
|
||||
HRGN hrgn;
|
||||
BOOL need_erase = FALSE;
|
||||
|
||||
/* loop while we find a child to repaint */
|
||||
for (;;)
|
||||
@ -295,12 +291,13 @@ void erase_now( HWND hwnd, UINT rdw_flags )
|
||||
|
||||
if (rdw_flags & RDW_NOCHILDREN) flags |= UPDATE_NOCHILDREN;
|
||||
else if (rdw_flags & RDW_ALLCHILDREN) flags |= UPDATE_ALLCHILDREN;
|
||||
if (need_erase) flags |= UPDATE_DELAYED_ERASE;
|
||||
|
||||
if (!(hrgn = send_ncpaint( hwnd, &child, &flags ))) break;
|
||||
send_erase( child, flags, hrgn, NULL, NULL );
|
||||
need_erase = send_erase( child, flags, hrgn, NULL, NULL );
|
||||
|
||||
if (!flags) break; /* nothing more to do */
|
||||
if (rdw_flags & RDW_NOCHILDREN) break;
|
||||
if ((rdw_flags & RDW_NOCHILDREN) && !need_erase) break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -736,7 +733,11 @@ INT WINAPI GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
|
||||
POINT offset;
|
||||
|
||||
retval = CombineRgn( hrgn, update_rgn, 0, RGN_COPY );
|
||||
send_erase( hwnd, flags, update_rgn, NULL, NULL );
|
||||
if (send_erase( hwnd, flags, update_rgn, NULL, NULL ))
|
||||
{
|
||||
flags = UPDATE_DELAYED_ERASE;
|
||||
get_update_flags( hwnd, NULL, &flags );
|
||||
}
|
||||
/* map region to client coordinates */
|
||||
offset.x = offset.y = 0;
|
||||
ScreenToClient( hwnd, &offset );
|
||||
@ -753,6 +754,7 @@ BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
|
||||
{
|
||||
UINT flags = UPDATE_NOCHILDREN;
|
||||
HRGN update_rgn;
|
||||
BOOL need_erase;
|
||||
|
||||
if (erase) flags |= UPDATE_NONCLIENT | UPDATE_ERASE;
|
||||
|
||||
@ -768,10 +770,11 @@ BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
|
||||
ReleaseDC( hwnd, hdc );
|
||||
}
|
||||
}
|
||||
send_erase( hwnd, flags, update_rgn, NULL, NULL );
|
||||
need_erase = send_erase( hwnd, flags, update_rgn, NULL, NULL );
|
||||
|
||||
/* check if we still have an update region */
|
||||
flags = UPDATE_PAINT | UPDATE_NOCHILDREN;
|
||||
if (need_erase) flags |= UPDATE_DELAYED_ERASE;
|
||||
return (get_update_flags( hwnd, NULL, &flags ) && (flags & UPDATE_PAINT));
|
||||
}
|
||||
|
||||
|
@ -3073,6 +3073,7 @@ struct get_update_region_reply
|
||||
#define UPDATE_ALLCHILDREN 0x10
|
||||
#define UPDATE_NOCHILDREN 0x20
|
||||
#define UPDATE_NOREGION 0x40
|
||||
#define UPDATE_DELAYED_ERASE 0x80
|
||||
|
||||
|
||||
|
||||
@ -4730,6 +4731,6 @@ union generic_reply
|
||||
struct make_process_system_reply make_process_system_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 309
|
||||
#define SERVER_PROTOCOL_VERSION 310
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
@ -2256,6 +2256,7 @@ enum message_type
|
||||
#define UPDATE_ALLCHILDREN 0x10 /* force repaint of all children */
|
||||
#define UPDATE_NOCHILDREN 0x20 /* don't try to repaint any children */
|
||||
#define UPDATE_NOREGION 0x40 /* don't return a region, only the flags */
|
||||
#define UPDATE_DELAYED_ERASE 0x80 /* still needs erase after BeginPaint */
|
||||
|
||||
|
||||
/* Update the z order of a window so that a given rectangle is fully visible */
|
||||
|
@ -88,9 +88,10 @@ struct window
|
||||
char extra_bytes[1]; /* extra bytes storage */
|
||||
};
|
||||
|
||||
#define PAINT_INTERNAL 0x01 /* internal WM_PAINT pending */
|
||||
#define PAINT_ERASE 0x02 /* needs WM_ERASEBKGND */
|
||||
#define PAINT_NONCLIENT 0x04 /* needs WM_NCPAINT */
|
||||
#define PAINT_INTERNAL 0x01 /* internal WM_PAINT pending */
|
||||
#define PAINT_ERASE 0x02 /* needs WM_ERASEBKGND */
|
||||
#define PAINT_NONCLIENT 0x04 /* needs WM_NCPAINT */
|
||||
#define PAINT_DELAYED_ERASE 0x08 /* still needs erase after WM_ERASEBKGND */
|
||||
|
||||
/* growable array of user handles */
|
||||
struct user_handle_array
|
||||
@ -978,7 +979,7 @@ static void set_update_region( struct window *win, struct region *region )
|
||||
inc_window_paint_count( win, -1 );
|
||||
free_region( win->update_region );
|
||||
}
|
||||
win->paint_flags &= ~(PAINT_ERASE | PAINT_NONCLIENT);
|
||||
win->paint_flags &= ~(PAINT_ERASE | PAINT_DELAYED_ERASE | PAINT_NONCLIENT);
|
||||
win->update_region = NULL;
|
||||
if (region) free_region( region );
|
||||
}
|
||||
@ -1122,7 +1123,7 @@ static void redraw_window( struct window *win, struct region *region, int frame,
|
||||
set_update_region( win, tmp );
|
||||
}
|
||||
if (flags & RDW_NOFRAME) validate_non_client( win );
|
||||
if (flags & RDW_NOERASE) win->paint_flags &= ~PAINT_ERASE;
|
||||
if (flags & RDW_NOERASE) win->paint_flags &= ~(PAINT_ERASE | PAINT_DELAYED_ERASE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1178,11 +1179,19 @@ static unsigned int get_update_flags( struct window *win, unsigned int flags )
|
||||
}
|
||||
if (flags & UPDATE_PAINT)
|
||||
{
|
||||
if (win->update_region) ret |= UPDATE_PAINT;
|
||||
if (win->update_region)
|
||||
{
|
||||
if (win->paint_flags & PAINT_DELAYED_ERASE) ret |= UPDATE_DELAYED_ERASE;
|
||||
ret |= UPDATE_PAINT;
|
||||
}
|
||||
}
|
||||
if (flags & UPDATE_INTERNALPAINT)
|
||||
{
|
||||
if (win->paint_flags & PAINT_INTERNAL) ret |= UPDATE_INTERNALPAINT;
|
||||
if (win->paint_flags & PAINT_INTERNAL)
|
||||
{
|
||||
ret |= UPDATE_INTERNALPAINT;
|
||||
if (win->paint_flags & PAINT_DELAYED_ERASE) ret |= UPDATE_DELAYED_ERASE;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1943,6 +1952,12 @@ DECL_HANDLER(get_update_region)
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & UPDATE_DELAYED_ERASE) /* this means that the previous call didn't erase */
|
||||
{
|
||||
if (from_child) from_child->paint_flags |= PAINT_DELAYED_ERASE;
|
||||
else win->paint_flags |= PAINT_DELAYED_ERASE;
|
||||
}
|
||||
|
||||
reply->flags = get_window_update_flags( win, from_child, flags, &win );
|
||||
reply->child = win->handle;
|
||||
|
||||
@ -1975,7 +1990,7 @@ DECL_HANDLER(get_update_region)
|
||||
if (reply->flags & UPDATE_NONCLIENT) validate_non_client( win );
|
||||
if (reply->flags & UPDATE_ERASE)
|
||||
{
|
||||
win->paint_flags &= ~PAINT_ERASE;
|
||||
win->paint_flags &= ~(PAINT_ERASE | PAINT_DELAYED_ERASE);
|
||||
/* desktop window only gets erased, not repainted */
|
||||
if (is_desktop_window(win)) validate_whole_window( win );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user