Commit 58c44886 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Move NtUserPeekMessage implementation from user32.

parent 6badbee3
......@@ -2596,6 +2596,19 @@ static void WINAPI User16CallFreeIcon( ULONG *param, ULONG size )
}
static DWORD WINAPI User16ThunkLock( DWORD *param, ULONG size )
{
if (size != sizeof(DWORD))
{
DWORD lock;
ReleaseThunkLock( &lock );
return lock;
}
RestoreThunkLock( *param );
return 0;
}
void register_wow_handlers(void)
{
void **callback_table = NtCurrentTeb()->Peb->KernelCallbackTable;
......@@ -2615,6 +2628,9 @@ void register_wow_handlers(void)
};
callback_table[NtUserCallFreeIcon] = User16CallFreeIcon;
callback_table[NtUserThunkLock] = User16ThunkLock;
NtUserCallOneParam( TRUE, NtUserEnableThunkLock );
UserRegisterWowHandlers( &handlers16, &wow_handlers32 );
}
......@@ -3208,36 +3208,7 @@ static inline void check_for_driver_events( UINT msg )
*/
BOOL WINAPI DECLSPEC_HOTPATCH PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT flags )
{
MSG msg;
int ret;
USER_CheckNotLock();
check_for_driver_events( 0 );
ret = peek_message( &msg, hwnd, first, last, flags, 0 );
if (ret < 0) return FALSE;
if (!ret)
{
flush_window_surfaces( TRUE );
ret = wow_handlers.wait_message( 0, NULL, 0, QS_ALLINPUT, 0 );
/* if we received driver events, check again for a pending message */
if (ret == WAIT_TIMEOUT || peek_message( &msg, hwnd, first, last, flags, 0 ) <= 0) return FALSE;
}
check_for_driver_events( msg.message );
/* copy back our internal safe copy of message data to msg_out.
* msg_out is a variable from the *program*, so it can't be used
* internally as it can get "corrupted" by our use of SendMessage()
* (back to the program) inside the message handling itself. */
if (!msg_out)
{
SetLastError( ERROR_NOACCESS );
return FALSE;
}
*msg_out = msg;
return TRUE;
return NtUserPeekMessage( msg_out, hwnd, first, last, flags );
}
......
......@@ -1190,6 +1190,7 @@ static struct unix_funcs unix_funcs =
NtUserMapVirtualKeyEx,
NtUserMessageCall,
NtUserMoveWindow,
NtUserPeekMessage,
NtUserRedrawWindow,
NtUserRegisterClassExWOW,
NtUserRegisterHotKey,
......
......@@ -856,6 +856,79 @@ void process_sent_messages(void)
peek_message( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE, 0 );
}
/* check for driver events if we detect that the app is not properly consuming messages */
static inline void check_for_driver_events( UINT msg )
{
if (get_user_thread_info()->message_count > 200)
{
flush_window_surfaces( FALSE );
user_driver->pMsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_ALLINPUT, 0 );
}
else if (msg == WM_TIMER || msg == WM_SYSTIMER)
{
/* driver events should have priority over timers, so make sure we'll check for them soon */
get_user_thread_info()->message_count += 100;
}
else get_user_thread_info()->message_count++;
}
/* wait for message or signaled handle */
static DWORD wait_message( DWORD count, const HANDLE *handles, DWORD timeout, DWORD mask, DWORD flags )
{
DWORD ret, lock;
void *ret_ptr;
ULONG ret_len;
if (enable_thunk_lock)
lock = KeUserModeCallback( NtUserThunkLock, NULL, 0, &ret_ptr, &ret_len );
ret = user_driver->pMsgWaitForMultipleObjectsEx( count, handles, timeout, mask, flags );
if (ret == WAIT_TIMEOUT && !count && !timeout) NtYieldExecution();
if ((mask & QS_INPUT) == QS_INPUT) get_user_thread_info()->message_count = 0;
if (enable_thunk_lock)
KeUserModeCallback( NtUserThunkLock, &lock, sizeof(lock), &ret_ptr, &ret_len );
return ret;
}
/***********************************************************************
* NtUserPeekMessage (win32u.@)
*/
BOOL WINAPI NtUserPeekMessage( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT flags )
{
MSG msg;
int ret;
user_check_not_lock();
check_for_driver_events( 0 );
ret = peek_message( &msg, hwnd, first, last, flags, 0 );
if (ret < 0) return FALSE;
if (!ret)
{
flush_window_surfaces( TRUE );
ret = wait_message( 0, NULL, 0, QS_ALLINPUT, 0 );
/* if we received driver events, check again for a pending message */
if (ret == WAIT_TIMEOUT || peek_message( &msg, hwnd, first, last, flags, 0 ) <= 0) return FALSE;
}
check_for_driver_events( msg.message );
/* copy back our internal safe copy of message data to msg_out.
* msg_out is a variable from the *program*, so it can't be used
* internally as it can get "corrupted" by our use of SendMessage()
* (back to the program) inside the message handling itself. */
if (!msg_out)
{
SetLastError( ERROR_NOACCESS );
return FALSE;
}
*msg_out = msg;
return TRUE;
}
/**********************************************************************
* dispatch_message
*/
......
......@@ -230,6 +230,8 @@ static struct list monitors = LIST_INIT(monitors);
static INT64 last_query_display_time;
static pthread_mutex_t display_lock = PTHREAD_MUTEX_INITIALIZER;
BOOL enable_thunk_lock = FALSE;
static struct monitor virtual_monitor =
{
.handle = NULLDRV_DEFAULT_HMONITOR,
......@@ -4669,6 +4671,9 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code )
return dispatch_message( (const MSG *)arg, TRUE );
case NtUserEnableDC:
return set_dce_flags( UlongToHandle(arg), DCHF_ENABLEDC );
case NtUserEnableThunkLock:
enable_thunk_lock = arg;
return 0;
case NtUserGetClipCursor:
return get_clip_cursor( (RECT *)arg );
case NtUserGetCursorPos:
......
......@@ -1098,7 +1098,7 @@
@ stub NtUserPaintDesktop
@ stub NtUserPaintMenuBar
@ stub NtUserPaintMonitor
@ stub NtUserPeekMessage
@ stdcall NtUserPeekMessage(ptr long long long long)
@ stub NtUserPerMonitorDPIPhysicalToLogicalPoint
@ stub NtUserPhysicalToLogicalDpiPointForWindow
@ stub NtUserPhysicalToLogicalPoint
......
......@@ -238,6 +238,7 @@ struct unix_funcs
BOOL (WINAPI *pNtUserMessageCall)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
ULONG_PTR result_info, DWORD type, BOOL ansi );
BOOL (WINAPI *pNtUserMoveWindow)( HWND hwnd, INT x, INT y, INT cx, INT cy, BOOL repaint );
BOOL (WINAPI *pNtUserPeekMessage)( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT flags );
BOOL (WINAPI *pNtUserRedrawWindow)( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags );
ATOM (WINAPI *pNtUserRegisterClassExWOW)( const WNDCLASSEXW *wc, UNICODE_STRING *name,
UNICODE_STRING *version,
......@@ -349,6 +350,7 @@ extern BOOL reply_message_result( LRESULT result, MSG *msg ) DECLSPEC_HIDDEN;
extern LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN;
/* sysparams.c */
extern BOOL enable_thunk_lock DECLSPEC_HIDDEN;
extern RECT get_display_rect( const WCHAR *display ) DECLSPEC_HIDDEN;
extern UINT get_monitor_dpi( HMONITOR monitor ) DECLSPEC_HIDDEN;
extern BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info ) DECLSPEC_HIDDEN;
......
......@@ -958,6 +958,12 @@ BOOL WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam
return unix_funcs->pNtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi );
}
BOOL WINAPI NtUserPeekMessage( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT flags )
{
if (!unix_funcs) return FALSE;
return unix_funcs->pNtUserPeekMessage( msg_out, hwnd, first, last, flags );
}
BOOL WINAPI NtUserRedrawWindow( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags )
{
if (!unix_funcs) return FALSE;
......
......@@ -35,6 +35,7 @@ enum
NtUserLoadDriver,
/* win16 hooks */
NtUserCallFreeIcon,
NtUserThunkLock,
/* Vulkan support */
NtUserCallVulkanDebugReportCallback,
NtUserCallVulkanDebugUtilsCallback,
......@@ -150,6 +151,7 @@ enum
NtUserCreateCursorIcon,
NtUserDispatchMessageA,
NtUserEnableDC,
NtUserEnableThunkLock,
NtUserGetClipCursor,
NtUserGetCursorPos,
NtUserGetIconParam,
......@@ -588,6 +590,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 NtUserPeekMessage( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT flags );
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,
......
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