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

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-08-27 12:45:20 +02:00 committed by Alexandre Julliard
parent 18b98df060
commit b36c6ae0e8
2 changed files with 53 additions and 6 deletions

View file

@ -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,

View file

@ -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;