win32u: Move NtUserRedrawWindow implementation from user32.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-03-14 11:45:30 +01:00 committed by Alexandre Julliard
parent 31a044efa5
commit 45e0afbca4
19 changed files with 234 additions and 180 deletions

View File

@ -1001,7 +1001,7 @@ static void CBDropDown( LPHEADCOMBO lphc )
if( !(lphc->wState & CBF_NOREDRAW) ) if( !(lphc->wState & CBF_NOREDRAW) )
RedrawWindow( lphc->self, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW ); NtUserRedrawWindow( lphc->self, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW );
EnableWindow( lphc->hWndLBox, TRUE ); EnableWindow( lphc->hWndLBox, TRUE );
if (GetCapture() != lphc->self) if (GetCapture() != lphc->self)
@ -1056,8 +1056,8 @@ static void CBRollUp( LPHEADCOMBO lphc, BOOL ok, BOOL bButton )
} }
if( bButton && !(lphc->wState & CBF_NOREDRAW) ) if( bButton && !(lphc->wState & CBF_NOREDRAW) )
RedrawWindow( hWnd, &rect, 0, RDW_INVALIDATE | NtUserRedrawWindow( hWnd, &rect, 0, RDW_INVALIDATE |
RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN ); RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN );
CB_NOTIFY( lphc, CBN_CLOSEUP ); CB_NOTIFY( lphc, CBN_CLOSEUP );
} }
} }
@ -1423,7 +1423,7 @@ static void CBResetPos(HEADCOMBO *combo, BOOL redraw)
} }
if (redraw && !(combo->wState & CBF_NOREDRAW)) if (redraw && !(combo->wState & CBF_NOREDRAW))
RedrawWindow(combo->self, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW); NtUserRedrawWindow( combo->self, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW );
} }
} }

View File

@ -387,14 +387,14 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
} }
case WM_SYNCPAINT: case WM_SYNCPAINT:
RedrawWindow ( hwnd, NULL, 0, RDW_ERASENOW | RDW_ERASE | RDW_ALLCHILDREN ); NtUserRedrawWindow ( hwnd, NULL, 0, RDW_ERASENOW | RDW_ERASE | RDW_ALLCHILDREN );
return 0; return 0;
case WM_SETREDRAW: case WM_SETREDRAW:
if (wParam) WIN_SetStyle( hwnd, WS_VISIBLE, 0 ); if (wParam) WIN_SetStyle( hwnd, WS_VISIBLE, 0 );
else else
{ {
RedrawWindow( hwnd, NULL, 0, RDW_ALLCHILDREN | RDW_VALIDATE ); NtUserRedrawWindow( hwnd, NULL, 0, RDW_ALLCHILDREN | RDW_VALIDATE );
WIN_SetStyle( hwnd, 0, WS_VISIBLE ); WIN_SetStyle( hwnd, 0, WS_VISIBLE );
} }
return 0; return 0;

View File

@ -219,6 +219,6 @@ BOOL update_wallpaper( const WCHAR *wallpaper, const WCHAR *pattern )
} }
} }
init_wallpaper( wallpaper ); init_wallpaper( wallpaper );
RedrawWindow( GetDesktopWindow(), 0, 0, RDW_INVALIDATE | RDW_ERASE | RDW_NOCHILDREN ); NtUserRedrawWindow( GetDesktopWindow(), 0, 0, RDW_INVALIDATE | RDW_ERASE | RDW_NOCHILDREN );
return TRUE; return TRUE;
} }

View File

@ -3751,7 +3751,7 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags )
/* Refresh the frame to reflect the change */ /* Refresh the frame to reflect the change */
WIN_GetRectangles(hwnd, COORDS_CLIENT, &rc, NULL); WIN_GetRectangles(hwnd, COORDS_CLIENT, &rc, NULL);
rc.bottom = 0; rc.bottom = 0;
RedrawWindow(hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN); NtUserRedrawWindow( hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN );
} }
else else
release_menu_ptr(menu); release_menu_ptr(menu);

View File

@ -35,45 +35,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(win); WINE_DEFAULT_DEBUG_CHANNEL(win);
/***********************************************************************
* dump_rdw_flags
*/
static void dump_rdw_flags(UINT flags)
{
TRACE("flags:");
if (flags & RDW_INVALIDATE) TRACE(" RDW_INVALIDATE");
if (flags & RDW_INTERNALPAINT) TRACE(" RDW_INTERNALPAINT");
if (flags & RDW_ERASE) TRACE(" RDW_ERASE");
if (flags & RDW_VALIDATE) TRACE(" RDW_VALIDATE");
if (flags & RDW_NOINTERNALPAINT) TRACE(" RDW_NOINTERNALPAINT");
if (flags & RDW_NOERASE) TRACE(" RDW_NOERASE");
if (flags & RDW_NOCHILDREN) TRACE(" RDW_NOCHILDREN");
if (flags & RDW_ALLCHILDREN) TRACE(" RDW_ALLCHILDREN");
if (flags & RDW_UPDATENOW) TRACE(" RDW_UPDATENOW");
if (flags & RDW_ERASENOW) TRACE(" RDW_ERASENOW");
if (flags & RDW_FRAME) TRACE(" RDW_FRAME");
if (flags & RDW_NOFRAME) TRACE(" RDW_NOFRAME");
#define RDW_FLAGS \
(RDW_INVALIDATE | \
RDW_INTERNALPAINT | \
RDW_ERASE | \
RDW_VALIDATE | \
RDW_NOINTERNALPAINT | \
RDW_NOERASE | \
RDW_NOCHILDREN | \
RDW_ALLCHILDREN | \
RDW_UPDATENOW | \
RDW_ERASENOW | \
RDW_FRAME | \
RDW_NOFRAME)
if (flags & ~RDW_FLAGS) TRACE(" %04x", flags & ~RDW_FLAGS);
TRACE("\n");
#undef RDW_FLAGS
}
/*********************************************************************** /***********************************************************************
* free_dce * free_dce
* *
@ -221,30 +182,6 @@ static BOOL get_update_flags( HWND hwnd, HWND *child, UINT *flags )
} }
/***********************************************************************
* redraw_window_rects
*
* Redraw part of a window.
*/
static BOOL redraw_window_rects( HWND hwnd, UINT flags, const RECT *rects, UINT count )
{
BOOL ret;
if (!(flags & (RDW_INVALIDATE|RDW_VALIDATE|RDW_INTERNALPAINT|RDW_NOINTERNALPAINT)))
return TRUE; /* nothing to do */
SERVER_START_REQ( redraw_window )
{
req->window = wine_server_user_handle( hwnd );
req->flags = flags;
wine_server_add_data( req, rects, count * sizeof(RECT) );
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
}
/*********************************************************************** /***********************************************************************
* send_ncpaint * send_ncpaint
* *
@ -469,35 +406,6 @@ void move_window_bits_parent( HWND hwnd, HWND parent, const RECT *window_rect, c
} }
/***********************************************************************
* update_now
*
* Implementation of RDW_UPDATENOW behavior.
*/
static void update_now( HWND hwnd, UINT rdw_flags )
{
HWND child = 0;
/* desktop window never gets WM_PAINT, only WM_ERASEBKGND */
if (hwnd == GetDesktopWindow()) erase_now( hwnd, rdw_flags | RDW_NOCHILDREN );
/* loop while we find a child to repaint */
for (;;)
{
UINT flags = UPDATE_PAINT | UPDATE_INTERNALPAINT;
if (rdw_flags & RDW_NOCHILDREN) flags |= UPDATE_NOCHILDREN;
else if (rdw_flags & RDW_ALLCHILDREN) flags |= UPDATE_ALLCHILDREN;
if (!get_update_flags( hwnd, &child, &flags )) break;
if (!flags) break; /* nothing more to do */
SendMessageW( child, WM_PAINT, 0, 0 );
if (rdw_flags & RDW_NOCHILDREN) break;
}
}
/************************************************************************* /*************************************************************************
* fix_caret * fix_caret
* *
@ -618,66 +526,6 @@ BOOL WINAPI LockWindowUpdate( HWND hwnd )
} }
/***********************************************************************
* RedrawWindow (USER32.@)
*/
BOOL WINAPI RedrawWindow( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags )
{
static const RECT empty;
BOOL ret;
if (TRACE_ON(win))
{
if (hrgn)
{
RECT r;
GetRgnBox( hrgn, &r );
TRACE( "%p region %p box %s ", hwnd, hrgn, wine_dbgstr_rect(&r) );
}
else if (rect)
TRACE( "%p rect %s ", hwnd, wine_dbgstr_rect(rect) );
else
TRACE( "%p whole window ", hwnd );
dump_rdw_flags(flags);
}
/* process pending expose events before painting */
if (flags & RDW_UPDATENOW) USER_Driver->pMsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_PAINT, 0 );
if (rect && !hrgn)
{
if (IsRectEmpty( rect )) rect = &empty;
ret = redraw_window_rects( hwnd, flags, rect, 1 );
}
else if (!hrgn)
{
ret = redraw_window_rects( hwnd, flags, NULL, 0 );
}
else /* need to build a list of the region rectangles */
{
DWORD size;
RGNDATA *data;
if (!(size = GetRegionData( hrgn, 0, NULL ))) return FALSE;
if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
GetRegionData( hrgn, size, data );
if (!data->rdh.nCount) /* empty region -> use a single all-zero rectangle */
ret = redraw_window_rects( hwnd, flags, &empty, 1 );
else
ret = redraw_window_rects( hwnd, flags, (const RECT *)data->Buffer, data->rdh.nCount );
HeapFree( GetProcessHeap(), 0, data );
}
if (!hwnd) hwnd = GetDesktopWindow();
if (flags & RDW_UPDATENOW) update_now( hwnd, flags );
else if (flags & RDW_ERASENOW) erase_now( hwnd, flags );
return ret;
}
/*********************************************************************** /***********************************************************************
* UpdateWindow (USER32.@) * UpdateWindow (USER32.@)
*/ */
@ -689,7 +537,7 @@ BOOL WINAPI UpdateWindow( HWND hwnd )
return FALSE; return FALSE;
} }
return RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN ); return NtUserRedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN );
} }
@ -704,7 +552,7 @@ BOOL WINAPI InvalidateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
return FALSE; return FALSE;
} }
return RedrawWindow(hwnd, NULL, hrgn, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) ); return NtUserRedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) );
} }
@ -724,7 +572,7 @@ BOOL WINAPI InvalidateRect( HWND hwnd, const RECT *rect, BOOL erase )
rect = NULL; rect = NULL;
} }
return RedrawWindow( hwnd, rect, 0, flags ); return NtUserRedrawWindow( hwnd, rect, 0, flags );
} }
@ -739,7 +587,7 @@ BOOL WINAPI ValidateRgn( HWND hwnd, HRGN hrgn )
return FALSE; return FALSE;
} }
return RedrawWindow( hwnd, NULL, hrgn, RDW_VALIDATE ); return NtUserRedrawWindow( hwnd, NULL, hrgn, RDW_VALIDATE );
} }
@ -759,7 +607,7 @@ BOOL WINAPI ValidateRect( HWND hwnd, const RECT *rect )
rect = NULL; rect = NULL;
} }
return RedrawWindow( hwnd, rect, 0, flags ); return NtUserRedrawWindow( hwnd, rect, 0, flags );
} }
@ -917,7 +765,7 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, const REC
NtUserReleaseDC( hwnd, hDC ); NtUserReleaseDC( hwnd, hDC );
if (!bUpdate) if (!bUpdate)
RedrawWindow( hwnd, NULL, hrgnUpdate, rdw_flags); NtUserRedrawWindow( hwnd, NULL, hrgnUpdate, rdw_flags);
} }
/* If the windows has an update region, this must be /* If the windows has an update region, this must be
@ -936,7 +784,7 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, const REC
CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND ); CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND );
if( !bOwnRgn) if( !bOwnRgn)
CombineRgn( hrgnWinupd, hrgnWinupd, hrgnTemp, RGN_OR ); CombineRgn( hrgnWinupd, hrgnWinupd, hrgnTemp, RGN_OR );
RedrawWindow( hwnd, NULL, hrgnTemp, rdw_flags); NtUserRedrawWindow( hwnd, NULL, hrgnTemp, rdw_flags);
/* Catch the case where the scrolling amount exceeds the size of the /* Catch the case where the scrolling amount exceeds the size of the
* original window. This generated a second update area that is the * original window. This generated a second update area that is the
@ -993,8 +841,8 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, const REC
} }
if( flags & (SW_INVALIDATE | SW_ERASE) ) if( flags & (SW_INVALIDATE | SW_ERASE) )
RedrawWindow( hwnd, NULL, hrgnUpdate, rdw_flags | NtUserRedrawWindow( hwnd, NULL, hrgnUpdate, rdw_flags |
((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) ); ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) );
if( hrgnWinupd) { if( hrgnWinupd) {
CombineRgn( hrgnUpdate, hrgnUpdate, hrgnWinupd, RGN_OR); CombineRgn( hrgnUpdate, hrgnUpdate, hrgnWinupd, RGN_OR);

View File

@ -473,7 +473,8 @@ LRESULT StaticWndProc_common( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
{ {
SetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET, wParam ); SetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET, wParam );
if (LOWORD(lParam)) if (LOWORD(lParam))
RedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN ); NtUserRedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE |
RDW_UPDATENOW | RDW_ALLCHILDREN );
} }
break; break;

View File

@ -590,7 +590,7 @@
# @ stub ReasonCodeNeedsBugID # @ stub ReasonCodeNeedsBugID
# @ stub ReasonCodeNeedsComment # @ stub ReasonCodeNeedsComment
# @ stub RecordShutdownReason # @ stub RecordShutdownReason
@ stdcall RedrawWindow(long ptr long long) @ stdcall RedrawWindow(long ptr long long) NtUserRedrawWindow
@ stdcall RegisterClassA(ptr) @ stdcall RegisterClassA(ptr)
@ stdcall RegisterClassExA(ptr) @ stdcall RegisterClassExA(ptr)
@ stdcall RegisterClassExW(ptr) @ stdcall RegisterClassExW(ptr)

View File

@ -145,7 +145,6 @@ static const struct user_callbacks user_funcs =
CopyImage, CopyImage,
HideCaret, HideCaret,
PostMessageW, PostMessageW,
RedrawWindow,
SendInput, SendInput,
SendMessageTimeoutW, SendMessageTimeoutW,
SendMessageW, SendMessageW,

View File

@ -2735,7 +2735,7 @@ void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam )
if (parent) SystemParametersInfoW( SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0 ); if (parent) SystemParametersInfoW( SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0 );
/* repaint the window before moving it around */ /* repaint the window before moving it around */
RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN ); NtUserRedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN );
SendMessageW( hwnd, WM_ENTERSIZEMOVE, 0, 0 ); SendMessageW( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
set_capture_window( hwnd, GUI_INMOVESIZE, NULL ); set_capture_window( hwnd, GUI_INMOVESIZE, NULL );

View File

@ -146,6 +146,44 @@ done:
pthread_mutex_unlock( &surfaces_lock ); pthread_mutex_unlock( &surfaces_lock );
} }
/***********************************************************************
* dump_rdw_flags
*/
static void dump_rdw_flags(UINT flags)
{
TRACE("flags:");
if (flags & RDW_INVALIDATE) TRACE(" RDW_INVALIDATE");
if (flags & RDW_INTERNALPAINT) TRACE(" RDW_INTERNALPAINT");
if (flags & RDW_ERASE) TRACE(" RDW_ERASE");
if (flags & RDW_VALIDATE) TRACE(" RDW_VALIDATE");
if (flags & RDW_NOINTERNALPAINT) TRACE(" RDW_NOINTERNALPAINT");
if (flags & RDW_NOERASE) TRACE(" RDW_NOERASE");
if (flags & RDW_NOCHILDREN) TRACE(" RDW_NOCHILDREN");
if (flags & RDW_ALLCHILDREN) TRACE(" RDW_ALLCHILDREN");
if (flags & RDW_UPDATENOW) TRACE(" RDW_UPDATENOW");
if (flags & RDW_ERASENOW) TRACE(" RDW_ERASENOW");
if (flags & RDW_FRAME) TRACE(" RDW_FRAME");
if (flags & RDW_NOFRAME) TRACE(" RDW_NOFRAME");
#define RDW_FLAGS \
(RDW_INVALIDATE | \
RDW_INTERNALPAINT | \
RDW_ERASE | \
RDW_VALIDATE | \
RDW_NOINTERNALPAINT | \
RDW_NOERASE | \
RDW_NOCHILDREN | \
RDW_ALLCHILDREN | \
RDW_UPDATENOW | \
RDW_ERASENOW | \
RDW_FRAME | \
RDW_NOFRAME)
if (flags & ~RDW_FLAGS) TRACE(" %04x", flags & ~RDW_FLAGS);
TRACE("\n");
#undef RDW_FLAGS
}
/*********************************************************************** /***********************************************************************
* update_visible_region * update_visible_region
* *
@ -790,6 +828,53 @@ static HRGN get_update_region( HWND hwnd, UINT *flags, HWND *child )
return hrgn; return hrgn;
} }
/***********************************************************************
* redraw_window_rects
*
* Redraw part of a window.
*/
static BOOL redraw_window_rects( HWND hwnd, UINT flags, const RECT *rects, UINT count )
{
BOOL ret;
if (!(flags & (RDW_INVALIDATE|RDW_VALIDATE|RDW_INTERNALPAINT|RDW_NOINTERNALPAINT)))
return TRUE; /* nothing to do */
SERVER_START_REQ( redraw_window )
{
req->window = wine_server_user_handle( hwnd );
req->flags = flags;
wine_server_add_data( req, rects, count * sizeof(RECT) );
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
}
/***********************************************************************
* get_update_flags
*
* Get only the update flags, not the update region.
*/
static BOOL get_update_flags( HWND hwnd, HWND *child, UINT *flags )
{
BOOL ret;
SERVER_START_REQ( get_update_region )
{
req->window = wine_server_user_handle( hwnd );
req->from_child = wine_server_user_handle( child ? *child : 0 );
req->flags = *flags | UPDATE_NOREGION;
if ((ret = !wine_server_call_err( req )))
{
if (child) *child = wine_server_ptr_handle( reply->child );
*flags = reply->flags;
}
}
SERVER_END_REQ;
return ret;
}
/*********************************************************************** /***********************************************************************
* send_ncpaint * send_ncpaint
* *
@ -938,3 +1023,118 @@ BOOL WINAPI NtUserEndPaint( HWND hwnd, const PAINTSTRUCT *ps )
release_dc( hwnd, ps->hdc, TRUE ); release_dc( hwnd, ps->hdc, TRUE );
return TRUE; return TRUE;
} }
/***********************************************************************
* erase_now
*
* Implementation of RDW_ERASENOW behavior.
*/
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 (;;)
{
UINT flags = UPDATE_NONCLIENT | UPDATE_ERASE;
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;
need_erase = send_erase( child, flags, hrgn, NULL, NULL );
if (!flags) break; /* nothing more to do */
if ((rdw_flags & RDW_NOCHILDREN) && !need_erase) break;
}
}
/***********************************************************************
* update_now
*
* Implementation of RDW_UPDATENOW behavior.
*/
static void update_now( HWND hwnd, UINT rdw_flags )
{
HWND child = 0;
/* desktop window never gets WM_PAINT, only WM_ERASEBKGND */
if (hwnd == get_desktop_window()) erase_now( hwnd, rdw_flags | RDW_NOCHILDREN );
/* loop while we find a child to repaint */
for (;;)
{
UINT flags = UPDATE_PAINT | UPDATE_INTERNALPAINT;
if (rdw_flags & RDW_NOCHILDREN) flags |= UPDATE_NOCHILDREN;
else if (rdw_flags & RDW_ALLCHILDREN) flags |= UPDATE_ALLCHILDREN;
if (!get_update_flags( hwnd, &child, &flags )) break;
if (!flags) break; /* nothing more to do */
send_message( child, WM_PAINT, 0, 0 );
if (rdw_flags & RDW_NOCHILDREN) break;
}
}
/***********************************************************************
* NtUserRedrawWindow (win32u.@)
*/
BOOL WINAPI NtUserRedrawWindow( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags )
{
static const RECT empty;
BOOL ret;
if (TRACE_ON(win))
{
if (hrgn)
{
RECT r;
NtGdiGetRgnBox( hrgn, &r );
TRACE( "%p region %p box %s ", hwnd, hrgn, wine_dbgstr_rect(&r) );
}
else if (rect)
TRACE( "%p rect %s ", hwnd, wine_dbgstr_rect(rect) );
else
TRACE( "%p whole window ", hwnd );
dump_rdw_flags(flags);
}
/* process pending expose events before painting */
if (flags & RDW_UPDATENOW) user_driver->pMsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_PAINT, 0 );
if (rect && !hrgn)
{
if (IsRectEmpty( rect )) rect = &empty;
ret = redraw_window_rects( hwnd, flags, rect, 1 );
}
else if (!hrgn)
{
ret = redraw_window_rects( hwnd, flags, NULL, 0 );
}
else /* need to build a list of the region rectangles */
{
DWORD size;
RGNDATA *data;
if (!(size = NtGdiGetRegionData( hrgn, 0, NULL ))) return FALSE;
if (!(data = malloc( size ))) return FALSE;
NtGdiGetRegionData( hrgn, size, data );
if (!data->rdh.nCount) /* empty region -> use a single all-zero rectangle */
ret = redraw_window_rects( hwnd, flags, &empty, 1 );
else
ret = redraw_window_rects( hwnd, flags, (const RECT *)data->Buffer, data->rdh.nCount );
free( data );
}
if (!hwnd) hwnd = get_desktop_window();
if (flags & RDW_UPDATENOW) update_now( hwnd, flags );
else if (flags & RDW_ERASENOW) erase_now( hwnd, flags );
return ret;
}

View File

@ -1181,6 +1181,7 @@ static struct unix_funcs unix_funcs =
NtUserIsClipboardFormatAvailable, NtUserIsClipboardFormatAvailable,
NtUserMapVirtualKeyEx, NtUserMapVirtualKeyEx,
NtUserMoveWindow, NtUserMoveWindow,
NtUserRedrawWindow,
NtUserRegisterClassExWOW, NtUserRegisterClassExWOW,
NtUserRegisterHotKey, NtUserRegisterHotKey,
NtUserReleaseDC, NtUserReleaseDC,

View File

@ -32,7 +32,6 @@ struct user_callbacks
HANDLE (WINAPI *pCopyImage)( HANDLE, UINT, INT, INT, UINT ); HANDLE (WINAPI *pCopyImage)( HANDLE, UINT, INT, INT, UINT );
BOOL (WINAPI *pHideCaret)( HWND hwnd ); BOOL (WINAPI *pHideCaret)( HWND hwnd );
BOOL (WINAPI *pPostMessageW)( HWND, UINT, WPARAM, LPARAM ); BOOL (WINAPI *pPostMessageW)( HWND, UINT, WPARAM, LPARAM );
BOOL (WINAPI *pRedrawWindow)( HWND, const RECT*, HRGN, UINT );
UINT (WINAPI *pSendInput)( UINT count, INPUT *inputs, int size ); UINT (WINAPI *pSendInput)( UINT count, INPUT *inputs, int size );
LRESULT (WINAPI *pSendMessageTimeoutW)( HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR ); LRESULT (WINAPI *pSendMessageTimeoutW)( HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR );
LRESULT (WINAPI *pSendMessageW)( HWND, UINT, WPARAM, LPARAM ); LRESULT (WINAPI *pSendMessageW)( HWND, UINT, WPARAM, LPARAM );

View File

@ -602,14 +602,13 @@ BOOL WINAPI NtGdiUpdateColors( HDC hDC )
HWND hwnd; HWND hwnd;
if (!size) return FALSE; if (!size) return FALSE;
if (!user_callbacks) return TRUE;
hwnd = NtUserWindowFromDC( hDC ); hwnd = NtUserWindowFromDC( hDC );
/* Docs say that we have to remap current drawable pixel by pixel /* Docs say that we have to remap current drawable pixel by pixel
* but it would take forever given the speed of XGet/PutPixel. * but it would take forever given the speed of XGet/PutPixel.
*/ */
if (hwnd && size) user_callbacks->pRedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE ); if (hwnd && size) NtUserRedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE );
return TRUE; return TRUE;
} }

View File

@ -4540,8 +4540,7 @@ BOOL WINAPI NtUserSetSysColors( INT count, const INT *colors, const COLORREF *va
user_callbacks->pSendMessageTimeoutW( HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0, user_callbacks->pSendMessageTimeoutW( HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0,
SMTO_ABORTIFHUNG, 2000, NULL ); SMTO_ABORTIFHUNG, 2000, NULL );
/* Repaint affected portions of all visible windows */ /* Repaint affected portions of all visible windows */
user_callbacks->pRedrawWindow( 0, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | NtUserRedrawWindow( 0, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
RDW_ALLCHILDREN );
return TRUE; return TRUE;
} }

View File

@ -1120,7 +1120,7 @@
@ stub NtUserRealChildWindowFromPoint @ stub NtUserRealChildWindowFromPoint
@ stub NtUserRealInternalGetMessage @ stub NtUserRealInternalGetMessage
@ stub NtUserRealWaitMessageEx @ stub NtUserRealWaitMessageEx
@ stub NtUserRedrawWindow @ stdcall NtUserRedrawWindow(long ptr long long)
@ stub NtUserRegisterBSDRWindow @ stub NtUserRegisterBSDRWindow
@ stdcall NtUserRegisterClassExWOW(ptr ptr ptr ptr long long long) @ stdcall NtUserRegisterClassExWOW(ptr ptr ptr ptr long long long)
@ stub NtUserRegisterDManipHook @ stub NtUserRegisterDManipHook

View File

@ -222,6 +222,7 @@ struct unix_funcs
BOOL (WINAPI *pNtUserIsClipboardFormatAvailable)( UINT format ); BOOL (WINAPI *pNtUserIsClipboardFormatAvailable)( UINT format );
UINT (WINAPI *pNtUserMapVirtualKeyEx)( UINT code, UINT type, HKL layout ); UINT (WINAPI *pNtUserMapVirtualKeyEx)( UINT code, UINT type, HKL layout );
BOOL (WINAPI *pNtUserMoveWindow)( HWND hwnd, INT x, INT y, INT cx, INT cy, BOOL repaint ); BOOL (WINAPI *pNtUserMoveWindow)( HWND hwnd, INT x, INT y, INT cx, INT cy, BOOL repaint );
BOOL (WINAPI *pNtUserRedrawWindow)( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags );
ATOM (WINAPI *pNtUserRegisterClassExWOW)( const WNDCLASSEXW *wc, UNICODE_STRING *name, ATOM (WINAPI *pNtUserRegisterClassExWOW)( const WNDCLASSEXW *wc, UNICODE_STRING *name,
UNICODE_STRING *version, UNICODE_STRING *version,
struct client_menu_name *client_menu_name, struct client_menu_name *client_menu_name,

View File

@ -1812,7 +1812,7 @@ BOOL WINAPI NtUserFlashWindowEx( FLASHWINFO *info )
if (is_iconic( info->hwnd )) if (is_iconic( info->hwnd ))
{ {
user_callbacks->pRedrawWindow( info->hwnd, 0, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_FRAME ); NtUserRedrawWindow( info->hwnd, 0, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_FRAME );
win = get_win_ptr( info->hwnd ); win = get_win_ptr( info->hwnd );
if (!win || win == WND_OTHER_PROCESS || win == WND_DESKTOP) return FALSE; if (!win || win == WND_OTHER_PROCESS || win == WND_DESKTOP) return FALSE;

View File

@ -894,6 +894,12 @@ UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout )
return unix_funcs->pNtUserMapVirtualKeyEx( code, type, layout ); return unix_funcs->pNtUserMapVirtualKeyEx( code, type, layout );
} }
BOOL WINAPI NtUserRedrawWindow( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags )
{
if (!unix_funcs) return FALSE;
return unix_funcs->pNtUserRedrawWindow( hwnd, rect, hrgn, flags );
}
ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *name, UNICODE_STRING *version, ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *name, UNICODE_STRING *version,
struct client_menu_name *client_menu_name, DWORD fnid, DWORD flags, struct client_menu_name *client_menu_name, DWORD fnid, DWORD flags,
DWORD *wow ) DWORD *wow )

View File

@ -365,6 +365,7 @@ HWINSTA WINAPI NtUserOpenWindowStation( OBJECT_ATTRIBUTES *attr, ACCESS_MASK acc
BOOL WINAPI NtUserSetObjectInformation( HANDLE handle, INT index, void *info, DWORD len ); BOOL WINAPI NtUserSetObjectInformation( HANDLE handle, INT index, void *info, DWORD len );
HDESK WINAPI NtUserOpenDesktop( OBJECT_ATTRIBUTES *attr, DWORD flags, ACCESS_MASK access ); HDESK WINAPI NtUserOpenDesktop( OBJECT_ATTRIBUTES *attr, DWORD flags, ACCESS_MASK access );
HDESK WINAPI NtUserOpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK access ); HDESK WINAPI NtUserOpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK access );
BOOL WINAPI NtUserRedrawWindow( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags );
ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *name, UNICODE_STRING *version, ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *name, UNICODE_STRING *version,
struct client_menu_name *client_menu_name, DWORD fnid, DWORD flags, struct client_menu_name *client_menu_name, DWORD fnid, DWORD flags,
DWORD *wow ); DWORD *wow );