Commit 0b0403ba authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Move NtUserBeginPaint implementation from user32.

parent b1708179
......@@ -246,7 +246,7 @@ LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = wParam ? (HDC)wParam : BeginPaint( hWnd, &ps );
HDC hdc = wParam ? (HDC)wParam : NtUserBeginPaint( hWnd, &ps );
if (btnPaintFunc[btn_type])
{
int nOldMode = SetBkMode( hdc, OPAQUE );
......
......@@ -28,8 +28,7 @@
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "ntuser.h"
#include "user_private.h"
#include "win.h"
#include "controls.h"
......@@ -792,8 +791,7 @@ static LRESULT COMBO_Paint(LPHEADCOMBO lphc, HDC hParamDC)
PAINTSTRUCT ps;
HDC hDC;
hDC = (hParamDC) ? hParamDC
: BeginPaint( lphc->self, &ps);
hDC = hParamDC ? hParamDC : NtUserBeginPaint( lphc->self, &ps );
TRACE("hdc=%p\n", hDC);
......
......@@ -365,7 +365,7 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps );
HDC hdc = NtUserBeginPaint( hwnd, &ps );
if( hdc )
{
HICON hIcon;
......
......@@ -3706,7 +3706,7 @@ static void EDIT_WM_Paint(EDITSTATE *es, HDC hdc)
BOOL rev = es->bEnableState &&
((es->flags & EF_FOCUSED) ||
(es->style & ES_NOHIDESEL));
dc = hdc ? hdc : BeginPaint(es->hwndSelf, &ps);
dc = hdc ? hdc : NtUserBeginPaint( es->hwndSelf, &ps );
/* The dc we use for calculating may not be the one we paint into.
This is the safest action. */
......
......@@ -3090,7 +3090,7 @@ LRESULT ListBoxWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = ( wParam ) ? ((HDC)wParam) : BeginPaint( descr->self, &ps );
HDC hdc = ( wParam ) ? ((HDC)wParam) : NtUserBeginPaint( descr->self, &ps );
ret = LISTBOX_Paint( descr, hdc );
if( !wParam ) EndPaint( descr->self, &ps );
}
......
......@@ -3581,7 +3581,7 @@ LRESULT WINAPI PopupMenuWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint( hwnd, &ps );
NtUserBeginPaint( hwnd, &ps );
MENU_DrawPopupMenu( hwnd, ps.hdc,
(HMENU)GetWindowLongPtrW( hwnd, 0 ) );
EndPaint( hwnd, &ps );
......
......@@ -551,37 +551,6 @@ static HWND fix_caret(HWND hWnd, const RECT *scroll_rect, INT dx, INT dy,
/***********************************************************************
* BeginPaint (USER32.@)
*/
HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps )
{
HRGN hrgn;
HDC hdc;
BOOL erase;
RECT rect;
UINT flags = UPDATE_NONCLIENT | UPDATE_ERASE | UPDATE_PAINT | UPDATE_INTERNALPAINT | UPDATE_NOCHILDREN;
HideCaret( hwnd );
if (!(hrgn = send_ncpaint( hwnd, NULL, &flags ))) return 0;
erase = send_erase( hwnd, flags, hrgn, &rect, &hdc );
TRACE("hdc = %p box = (%s), fErase = %d\n", hdc, wine_dbgstr_rect(&rect), erase);
if (!lps)
{
release_dc( hwnd, hdc, TRUE );
return 0;
}
lps->fErase = erase;
lps->rcPaint = rect;
lps->hdc = hdc;
return hdc;
}
/***********************************************************************
* EndPaint (USER32.@)
*/
BOOL WINAPI EndPaint( HWND hwnd, const PAINTSTRUCT *lps )
......
......@@ -644,7 +644,7 @@ void WINAPI USER_ScrollBarDraw( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTES
}
}
void SCROLL_SetStandardScrollPainted( HWND hwnd, INT bar, BOOL painted )
void WINAPI SCROLL_SetStandardScrollPainted( HWND hwnd, INT bar, BOOL painted )
{
LPSCROLLBAR_INFO info;
......@@ -1521,7 +1521,7 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = wParam ? (HDC)wParam : BeginPaint(hwnd, &ps);
HDC hdc = wParam ? (HDC)wParam : NtUserBeginPaint( hwnd, &ps );
SCROLL_DrawScrollBar( hwnd, hdc, SB_CTL, g_tracking_info.hit_test, &g_tracking_info, TRUE, TRUE );
if (!wParam) EndPaint(hwnd, &ps);
}
......
......@@ -374,7 +374,7 @@ LRESULT StaticWndProc_common( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
{
PAINTSTRUCT ps;
RECT rect;
HDC hdc = wParam ? (HDC)wParam : BeginPaint(hwnd, &ps);
HDC hdc = wParam ? (HDC)wParam : NtUserBeginPaint( hwnd, &ps );
HRGN hrgn;
HBRUSH hbrush;
......
......@@ -14,7 +14,7 @@
@ stdcall ArrangeIconicWindows(long)
@ stdcall AttachThreadInput(long long long) NtUserAttachThreadInput
@ stdcall BeginDeferWindowPos(long)
@ stdcall BeginPaint(long ptr)
@ stdcall BeginPaint(long ptr) NtUserBeginPaint
@ stdcall BlockInput(long)
@ stdcall BringWindowToTop(long)
@ stdcall BroadcastSystemMessage(long ptr long long long) BroadcastSystemMessageA
......
......@@ -143,6 +143,7 @@ static void CDECL notify_ime( HWND hwnd, UINT param )
static const struct user_callbacks user_funcs =
{
CopyImage,
HideCaret,
PostMessageW,
RedrawWindow,
SendInput,
......@@ -154,6 +155,7 @@ static const struct user_callbacks user_funcs =
notify_ime,
register_builtin_classes,
MSG_SendInternalMessageTimeout,
SCROLL_SetStandardScrollPainted,
(void *)__wine_set_user_driver,
set_window_pos,
};
......
......@@ -243,6 +243,6 @@ LRESULT WINAPI USER_ScrollBarProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HID
void WINAPI USER_ScrollBarDraw(HWND, HDC, INT, enum SCROLL_HITTEST,
const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, INT, INT,
INT, BOOL) DECLSPEC_HIDDEN;
void SCROLL_SetStandardScrollPainted(HWND hwnd, INT bar, BOOL visible);
void WINAPI SCROLL_SetStandardScrollPainted(HWND hwnd, INT bar, BOOL visible);
#endif /* __WINE_USER_PRIVATE_H */
......@@ -742,3 +742,187 @@ HWND WINAPI NtUserWindowFromDC( HDC hdc )
user_unlock();
return hwnd;
}
/***********************************************************************
* get_update_region
*
* Return update region (in screen coordinates) for a window.
*/
static HRGN get_update_region( HWND hwnd, UINT *flags, HWND *child )
{
HRGN hrgn = 0;
NTSTATUS status;
RGNDATA *data;
size_t size = 256;
do
{
if (!(data = malloc( sizeof(*data) + size - 1 )))
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
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;
wine_server_set_reply( req, data->Buffer, size );
if (!(status = wine_server_call( req )))
{
size_t reply_size = wine_server_reply_size( reply );
data->rdh.dwSize = sizeof(data->rdh);
data->rdh.iType = RDH_RECTANGLES;
data->rdh.nCount = reply_size / sizeof(RECT);
data->rdh.nRgnSize = reply_size;
hrgn = NtGdiExtCreateRegion( NULL, data->rdh.dwSize + data->rdh.nRgnSize, data );
if (child) *child = wine_server_ptr_handle( reply->child );
*flags = reply->flags;
}
else size = reply->total_size;
}
SERVER_END_REQ;
free( data );
} while (status == STATUS_BUFFER_OVERFLOW);
if (status) SetLastError( RtlNtStatusToDosError(status) );
return hrgn;
}
/***********************************************************************
* send_ncpaint
*
* Send a WM_NCPAINT message if needed, and return the resulting update region (in screen coords).
* Helper for erase_now and BeginPaint.
*/
static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags )
{
HRGN whole_rgn = get_update_region( hwnd, flags, child );
HRGN client_rgn = 0;
DWORD style;
if (child) hwnd = *child;
if (hwnd == get_desktop_window()) return whole_rgn;
if (whole_rgn)
{
DPI_AWARENESS_CONTEXT context;
RECT client, window, update;
INT type;
context = set_thread_dpi_awareness_context( get_window_dpi_awareness_context( hwnd ));
/* check if update rgn overlaps with nonclient area */
type = NtGdiGetRgnBox( whole_rgn, &update );
get_window_rects( hwnd, COORDS_SCREEN, &window, &client, get_thread_dpi() );
if ((*flags & UPDATE_NONCLIENT) ||
update.left < client.left || update.top < client.top ||
update.right > client.right || update.bottom > client.bottom)
{
client_rgn = NtGdiCreateRectRgn( client.left, client.top, client.right, client.bottom );
NtGdiCombineRgn( client_rgn, client_rgn, whole_rgn, RGN_AND );
/* check if update rgn contains complete nonclient area */
if (type == SIMPLEREGION && EqualRect( &window, &update ))
{
NtGdiDeleteObjectApp( whole_rgn );
whole_rgn = (HRGN)1;
}
}
else
{
client_rgn = whole_rgn;
whole_rgn = 0;
}
if (whole_rgn) /* NOTE: WM_NCPAINT allows wParam to be 1 */
{
if ((*flags & UPDATE_NONCLIENT) && user_callbacks)
{
/* Mark standard scroll bars as not painted before sending WM_NCPAINT */
style = get_window_long( hwnd, GWL_STYLE );
if (style & WS_HSCROLL)
user_callbacks->set_standard_scroll_painted( hwnd, SB_HORZ, FALSE );
if (style & WS_VSCROLL)
user_callbacks->set_standard_scroll_painted( hwnd, SB_VERT, FALSE );
send_message( hwnd, WM_NCPAINT, (WPARAM)whole_rgn, 0 );
}
if (whole_rgn > (HRGN)1) NtGdiDeleteObjectApp( whole_rgn );
}
set_thread_dpi_awareness_context( context );
}
return client_rgn;
}
/***********************************************************************
* send_erase
*
* Send a WM_ERASEBKGND message if needed, and optionally return the DC for painting.
* If a DC is requested, the region is selected into it. In all cases the region is deleted.
* Helper for erase_now and BeginPaint.
*/
static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn,
RECT *clip_rect, HDC *hdc_ret )
{
BOOL need_erase = (flags & UPDATE_DELAYED_ERASE) != 0;
HDC hdc = 0;
RECT dummy;
if (!clip_rect) clip_rect = &dummy;
if (hdc_ret || (flags & UPDATE_ERASE))
{
UINT dcx_flags = DCX_INTERSECTRGN | DCX_USESTYLE;
if (is_iconic(hwnd)) dcx_flags |= DCX_WINDOW;
if ((hdc = NtUserGetDCEx( hwnd, client_rgn, dcx_flags )))
{
INT type = NtGdiGetAppClipBox( hdc, clip_rect );
if (flags & UPDATE_ERASE)
{
/* don't erase if the clip box is empty */
if (type != NULLREGION)
need_erase = !send_message( hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0 );
}
if (!hdc_ret) release_dc( hwnd, hdc, TRUE );
}
if (hdc_ret) *hdc_ret = hdc;
}
if (!hdc) NtGdiDeleteObjectApp( client_rgn );
return need_erase;
}
/***********************************************************************
* NtUserBeginPaint (win32u.@)
*/
HDC WINAPI NtUserBeginPaint( HWND hwnd, PAINTSTRUCT *ps )
{
HRGN hrgn;
HDC hdc;
BOOL erase;
RECT rect;
UINT flags = UPDATE_NONCLIENT | UPDATE_ERASE | UPDATE_PAINT | UPDATE_INTERNALPAINT | UPDATE_NOCHILDREN;
if (user_callbacks) user_callbacks->pHideCaret( hwnd );
if (!(hrgn = send_ncpaint( hwnd, NULL, &flags ))) return 0;
erase = send_erase( hwnd, flags, hrgn, &rect, &hdc );
TRACE( "hdc = %p box = (%s), fErase = %d\n", hdc, wine_dbgstr_rect(&rect), erase );
if (!ps)
{
release_dc( hwnd, hdc, TRUE );
return 0;
}
ps->fErase = erase;
ps->rcPaint = rect;
ps->hdc = hdc;
return hdc;
}
......@@ -1150,6 +1150,7 @@ static struct unix_funcs unix_funcs =
NtGdiUpdateColors,
NtGdiWidenPath,
NtUserActivateKeyboardLayout,
NtUserBeginPaint,
NtUserCallHwnd,
NtUserCallHwndParam,
NtUserCallNextHookEx,
......
......@@ -30,6 +30,7 @@ struct dce;
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 );
......@@ -41,6 +42,7 @@ struct user_callbacks
void (CDECL *notify_ime)( HWND hwnd, UINT param );
void (CDECL *register_builtin_classes)(void);
LRESULT (WINAPI *send_ll_message)( DWORD, DWORD, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR );
void (WINAPI *set_standard_scroll_painted)( HWND hwnd, INT bar, BOOL visible );
void (CDECL *set_user_driver)( void *, UINT );
BOOL (CDECL *set_window_pos)( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect,
......
......@@ -758,7 +758,7 @@
@ stub NtUserAutoPromoteMouseInPointer
@ stub NtUserAutoRotateScreen
@ stub NtUserBeginLayoutUpdate
@ stub NtUserBeginPaint
@ stdcall NtUserBeginPaint(long ptr)
@ stub NtUserBitBltSysBmp
@ stub NtUserBlockInput
@ stub NtUserBroadcastThemeChangeEvent
......
......@@ -184,6 +184,7 @@ struct unix_funcs
BOOL (WINAPI *pNtGdiUpdateColors)( HDC hdc );
BOOL (WINAPI *pNtGdiWidenPath)( HDC hdc );
HKL (WINAPI *pNtUserActivateKeyboardLayout)( HKL layout, UINT flags );
HDC (WINAPI *pNtUserBeginPaint)( HWND hwnd, PAINTSTRUCT *ps );
ULONG_PTR (WINAPI *pNtUserCallHwnd)( HWND hwnd, DWORD code );
ULONG_PTR (WINAPI *pNtUserCallHwndParam)( HWND hwnd, DWORD_PTR param, DWORD code );
LRESULT (WINAPI *pNtUserCallNextHookEx)( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam );
......
......@@ -701,6 +701,12 @@ HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags )
return unix_funcs->pNtUserActivateKeyboardLayout( layout, flags );
}
HDC WINAPI NtUserBeginPaint( HWND hwnd, PAINTSTRUCT *ps )
{
if (!unix_funcs) return 0;
return unix_funcs->pNtUserBeginPaint( hwnd, ps );
}
LRESULT WINAPI NtUserCallNextHookEx( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam )
{
if (!unix_funcs) return 0;
......
......@@ -271,6 +271,7 @@ enum wine_internal_message
HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags );
BOOL WINAPI NtUserAddClipboardFormatListener( HWND hwnd );
BOOL WINAPI NtUserAttachThreadInput( DWORD from, DWORD to, BOOL attach );
HDC WINAPI NtUserBeginPaint( HWND hwnd, PAINTSTRUCT *ps );
NTSTATUS WINAPI NtUserBuildHwndList( HDESK desktop, ULONG unk2, ULONG unk3, ULONG unk4,
ULONG thread_id, ULONG count, HWND *buffer, ULONG *size );
ULONG_PTR WINAPI NtUserCallHwnd( HWND hwnd, DWORD code );
......
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