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