Browse Source

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

Sam Lantinga 6 years ago
parent
commit
888bf1af69

+ 18 - 4
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) {

+ 1 - 5
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);
 

+ 0 - 7
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,

+ 0 - 6
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)
 {

+ 0 - 7
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,

+ 0 - 7
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,

+ 0 - 6
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

+ 0 - 6
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

+ 0 - 16
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,

+ 0 - 7
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,

+ 0 - 8
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,

+ 0 - 6
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

+ 0 - 4
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;
     }
 

+ 0 - 6
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)
 {

+ 1 - 13
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,

+ 0 - 2
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

+ 11 - 8
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;
     }