From 888bf1af69492fb5044a5a7082132e7e2ee0fdf3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 9 Aug 2018 16:03:50 -0700 Subject: [PATCH] Worked around bug with Sony PS Now PS3 controller where DirectInput polling will continue to return success after the controller is unplugged. The code is now reliant on SDL_PrivateJoystickAdded() and SDL_PrivateJoystickRemoved() being called correctly when devices are added or removed on Windows --- src/joystick/SDL_joystick.c | 22 ++++++++++++++++---- src/joystick/SDL_sysjoystick.h | 6 +----- src/joystick/android/SDL_sysjoystick.c | 7 ------- src/joystick/bsd/SDL_sysjoystick.c | 6 ------ src/joystick/darwin/SDL_sysjoystick.c | 7 ------- src/joystick/dummy/SDL_sysjoystick.c | 7 ------- src/joystick/emscripten/SDL_sysjoystick.c | 6 ------ src/joystick/haiku/SDL_haikujoystick.cc | 6 ------ src/joystick/hidapi/SDL_hidapijoystick.c | 16 -------------- src/joystick/iphoneos/SDL_sysjoystick.m | 7 ------- src/joystick/linux/SDL_sysjoystick.c | 8 ------- src/joystick/psp/SDL_sysjoystick.c | 6 ------ src/joystick/windows/SDL_dinputjoystick.c | 4 ---- src/joystick/windows/SDL_mmjoystick.c | 6 ------ src/joystick/windows/SDL_windowsjoystick.c | 14 +------------ src/joystick/windows/SDL_windowsjoystick_c.h | 2 -- src/joystick/windows/SDL_xinputjoystick.c | 19 ++++++++++------- 17 files changed, 31 insertions(+), 118 deletions(-) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 30210e16a..1451e2531 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -297,6 +297,7 @@ SDL_JoystickOpen(int device_index) } joystick->driver = driver; joystick->instance_id = instance_id; + joystick->attached = SDL_TRUE; if (driver->Open(joystick, device_index) < 0) { SDL_free(joystick); @@ -545,7 +546,7 @@ SDL_JoystickGetAttached(SDL_Joystick * joystick) return SDL_FALSE; } - return joystick->driver->IsAttached(joystick); + return joystick->attached; } /* @@ -765,6 +766,8 @@ static void UpdateEventsForDeviceRemoval() void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance) { + SDL_Joystick *joystick; + #if !SDL_EVENTS_DISABLED SDL_Event event; @@ -777,6 +780,15 @@ void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance) UpdateEventsForDeviceRemoval(); #endif /* !SDL_EVENTS_DISABLED */ + + /* Mark this joystick as no longer attached */ + for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { + if (joystick->instance_id == device_instance) { + joystick->attached = SDL_FALSE; + joystick->force_recentering = SDL_TRUE; + break; + } + } } int @@ -984,10 +996,12 @@ SDL_JoystickUpdate(void) SDL_UnlockJoysticks(); for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { - joystick->driver->Update(joystick); + if (joystick->attached) { + joystick->driver->Update(joystick); - if (joystick->delayed_guide_button) { - SDL_GameControllerHandleDelayedGuideButton(joystick); + if (joystick->delayed_guide_button) { + SDL_GameControllerHandleDelayedGuideButton(joystick); + } } if (joystick->force_recentering) { diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 99ed52b4e..11a259ce5 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -59,6 +59,7 @@ struct _SDL_Joystick int nbuttons; /* Number of buttons on the joystick */ Uint8 *buttons; /* Current button states */ + SDL_bool attached; SDL_bool is_game_controller; SDL_bool delayed_guide_button; /* SDL_TRUE if this device has the guide button event delayed */ SDL_bool force_recentering; /* SDL_TRUE if this device needs to have its state reset to 0 */ @@ -117,11 +118,6 @@ typedef struct _SDL_JoystickDriver */ int (*Open)(SDL_Joystick * joystick, int device_index); - /* Function to query if the joystick is currently attached - * It returns SDL_TRUE if attached, SDL_FALSE otherwise. - */ - SDL_bool (*IsAttached)(SDL_Joystick * joystick); - /* Rumble functionality */ int (*Rumble)(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c index 6b12c511b..9937723d0 100644 --- a/src/joystick/android/SDL_sysjoystick.c +++ b/src/joystick/android/SDL_sysjoystick.c @@ -617,12 +617,6 @@ ANDROID_JoystickOpen(SDL_Joystick * joystick, int device_index) return (0); } -static SDL_bool -ANDROID_JoystickIsAttached(SDL_Joystick *joystick) -{ - return joystick->hwdata != NULL; -} - static int ANDROID_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) { @@ -698,7 +692,6 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver = ANDROID_JoystickGetDeviceGUID, ANDROID_JoystickGetDeviceInstanceID, ANDROID_JoystickOpen, - ANDROID_JoystickIsAttached, ANDROID_JoystickRumble, ANDROID_JoystickUpdate, ANDROID_JoystickClose, diff --git a/src/joystick/bsd/SDL_sysjoystick.c b/src/joystick/bsd/SDL_sysjoystick.c index 940854504..2c55b2301 100644 --- a/src/joystick/bsd/SDL_sysjoystick.c +++ b/src/joystick/bsd/SDL_sysjoystick.c @@ -467,12 +467,6 @@ desc_failed: return (-1); } -/* Function to determine if this joystick is attached to the system right now */ -SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) -{ - return SDL_TRUE; -} - void SDL_SYS_JoystickUpdate(SDL_Joystick * joy) { diff --git a/src/joystick/darwin/SDL_sysjoystick.c b/src/joystick/darwin/SDL_sysjoystick.c index 0b72d052c..88cc92b7a 100644 --- a/src/joystick/darwin/SDL_sysjoystick.c +++ b/src/joystick/darwin/SDL_sysjoystick.c @@ -736,12 +736,6 @@ DARWIN_JoystickOpen(SDL_Joystick * joystick, int device_index) return 0; } -static SDL_bool -DARWIN_JoystickIsAttached(SDL_Joystick * joystick) -{ - return joystick->hwdata != NULL; -} - /* * Like strerror but for force feedback errors. */ @@ -1007,7 +1001,6 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver = DARWIN_JoystickGetDeviceGUID, DARWIN_JoystickGetDeviceInstanceID, DARWIN_JoystickOpen, - DARWIN_JoystickIsAttached, DARWIN_JoystickRumble, DARWIN_JoystickUpdate, DARWIN_JoystickClose, diff --git a/src/joystick/dummy/SDL_sysjoystick.c b/src/joystick/dummy/SDL_sysjoystick.c index c491e13f7..f03ee3c20 100644 --- a/src/joystick/dummy/SDL_sysjoystick.c +++ b/src/joystick/dummy/SDL_sysjoystick.c @@ -72,12 +72,6 @@ DUMMY_JoystickOpen(SDL_Joystick * joystick, int device_index) return SDL_SetError("Logic error: No joysticks available"); } -static SDL_bool -DUMMY_JoystickIsAttached(SDL_Joystick *joystick) -{ - return SDL_FALSE; -} - static int DUMMY_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) { @@ -108,7 +102,6 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver = DUMMY_JoystickGetDeviceGUID, DUMMY_JoystickGetDeviceInstanceID, DUMMY_JoystickOpen, - DUMMY_JoystickIsAttached, DUMMY_JoystickRumble, DUMMY_JoystickUpdate, DUMMY_JoystickClose, diff --git a/src/joystick/emscripten/SDL_sysjoystick.c b/src/joystick/emscripten/SDL_sysjoystick.c index b5bcaad6c..c45ad7c78 100644 --- a/src/joystick/emscripten/SDL_sysjoystick.c +++ b/src/joystick/emscripten/SDL_sysjoystick.c @@ -295,12 +295,6 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) return (0); } -/* Function to determine if this joystick is attached to the system right now */ -SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) -{ - return joystick->hwdata != NULL; -} - /* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events diff --git a/src/joystick/haiku/SDL_haikujoystick.cc b/src/joystick/haiku/SDL_haikujoystick.cc index 9ab2c72fd..08320951a 100644 --- a/src/joystick/haiku/SDL_haikujoystick.cc +++ b/src/joystick/haiku/SDL_haikujoystick.cc @@ -152,12 +152,6 @@ extern "C" return (0); } -/* Function to determine if this joystick is attached to the system right now */ - SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) - { - return SDL_TRUE; - } - /* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index 98720aacd..010c2b2aa 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -458,21 +458,6 @@ HIDAPI_JoystickOpen(SDL_Joystick * joystick, int device_index) return 0; } -static SDL_bool -HIDAPI_JoystickIsAttached(SDL_Joystick *joystick) -{ - SDL_HIDAPI_Device *device = SDL_HIDAPI_devices; - while (device) { - if (device->driver) { - if (joystick->instance_id == device->instance_id) { - return SDL_TRUE; - } - } - device = device->next; - } - return SDL_FALSE; -} - static int HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) { @@ -529,7 +514,6 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver = HIDAPI_JoystickGetDeviceGUID, HIDAPI_JoystickGetDeviceInstanceID, HIDAPI_JoystickOpen, - HIDAPI_JoystickIsAttached, HIDAPI_JoystickRumble, HIDAPI_JoystickUpdate, HIDAPI_JoystickClose, diff --git a/src/joystick/iphoneos/SDL_sysjoystick.m b/src/joystick/iphoneos/SDL_sysjoystick.m index db5ab9a79..ed7ddf1da 100644 --- a/src/joystick/iphoneos/SDL_sysjoystick.m +++ b/src/joystick/iphoneos/SDL_sysjoystick.m @@ -425,12 +425,6 @@ IOS_JoystickOpen(SDL_Joystick * joystick, int device_index) return 0; } -static SDL_bool -IOS_JoystickIsAttached(SDL_Joystick *joystick) -{ - return joystick->hwdata != NULL; -} - static void IOS_AccelerometerUpdate(SDL_Joystick * joystick) { @@ -724,7 +718,6 @@ SDL_JoystickDriver SDL_IOS_JoystickDriver = IOS_JoystickGetDeviceGUID, IOS_JoystickGetDeviceInstanceID, IOS_JoystickOpen, - IOS_JoystickIsAttached, IOS_JoystickRumble, IOS_JoystickUpdate, IOS_JoystickClose, diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c index 5a69aa8b3..ede8fb124 100644 --- a/src/joystick/linux/SDL_sysjoystick.c +++ b/src/joystick/linux/SDL_sysjoystick.c @@ -809,13 +809,6 @@ LINUX_JoystickOpen(SDL_Joystick * joystick, int device_index) return (0); } -/* Function to determine if this joystick is attached to the system right now */ -static SDL_bool -LINUX_JoystickIsAttached(SDL_Joystick *joystick) -{ - return joystick->hwdata->item != NULL; -} - static int LINUX_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) { @@ -1112,7 +1105,6 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver = LINUX_JoystickGetDeviceGUID, LINUX_JoystickGetDeviceInstanceID, LINUX_JoystickOpen, - LINUX_JoystickIsAttached, LINUX_JoystickRumble, LINUX_JoystickUpdate, LINUX_JoystickClose, diff --git a/src/joystick/psp/SDL_sysjoystick.c b/src/joystick/psp/SDL_sysjoystick.c index 228cbb209..262da858e 100644 --- a/src/joystick/psp/SDL_sysjoystick.c +++ b/src/joystick/psp/SDL_sysjoystick.c @@ -177,12 +177,6 @@ int SDL_SYS_JoystickOpen(SDL_Joystick *joystick, int device_index) return 0; } -/* Function to determine if this joystick is attached to the system right now */ -SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) -{ - return SDL_TRUE; -} - /* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c index b6691c222..4b736918a 100644 --- a/src/joystick/windows/SDL_dinputjoystick.c +++ b/src/joystick/windows/SDL_dinputjoystick.c @@ -955,8 +955,6 @@ UpdateDINPUTJoystickState_Buffered(SDL_Joystick * joystick) /* Handle the events or punt */ if (FAILED(result)) { - joystick->hwdata->send_remove_event = SDL_TRUE; - joystick->hwdata->removed = SDL_TRUE; return; } @@ -1011,8 +1009,6 @@ UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick) } if (result != DI_OK) { - joystick->hwdata->send_remove_event = SDL_TRUE; - joystick->hwdata->removed = SDL_TRUE; return; } diff --git a/src/joystick/windows/SDL_mmjoystick.c b/src/joystick/windows/SDL_mmjoystick.c index 47ceec166..60e3fcb31 100644 --- a/src/joystick/windows/SDL_mmjoystick.c +++ b/src/joystick/windows/SDL_mmjoystick.c @@ -279,12 +279,6 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) return (0); } -/* Function to determine if this joystick is attached to the system right now */ -SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) -{ - return SDL_TRUE; -} - static Uint8 TranslatePOV(DWORD value) { diff --git a/src/joystick/windows/SDL_windowsjoystick.c b/src/joystick/windows/SDL_windowsjoystick.c index 47866b50c..4ae17cc8e 100644 --- a/src/joystick/windows/SDL_windowsjoystick.c +++ b/src/joystick/windows/SDL_windowsjoystick.c @@ -463,13 +463,6 @@ WINDOWS_JoystickOpen(SDL_Joystick * joystick, int device_index) } } -/* return true if this joystick is plugged in right now */ -static SDL_bool -WINDOWS_JoystickIsAttached(SDL_Joystick * joystick) -{ - return joystick->hwdata && !joystick->hwdata->removed; -} - static int WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) { @@ -483,7 +476,7 @@ WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uin static void WINDOWS_JoystickUpdate(SDL_Joystick * joystick) { - if (!joystick->hwdata || joystick->hwdata->removed) { + if (!joystick->hwdata) { return; } @@ -492,10 +485,6 @@ WINDOWS_JoystickUpdate(SDL_Joystick * joystick) } else { SDL_DINPUT_JoystickUpdate(joystick); } - - if (joystick->hwdata->removed) { - joystick->force_recentering = SDL_TRUE; - } } /* Function to close a joystick after use */ @@ -558,7 +547,6 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver = WINDOWS_JoystickGetDeviceGUID, WINDOWS_JoystickGetDeviceInstanceID, WINDOWS_JoystickOpen, - WINDOWS_JoystickIsAttached, WINDOWS_JoystickRumble, WINDOWS_JoystickUpdate, WINDOWS_JoystickClose, diff --git a/src/joystick/windows/SDL_windowsjoystick_c.h b/src/joystick/windows/SDL_windowsjoystick_c.h index 2bccfb52f..611f7e620 100644 --- a/src/joystick/windows/SDL_windowsjoystick_c.h +++ b/src/joystick/windows/SDL_windowsjoystick_c.h @@ -66,8 +66,6 @@ typedef struct input_t struct joystick_hwdata { SDL_JoystickGUID guid; - SDL_bool removed; - SDL_bool send_remove_event; Uint32 rumble_expiration; #if SDL_JOYSTICK_DINPUT diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c index 88e33269d..6ca369b1a 100644 --- a/src/joystick/windows/SDL_xinputjoystick.c +++ b/src/joystick/windows/SDL_xinputjoystick.c @@ -270,6 +270,15 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext) WINDOWS_AddJoystickDevice(pNewJoystick); } +static void +DelXInputDevice(Uint8 userid) +{ + if (s_arrXInputDevicePath[userid]) { + SDL_free(s_arrXInputDevicePath[userid]); + s_arrXInputDevicePath[userid] = NULL; + } +} + void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext) { @@ -285,6 +294,8 @@ SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext) XINPUT_CAPABILITIES capabilities; if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) { AddXInputDevice(userid, capabilities.SubType, pContext); + } else { + DelXInputDevice(userid); } } } @@ -456,14 +467,6 @@ SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick) result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState); if (result == ERROR_DEVICE_NOT_CONNECTED) { - Uint8 userid = joystick->hwdata->userid; - - joystick->hwdata->send_remove_event = SDL_TRUE; - joystick->hwdata->removed = SDL_TRUE; - if (s_arrXInputDevicePath[userid]) { - SDL_free(s_arrXInputDevicePath[userid]); - s_arrXInputDevicePath[userid] = NULL; - } return; }