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 ) ...@@ -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 register_wow_handlers(void)
{ {
void **callback_table = NtCurrentTeb()->Peb->KernelCallbackTable; void **callback_table = NtCurrentTeb()->Peb->KernelCallbackTable;
...@@ -2615,6 +2628,9 @@ void register_wow_handlers(void) ...@@ -2615,6 +2628,9 @@ void register_wow_handlers(void)
}; };
callback_table[NtUserCallFreeIcon] = User16CallFreeIcon; callback_table[NtUserCallFreeIcon] = User16CallFreeIcon;
callback_table[NtUserThunkLock] = User16ThunkLock;
NtUserCallOneParam( TRUE, NtUserEnableThunkLock );
UserRegisterWowHandlers( &handlers16, &wow_handlers32 ); UserRegisterWowHandlers( &handlers16, &wow_handlers32 );
} }
...@@ -3208,36 +3208,7 @@ static inline void check_for_driver_events( UINT msg ) ...@@ -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 ) BOOL WINAPI DECLSPEC_HOTPATCH PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT flags )
{ {
MSG msg; return NtUserPeekMessage( msg_out, hwnd, first, last, flags );
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;
} }
......
...@@ -1190,6 +1190,7 @@ static struct unix_funcs unix_funcs = ...@@ -1190,6 +1190,7 @@ static struct unix_funcs unix_funcs =
NtUserMapVirtualKeyEx, NtUserMapVirtualKeyEx,
NtUserMessageCall, NtUserMessageCall,
NtUserMoveWindow, NtUserMoveWindow,
NtUserPeekMessage,
NtUserRedrawWindow, NtUserRedrawWindow,
NtUserRegisterClassExWOW, NtUserRegisterClassExWOW,
NtUserRegisterHotKey, NtUserRegisterHotKey,
......
...@@ -856,6 +856,79 @@ void process_sent_messages(void) ...@@ -856,6 +856,79 @@ void process_sent_messages(void)
peek_message( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE, 0 ); 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 * dispatch_message
*/ */
......
...@@ -230,6 +230,8 @@ static struct list monitors = LIST_INIT(monitors); ...@@ -230,6 +230,8 @@ static struct list monitors = LIST_INIT(monitors);
static INT64 last_query_display_time; static INT64 last_query_display_time;
static pthread_mutex_t display_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t display_lock = PTHREAD_MUTEX_INITIALIZER;
BOOL enable_thunk_lock = FALSE;
static struct monitor virtual_monitor = static struct monitor virtual_monitor =
{ {
.handle = NULLDRV_DEFAULT_HMONITOR, .handle = NULLDRV_DEFAULT_HMONITOR,
...@@ -4669,6 +4671,9 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code ) ...@@ -4669,6 +4671,9 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code )
return dispatch_message( (const MSG *)arg, TRUE ); return dispatch_message( (const MSG *)arg, TRUE );
case NtUserEnableDC: case NtUserEnableDC:
return set_dce_flags( UlongToHandle(arg), DCHF_ENABLEDC ); return set_dce_flags( UlongToHandle(arg), DCHF_ENABLEDC );
case NtUserEnableThunkLock:
enable_thunk_lock = arg;
return 0;
case NtUserGetClipCursor: case NtUserGetClipCursor:
return get_clip_cursor( (RECT *)arg ); return get_clip_cursor( (RECT *)arg );
case NtUserGetCursorPos: case NtUserGetCursorPos:
......
...@@ -1098,7 +1098,7 @@ ...@@ -1098,7 +1098,7 @@
@ stub NtUserPaintDesktop @ stub NtUserPaintDesktop
@ stub NtUserPaintMenuBar @ stub NtUserPaintMenuBar
@ stub NtUserPaintMonitor @ stub NtUserPaintMonitor
@ stub NtUserPeekMessage @ stdcall NtUserPeekMessage(ptr long long long long)
@ stub NtUserPerMonitorDPIPhysicalToLogicalPoint @ stub NtUserPerMonitorDPIPhysicalToLogicalPoint
@ stub NtUserPhysicalToLogicalDpiPointForWindow @ stub NtUserPhysicalToLogicalDpiPointForWindow
@ stub NtUserPhysicalToLogicalPoint @ stub NtUserPhysicalToLogicalPoint
......
...@@ -238,6 +238,7 @@ struct unix_funcs ...@@ -238,6 +238,7 @@ struct unix_funcs
BOOL (WINAPI *pNtUserMessageCall)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL (WINAPI *pNtUserMessageCall)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
ULONG_PTR result_info, DWORD type, BOOL ansi ); 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 *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 ); 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,
...@@ -349,6 +350,7 @@ extern BOOL reply_message_result( LRESULT result, MSG *msg ) DECLSPEC_HIDDEN; ...@@ -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; extern LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN;
/* sysparams.c */ /* sysparams.c */
extern BOOL enable_thunk_lock DECLSPEC_HIDDEN;
extern RECT get_display_rect( const WCHAR *display ) DECLSPEC_HIDDEN; extern RECT get_display_rect( const WCHAR *display ) DECLSPEC_HIDDEN;
extern UINT get_monitor_dpi( HMONITOR monitor ) DECLSPEC_HIDDEN; extern UINT get_monitor_dpi( HMONITOR monitor ) DECLSPEC_HIDDEN;
extern BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info ) 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 ...@@ -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 ); 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 ) BOOL WINAPI NtUserRedrawWindow( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags )
{ {
if (!unix_funcs) return FALSE; if (!unix_funcs) return FALSE;
......
...@@ -35,6 +35,7 @@ enum ...@@ -35,6 +35,7 @@ enum
NtUserLoadDriver, NtUserLoadDriver,
/* win16 hooks */ /* win16 hooks */
NtUserCallFreeIcon, NtUserCallFreeIcon,
NtUserThunkLock,
/* Vulkan support */ /* Vulkan support */
NtUserCallVulkanDebugReportCallback, NtUserCallVulkanDebugReportCallback,
NtUserCallVulkanDebugUtilsCallback, NtUserCallVulkanDebugUtilsCallback,
...@@ -150,6 +151,7 @@ enum ...@@ -150,6 +151,7 @@ enum
NtUserCreateCursorIcon, NtUserCreateCursorIcon,
NtUserDispatchMessageA, NtUserDispatchMessageA,
NtUserEnableDC, NtUserEnableDC,
NtUserEnableThunkLock,
NtUserGetClipCursor, NtUserGetClipCursor,
NtUserGetCursorPos, NtUserGetCursorPos,
NtUserGetIconParam, NtUserGetIconParam,
...@@ -588,6 +590,7 @@ HWINSTA WINAPI NtUserOpenWindowStation( OBJECT_ATTRIBUTES *attr, ACCESS_MASK acc ...@@ -588,6 +590,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 NtUserPeekMessage( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT flags );
BOOL WINAPI NtUserRedrawWindow( HWND hwnd, const RECT *rect, HRGN hrgn, 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, 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,
......
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