From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/rawinput.c | 19 ------------------- dlls/win32u/win32u_private.h | 1 - 2 files changed, 20 deletions(-)
diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c index 1120ce053aa..c86e28dea8d 100644 --- a/dlls/win32u/rawinput.c +++ b/dlls/win32u/rawinput.c @@ -316,25 +316,6 @@ static struct device *find_device_from_handle( HANDLE handle ) return NULL; }
-BOOL rawinput_device_get_usages( HANDLE handle, USAGE *usage_page, USAGE *usage ) -{ - struct device *device; - - pthread_mutex_lock( &rawinput_mutex ); - - if (!(device = find_device_from_handle( handle )) || device->info.dwType != RIM_TYPEHID) - *usage_page = *usage = 0; - else - { - *usage_page = device->info.hid.usUsagePage; - *usage = device->info.hid.usUsage; - } - - pthread_mutex_unlock( &rawinput_mutex ); - - return *usage_page || *usage; -} - /********************************************************************** * NtUserGetRawInputDeviceList (win32u.@) */ diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index ff861db4dd9..24e8b1b498d 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -146,7 +146,6 @@ extern void pack_user_message( void *buffer, size_t size, UINT message,
/* rawinput.c */ extern BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ); -extern BOOL rawinput_device_get_usages( HANDLE handle, USHORT *usage_page, USHORT *usage );
/* scroll.c */ extern void draw_nc_scrollbar( HWND hwnd, HDC hdc, BOOL draw_horizontal, BOOL draw_vertical );
From: Rémi Bernon rbernon@codeweavers.com
And only refresh the list if the device handle isn't known. --- dlls/win32u/rawinput.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c index c86e28dea8d..c004f296038 100644 --- a/dlls/win32u/rawinput.c +++ b/dlls/win32u/rawinput.c @@ -301,12 +301,13 @@ static void rawinput_update_device_list(void) enumerate_devices( RIM_TYPEHID, guid_devinterface_hidW ); }
-static struct device *find_device_from_handle( HANDLE handle ) +static struct device *find_device_from_handle( HANDLE handle, BOOL refresh ) { struct device *device;
LIST_FOR_EACH_ENTRY( device, &devices, struct device, entry ) if (device->handle == handle) return device; + if (!refresh) return NULL;
rawinput_update_device_list();
@@ -399,7 +400,7 @@ UINT WINAPI NtUserGetRawInputDeviceInfo( HANDLE handle, UINT command, void *data
pthread_mutex_lock( &rawinput_mutex );
- if (!(device = find_device_from_handle( handle ))) + if (!(device = find_device_from_handle( handle, TRUE ))) { pthread_mutex_unlock( &rawinput_mutex ); RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); @@ -568,8 +569,20 @@ BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_d
if (msg->message == WM_INPUT_DEVICE_CHANGE) { + BOOL refresh = msg->wParam == GIDC_ARRIVAL; + struct device *device; + pthread_mutex_lock( &rawinput_mutex ); - rawinput_update_device_list(); + if ((device = find_device_from_handle( UlongToHandle( msg_data->rawinput.device ), refresh ))) + { + if (msg->wParam == GIDC_REMOVAL) + { + list_remove( &device->entry ); + NtClose( device->file ); + free( device->data ); + free( device ); + } + } pthread_mutex_unlock( &rawinput_mutex ); } else
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/rawinput.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c index c004f296038..5b1d9d211df 100644 --- a/dlls/win32u/rawinput.c +++ b/dlls/win32u/rawinput.c @@ -282,12 +282,17 @@ static void enumerate_devices( DWORD type, const WCHAR *class ) NtClose( class_key ); }
-static void rawinput_update_device_list(void) +static void rawinput_update_device_list( BOOL force ) { + unsigned int ticks = NtGetTickCount(); + static unsigned int last_check; struct device *device, *next;
TRACE( "\n" );
+ if (ticks - last_check <= 2000 && !force) return; + last_check = ticks; + LIST_FOR_EACH_ENTRY_SAFE( device, next, &devices, struct device, entry ) { list_remove( &device->entry ); @@ -309,7 +314,7 @@ static struct device *find_device_from_handle( HANDLE handle, BOOL refresh ) if (device->handle == handle) return device; if (!refresh) return NULL;
- rawinput_update_device_list(); + rawinput_update_device_list( TRUE );
LIST_FOR_EACH_ENTRY( device, &devices, struct device, entry ) if (device->handle == handle) return device; @@ -322,8 +327,7 @@ static struct device *find_device_from_handle( HANDLE handle, BOOL refresh ) */ UINT WINAPI NtUserGetRawInputDeviceList( RAWINPUTDEVICELIST *device_list, UINT *device_count, UINT size ) { - unsigned int count = 0, ticks = NtGetTickCount(); - static unsigned int last_check; + unsigned int count = 0; struct device *device;
TRACE( "device_list %p, device_count %p, size %u.\n", device_list, device_count, size ); @@ -342,11 +346,7 @@ UINT WINAPI NtUserGetRawInputDeviceList( RAWINPUTDEVICELIST *device_list, UINT *
pthread_mutex_lock( &rawinput_mutex );
- if (ticks - last_check > 2000) - { - last_check = ticks; - rawinput_update_device_list(); - } + rawinput_update_device_list( FALSE );
LIST_FOR_EACH_ENTRY( device, &devices, struct device, entry ) {
From: Evan Tang etang@codeweavers.com
--- dlls/user32/tests/input.c | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index b92e59396ac..8b374fae8a3 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1778,6 +1778,7 @@ static void test_RegisterRawInputDevices(void) HWND hwnd; RAWINPUTDEVICE raw_devices[2] = {0}; UINT count, raw_devices_count; + MSG msg;
raw_devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC; raw_devices[0].usUsage = HID_USAGE_GENERIC_GAMEPAD; @@ -1849,6 +1850,48 @@ static void test_RegisterRawInputDevices(void) raw_devices[1].hwndTarget = hwnd; ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) );
+ /* RIDEV_DEVNOTIFY send messages for any pre-existing device */ + raw_devices[0].dwFlags = RIDEV_DEVNOTIFY; + raw_devices[0].hwndTarget = 0; + raw_devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC; + raw_devices[0].usUsage = HID_USAGE_GENERIC_MOUSE; + raw_devices[1].dwFlags = RIDEV_DEVNOTIFY; + raw_devices[1].hwndTarget = 0; + raw_devices[1].usUsagePage = HID_USAGE_PAGE_GENERIC; + raw_devices[1].usUsage = HID_USAGE_GENERIC_KEYBOARD; + + ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) ); + while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) + { + ok_ne( WM_INPUT_DEVICE_CHANGE, msg.message, UINT, "%#x" ); + TranslateMessage( &msg ); + DispatchMessageW( &msg ); + } + + /* RIDEV_DEVNOTIFY send messages only to hwndTarget */ + raw_devices[0].hwndTarget = hwnd; + raw_devices[1].hwndTarget = hwnd; + + count = 0; + ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) ); + while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) + { + if (msg.message == WM_INPUT_DEVICE_CHANGE) count++; + TranslateMessage( &msg ); + DispatchMessageW( &msg ); + } + todo_wine ok( count >= 2, "got %u messages\n", count ); + + count = 0; + ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) ); + while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) + { + if (msg.message == WM_INPUT_DEVICE_CHANGE) count++; + TranslateMessage( &msg ); + DispatchMessageW( &msg ); + } + todo_wine ok( count >= 2, "got %u messages\n", count ); + /* RIDEV_REMOVE requires hwndTarget == NULL */ raw_devices[0].dwFlags = RIDEV_REMOVE; raw_devices[0].hwndTarget = hwnd;
From: Evan Tang etang@codeweavers.com
--- dlls/user32/tests/input.c | 4 ++-- dlls/win32u/rawinput.c | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 8b374fae8a3..fcaa4229b02 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1880,7 +1880,7 @@ static void test_RegisterRawInputDevices(void) TranslateMessage( &msg ); DispatchMessageW( &msg ); } - todo_wine ok( count >= 2, "got %u messages\n", count ); + ok( count >= 2, "got %u messages\n", count );
count = 0; ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) ); @@ -1890,7 +1890,7 @@ static void test_RegisterRawInputDevices(void) TranslateMessage( &msg ); DispatchMessageW( &msg ); } - todo_wine ok( count >= 2, "got %u messages\n", count ); + ok( count >= 2, "got %u messages\n", count );
/* RIDEV_REMOVE requires hwndTarget == NULL */ raw_devices[0].dwFlags = RIDEV_REMOVE; diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c index 5b1d9d211df..1083571802d 100644 --- a/dlls/win32u/rawinput.c +++ b/dlls/win32u/rawinput.c @@ -598,6 +598,30 @@ BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_d return TRUE; }
+static void post_device_notifications( const RAWINPUTDEVICE *filter ) +{ + ULONG usages = MAKELONG( filter->usUsagePage, filter->usUsage ); + struct device *device; + + LIST_FOR_EACH_ENTRY( device, &devices, struct device, entry ) + { + switch (device->info.dwType) + { + case RIM_TYPEMOUSE: + if (usages != MAKELONG( HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_MOUSE )) continue; + break; + case RIM_TYPEKEYBOARD: + if (usages != MAKELONG( HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_KEYBOARD )) continue; + break; + case RIM_TYPEHID: + if (usages != MAKELONG( device->info.hid.usUsagePage, device->info.hid.usUsage )) continue; + break; + } + + NtUserPostMessage( filter->hwndTarget, WM_INPUT_DEVICE_CHANGE, GIDC_ARRIVAL, (LPARAM)device->handle ); + } +} + static void register_rawinput_device( const RAWINPUTDEVICE *device ) { RAWINPUTDEVICE *pos, *end; @@ -619,6 +643,7 @@ static void register_rawinput_device( const RAWINPUTDEVICE *device ) } else { + if ((device->dwFlags & RIDEV_DEVNOTIFY) && device->hwndTarget) post_device_notifications( device ); if (pos == end || pos->usUsagePage != device->usUsagePage || pos->usUsage != device->usUsage) { memmove( pos + 1, pos, (char *)end - (char *)pos ); @@ -684,6 +709,8 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d return FALSE; }
+ rawinput_update_device_list( TRUE ); + registered_devices = new_registered_devices; for (i = 0; i < device_count; ++i) register_rawinput_device( devices + i );
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=145352
Your paranoid android.
=== w1064v1809 (32 bit report) ===
user32: input.c:3922: Test failed: button_up_hwnd 1 (missing): MSG_TEST_WIN hwnd 00040280, WM_LBUTTONUP, wparam 0, lparam 0x320032
=== w11pro64 (32 bit report) ===
user32: input.c:4030: Test failed: layered 4: button_up_hwnd_todo 0: got MSG_TEST_WIN hwnd 000A01FC, msg WM_LBUTTONUP, wparam 0, lparam 0x320032 input.c:4030: Test failed: layered 4: button_up_hwnd_todo 1 (missing): MSG_TEST_WIN hwnd 000A01FC, WM_LBUTTONUP, wparam 0, lparam 0x320032 input.c:4081: Test failed: button_up_hwnd 0: got MSG_TEST_WIN hwnd 000A01FC, msg WM_LBUTTONUP, wparam 0, lparam 0x320032 input.c:4081: Test failed: button_up_hwnd 1 (missing): MSG_TEST_WIN hwnd 000A01FC, WM_LBUTTONUP, wparam 0, lparam 0x320032
=== w1064_tsign (64 bit report) ===
user32: input.c:3854: Test failed: button_up_hwnd_todo 0: got MSG_TEST_WIN hwnd 00000000000401CE, msg WM_LBUTTONUP, wparam 0, lparam 0x320032 input.c:3854: Test failed: button_up_hwnd_todo 1 (missing): MSG_TEST_WIN hwnd 00000000000401CE, WM_LBUTTONUP, wparam 0, lparam 0x320032
=== w11pro64_amd (64 bit report) ===
user32: input.c:4030: Test failed: layered 0: button_up_hwnd_todo 0: got MSG_TEST_WIN hwnd 000000000005007E, msg WM_LBUTTONUP, wparam 0, lparam 0x320032 input.c:4030: Test failed: layered 0: button_up_hwnd_todo 1 (missing): MSG_TEST_WIN hwnd 000000000005007E, WM_LBUTTONUP, wparam 0, lparam 0x320032
=== debian11 (32 bit he:IL report) ===
user32: input.c:3918: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00040096, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
This merge request was approved by Rémi Bernon.