[PATCH 2/3] xinput1_3: Update the controller list in the update thread.
Rémi Bernon
rbernon at codeweavers.com
Tue Aug 10 06:27:23 CDT 2021
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/xinput1_3/main.c | 49 +++++++++++++++++++------------------------
1 file changed, 22 insertions(+), 27 deletions(-)
diff --git a/dlls/xinput1_3/main.c b/dlls/xinput1_3/main.c
index 63f125ae528..45ccb5f79db 100644
--- a/dlls/xinput1_3/main.c
+++ b/dlls/xinput1_3/main.c
@@ -118,7 +118,6 @@ static struct xinput_controller controllers[XUSER_MAX_COUNT] =
{{ &controller_critsect_debug[3], -1, 0, 0, 0, 0 }},
};
-static DWORD last_check = 0;
static HANDLE stop_event;
static HANDLE done_event;
@@ -296,12 +295,8 @@ failed:
return FALSE;
}
-static BOOL WINAPI start_update_thread_once( INIT_ONCE *once, void *param, void **context );
-
-static void HID_find_gamepads(void)
+static void update_controller_list(void)
{
- static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
-
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_DATA iface = {sizeof(iface)};
@@ -314,20 +309,6 @@ static void HID_find_gamepads(void)
GUID guid;
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);
set = SetupDiGetClassDevsW(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
@@ -368,7 +349,6 @@ static void HID_find_gamepads(void)
}
SetupDiDestroyDeviceInfoList(set);
- LeaveCriticalSection(&xinput_crit);
}
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)
{
HANDLE events[1];
- DWORD count, ret;
+ DWORD count, ret = WAIT_TIMEOUT;
do
{
+ EnterCriticalSection(&xinput_crit);
+ if (ret == WAIT_TIMEOUT) update_controller_list();
+
count = 0;
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);
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());
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;
}
+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)
{
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
value (sent to XInputSetState) to the controller and allow messages to
be sent */
- HID_find_gamepads();
+ start_update_thread();
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);
- HID_find_gamepads();
+ start_update_thread();
if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS;
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;
- HID_find_gamepads();
+ start_update_thread();
if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS;
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);
- HID_find_gamepads();
+ start_update_thread();
if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS;
--
2.32.0
More information about the wine-devel
mailing list