win32u: Move NtUserPeekMessage 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:
parent
6badbee323
commit
58c4488626
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue