dinput: Keep a reference on acquired devices while waiting.
This commit is contained in:
parent
5fa11f5fb6
commit
d58055dd7d
1 changed files with 16 additions and 15 deletions
|
@ -46,10 +46,14 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dinput);
|
||||
|
||||
#define INPUT_THREAD_MAX_DEVICES 128
|
||||
|
||||
struct input_thread_state
|
||||
{
|
||||
UINT events_count;
|
||||
HANDLE events[128];
|
||||
UINT devices_count;
|
||||
struct dinput_device *devices[INPUT_THREAD_MAX_DEVICES];
|
||||
HANDLE events[INPUT_THREAD_MAX_DEVICES];
|
||||
};
|
||||
|
||||
static inline struct dinput_device *impl_from_IDirectInputDevice8W( IDirectInputDevice8W *iface )
|
||||
|
@ -247,9 +251,11 @@ static void input_thread_update_device_list( struct input_thread_state *state )
|
|||
{
|
||||
if (!device->read_event || !device->vtbl->read) continue;
|
||||
state->events[count] = device->read_event;
|
||||
if (++count >= ARRAY_SIZE(state->events)) break;
|
||||
dinput_device_internal_addref( (state->devices[count] = device) );
|
||||
if (++count >= INPUT_THREAD_MAX_DEVICES) break;
|
||||
}
|
||||
state->events_count = count;
|
||||
state->devices_count = count;
|
||||
LeaveCriticalSection( &dinput_hook_crit );
|
||||
}
|
||||
|
||||
|
@ -258,7 +264,7 @@ static DWORD WINAPI dinput_thread_proc( void *params )
|
|||
HANDLE finished_event, start_event = params;
|
||||
struct input_thread_state state = {0};
|
||||
static HHOOK kbd_hook, mouse_hook;
|
||||
struct dinput_device *impl, *next;
|
||||
struct dinput_device *device;
|
||||
DWORD ret;
|
||||
MSG msg;
|
||||
|
||||
|
@ -273,21 +279,14 @@ static DWORD WINAPI dinput_thread_proc( void *params )
|
|||
UINT kbd_cnt = 0, mice_cnt = 0;
|
||||
|
||||
if (ret < state.events_count)
|
||||
{
|
||||
if ((device = state.devices[ret]) && FAILED( device->vtbl->read( &device->IDirectInputDevice8W_iface ) ))
|
||||
{
|
||||
EnterCriticalSection( &dinput_hook_crit );
|
||||
LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_device_list, struct dinput_device, entry )
|
||||
{
|
||||
if (impl->read_event == state.events[ret])
|
||||
{
|
||||
if (FAILED( impl->vtbl->read( &impl->IDirectInputDevice8W_iface ) ))
|
||||
{
|
||||
dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface );
|
||||
impl->status = STATUS_UNPLUGGED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
dinput_device_internal_unacquire( &device->IDirectInputDevice8W_iface );
|
||||
LeaveCriticalSection( &dinput_hook_crit );
|
||||
device->status = STATUS_UNPLUGGED;
|
||||
}
|
||||
}
|
||||
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
|
||||
|
@ -335,12 +334,14 @@ static DWORD WINAPI dinput_thread_proc( void *params )
|
|||
SetEvent(finished_event);
|
||||
}
|
||||
|
||||
while (state.devices_count--) dinput_device_internal_release( state.devices[state.devices_count] );
|
||||
input_thread_update_device_list( &state );
|
||||
}
|
||||
|
||||
if (ret != state.events_count) ERR("Unexpected termination, ret %#lx\n", ret);
|
||||
|
||||
done:
|
||||
while (state.devices_count--) dinput_device_internal_release( state.devices[state.devices_count] );
|
||||
DestroyWindow( di_em_win );
|
||||
di_em_win = NULL;
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue