Worked around bug with Sony PS Now PS3 controller where DirectInput polling will continue to return success after the controller is unplugged.
authorSam Lantinga <slouken@libsdl.org>
Thu, 09 Aug 2018 16:03:50 -0700
changeset 12090c3209fca27b2
parent 12089 d544367b1ef0
child 12091 1ee17930a843
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
src/joystick/SDL_sysjoystick.h
src/joystick/android/SDL_sysjoystick.c
src/joystick/bsd/SDL_sysjoystick.c
src/joystick/darwin/SDL_sysjoystick.c
src/joystick/dummy/SDL_sysjoystick.c
src/joystick/emscripten/SDL_sysjoystick.c
src/joystick/haiku/SDL_haikujoystick.cc
src/joystick/hidapi/SDL_hidapijoystick.c
src/joystick/iphoneos/SDL_sysjoystick.m
src/joystick/linux/SDL_sysjoystick.c
src/joystick/psp/SDL_sysjoystick.c
src/joystick/windows/SDL_dinputjoystick.c
src/joystick/windows/SDL_mmjoystick.c
src/joystick/windows/SDL_windowsjoystick.c
src/joystick/windows/SDL_windowsjoystick_c.h
src/joystick/windows/SDL_xinputjoystick.c
     1.1 --- a/src/joystick/SDL_joystick.c	Thu Aug 09 16:03:29 2018 -0700
     1.2 +++ b/src/joystick/SDL_joystick.c	Thu Aug 09 16:03:50 2018 -0700
     1.3 @@ -297,6 +297,7 @@
     1.4      }
     1.5      joystick->driver = driver;
     1.6      joystick->instance_id = instance_id;
     1.7 +    joystick->attached = SDL_TRUE;
     1.8  
     1.9      if (driver->Open(joystick, device_index) < 0) {
    1.10          SDL_free(joystick);
    1.11 @@ -545,7 +546,7 @@
    1.12          return SDL_FALSE;
    1.13      }
    1.14  
    1.15 -    return joystick->driver->IsAttached(joystick);
    1.16 +    return joystick->attached;
    1.17  }
    1.18  
    1.19  /*
    1.20 @@ -765,6 +766,8 @@
    1.21  
    1.22  void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
    1.23  {
    1.24 +    SDL_Joystick *joystick;
    1.25 +
    1.26  #if !SDL_EVENTS_DISABLED
    1.27      SDL_Event event;
    1.28  
    1.29 @@ -777,6 +780,15 @@
    1.30  
    1.31      UpdateEventsForDeviceRemoval();
    1.32  #endif /* !SDL_EVENTS_DISABLED */
    1.33 +
    1.34 +    /* Mark this joystick as no longer attached */
    1.35 +    for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
    1.36 +        if (joystick->instance_id == device_instance) {
    1.37 +            joystick->attached = SDL_FALSE;
    1.38 +            joystick->force_recentering = SDL_TRUE;
    1.39 +            break;
    1.40 +        }
    1.41 +    }
    1.42  }
    1.43  
    1.44  int
    1.45 @@ -984,10 +996,12 @@
    1.46      SDL_UnlockJoysticks();
    1.47  
    1.48      for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
    1.49 -        joystick->driver->Update(joystick);
    1.50 +        if (joystick->attached) {
    1.51 +            joystick->driver->Update(joystick);
    1.52  
    1.53 -        if (joystick->delayed_guide_button) {
    1.54 -            SDL_GameControllerHandleDelayedGuideButton(joystick);
    1.55 +            if (joystick->delayed_guide_button) {
    1.56 +                SDL_GameControllerHandleDelayedGuideButton(joystick);
    1.57 +            }
    1.58          }
    1.59  
    1.60          if (joystick->force_recentering) {
     2.1 --- a/src/joystick/SDL_sysjoystick.h	Thu Aug 09 16:03:29 2018 -0700
     2.2 +++ b/src/joystick/SDL_sysjoystick.h	Thu Aug 09 16:03:50 2018 -0700
     2.3 @@ -59,6 +59,7 @@
     2.4      int nbuttons;               /* Number of buttons on the joystick */
     2.5      Uint8 *buttons;             /* Current button states */
     2.6  
     2.7 +    SDL_bool attached;
     2.8      SDL_bool is_game_controller;
     2.9      SDL_bool delayed_guide_button; /* SDL_TRUE if this device has the guide button event delayed */
    2.10      SDL_bool force_recentering; /* SDL_TRUE if this device needs to have its state reset to 0 */
    2.11 @@ -117,11 +118,6 @@
    2.12       */
    2.13      int (*Open)(SDL_Joystick * joystick, int device_index);
    2.14  
    2.15 -    /* Function to query if the joystick is currently attached
    2.16 -     * It returns SDL_TRUE if attached, SDL_FALSE otherwise.
    2.17 -     */
    2.18 -    SDL_bool (*IsAttached)(SDL_Joystick * joystick);
    2.19 -
    2.20      /* Rumble functionality */
    2.21      int (*Rumble)(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
    2.22  
     3.1 --- a/src/joystick/android/SDL_sysjoystick.c	Thu Aug 09 16:03:29 2018 -0700
     3.2 +++ b/src/joystick/android/SDL_sysjoystick.c	Thu Aug 09 16:03:50 2018 -0700
     3.3 @@ -617,12 +617,6 @@
     3.4      return (0);
     3.5  }
     3.6  
     3.7 -static SDL_bool
     3.8 -ANDROID_JoystickIsAttached(SDL_Joystick *joystick)
     3.9 -{
    3.10 -    return joystick->hwdata != NULL;
    3.11 -}
    3.12 -
    3.13  static int
    3.14  ANDROID_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
    3.15  {
    3.16 @@ -698,7 +692,6 @@
    3.17      ANDROID_JoystickGetDeviceGUID,
    3.18      ANDROID_JoystickGetDeviceInstanceID,
    3.19      ANDROID_JoystickOpen,
    3.20 -    ANDROID_JoystickIsAttached,
    3.21      ANDROID_JoystickRumble,
    3.22      ANDROID_JoystickUpdate,
    3.23      ANDROID_JoystickClose,
     4.1 --- a/src/joystick/bsd/SDL_sysjoystick.c	Thu Aug 09 16:03:29 2018 -0700
     4.2 +++ b/src/joystick/bsd/SDL_sysjoystick.c	Thu Aug 09 16:03:50 2018 -0700
     4.3 @@ -467,12 +467,6 @@
     4.4      return (-1);
     4.5  }
     4.6  
     4.7 -/* Function to determine if this joystick is attached to the system right now */
     4.8 -SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
     4.9 -{
    4.10 -    return SDL_TRUE;
    4.11 -}
    4.12 -
    4.13  void
    4.14  SDL_SYS_JoystickUpdate(SDL_Joystick * joy)
    4.15  {
     5.1 --- a/src/joystick/darwin/SDL_sysjoystick.c	Thu Aug 09 16:03:29 2018 -0700
     5.2 +++ b/src/joystick/darwin/SDL_sysjoystick.c	Thu Aug 09 16:03:50 2018 -0700
     5.3 @@ -736,12 +736,6 @@
     5.4      return 0;
     5.5  }
     5.6  
     5.7 -static SDL_bool
     5.8 -DARWIN_JoystickIsAttached(SDL_Joystick * joystick)
     5.9 -{
    5.10 -    return joystick->hwdata != NULL;
    5.11 -}
    5.12 -
    5.13  /*
    5.14   * Like strerror but for force feedback errors.
    5.15   */
    5.16 @@ -1007,7 +1001,6 @@
    5.17      DARWIN_JoystickGetDeviceGUID,
    5.18      DARWIN_JoystickGetDeviceInstanceID,
    5.19      DARWIN_JoystickOpen,
    5.20 -    DARWIN_JoystickIsAttached,
    5.21      DARWIN_JoystickRumble,
    5.22      DARWIN_JoystickUpdate,
    5.23      DARWIN_JoystickClose,
     6.1 --- a/src/joystick/dummy/SDL_sysjoystick.c	Thu Aug 09 16:03:29 2018 -0700
     6.2 +++ b/src/joystick/dummy/SDL_sysjoystick.c	Thu Aug 09 16:03:50 2018 -0700
     6.3 @@ -72,12 +72,6 @@
     6.4      return SDL_SetError("Logic error: No joysticks available");
     6.5  }
     6.6  
     6.7 -static SDL_bool
     6.8 -DUMMY_JoystickIsAttached(SDL_Joystick *joystick)
     6.9 -{
    6.10 -    return SDL_FALSE;
    6.11 -}
    6.12 -
    6.13  static int
    6.14  DUMMY_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
    6.15  {
    6.16 @@ -108,7 +102,6 @@
    6.17      DUMMY_JoystickGetDeviceGUID,
    6.18      DUMMY_JoystickGetDeviceInstanceID,
    6.19      DUMMY_JoystickOpen,
    6.20 -    DUMMY_JoystickIsAttached,
    6.21      DUMMY_JoystickRumble,
    6.22      DUMMY_JoystickUpdate,
    6.23      DUMMY_JoystickClose,
     7.1 --- a/src/joystick/emscripten/SDL_sysjoystick.c	Thu Aug 09 16:03:29 2018 -0700
     7.2 +++ b/src/joystick/emscripten/SDL_sysjoystick.c	Thu Aug 09 16:03:50 2018 -0700
     7.3 @@ -295,12 +295,6 @@
     7.4      return (0);
     7.5  }
     7.6  
     7.7 -/* Function to determine if this joystick is attached to the system right now */
     7.8 -SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
     7.9 -{
    7.10 -    return joystick->hwdata != NULL;
    7.11 -}
    7.12 -
    7.13  /* Function to update the state of a joystick - called as a device poll.
    7.14   * This function shouldn't update the joystick structure directly,
    7.15   * but instead should call SDL_PrivateJoystick*() to deliver events
     8.1 --- a/src/joystick/haiku/SDL_haikujoystick.cc	Thu Aug 09 16:03:29 2018 -0700
     8.2 +++ b/src/joystick/haiku/SDL_haikujoystick.cc	Thu Aug 09 16:03:50 2018 -0700
     8.3 @@ -152,12 +152,6 @@
     8.4          return (0);
     8.5      }
     8.6  
     8.7 -/* Function to determine if this joystick is attached to the system right now */
     8.8 -    SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
     8.9 -    {
    8.10 -        return SDL_TRUE;
    8.11 -    }
    8.12 -
    8.13  /* Function to update the state of a joystick - called as a device poll.
    8.14   * This function shouldn't update the joystick structure directly,
    8.15   * but instead should call SDL_PrivateJoystick*() to deliver events
     9.1 --- a/src/joystick/hidapi/SDL_hidapijoystick.c	Thu Aug 09 16:03:29 2018 -0700
     9.2 +++ b/src/joystick/hidapi/SDL_hidapijoystick.c	Thu Aug 09 16:03:50 2018 -0700
     9.3 @@ -458,21 +458,6 @@
     9.4      return 0;
     9.5  }
     9.6  
     9.7 -static SDL_bool
     9.8 -HIDAPI_JoystickIsAttached(SDL_Joystick *joystick)
     9.9 -{
    9.10 -    SDL_HIDAPI_Device *device = SDL_HIDAPI_devices;
    9.11 -    while (device) {
    9.12 -        if (device->driver) {
    9.13 -            if (joystick->instance_id == device->instance_id) {
    9.14 -                return SDL_TRUE;
    9.15 -            }
    9.16 -        }
    9.17 -        device = device->next;
    9.18 -    }
    9.19 -    return SDL_FALSE;
    9.20 -}
    9.21 -
    9.22  static int
    9.23  HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
    9.24  {
    9.25 @@ -529,7 +514,6 @@
    9.26      HIDAPI_JoystickGetDeviceGUID,
    9.27      HIDAPI_JoystickGetDeviceInstanceID,
    9.28      HIDAPI_JoystickOpen,
    9.29 -    HIDAPI_JoystickIsAttached,
    9.30      HIDAPI_JoystickRumble,
    9.31      HIDAPI_JoystickUpdate,
    9.32      HIDAPI_JoystickClose,
    10.1 --- a/src/joystick/iphoneos/SDL_sysjoystick.m	Thu Aug 09 16:03:29 2018 -0700
    10.2 +++ b/src/joystick/iphoneos/SDL_sysjoystick.m	Thu Aug 09 16:03:50 2018 -0700
    10.3 @@ -425,12 +425,6 @@
    10.4      return 0;
    10.5  }
    10.6  
    10.7 -static SDL_bool
    10.8 -IOS_JoystickIsAttached(SDL_Joystick *joystick)
    10.9 -{
   10.10 -    return joystick->hwdata != NULL;
   10.11 -}
   10.12 -
   10.13  static void
   10.14  IOS_AccelerometerUpdate(SDL_Joystick * joystick)
   10.15  {
   10.16 @@ -724,7 +718,6 @@
   10.17      IOS_JoystickGetDeviceGUID,
   10.18      IOS_JoystickGetDeviceInstanceID,
   10.19      IOS_JoystickOpen,
   10.20 -    IOS_JoystickIsAttached,
   10.21      IOS_JoystickRumble,
   10.22      IOS_JoystickUpdate,
   10.23      IOS_JoystickClose,
    11.1 --- a/src/joystick/linux/SDL_sysjoystick.c	Thu Aug 09 16:03:29 2018 -0700
    11.2 +++ b/src/joystick/linux/SDL_sysjoystick.c	Thu Aug 09 16:03:50 2018 -0700
    11.3 @@ -809,13 +809,6 @@
    11.4      return (0);
    11.5  }
    11.6  
    11.7 -/* Function to determine if this joystick is attached to the system right now */
    11.8 -static SDL_bool
    11.9 -LINUX_JoystickIsAttached(SDL_Joystick *joystick)
   11.10 -{
   11.11 -    return joystick->hwdata->item != NULL;
   11.12 -}
   11.13 -
   11.14  static int
   11.15  LINUX_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   11.16  {
   11.17 @@ -1112,7 +1105,6 @@
   11.18      LINUX_JoystickGetDeviceGUID,
   11.19      LINUX_JoystickGetDeviceInstanceID,
   11.20      LINUX_JoystickOpen,
   11.21 -    LINUX_JoystickIsAttached,
   11.22      LINUX_JoystickRumble,
   11.23      LINUX_JoystickUpdate,
   11.24      LINUX_JoystickClose,
    12.1 --- a/src/joystick/psp/SDL_sysjoystick.c	Thu Aug 09 16:03:29 2018 -0700
    12.2 +++ b/src/joystick/psp/SDL_sysjoystick.c	Thu Aug 09 16:03:50 2018 -0700
    12.3 @@ -177,12 +177,6 @@
    12.4      return 0;
    12.5  }
    12.6  
    12.7 -/* Function to determine if this joystick is attached to the system right now */
    12.8 -SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
    12.9 -{
   12.10 -    return SDL_TRUE;
   12.11 -}
   12.12 -
   12.13  /* Function to update the state of a joystick - called as a device poll.
   12.14   * This function shouldn't update the joystick structure directly,
   12.15   * but instead should call SDL_PrivateJoystick*() to deliver events
    13.1 --- a/src/joystick/windows/SDL_dinputjoystick.c	Thu Aug 09 16:03:29 2018 -0700
    13.2 +++ b/src/joystick/windows/SDL_dinputjoystick.c	Thu Aug 09 16:03:50 2018 -0700
    13.3 @@ -955,8 +955,6 @@
    13.4  
    13.5      /* Handle the events or punt */
    13.6      if (FAILED(result)) {
    13.7 -        joystick->hwdata->send_remove_event = SDL_TRUE;
    13.8 -        joystick->hwdata->removed = SDL_TRUE;
    13.9          return;
   13.10      }
   13.11  
   13.12 @@ -1011,8 +1009,6 @@
   13.13      }
   13.14  
   13.15      if (result != DI_OK) {
   13.16 -        joystick->hwdata->send_remove_event = SDL_TRUE;
   13.17 -        joystick->hwdata->removed = SDL_TRUE;
   13.18          return;
   13.19      }
   13.20  
    14.1 --- a/src/joystick/windows/SDL_mmjoystick.c	Thu Aug 09 16:03:29 2018 -0700
    14.2 +++ b/src/joystick/windows/SDL_mmjoystick.c	Thu Aug 09 16:03:50 2018 -0700
    14.3 @@ -279,12 +279,6 @@
    14.4      return (0);
    14.5  }
    14.6  
    14.7 -/* Function to determine if this joystick is attached to the system right now */
    14.8 -SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
    14.9 -{
   14.10 -    return SDL_TRUE;
   14.11 -}
   14.12 -
   14.13  static Uint8
   14.14  TranslatePOV(DWORD value)
   14.15  {
    15.1 --- a/src/joystick/windows/SDL_windowsjoystick.c	Thu Aug 09 16:03:29 2018 -0700
    15.2 +++ b/src/joystick/windows/SDL_windowsjoystick.c	Thu Aug 09 16:03:50 2018 -0700
    15.3 @@ -463,13 +463,6 @@
    15.4      }
    15.5  }
    15.6  
    15.7 -/* return true if this joystick is plugged in right now */
    15.8 -static SDL_bool 
    15.9 -WINDOWS_JoystickIsAttached(SDL_Joystick * joystick)
   15.10 -{
   15.11 -    return joystick->hwdata && !joystick->hwdata->removed;
   15.12 -}
   15.13 -
   15.14  static int
   15.15  WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   15.16  {
   15.17 @@ -483,7 +476,7 @@
   15.18  static void
   15.19  WINDOWS_JoystickUpdate(SDL_Joystick * joystick)
   15.20  {
   15.21 -    if (!joystick->hwdata || joystick->hwdata->removed) {
   15.22 +    if (!joystick->hwdata) {
   15.23          return;
   15.24      }
   15.25  
   15.26 @@ -492,10 +485,6 @@
   15.27      } else {
   15.28          SDL_DINPUT_JoystickUpdate(joystick);
   15.29      }
   15.30 -
   15.31 -    if (joystick->hwdata->removed) {
   15.32 -        joystick->force_recentering = SDL_TRUE;
   15.33 -    }
   15.34  }
   15.35  
   15.36  /* Function to close a joystick after use */
   15.37 @@ -558,7 +547,6 @@
   15.38      WINDOWS_JoystickGetDeviceGUID,
   15.39      WINDOWS_JoystickGetDeviceInstanceID,
   15.40      WINDOWS_JoystickOpen,
   15.41 -    WINDOWS_JoystickIsAttached,
   15.42      WINDOWS_JoystickRumble,
   15.43      WINDOWS_JoystickUpdate,
   15.44      WINDOWS_JoystickClose,
    16.1 --- a/src/joystick/windows/SDL_windowsjoystick_c.h	Thu Aug 09 16:03:29 2018 -0700
    16.2 +++ b/src/joystick/windows/SDL_windowsjoystick_c.h	Thu Aug 09 16:03:50 2018 -0700
    16.3 @@ -66,8 +66,6 @@
    16.4  struct joystick_hwdata
    16.5  {
    16.6      SDL_JoystickGUID guid;
    16.7 -    SDL_bool removed;
    16.8 -    SDL_bool send_remove_event;
    16.9      Uint32 rumble_expiration;
   16.10  
   16.11  #if SDL_JOYSTICK_DINPUT
    17.1 --- a/src/joystick/windows/SDL_xinputjoystick.c	Thu Aug 09 16:03:29 2018 -0700
    17.2 +++ b/src/joystick/windows/SDL_xinputjoystick.c	Thu Aug 09 16:03:50 2018 -0700
    17.3 @@ -270,6 +270,15 @@
    17.4      WINDOWS_AddJoystickDevice(pNewJoystick);
    17.5  }
    17.6  
    17.7 +static void
    17.8 +DelXInputDevice(Uint8 userid)
    17.9 +{
   17.10 +    if (s_arrXInputDevicePath[userid]) {
   17.11 +        SDL_free(s_arrXInputDevicePath[userid]);
   17.12 +        s_arrXInputDevicePath[userid] = NULL;
   17.13 +    }
   17.14 +}
   17.15 +
   17.16  void
   17.17  SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
   17.18  {
   17.19 @@ -285,6 +294,8 @@
   17.20          XINPUT_CAPABILITIES capabilities;
   17.21          if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) {
   17.22              AddXInputDevice(userid, capabilities.SubType, pContext);
   17.23 +        } else {
   17.24 +            DelXInputDevice(userid);
   17.25          }
   17.26      }
   17.27  }
   17.28 @@ -456,14 +467,6 @@
   17.29  
   17.30      result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState);
   17.31      if (result == ERROR_DEVICE_NOT_CONNECTED) {
   17.32 -        Uint8 userid = joystick->hwdata->userid;
   17.33 -
   17.34 -        joystick->hwdata->send_remove_event = SDL_TRUE;
   17.35 -        joystick->hwdata->removed = SDL_TRUE;
   17.36 -        if (s_arrXInputDevicePath[userid]) {
   17.37 -            SDL_free(s_arrXInputDevicePath[userid]);
   17.38 -            s_arrXInputDevicePath[userid] = NULL;
   17.39 -        }
   17.40          return;
   17.41      }
   17.42