xinput1_3: Update the controller list in the update thread.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
40cb5510ae
commit
8bf147b990
|
@ -118,7 +118,6 @@ static struct xinput_controller controllers[XUSER_MAX_COUNT] =
|
||||||
{{ &controller_critsect_debug[3], -1, 0, 0, 0, 0 }},
|
{{ &controller_critsect_debug[3], -1, 0, 0, 0, 0 }},
|
||||||
};
|
};
|
||||||
|
|
||||||
static DWORD last_check = 0;
|
|
||||||
static HANDLE stop_event;
|
static HANDLE stop_event;
|
||||||
static HANDLE done_event;
|
static HANDLE done_event;
|
||||||
|
|
||||||
|
@ -296,12 +295,8 @@ failed:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI start_update_thread_once( INIT_ONCE *once, void *param, void **context );
|
static void update_controller_list(void)
|
||||||
|
|
||||||
static void HID_find_gamepads(void)
|
|
||||||
{
|
{
|
||||||
static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
|
|
||||||
|
|
||||||
char buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + MAX_PATH * sizeof(WCHAR)];
|
char buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + MAX_PATH * sizeof(WCHAR)];
|
||||||
SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)buffer;
|
SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)buffer;
|
||||||
SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)};
|
SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)};
|
||||||
|
@ -314,20 +309,6 @@ static void HID_find_gamepads(void)
|
||||||
GUID guid;
|
GUID guid;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
InitOnceExecuteOnce(&init_once, start_update_thread_once, NULL, NULL);
|
|
||||||
|
|
||||||
idx = GetTickCount();
|
|
||||||
if ((idx - last_check) < 2000) return;
|
|
||||||
|
|
||||||
EnterCriticalSection(&xinput_crit);
|
|
||||||
|
|
||||||
if ((idx - last_check) < 2000)
|
|
||||||
{
|
|
||||||
LeaveCriticalSection(&xinput_crit);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
last_check = idx;
|
|
||||||
|
|
||||||
HidD_GetHidGuid(&guid);
|
HidD_GetHidGuid(&guid);
|
||||||
|
|
||||||
set = SetupDiGetClassDevsW(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
|
set = SetupDiGetClassDevsW(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
|
||||||
|
@ -368,7 +349,6 @@ static void HID_find_gamepads(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
SetupDiDestroyDeviceInfoList(set);
|
SetupDiDestroyDeviceInfoList(set);
|
||||||
LeaveCriticalSection(&xinput_crit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void controller_destroy(struct xinput_controller *controller)
|
static void controller_destroy(struct xinput_controller *controller)
|
||||||
|
@ -541,14 +521,18 @@ static void HID_update_state(struct xinput_controller *controller, XINPUT_STATE
|
||||||
static DWORD WINAPI hid_update_thread_proc(void *param)
|
static DWORD WINAPI hid_update_thread_proc(void *param)
|
||||||
{
|
{
|
||||||
HANDLE events[1];
|
HANDLE events[1];
|
||||||
DWORD count, ret;
|
DWORD count, ret = WAIT_TIMEOUT;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
EnterCriticalSection(&xinput_crit);
|
||||||
|
if (ret == WAIT_TIMEOUT) update_controller_list();
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
events[count++] = stop_event;
|
events[count++] = stop_event;
|
||||||
|
LeaveCriticalSection(&xinput_crit);
|
||||||
}
|
}
|
||||||
while ((ret = WaitForMultipleObjectsEx( count, events, FALSE, INFINITE, TRUE )) < count - 1);
|
while ((ret = WaitForMultipleObjectsEx( count, events, FALSE, 2000, TRUE )) < count - 1 || ret == WAIT_TIMEOUT);
|
||||||
|
|
||||||
if (ret != count - 1) ERR("update thread exited unexpectedly, ret %u\n", ret);
|
if (ret != count - 1) ERR("update thread exited unexpectedly, ret %u\n", ret);
|
||||||
SetEvent(done_event);
|
SetEvent(done_event);
|
||||||
|
@ -569,9 +553,20 @@ static BOOL WINAPI start_update_thread_once( INIT_ONCE *once, void *param, void
|
||||||
if (!thread) ERR("failed to create update thread, error %u\n", GetLastError());
|
if (!thread) ERR("failed to create update thread, error %u\n", GetLastError());
|
||||||
CloseHandle(thread);
|
CloseHandle(thread);
|
||||||
|
|
||||||
|
/* do it once now, to resolve delayed imports and populate the initial list */
|
||||||
|
EnterCriticalSection(&xinput_crit);
|
||||||
|
update_controller_list();
|
||||||
|
LeaveCriticalSection(&xinput_crit);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void start_update_thread(void)
|
||||||
|
{
|
||||||
|
static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
|
||||||
|
InitOnceExecuteOnce(&init_once, start_update_thread_once, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL controller_lock(struct xinput_controller *controller)
|
static BOOL controller_lock(struct xinput_controller *controller)
|
||||||
{
|
{
|
||||||
if (!controller->device) return FALSE;
|
if (!controller->device) return FALSE;
|
||||||
|
@ -617,7 +612,7 @@ void WINAPI DECLSPEC_HOTPATCH XInputEnable(BOOL enable)
|
||||||
to the controllers. Setting to true will send the last vibration
|
to the controllers. Setting to true will send the last vibration
|
||||||
value (sent to XInputSetState) to the controller and allow messages to
|
value (sent to XInputSetState) to the controller and allow messages to
|
||||||
be sent */
|
be sent */
|
||||||
HID_find_gamepads();
|
start_update_thread();
|
||||||
|
|
||||||
for (index = 0; index < XUSER_MAX_COUNT; index++)
|
for (index = 0; index < XUSER_MAX_COUNT; index++)
|
||||||
{
|
{
|
||||||
|
@ -634,7 +629,7 @@ DWORD WINAPI DECLSPEC_HOTPATCH XInputSetState(DWORD index, XINPUT_VIBRATION *vib
|
||||||
|
|
||||||
TRACE("(index %u, vibration %p)\n", index, vibration);
|
TRACE("(index %u, vibration %p)\n", index, vibration);
|
||||||
|
|
||||||
HID_find_gamepads();
|
start_update_thread();
|
||||||
|
|
||||||
if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS;
|
if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS;
|
||||||
if (!controller_lock(&controllers[index])) return ERROR_DEVICE_NOT_CONNECTED;
|
if (!controller_lock(&controllers[index])) return ERROR_DEVICE_NOT_CONNECTED;
|
||||||
|
@ -652,7 +647,7 @@ static DWORD xinput_get_state(DWORD index, XINPUT_STATE *state)
|
||||||
{
|
{
|
||||||
if (!state) return ERROR_BAD_ARGUMENTS;
|
if (!state) return ERROR_BAD_ARGUMENTS;
|
||||||
|
|
||||||
HID_find_gamepads();
|
start_update_thread();
|
||||||
|
|
||||||
if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS;
|
if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS;
|
||||||
if (!controller_lock(&controllers[index])) return ERROR_DEVICE_NOT_CONNECTED;
|
if (!controller_lock(&controllers[index])) return ERROR_DEVICE_NOT_CONNECTED;
|
||||||
|
@ -908,7 +903,7 @@ DWORD WINAPI DECLSPEC_HOTPATCH XInputGetCapabilities(DWORD index, DWORD flags, X
|
||||||
{
|
{
|
||||||
TRACE("(index %u, flags 0x%x, capabilities %p)\n", index, flags, capabilities);
|
TRACE("(index %u, flags 0x%x, capabilities %p)\n", index, flags, capabilities);
|
||||||
|
|
||||||
HID_find_gamepads();
|
start_update_thread();
|
||||||
|
|
||||||
if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS;
|
if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue