Commit dda4b573 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Move NtUserGetMessage implementation from user32.

parent 58c44886
......@@ -1181,6 +1181,7 @@ static struct unix_funcs unix_funcs =
NtUserGetIconInfo,
NtUserGetKeyNameText,
NtUserGetKeyboardLayoutList,
NtUserGetMessage,
NtUserGetPriorityClipboardFormat,
NtUserGetQueueStatus,
NtUserGetUpdateRect,
......
......@@ -24,6 +24,7 @@
#pragma makedep unix
#endif
#include <assert.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "win32u_private.h"
......@@ -37,6 +38,9 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
#define MAX_WINPROC_RECURSION 64
#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
#define WM_NCMOUSELAST (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST))
#define MAX_PACK_COUNT 4
struct packed_hook_extra_info
......@@ -384,22 +388,24 @@ static void reply_message( struct received_message_info *info, LRESULT result, M
{
struct packed_message data;
int i, replied = info->flags & ISMEX_REPLIED;
BOOL remove = msg != NULL;
if (info->flags & ISMEX_NOTIFY) return; /* notify messages don't get replies */
if (!msg && replied) return; /* replied already */
if (!remove && replied) return; /* replied already */
memset( &data, 0, sizeof(data) );
info->flags |= ISMEX_REPLIED;
if (info->type == MSG_OTHER_PROCESS && !replied)
{
if (!msg) msg = &info->msg;
pack_reply( msg->hwnd, msg->message, msg->wParam, msg->lParam, result, &data );
}
SERVER_START_REQ( reply_message )
{
req->result = result;
req->remove = msg != NULL;
req->remove = remove;
for (i = 0; i < data.count; i++) wine_server_add_data( req, data.data[i], data.size[i] );
wine_server_call( req );
}
......@@ -856,6 +862,30 @@ void process_sent_messages(void)
peek_message( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE, 0 );
}
/***********************************************************************
* get_server_queue_handle
*
* Get a handle to the server message queue for the current thread.
*/
static HANDLE get_server_queue_handle(void)
{
struct user_thread_info *thread_info = get_user_thread_info();
HANDLE ret;
if (!(ret = thread_info->server_queue))
{
SERVER_START_REQ( get_msg_queue )
{
wine_server_call( req );
ret = wine_server_ptr_handle( reply->handle );
}
SERVER_END_REQ;
thread_info->server_queue = ret;
if (!ret) ERR( "Cannot get server thread queue\n" );
}
return ret;
}
/* check for driver events if we detect that the app is not properly consuming messages */
static inline void check_for_driver_events( UINT msg )
{
......@@ -893,6 +923,41 @@ static DWORD wait_message( DWORD count, const HANDLE *handles, DWORD timeout, DW
}
/***********************************************************************
* wait_objects
*
* Wait for multiple objects including the server queue, with specific queue masks.
*/
static DWORD wait_objects( DWORD count, const HANDLE *handles, DWORD timeout,
DWORD wake_mask, DWORD changed_mask, DWORD flags )
{
struct user_thread_info *thread_info = get_user_thread_info();
DWORD ret;
assert( count ); /* we must have at least the server queue */
flush_window_surfaces( TRUE );
if (thread_info->wake_mask != wake_mask || thread_info->changed_mask != changed_mask)
{
SERVER_START_REQ( set_queue_mask )
{
req->wake_mask = wake_mask;
req->changed_mask = changed_mask;
req->skip_wait = 0;
wine_server_call( req );
}
SERVER_END_REQ;
thread_info->wake_mask = wake_mask;
thread_info->changed_mask = changed_mask;
}
ret = wait_message( count, handles, timeout, changed_mask, flags );
if (ret != WAIT_TIMEOUT) thread_info->wake_mask = thread_info->changed_mask = 0;
return ret;
}
/***********************************************************************
* NtUserPeekMessage (win32u.@)
*/
BOOL WINAPI NtUserPeekMessage( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT flags )
......@@ -929,6 +994,40 @@ BOOL WINAPI NtUserPeekMessage( MSG *msg_out, HWND hwnd, UINT first, UINT last, U
return TRUE;
}
/***********************************************************************
* NtUserGetMessage (win32u.@)
*/
BOOL WINAPI NtUserGetMessage( MSG *msg, HWND hwnd, UINT first, UINT last )
{
HANDLE server_queue = get_server_queue_handle();
unsigned int mask = QS_POSTMESSAGE | QS_SENDMESSAGE; /* Always selected */
int ret;
user_check_not_lock();
check_for_driver_events( 0 );
if (first || last)
{
if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY;
if ( ((first <= WM_MOUSELAST) && (last >= WM_MOUSEFIRST)) ||
((first <= WM_NCMOUSELAST) && (last >= WM_NCMOUSEFIRST)) ) mask |= QS_MOUSE;
if ((first <= WM_TIMER) && (last >= WM_TIMER)) mask |= QS_TIMER;
if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= QS_TIMER;
if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= QS_PAINT;
}
else mask = QS_ALLINPUT;
while (!(ret = peek_message( msg, hwnd, first, last, PM_REMOVE | (mask << 16), mask )))
{
wait_objects( 1, &server_queue, INFINITE, mask & (QS_SENDMESSAGE | QS_SMRESULT), mask, 0 );
}
if (ret < 0) return -1;
check_for_driver_events( msg->message );
return msg->message != WM_QUIT;
}
/**********************************************************************
* dispatch_message
*/
......
......@@ -955,7 +955,7 @@
@ stub NtUserGetMenuBarInfo
@ stub NtUserGetMenuIndex
@ stub NtUserGetMenuItemRect
@ stub NtUserGetMessage
@ stdcall NtUserGetMessage(ptr long long long)
@ stdcall -syscall NtUserGetMouseMovePointsEx(long ptr ptr long long)
@ stdcall -syscall NtUserGetObjectInformation(long long long long ptr)
@ stub NtUserGetOemBitmapSize
......
......@@ -228,6 +228,7 @@ struct unix_funcs
UNICODE_STRING *res_name, DWORD *bpp, LONG unk );
INT (WINAPI *pNtUserGetKeyNameText)( LONG lparam, WCHAR *buffer, INT size );
UINT (WINAPI *pNtUserGetKeyboardLayoutList)( INT size, HKL *layouts );
BOOL (WINAPI *pNtUserGetMessage)( MSG *msg, HWND hwnd, UINT first, UINT last );
INT (WINAPI *pNtUserGetPriorityClipboardFormat)( UINT *list, INT count );
DWORD (WINAPI *pNtUserGetQueueStatus)( UINT flags );
BOOL (WINAPI *pNtUserGetUpdateRect)( HWND hwnd, RECT *rect, BOOL erase );
......
......@@ -903,6 +903,12 @@ INT WINAPI NtUserGetKeyNameText( LONG lparam, WCHAR *buffer, INT size )
return unix_funcs->pNtUserGetKeyNameText( lparam, buffer, size );
}
BOOL WINAPI NtUserGetMessage( MSG *msg, HWND hwnd, UINT first, UINT last )
{
if (!unix_funcs) return FALSE;
return unix_funcs->pNtUserGetMessage( msg, hwnd, first, last );
}
BOOL WINAPI NtUserGetUpdateRect( HWND hwnd, RECT *rect, BOOL erase )
{
if (!unix_funcs) return FALSE;
......
......@@ -559,6 +559,7 @@ UINT WINAPI NtUserGetKeyboardLayoutList( INT size, HKL *layouts );
BOOL WINAPI NtUserGetKeyboardLayoutName( WCHAR *name );
BOOL WINAPI NtUserGetKeyboardState( BYTE *state );
BOOL WINAPI NtUserGetLayeredWindowAttributes( HWND hwnd, COLORREF *key, BYTE *alpha, DWORD *flags );
BOOL WINAPI NtUserGetMessage( MSG *msg, HWND hwnd, UINT first, UINT last );
int WINAPI NtUserGetMouseMovePointsEx( UINT size, MOUSEMOVEPOINT *ptin, MOUSEMOVEPOINT *ptout,
int count, DWORD resolution );
BOOL WINAPI NtUserGetObjectInformation( HANDLE handle, INT index, void *info,
......
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