From: Paul Gofman pgofman@codeweavers.com
--- dlls/user32/tests/input.c | 72 +++++++++++++++++++++++++++++++++++++-- dlls/win32u/rawinput.c | 3 ++ server/protocol.def | 1 + server/queue.c | 1 + 4 files changed, 74 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index fcaa4229b02..19014d8a234 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -377,6 +377,7 @@ static UINT (WINAPI *pGetRawInputDeviceInfoW) (HANDLE, UINT, void *, UINT *); static UINT (WINAPI *pGetRawInputDeviceInfoA) (HANDLE, UINT, void *, UINT *); static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); static HKL (WINAPI *pLoadKeyboardLayoutEx)(HKL, const WCHAR *, UINT); +static BOOL (WINAPI *pGetCurrentInputMessageSource)( INPUT_MESSAGE_SOURCE *source );
/**********************adapted from input.c **********************************/
@@ -403,6 +404,7 @@ static void init_function_pointers(void) GET_PROC(GetRawInputDeviceInfoW); GET_PROC(GetRawInputDeviceInfoA); GET_PROC(LoadKeyboardLayoutEx); + GET_PROC(GetCurrentInputMessageSource);
hdll = GetModuleHandleA("kernel32"); GET_PROC(IsWow64Process); @@ -2091,7 +2093,12 @@ static void test_GetRawInputBuffer(void) char buffer[16 * sizeof(RAWINPUT64)]; RAWINPUT64 *rawbuffer64 = (RAWINPUT64 *)buffer; RAWINPUT *rawbuffer = (RAWINPUT *)buffer; + DWORD t1, t2, t3, now, pos1, pos2; + LPARAM extra_info1, extra_info2; + INPUT_MESSAGE_SOURCE source; + POINT pt; HWND hwnd; + BOOL ret;
if (is_wow64) rawinput_size = sizeof(RAWINPUTHEADER64) + sizeof(RAWMOUSE); else rawinput_size = sizeof(RAWINPUTHEADER) + sizeof(RAWMOUSE); @@ -2099,6 +2106,14 @@ static void test_GetRawInputBuffer(void) hwnd = create_foreground_window( TRUE ); SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)rawinputbuffer_wndproc );
+ if (pGetCurrentInputMessageSource) + { + ret = pGetCurrentInputMessageSource( &source ); + ok( ret, "got error %lu.\n", GetLastError() ); + ok( !source.deviceType, "got %#x.\n", source.deviceType ); + ok( !source.originId, "got %#x.\n", source.originId ); + } + raw_devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC; raw_devices[0].usUsage = HID_USAGE_GENERIC_MOUSE; raw_devices[0].dwFlags = RIDEV_INPUTSINK; @@ -2116,6 +2131,11 @@ static void test_GetRawInputBuffer(void) ok_ret( ERROR_INVALID_PARAMETER, GetLastError() );
/* valid calls, but no input */ + t1 = GetMessageTime(); + pos1 = GetMessagePos(); + extra_info1 = GetMessageExtraInfo(); + now = GetTickCount(); + ok( t1 <= now, "got %lu, %lu.\n", t1, now );
size = sizeof(buffer); ok_ret( 0, GetRawInputBuffer( NULL, &size, sizeof(RAWINPUTHEADER) ) ); @@ -2128,8 +2148,10 @@ static void test_GetRawInputBuffer(void) ok_eq( 0, size, UINT, "%u" );
- mouse_event( MOUSEEVENTF_MOVE, 5, 0, 0, 0 ); - + Sleep( 20 ); + mouse_event( MOUSEEVENTF_MOVE, 5, 0, 0, 0xdeadbeef ); + t2 = GetMessageTime(); + ok( t2 == t1, "got %lu, %lu.\n", t1, t2 ); /* invalid calls with input */
SetLastError( 0xdeadbeef ); @@ -2137,6 +2159,9 @@ static void test_GetRawInputBuffer(void) ok_ret( (UINT)-1, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) ); ok_eq( rawinput_size, size, UINT, "%u" ); ok_ret( ERROR_INSUFFICIENT_BUFFER, GetLastError() ); + t2 = GetMessageTime(); + ok( t2 == t1, "got %lu, %lu.\n", t1, t2 ); + SetLastError( 0xdeadbeef ); size = sizeof(buffer); ok_ret( (UINT)-1, GetRawInputBuffer( rawbuffer, &size, 0 ) ); @@ -2158,6 +2183,8 @@ static void test_GetRawInputBuffer(void) /* NOTE: calling with size == rawinput_size returns an error, */ /* BUT it fills the buffer nonetheless and empties the internal buffer (!!) */
+ Sleep( 20 ); + t2 = GetTickCount(); size = 0; ok_ret( 0, GetRawInputBuffer( NULL, &size, sizeof(RAWINPUTHEADER) ) ); ok_eq( rawinput_size, size, UINT, "%u" ); @@ -2170,6 +2197,23 @@ static void test_GetRawInputBuffer(void) if (is_wow64) ok_eq( 5, rawbuffer64->data.mouse.lLastX, UINT, "%u" ); else ok_eq( 5, rawbuffer->data.mouse.lLastX, UINT, "%u" );
+ t3 = GetMessageTime(); + pos2 = GetMessagePos(); + extra_info2 = GetMessageExtraInfo(); + ok( extra_info2 == extra_info1, "got %#Ix, %#Ix.\n", extra_info1, extra_info2 ); + GetCursorPos( &pt ); + ok( t3 > t1, "got %lu, %lu.\n", t1, t3 ); + ok( t3 < t2, "got %lu, %lu.\n", t2, t3 ); + ok( pos1 == pos2, "got pos1 (%ld, %ld), pos2 (%ld, %ld), pt (%ld %ld).\n", + pos1 & 0xffff, pos1 >> 16, pos2 & 0xffff, pos2 >> 16, pt.x, pt.y ); + if (pGetCurrentInputMessageSource) + { + ret = pGetCurrentInputMessageSource( &source ); + ok( ret, "got error %lu.\n", GetLastError() ); + ok( !source.deviceType, "got %#x.\n", source.deviceType ); + ok( !source.originId, "got %#x.\n", source.originId ); + } + /* no more data to read */
size = sizeof(buffer); @@ -2178,8 +2222,20 @@ static void test_GetRawInputBuffer(void)
/* rawinput_size + 1 succeeds */ + t1 = GetMessageTime(); + pos1 = GetMessagePos(); + extra_info1 = GetMessageExtraInfo(); + now = GetTickCount(); + ok( t1 <= now, "got %lu, %lu.\n", t1, now ); + + Sleep( 20 ); + mouse_event( MOUSEEVENTF_MOVE, 5, 0, 0, 0xfeedcafe );
- mouse_event( MOUSEEVENTF_MOVE, 5, 0, 0, 0 ); + t2 = GetMessageTime(); + ok( t2 == t1, "got %lu, %lu.\n", t1, t2 ); + + Sleep( 20 ); + t2 = GetTickCount();
size = rawinput_size + 1; memset( buffer, 0, sizeof(buffer) ); @@ -2202,6 +2258,16 @@ static void test_GetRawInputBuffer(void) ok_ret( 0, GetRawInputBuffer( NULL, &size, sizeof(RAWINPUTHEADER) ) ); ok_eq( 0, size, UINT, "%u" );
+ t3 = GetMessageTime(); + pos2 = GetMessagePos(); + extra_info2 = GetMessageExtraInfo(); + GetCursorPos(&pt); + ok( extra_info2 == extra_info1, "got %#Ix, %#Ix.\n", extra_info1, extra_info2 ); + ok( t3 > t1, "got %lu, %lu.\n", t1, t3 ); + ok( t3 < t2, "got %lu, %lu.\n", t2, t3 ); + ok( pos1 == pos2, "got pos1 (%ld, %ld), pos2 (%ld, %ld), pt (%ld %ld).\n", + pos1 & 0xffff, pos1 >> 16, pos2 & 0xffff, pos2 >> 16, pt.x, pt.y ); + raw_devices[0].dwFlags = RIDEV_REMOVE; raw_devices[0].hwndTarget = 0; ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE) ) ); diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c index 1083571802d..d18f0c16eff 100644 --- a/dlls/win32u/rawinput.c +++ b/dlls/win32u/rawinput.c @@ -454,6 +454,7 @@ UINT WINAPI NtUserGetRawInputDeviceInfo( HANDLE handle, UINT command, void *data */ UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT header_size ) { + struct user_thread_info *thread_info; UINT count;
TRACE( "data %p, data_size %p, header_size %u\n", data, data_size, header_size ); @@ -473,6 +474,7 @@ UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT heade /* with old WOW64 mode we didn't go through the WOW64 thunks, patch the header size here */ if (NtCurrentTeb()->WowTebOffset) header_size = sizeof(RAWINPUTHEADER64);
+ thread_info = get_user_thread_info(); SERVER_START_REQ( get_rawinput_buffer ) { req->header_size = header_size; @@ -480,6 +482,7 @@ UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT heade if (!wine_server_call_err( req )) count = reply->count; else count = -1; *data_size = reply->next_size; + if (reply->count) thread_info->client_info.message_time = reply->last_message_time; } SERVER_END_REQ;
diff --git a/server/protocol.def b/server/protocol.def index f6d644d6182..fc5da9e3563 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3791,6 +3791,7 @@ struct handle_info int read_data; /* read the rawinput buffer data */ @REPLY data_size_t next_size; /* minimum size to get next message data */ + unsigned int last_message_time; /* Time of the last removed message. */ unsigned int count; VARARG(data,bytes); @END diff --git a/server/queue.c b/server/queue.c index ed099b3b989..f55af8d23ea 100644 --- a/server/queue.c +++ b/server/queue.c @@ -3751,6 +3751,7 @@ DECL_HANDLER(get_rawinput_buffer) memcpy( &rawinput->header + 1, msg_data + 1, data_size );
total_size += (rawinput->header.dwSize + align) & ~align; + reply->last_message_time = msg->time; list_remove( &msg->entry ); free_message( msg ); count++;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=145458
Your paranoid android.
=== debian11 (32 bit ja:JP report) ===
user32: input.c:3984: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 0004009A, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
=== debian11b (32 bit WoW report) ===
user32: input.c:3984: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 0004009A, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
Tests suggest that only last message time is updated and not the other info related to the last message.
The Finals depends on this.