-- v2: win32u: Update last message time in NtUserGetRawInputBuffer().
From: Paul Gofman pgofman@codeweavers.com
--- dlls/user32/tests/input.c | 70 +++++++++++++++++++++++++++++++++++++-- dlls/win32u/rawinput.c | 3 ++ server/protocol.def | 1 + server/queue.c | 1 + 4 files changed, 72 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index fcaa4229b02..81af2aa5f28 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -2091,7 +2091,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 +2104,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 +2129,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 +2146,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 +2157,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 +2181,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 +2195,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 +2220,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 +2256,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=145459
Your paranoid android.
=== w11pro64 (32 bit report) ===
user32: input.c:4114: Test failed: layered 1: button_up_hwnd_todo 0: got MSG_TEST_WIN hwnd 000D0278, msg WM_LBUTTONUP, wparam 0, lparam 0x320032 input.c:4114: Test failed: layered 1: button_up_hwnd_todo 1 (missing): MSG_TEST_WIN hwnd 000D0278, WM_LBUTTONUP, wparam 0, lparam 0x320032 input.c:4108: Test failed: layered 6: button_down_hwnd_todo 0: got MSG_TEST_WIN hwnd 00120278, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032 input.c:4108: Test failed: layered 6: button_down_hwnd_todo 1 (missing): MSG_TEST_WIN hwnd 00120278, WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
This merge request was approved by Rémi Bernon.