[PATCH] user32: Update rawinput device list upon WM_INPUT_DEVICE_CHANGE reception.

Rémi Bernon rbernon at codeweavers.com
Tue Dec 14 11:14:07 CST 2021


This fixes a regression from c2c78a2fe0ac13e4fca7ab4c17977b65e358485c,
which caused severe FPS drop in Samurai Shodown.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51282
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/user32/message.c      |  1 +
 dlls/user32/rawinput.c     | 16 ++++++++++++----
 dlls/user32/user_private.h |  1 +
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 03fa42f0ae5..7be7a1ebca4 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -3254,6 +3254,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
         {
             hid_usage_page = ((USAGE *)rawinput->data.hid.bRawData)[0];
             hid_usage = ((USAGE *)rawinput->data.hid.bRawData)[1];
+            rawinput_update_device_list();
         }
         if (input->u.hi.uMsg == WM_INPUT)
         {
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index 3a316024656..1cdcde914eb 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -168,7 +168,7 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
     return device;
 }
 
-static void find_devices(void)
+void rawinput_update_device_list(void)
 {
     SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) };
     struct device *device;
@@ -178,6 +178,8 @@ static void find_devices(void)
     HDEVINFO set;
     DWORD idx;
 
+    TRACE("\n");
+
     HidD_GetHidGuid(&hid_guid);
 
     EnterCriticalSection(&rawinput_devices_cs);
@@ -259,7 +261,7 @@ static struct device *find_device_from_handle(HANDLE handle)
     for (i = 0; i < rawinput_devices_count; ++i)
         if (rawinput_devices[i].handle == handle)
             return rawinput_devices + i;
-    find_devices();
+    rawinput_update_device_list();
     for (i = 0; i < rawinput_devices_count; ++i)
         if (rawinput_devices[i].handle == handle)
             return rawinput_devices + i;
@@ -410,16 +412,24 @@ BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_ms
     return TRUE;
 }
 
+static BOOL WINAPI rawinput_init_device_list(INIT_ONCE *once, void *param, void **context)
+{
+    rawinput_update_device_list();
+    return TRUE;
+}
 
 /***********************************************************************
  *              GetRawInputDeviceList   (USER32.@)
  */
 UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_count, UINT size)
 {
+    static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
     UINT i;
 
     TRACE("devices %p, device_count %p, size %u.\n", devices, device_count, size);
 
+    InitOnceExecuteOnce(&init_once, rawinput_init_device_list, NULL, NULL);
+
     if (size != sizeof(*devices))
     {
         SetLastError(ERROR_INVALID_PARAMETER);
@@ -432,8 +442,6 @@ UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_coun
         return ~0U;
     }
 
-    find_devices();
-
     if (!devices)
     {
         *device_count = rawinput_devices_count;
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 96704ac68ae..6923ddb2906 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -160,6 +160,7 @@ struct hardware_msg_data;
 extern BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_msg_data *msg_data);
 extern BOOL rawinput_device_get_usages(HANDLE handle, USAGE *usage_page, USAGE *usage);
 extern struct rawinput_thread_data *rawinput_thread_data(void);
+extern void rawinput_update_device_list(void);
 
 extern void create_offscreen_window_surface( const RECT *visible_rect, struct window_surface **surface ) DECLSPEC_HIDDEN;
 
-- 
2.34.0




More information about the wine-devel mailing list