diff --git a/dlls/user32/combo.c b/dlls/user32/combo.c index 7fc75e8038a..c4fe24cd61f 100644 --- a/dlls/user32/combo.c +++ b/dlls/user32/combo.c @@ -1001,7 +1001,7 @@ static void CBDropDown( LPHEADCOMBO lphc ) 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 ); if (GetCapture() != lphc->self) @@ -1056,8 +1056,8 @@ static void CBRollUp( LPHEADCOMBO lphc, BOOL ok, BOOL bButton ) } if( bButton && !(lphc->wState & CBF_NOREDRAW) ) - RedrawWindow( hWnd, &rect, 0, RDW_INVALIDATE | - RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN ); + NtUserRedrawWindow( hWnd, &rect, 0, RDW_INVALIDATE | + RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN ); CB_NOTIFY( lphc, CBN_CLOSEUP ); } } @@ -1423,7 +1423,7 @@ static void CBResetPos(HEADCOMBO *combo, BOOL redraw) } 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 ); } } diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c index c4de8928462..f9f9fa056a4 100644 --- a/dlls/user32/defwnd.c +++ b/dlls/user32/defwnd.c @@ -387,14 +387,14 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa } 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; case WM_SETREDRAW: if (wParam) WIN_SetStyle( hwnd, WS_VISIBLE, 0 ); else { - RedrawWindow( hwnd, NULL, 0, RDW_ALLCHILDREN | RDW_VALIDATE ); + NtUserRedrawWindow( hwnd, NULL, 0, RDW_ALLCHILDREN | RDW_VALIDATE ); WIN_SetStyle( hwnd, 0, WS_VISIBLE ); } return 0; diff --git a/dlls/user32/desktop.c b/dlls/user32/desktop.c index e1cd6985ad3..9d1484fdcbb 100644 --- a/dlls/user32/desktop.c +++ b/dlls/user32/desktop.c @@ -219,6 +219,6 @@ BOOL update_wallpaper( const WCHAR *wallpaper, const WCHAR *pattern ) } } 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; } diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index c0d03d30d0f..28fe35cc917 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -3751,7 +3751,7 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags ) /* Refresh the frame to reflect the change */ WIN_GetRectangles(hwnd, COORDS_CLIENT, &rc, NULL); rc.bottom = 0; - RedrawWindow(hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN); + NtUserRedrawWindow( hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN ); } else release_menu_ptr(menu); diff --git a/dlls/user32/painting.c b/dlls/user32/painting.c index 218f57f1670..336340c75a9 100644 --- a/dlls/user32/painting.c +++ b/dlls/user32/painting.c @@ -35,45 +35,6 @@ 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 * @@ -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 * @@ -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 * @@ -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 = ∅ - 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.@) */ @@ -689,7 +537,7 @@ BOOL WINAPI UpdateWindow( HWND hwnd ) 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 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; } - 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 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; } - 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 ); if (!bUpdate) - RedrawWindow( hwnd, NULL, hrgnUpdate, rdw_flags); + NtUserRedrawWindow( hwnd, NULL, hrgnUpdate, rdw_flags); } /* 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 ); if( !bOwnRgn) 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 * 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) ) - RedrawWindow( hwnd, NULL, hrgnUpdate, rdw_flags | - ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) ); + NtUserRedrawWindow( hwnd, NULL, hrgnUpdate, rdw_flags | + ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) ); if( hrgnWinupd) { CombineRgn( hrgnUpdate, hrgnUpdate, hrgnWinupd, RGN_OR); diff --git a/dlls/user32/static.c b/dlls/user32/static.c index 013e5c20312..44107dbd52c 100644 --- a/dlls/user32/static.c +++ b/dlls/user32/static.c @@ -473,7 +473,8 @@ LRESULT StaticWndProc_common( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam { SetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET, wParam ); 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; diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index 8b339f7bfac..143eee5f4d1 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -590,7 +590,7 @@ # @ stub ReasonCodeNeedsBugID # @ stub ReasonCodeNeedsComment # @ stub RecordShutdownReason -@ stdcall RedrawWindow(long ptr long long) +@ stdcall RedrawWindow(long ptr long long) NtUserRedrawWindow @ stdcall RegisterClassA(ptr) @ stdcall RegisterClassExA(ptr) @ stdcall RegisterClassExW(ptr) diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 1b4e8833a89..68c8fc7eada 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -145,7 +145,6 @@ static const struct user_callbacks user_funcs = CopyImage, HideCaret, PostMessageW, - RedrawWindow, SendInput, SendMessageTimeoutW, SendMessageW, diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index e7b90f60355..dd3cd57132a 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -2735,7 +2735,7 @@ void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam ) if (parent) SystemParametersInfoW( SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0 ); /* 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 ); set_capture_window( hwnd, GUI_INMOVESIZE, NULL ); diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 218f502f848..d3a69aa0763 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -146,6 +146,44 @@ done: 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 * @@ -790,6 +828,53 @@ static HRGN get_update_region( HWND hwnd, UINT *flags, HWND *child ) 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 * @@ -938,3 +1023,118 @@ BOOL WINAPI NtUserEndPaint( HWND hwnd, const PAINTSTRUCT *ps ) release_dc( hwnd, ps->hdc, 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 = ∅ + 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; +} diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index 68cde8936a3..689813a724c 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1181,6 +1181,7 @@ static struct unix_funcs unix_funcs = NtUserIsClipboardFormatAvailable, NtUserMapVirtualKeyEx, NtUserMoveWindow, + NtUserRedrawWindow, NtUserRegisterClassExWOW, NtUserRegisterHotKey, NtUserReleaseDC, diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 0e73be6fcd0..4d3e0fe5bf0 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -32,7 +32,6 @@ struct user_callbacks HANDLE (WINAPI *pCopyImage)( HANDLE, UINT, INT, INT, UINT ); BOOL (WINAPI *pHideCaret)( HWND hwnd ); BOOL (WINAPI *pPostMessageW)( HWND, UINT, WPARAM, LPARAM ); - BOOL (WINAPI *pRedrawWindow)( HWND, const RECT*, HRGN, UINT ); UINT (WINAPI *pSendInput)( UINT count, INPUT *inputs, int size ); LRESULT (WINAPI *pSendMessageTimeoutW)( HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR ); LRESULT (WINAPI *pSendMessageW)( HWND, UINT, WPARAM, LPARAM ); diff --git a/dlls/win32u/palette.c b/dlls/win32u/palette.c index 18885c7fba8..2a394ba7eba 100644 --- a/dlls/win32u/palette.c +++ b/dlls/win32u/palette.c @@ -602,14 +602,13 @@ BOOL WINAPI NtGdiUpdateColors( HDC hDC ) HWND hwnd; if (!size) return FALSE; - if (!user_callbacks) return TRUE; hwnd = NtUserWindowFromDC( hDC ); /* Docs say that we have to remap current drawable pixel by pixel * 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; } diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index f72b071ed9e..ea96a704776 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -4540,8 +4540,7 @@ BOOL WINAPI NtUserSetSysColors( INT count, const INT *colors, const COLORREF *va user_callbacks->pSendMessageTimeoutW( HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0, SMTO_ABORTIFHUNG, 2000, NULL ); /* Repaint affected portions of all visible windows */ - user_callbacks->pRedrawWindow( 0, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | - RDW_ALLCHILDREN ); + NtUserRedrawWindow( 0, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN ); return TRUE; } diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index ad24113adff..882759a9802 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1120,7 +1120,7 @@ @ stub NtUserRealChildWindowFromPoint @ stub NtUserRealInternalGetMessage @ stub NtUserRealWaitMessageEx -@ stub NtUserRedrawWindow +@ stdcall NtUserRedrawWindow(long ptr long long) @ stub NtUserRegisterBSDRWindow @ stdcall NtUserRegisterClassExWOW(ptr ptr ptr ptr long long long) @ stub NtUserRegisterDManipHook diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index b67a90c26c7..65b6f4df7b7 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -222,6 +222,7 @@ struct unix_funcs BOOL (WINAPI *pNtUserIsClipboardFormatAvailable)( UINT format ); 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 *pNtUserRedrawWindow)( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags ); ATOM (WINAPI *pNtUserRegisterClassExWOW)( const WNDCLASSEXW *wc, UNICODE_STRING *name, UNICODE_STRING *version, struct client_menu_name *client_menu_name, diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 0cd70cdca02..09a4d9cf3e7 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1812,7 +1812,7 @@ BOOL WINAPI NtUserFlashWindowEx( FLASHWINFO *info ) 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 ); if (!win || win == WND_OTHER_PROCESS || win == WND_DESKTOP) return FALSE; diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index 40100c7cde2..452bde6683e 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -894,6 +894,12 @@ UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL 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, struct client_menu_name *client_menu_name, DWORD fnid, DWORD flags, DWORD *wow ) diff --git a/include/ntuser.h b/include/ntuser.h index e27ef262403..b0285b7418b 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -365,6 +365,7 @@ HWINSTA WINAPI NtUserOpenWindowStation( OBJECT_ATTRIBUTES *attr, ACCESS_MASK acc BOOL WINAPI NtUserSetObjectInformation( HANDLE handle, INT index, void *info, DWORD len ); HDESK WINAPI NtUserOpenDesktop( OBJECT_ATTRIBUTES *attr, DWORD flags, 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, struct client_menu_name *client_menu_name, DWORD fnid, DWORD flags, DWORD *wow );