Fixed controller hotplug detection when joystick thread is not enabled

This commit is contained in:
Sam Lantinga 2020-12-18 13:10:36 -08:00
parent 6ac0b23d3a
commit cbe13d232d
1 changed files with 24 additions and 42 deletions

View File

@ -61,8 +61,7 @@
/* local variables */ /* local variables */
static SDL_bool s_bJoystickThread = SDL_FALSE; static SDL_bool s_bJoystickThread = SDL_FALSE;
static SDL_bool s_bDeviceAdded = SDL_FALSE; static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;
static SDL_bool s_bDeviceRemoved = SDL_FALSE;
static SDL_cond *s_condJoystickThread = NULL; static SDL_cond *s_condJoystickThread = NULL;
static SDL_mutex *s_mutexJoyStickEnum = NULL; static SDL_mutex *s_mutexJoyStickEnum = NULL;
static SDL_Thread *s_joystickThread = NULL; static SDL_Thread *s_joystickThread = NULL;
@ -70,8 +69,6 @@ static SDL_bool s_bJoystickThreadQuit = SDL_FALSE;
JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */ JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */
static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;
#ifdef __WINRT__ #ifdef __WINRT__
typedef struct typedef struct
@ -127,10 +124,14 @@ SDL_PrivateJoystickDetectProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
} }
return 0; return 0;
case WM_TIMER: case WM_TIMER:
if (wParam == IDT_SDL_DEVICE_CHANGE_TIMER_1 ||
wParam == IDT_SDL_DEVICE_CHANGE_TIMER_2) {
KillTimer(hwnd, wParam); KillTimer(hwnd, wParam);
s_bWindowsDeviceChanged = SDL_TRUE; s_bWindowsDeviceChanged = SDL_TRUE;
return 0; return 0;
} }
break;
}
#if SDL_JOYSTICK_RAWINPUT #if SDL_JOYSTICK_RAWINPUT
return CallWindowProc(RAWINPUT_WindowProc, hwnd, msg, wParam, lParam); return CallWindowProc(RAWINPUT_WindowProc, hwnd, msg, wParam, lParam);
@ -246,8 +247,6 @@ SDL_JoystickThread(void *_data)
SDL_LockMutex(s_mutexJoyStickEnum); SDL_LockMutex(s_mutexJoyStickEnum);
while (s_bJoystickThreadQuit == SDL_FALSE) { while (s_bJoystickThreadQuit == SDL_FALSE) {
SDL_bool bXInputChanged = SDL_FALSE;
if (SDL_WaitForDeviceNotification(&s_notification_data, s_mutexJoyStickEnum) == SDL_FALSE) { if (SDL_WaitForDeviceNotification(&s_notification_data, s_mutexJoyStickEnum) == SDL_FALSE) {
#if SDL_JOYSTICK_XINPUT #if SDL_JOYSTICK_XINPUT
/* WM_DEVICECHANGE not working, poll for new XINPUT controllers */ /* WM_DEVICECHANGE not working, poll for new XINPUT controllers */
@ -260,7 +259,7 @@ SDL_JoystickThread(void *_data)
const DWORD result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities); const DWORD result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities);
const SDL_bool available = (result == ERROR_SUCCESS); const SDL_bool available = (result == ERROR_SUCCESS);
if (bOpenedXInputDevices[userId] != available) { if (bOpenedXInputDevices[userId] != available) {
bXInputChanged = SDL_TRUE; s_bWindowsDeviceChanged = SDL_TRUE;
bOpenedXInputDevices[userId] = available; bOpenedXInputDevices[userId] = available;
} }
} }
@ -270,12 +269,6 @@ SDL_JoystickThread(void *_data)
break; break;
#endif /* SDL_JOYSTICK_XINPUT */ #endif /* SDL_JOYSTICK_XINPUT */
} }
if (s_bWindowsDeviceChanged || bXInputChanged) {
s_bDeviceRemoved = SDL_TRUE;
s_bDeviceAdded = SDL_TRUE;
s_bWindowsDeviceChanged = SDL_FALSE;
}
} }
SDL_UnlockMutex(s_mutexJoyStickEnum); SDL_UnlockMutex(s_mutexJoyStickEnum);
@ -337,8 +330,6 @@ void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device)
device->nInstanceID = SDL_GetNextJoystickInstanceID(); device->nInstanceID = SDL_GetNextJoystickInstanceID();
device->pNext = SYS_Joystick; device->pNext = SYS_Joystick;
SYS_Joystick = device; SYS_Joystick = device;
s_bDeviceAdded = SDL_TRUE;
} }
static void WINDOWS_JoystickDetect(void); static void WINDOWS_JoystickDetect(void);
@ -361,7 +352,7 @@ WINDOWS_JoystickInit(void)
return -1; return -1;
} }
s_bDeviceAdded = SDL_TRUE; /* force a scan of the system for joysticks this first time */ s_bWindowsDeviceChanged = SDL_TRUE; /* force a scan of the system for joysticks this first time */
WINDOWS_JoystickDetect(); WINDOWS_JoystickDetect();
@ -396,10 +387,11 @@ WINDOWS_JoystickGetCount(void)
static void static void
WINDOWS_JoystickDetect(void) WINDOWS_JoystickDetect(void)
{ {
int device_index = 0;
JoyStick_DeviceData *pCurList = NULL; JoyStick_DeviceData *pCurList = NULL;
/* only enum the devices if the joystick thread told us something changed */ /* only enum the devices if the joystick thread told us something changed */
if (!s_bDeviceAdded && !s_bDeviceRemoved) { if (!s_bWindowsDeviceChanged) {
return; /* thread hasn't signaled, nothing to do right now. */ return; /* thread hasn't signaled, nothing to do right now. */
} }
@ -407,8 +399,7 @@ WINDOWS_JoystickDetect(void)
SDL_LockMutex(s_mutexJoyStickEnum); SDL_LockMutex(s_mutexJoyStickEnum);
} }
s_bDeviceAdded = SDL_FALSE; s_bWindowsDeviceChanged = SDL_FALSE;
s_bDeviceRemoved = SDL_FALSE;
pCurList = SYS_Joystick; pCurList = SYS_Joystick;
SYS_Joystick = NULL; SYS_Joystick = NULL;
@ -444,29 +435,21 @@ WINDOWS_JoystickDetect(void)
pCurList = pListNext; pCurList = pListNext;
} }
if (s_bDeviceAdded) { for (device_index = 0, pCurList = SYS_Joystick; pCurList; ++device_index, pCurList = pCurList->pNext) {
JoyStick_DeviceData *pNewJoystick; if (pCurList->send_add_event) {
int device_index = 0; if (pCurList->bXInputDevice) {
s_bDeviceAdded = SDL_FALSE;
pNewJoystick = SYS_Joystick;
while (pNewJoystick) {
if (pNewJoystick->send_add_event) {
if (pNewJoystick->bXInputDevice) {
#if SDL_HAPTIC_XINPUT #if SDL_HAPTIC_XINPUT
SDL_XINPUT_MaybeAddDevice(pNewJoystick->XInputUserId); SDL_XINPUT_MaybeAddDevice(pCurList->XInputUserId);
#endif #endif
} else { } else {
#if SDL_HAPTIC_DINPUT #if SDL_HAPTIC_DINPUT
SDL_DINPUT_MaybeAddDevice(&pNewJoystick->dxdevice); SDL_DINPUT_MaybeAddDevice(&pCurList->dxdevice);
#endif #endif
} }
SDL_PrivateJoystickAdded(pNewJoystick->nInstanceID); SDL_PrivateJoystickAdded(pCurList->nInstanceID);
pNewJoystick->send_add_event = SDL_FALSE; pCurList->send_add_event = SDL_FALSE;
}
device_index++;
pNewJoystick = pNewJoystick->pNext;
} }
} }
} }
@ -642,8 +625,7 @@ WINDOWS_JoystickQuit(void)
SDL_DINPUT_JoystickQuit(); SDL_DINPUT_JoystickQuit();
SDL_XINPUT_JoystickQuit(); SDL_XINPUT_JoystickQuit();
s_bDeviceAdded = SDL_FALSE; s_bWindowsDeviceChanged = SDL_FALSE;
s_bDeviceRemoved = SDL_FALSE;
} }
static SDL_bool static SDL_bool