[PATCH 3/3] dinput: Use dedicated list for mouse and keyboard.

Rémi Bernon rbernon at codeweavers.com
Mon Jun 8 02:47:09 CDT 2020


Instead of using function pointer, which is also not very CPU friendly.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/dinput/device_private.h |  1 -
 dlls/dinput/dinput_main.c    | 54 +++++++++++++++++++++++-------------
 dlls/dinput/dinput_private.h |  3 +-
 dlls/dinput/keyboard.c       |  3 +-
 dlls/dinput/mouse.c          |  5 +---
 5 files changed, 38 insertions(+), 28 deletions(-)

diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index 5879409c1de..fe5644f21c7 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -68,7 +68,6 @@ struct IDirectInputDeviceImpl
     DWORD                       dwCoopLevel;
     HWND                        win;
     int                         acquired;
-    DI_EVENT_PROC               event_proc;  /* function to receive mouse & keyboard events */
 
     LPDIDEVICEOBJECTDATA        data_queue;  /* buffer for 'GetDeviceData'.                 */
     int                         queue_len;   /* valid size of the queue                     */
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 4986e5857b4..2e561502406 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -100,6 +100,8 @@ HINSTANCE DINPUT_instance;
 static BOOL check_hook_thread(void);
 static CRITICAL_SECTION dinput_hook_crit;
 static struct list direct_input_list = LIST_INIT( direct_input_list );
+static struct list acquired_mouse_list = LIST_INIT( acquired_mouse_list );
+static struct list acquired_keyboard_list = LIST_INIT( acquired_keyboard_list );
 static struct list acquired_device_list = LIST_INIT( acquired_device_list );
 
 static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwVersion);
@@ -110,7 +112,12 @@ void dinput_hooks_acquire_device(LPDIRECTINPUTDEVICE8W iface)
     IDirectInputDeviceImpl *dev = impl_from_IDirectInputDevice8W(iface);
 
     EnterCriticalSection( &dinput_hook_crit );
-    list_add_tail( &acquired_device_list, &dev->entry );
+    if (IsEqualGUID( &dev->guid, &GUID_SysMouse ))
+        list_add_tail( &acquired_mouse_list, &dev->entry );
+    else if (IsEqualGUID( &dev->guid, &GUID_SysKeyboard ))
+        list_add_tail( &acquired_keyboard_list, &dev->entry );
+    else
+        list_add_tail( &acquired_device_list, &dev->entry );
     LeaveCriticalSection( &dinput_hook_crit );
 }
 
@@ -1659,13 +1666,15 @@ static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam )
     if (code != HC_ACTION) return CallNextHookEx( 0, code, wparam, lparam );
 
     EnterCriticalSection( &dinput_hook_crit );
-    LIST_FOR_EACH_ENTRY( dev, &acquired_device_list, IDirectInputDeviceImpl, entry )
+    LIST_FOR_EACH_ENTRY( dev, &acquired_mouse_list, IDirectInputDeviceImpl, entry )
     {
-        if (dev->event_proc)
-        {
-            TRACE("calling %p->%p (%lx %lx)\n", dev, dev->event_proc, wparam, lparam);
-            skip |= dev->event_proc( &dev->IDirectInputDevice8A_iface, wparam, lparam );
-        }
+        TRACE("calling dinput_mouse_hook (%p %lx %lx)\n", dev, wparam, lparam);
+        skip |= dinput_mouse_hook( &dev->IDirectInputDevice8A_iface, wparam, lparam );
+    }
+    LIST_FOR_EACH_ENTRY( dev, &acquired_keyboard_list, IDirectInputDeviceImpl, entry )
+    {
+        TRACE("calling dinput_keyboard_hook (%p %lx %lx)\n", dev, wparam, lparam);
+        skip |= dinput_keyboard_hook( &dev->IDirectInputDevice8A_iface, wparam, lparam );
     }
     LeaveCriticalSection( &dinput_hook_crit );
 
@@ -1693,6 +1702,22 @@ static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam
             IDirectInputDevice_Unacquire( &dev->IDirectInputDevice8A_iface );
         }
     }
+    LIST_FOR_EACH_ENTRY_SAFE( dev, next, &acquired_mouse_list, IDirectInputDeviceImpl, entry )
+    {
+        if (msg->hwnd == dev->win && msg->hwnd != foreground)
+        {
+            TRACE( "%p window is not foreground - unacquiring %p\n", dev->win, dev );
+            IDirectInputDevice_Unacquire( &dev->IDirectInputDevice8A_iface );
+        }
+    }
+    LIST_FOR_EACH_ENTRY_SAFE( dev, next, &acquired_keyboard_list, IDirectInputDeviceImpl, entry )
+    {
+        if (msg->hwnd == dev->win && msg->hwnd != foreground)
+        {
+            TRACE( "%p window is not foreground - unacquiring %p\n", dev->win, dev );
+            IDirectInputDevice_Unacquire( &dev->IDirectInputDevice8A_iface );
+        }
+    }
     LeaveCriticalSection( &dinput_hook_crit );
 
     return CallNextHookEx( 0, code, wparam, lparam );
@@ -1713,7 +1738,6 @@ static DWORD WINAPI hook_thread_proc(void *param)
 
         if (msg.message == WM_USER+0x10)
         {
-            IDirectInputDeviceImpl *dev;
             HANDLE finished_event = (HANDLE)msg.lParam;
 
             TRACE( "Processing hook change notification wp:%ld lp:%#lx\n", msg.wParam, msg.lParam );
@@ -1727,18 +1751,8 @@ static DWORD WINAPI hook_thread_proc(void *param)
             }
 
             EnterCriticalSection( &dinput_hook_crit );
-
-            /* Count acquired keyboards and mice*/
-            LIST_FOR_EACH_ENTRY( dev, &acquired_device_list, IDirectInputDeviceImpl, entry )
-            {
-                if (!dev->event_proc) continue;
-
-                if (IsEqualGUID( &dev->guid, &GUID_SysKeyboard ))
-                    kbd_cnt++;
-                else
-                    if (IsEqualGUID( &dev->guid, &GUID_SysMouse ))
-                        mice_cnt++;
-            }
+            kbd_cnt = list_count( &acquired_keyboard_list );
+            mice_cnt = list_count( &acquired_mouse_list );
             LeaveCriticalSection( &dinput_hook_crit );
 
             if (kbd_cnt && !kbd_hook)
diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h
index 121c487c2d8..06a439d6a41 100644
--- a/dlls/dinput/dinput_private.h
+++ b/dlls/dinput/dinput_private.h
@@ -71,10 +71,11 @@ extern const struct dinput_device joystick_osx_device DECLSPEC_HIDDEN;
 
 extern void dinput_hooks_acquire_device(LPDIRECTINPUTDEVICE8W iface);
 extern void dinput_hooks_unacquire_device(LPDIRECTINPUTDEVICE8W iface);
+extern int dinput_mouse_hook(LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam);
+extern int dinput_keyboard_hook(LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam);
 
 extern void check_dinput_hooks(LPDIRECTINPUTDEVICE8W, BOOL) DECLSPEC_HIDDEN;
 extern void check_dinput_events(void) DECLSPEC_HIDDEN;
-typedef int (*DI_EVENT_PROC)(LPDIRECTINPUTDEVICE8A, WPARAM, LPARAM);
 
 extern void _copy_diactionformatAtoW(LPDIACTIONFORMATW, LPDIACTIONFORMATA) DECLSPEC_HIDDEN;
 extern void _copy_diactionformatWtoA(LPDIACTIONFORMATA, LPDIACTIONFORMATW) DECLSPEC_HIDDEN;
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index 6675a79f84b..9981372d957 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -103,7 +103,7 @@ static BYTE map_dik_code(DWORD scanCode, DWORD vkCode, DWORD subType, DWORD vers
     return scanCode;
 }
 
-static int KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam )
+int dinput_keyboard_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam )
 {
     SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface);
     int dik_code, ret = This->base.dwCoopLevel & DISCL_EXCLUSIVE;
@@ -264,7 +264,6 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
     newDevice->base.ref = 1;
     memcpy(&newDevice->base.guid, rguid, sizeof(*rguid));
     newDevice->base.dinput = dinput;
-    newDevice->base.event_proc = KeyboardCallback;
     InitializeCriticalSection(&newDevice->base.crit);
     newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysKeyboardImpl*->base.crit");
     newDevice->subtype = get_keyboard_subtype();
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
index abf6fb9599c..5e6f34f0eca 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -92,8 +92,6 @@ static inline IDirectInputDevice8W *IDirectInputDevice8W_from_impl(SysMouseImpl
     return &This->base.IDirectInputDevice8W_iface;
 }
 
-static int dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam );
-
 static void _dump_mouse_state(const DIMOUSESTATE2 *m_state)
 {
     int i;
@@ -213,7 +211,6 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
     InitializeCriticalSection(&newDevice->base.crit);
     newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysMouseImpl*->base.crit");
     newDevice->base.dinput = dinput;
-    newDevice->base.event_proc = dinput_mouse_hook;
 
     get_app_key(&hkey, &appkey);
     if (!get_config_key(hkey, appkey, "MouseWarpOverride", buffer, sizeof(buffer)))
@@ -310,7 +307,7 @@ const struct dinput_device mouse_device = {
  */
 
 /* low-level mouse hook */
-static int dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam )
+int dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam )
 {
     MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam;
     SysMouseImpl* This = impl_from_IDirectInputDevice8A(iface);
-- 
2.27.0




More information about the wine-devel mailing list