Commit 8bf147b9 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

xinput1_3: Update the controller list in the update thread.

parent 40cb5510
...@@ -118,7 +118,6 @@ static struct xinput_controller controllers[XUSER_MAX_COUNT] = ...@@ -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: ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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 ...@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment