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++;