Rémi Bernon : dinput: Add read event and callback for file-based devices.

Alexandre Julliard julliard at winehq.org
Fri Aug 27 15:03:33 CDT 2021


Module: wine
Branch: master
Commit: b36c6ae0e8d529cec1272156e808dddf04996187
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b36c6ae0e8d529cec1272156e808dddf04996187

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Fri Aug 27 12:45:20 2021 +0200

dinput: Add read event and callback for file-based devices.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dinput/device_private.h |  6 +++++
 dlls/dinput/dinput_main.c    | 53 +++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index 1811e0cc5a6..0e72ee77bf1 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -53,6 +53,8 @@ typedef struct
     UINT_PTR uAppData;
 } ActionMap;
 
+typedef HRESULT dinput_device_read_state( IDirectInputDevice8W *iface );
+
 /* Device implementation */
 typedef struct IDirectInputDeviceImpl IDirectInputDeviceImpl;
 struct IDirectInputDeviceImpl
@@ -84,6 +86,10 @@ struct IDirectInputDeviceImpl
     /* Action mapping */
     int                         num_actions; /* number of actions mapped */
     ActionMap                  *action_map;  /* array of mappings */
+
+    /* internal device file reading */
+    HANDLE                    read_event;
+    dinput_device_read_state *read_callback;
 };
 
 extern HRESULT direct_input_device_alloc( SIZE_T size, const IDirectInputDevice8WVtbl *vtbl, const GUID *guid,
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 88ee1855675..1cd6d390430 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -1289,6 +1289,12 @@ static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam
 static DWORD WINAPI hook_thread_proc(void *param)
 {
     static HHOOK kbd_hook, mouse_hook;
+    IDirectInputDeviceImpl *impl;
+    IDirectInputDevice8W *iface;
+    SIZE_T events_count = 0;
+    HANDLE finished_event;
+    HANDLE events[128];
+    DWORD ret;
     MSG msg;
 
     di_em_win = CreateWindowW( di_em_win_w, di_em_win_w, 0, 0, 0, 0, 0,
@@ -1298,13 +1304,42 @@ static DWORD WINAPI hook_thread_proc(void *param)
     PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE );
     SetEvent(param);
 
-    while (GetMessageW( &msg, 0, 0, 0 ))
+    while ((ret = MsgWaitForMultipleObjectsEx( events_count, events, INFINITE, QS_ALLINPUT, 0 )) <= events_count)
     {
         UINT kbd_cnt = 0, mice_cnt = 0;
 
-        if (msg.message == WM_USER+0x10)
+        if (ret < events_count)
         {
-            HANDLE finished_event = (HANDLE)msg.lParam;
+            iface = NULL;
+            EnterCriticalSection( &dinput_hook_crit );
+            LIST_FOR_EACH_ENTRY( impl, &acquired_device_list, IDirectInputDeviceImpl, entry )
+            {
+                if (impl->read_event == events[ret])
+                {
+                    iface = &impl->IDirectInputDevice8W_iface;
+                    IDirectInputDevice8_AddRef( iface );
+                    break;
+                }
+            }
+            LeaveCriticalSection( &dinput_hook_crit );
+
+            if (iface)
+            {
+                impl->read_callback( iface );
+                IDirectInputDevice8_Release( iface );
+            }
+        }
+
+        while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
+        {
+            if (msg.message != WM_USER+0x10)
+            {
+                TranslateMessage(&msg);
+                DispatchMessageW(&msg);
+                continue;
+            }
+
+            finished_event = (HANDLE)msg.lParam;
 
             TRACE( "Processing hook change notification wp:%ld lp:%#lx\n", msg.wParam, msg.lParam );
 
@@ -1313,12 +1348,19 @@ static DWORD WINAPI hook_thread_proc(void *param)
                 if (kbd_hook) UnhookWindowsHookEx( kbd_hook );
                 if (mouse_hook) UnhookWindowsHookEx( mouse_hook );
                 kbd_hook = mouse_hook = NULL;
-                break;
+                goto done;
             }
 
+            events_count = 0;
             EnterCriticalSection( &dinput_hook_crit );
             kbd_cnt = list_count( &acquired_keyboard_list );
             mice_cnt = list_count( &acquired_mouse_list );
+            LIST_FOR_EACH_ENTRY( impl, &acquired_device_list, IDirectInputDeviceImpl, entry )
+            {
+                if (!impl->read_event || !impl->read_callback) continue;
+                if (events_count >= ARRAY_SIZE(events)) break;
+                events[events_count++] = impl->read_event;
+            }
             LeaveCriticalSection( &dinput_hook_crit );
 
             if (kbd_cnt && !kbd_hook)
@@ -1340,10 +1382,9 @@ static DWORD WINAPI hook_thread_proc(void *param)
             if (finished_event)
                 SetEvent(finished_event);
         }
-        TranslateMessage(&msg);
-        DispatchMessageW(&msg);
     }
 
+done:
     DestroyWindow( di_em_win );
     di_em_win = NULL;
 




More information about the wine-cvs mailing list