Module: wine Branch: master Commit: 0884b503c9d5956cd828b9e81d09e3b9f396f283 URL: https://gitlab.winehq.org/wine/wine/-/commit/0884b503c9d5956cd828b9e81d09e3b...
Author: Paul Gofman pgofman@codeweavers.com Date: Tue May 7 15:11:27 2024 -0600
win32u: Update last message time in NtUserGetRawInputBuffer().
---
dlls/user32/tests/input.c | 70 ++++++++++++++++++++++++++++++++++++++++-- dlls/win32u/rawinput.c | 3 ++ include/wine/server_protocol.h | 4 ++- server/protocol.def | 1 + server/queue.c | 1 + server/request.h | 5 +-- server/trace.c | 1 + 7 files changed, 79 insertions(+), 6 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..62b1707dbfe 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->time; } SERVER_END_REQ;
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 48e778ce07f..d17f0936c3f 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -5473,8 +5473,10 @@ struct get_rawinput_buffer_reply { struct reply_header __header; data_size_t next_size; + unsigned int time; unsigned int count; /* VARARG(data,bytes); */ + char __pad_20[4]; };
@@ -6522,7 +6524,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 800 +#define SERVER_PROTOCOL_VERSION 801
/* ### protocol_version end ### */
diff --git a/server/protocol.def b/server/protocol.def index f6d644d6182..37a39206ca4 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 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..cc10d0254eb 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->time = msg->time; list_remove( &msg->entry ); free_message( msg ); count++; diff --git a/server/request.h b/server/request.h index 5e85e31de45..5061e0ed399 100644 --- a/server/request.h +++ b/server/request.h @@ -2297,8 +2297,9 @@ C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_request, header_size) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_request, read_data) == 16 ); C_ASSERT( sizeof(struct get_rawinput_buffer_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_reply, next_size) == 8 ); -C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_reply, count) == 12 ); -C_ASSERT( sizeof(struct get_rawinput_buffer_reply) == 16 ); +C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_reply, time) == 12 ); +C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_reply, count) == 16 ); +C_ASSERT( sizeof(struct get_rawinput_buffer_reply) == 24 ); C_ASSERT( sizeof(struct update_rawinput_devices_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_job_request, access) == 12 ); C_ASSERT( sizeof(struct create_job_request) == 16 ); diff --git a/server/trace.c b/server/trace.c index d76d13152aa..f9c78ade989 100644 --- a/server/trace.c +++ b/server/trace.c @@ -4503,6 +4503,7 @@ static void dump_get_rawinput_buffer_request( const struct get_rawinput_buffer_r static void dump_get_rawinput_buffer_reply( const struct get_rawinput_buffer_reply *req ) { fprintf( stderr, " next_size=%u", req->next_size ); + fprintf( stderr, ", time=%08x", req->time ); fprintf( stderr, ", count=%08x", req->count ); dump_varargs_bytes( ", data=", cur_size ); }