Remove the HIDAPI device if we get a read error from it
authorSam Lantinga <slouken@libsdl.org>
Wed, 15 Aug 2018 19:53:26 -0700
changeset 121116c1ae9f1effb
parent 12110 c52772e46ee2
child 12112 547ea8a49167
Remove the HIDAPI device if we get a read error from it
This fixes detecting PS4 controller disconnect on Mac OS X, where there isn't any device removed notification
src/joystick/hidapi/SDL_hidapi_ps4.c
src/joystick/hidapi/SDL_hidapi_switch.c
src/joystick/hidapi/SDL_hidapi_xbox360.c
src/joystick/hidapi/SDL_hidapi_xboxone.c
src/joystick/hidapi/SDL_hidapijoystick.c
src/joystick/hidapi/SDL_hidapijoystick_c.h
     1.1 --- a/src/joystick/hidapi/SDL_hidapi_ps4.c	Wed Aug 15 19:53:24 2018 -0700
     1.2 +++ b/src/joystick/hidapi/SDL_hidapi_ps4.c	Wed Aug 15 19:53:26 2018 -0700
     1.3 @@ -479,7 +479,7 @@
     1.4      SDL_memcpy(&ctx->last_state, packet, sizeof(ctx->last_state));
     1.5  }
     1.6  
     1.7 -static void
     1.8 +static SDL_bool
     1.9  HIDAPI_DriverPS4_Update(SDL_Joystick *joystick, hid_device *dev, void *context)
    1.10  {
    1.11      SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context;
    1.12 @@ -509,6 +509,8 @@
    1.13              HIDAPI_DriverPS4_Rumble(joystick, dev, context, 0, 0, 0);
    1.14          }
    1.15      }
    1.16 +
    1.17 +	return (size >= 0);
    1.18  }
    1.19  
    1.20  static void
     2.1 --- a/src/joystick/hidapi/SDL_hidapi_switch.c	Wed Aug 15 19:53:24 2018 -0700
     2.2 +++ b/src/joystick/hidapi/SDL_hidapi_switch.c	Wed Aug 15 19:53:26 2018 -0700
     2.3 @@ -846,12 +846,13 @@
     2.4      ctx->m_lastFullState = *packet;
     2.5  }
     2.6  
     2.7 -static void
     2.8 +static SDL_bool
     2.9  HIDAPI_DriverSwitch_Update(SDL_Joystick *joystick, hid_device *dev, void *context)
    2.10  {
    2.11      SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)context;
    2.12 +	int size;
    2.13  
    2.14 -    while (ReadInput(ctx) > 0) {
    2.15 +    while ((size = ReadInput(ctx)) > 0) {
    2.16          switch (ctx->m_rgucReadBuffer[0]) {
    2.17          case k_eSwitchInputReportIDs_SimpleControllerState:
    2.18              HandleSimpleControllerState(joystick, ctx, (SwitchSimpleStatePacket_t *)&ctx->m_rgucReadBuffer[1]);
    2.19 @@ -870,6 +871,7 @@
    2.20              HIDAPI_DriverSwitch_Rumble(joystick, dev, context, 0, 0, 0);
    2.21          }
    2.22      }
    2.23 +	return (size >= 0);
    2.24  }
    2.25  
    2.26  static void
     3.1 --- a/src/joystick/hidapi/SDL_hidapi_xbox360.c	Wed Aug 15 19:53:24 2018 -0700
     3.2 +++ b/src/joystick/hidapi/SDL_hidapi_xbox360.c	Wed Aug 15 19:53:26 2018 -0700
     3.3 @@ -310,7 +310,7 @@
     3.4      SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
     3.5  }
     3.6  
     3.7 -static void
     3.8 +static SDL_bool
     3.9  HIDAPI_DriverXbox360_Update(SDL_Joystick *joystick, hid_device *dev, void *context)
    3.10  {
    3.11      SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)context;
    3.12 @@ -336,6 +336,8 @@
    3.13              HIDAPI_DriverXbox360_Rumble(joystick, dev, context, 0, 0, 0);
    3.14          }
    3.15      }
    3.16 +
    3.17 +	return (size >= 0);
    3.18  }
    3.19  
    3.20  static void
     4.1 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c	Wed Aug 15 19:53:24 2018 -0700
     4.2 +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c	Wed Aug 15 19:53:26 2018 -0700
     4.3 @@ -308,7 +308,7 @@
     4.4      SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[4] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
     4.5  }
     4.6  
     4.7 -static void
     4.8 +static SDL_bool
     4.9  HIDAPI_DriverXboxOne_Update(SDL_Joystick *joystick, hid_device *dev, void *context)
    4.10  {
    4.11      SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)context;
    4.12 @@ -337,6 +337,8 @@
    4.13              HIDAPI_DriverXboxOne_Rumble(joystick, dev, context, 0, 0, 0);
    4.14          }
    4.15      }
    4.16 +
    4.17 +	return (size >= 0);
    4.18  }
    4.19  
    4.20  static void
     5.1 --- a/src/joystick/hidapi/SDL_hidapijoystick.c	Wed Aug 15 19:53:24 2018 -0700
     5.2 +++ b/src/joystick/hidapi/SDL_hidapijoystick.c	Wed Aug 15 19:53:26 2018 -0700
     5.3 @@ -146,7 +146,7 @@
     5.4  #define DBT_DEVNODES_CHANGED            0x0007
     5.5  #define DBT_CONFIGCHANGED               0x0018
     5.6  #define DBT_DEVICETYPESPECIFIC          0x8005  /* type specific event */
     5.7 -#define DBT_DEVINSTSTARTED               0x8008  /* device installed and started */
     5.8 +#define DBT_DEVINSTSTARTED              0x8008  /* device installed and started */
     5.9  
    5.10  #include <initguid.h>
    5.11  DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
    5.12 @@ -605,6 +605,7 @@
    5.13          return;
    5.14      }
    5.15  
    5.16 +#define DEBUG_HIDAPI
    5.17  #ifdef DEBUG_HIDAPI
    5.18      SDL_Log("Adding HIDAPI device '%s' interface %d, usage page 0x%.4x, usage 0x%.4x\n", device->name, device->interface_number, device->usage_page, device->usage);
    5.19  #endif
    5.20 @@ -786,7 +787,15 @@
    5.21  {
    5.22      struct joystick_hwdata *hwdata = joystick->hwdata;
    5.23      SDL_HIDAPI_DeviceDriver *driver = hwdata->driver;
    5.24 -    driver->Update(joystick, hwdata->dev, hwdata->context);
    5.25 +    if (!driver->Update(joystick, hwdata->dev, hwdata->context)) {
    5.26 +		SDL_HIDAPI_Device *device;
    5.27 +		for (device = SDL_HIDAPI_devices; device; device = device->next) {
    5.28 +			if (device->instance_id == joystick->instance_id) {
    5.29 +				HIDAPI_DelDevice(device, SDL_TRUE);
    5.30 +				break;
    5.31 +			}
    5.32 +		}
    5.33 +	}
    5.34  }
    5.35  
    5.36  static void
     6.1 --- a/src/joystick/hidapi/SDL_hidapijoystick_c.h	Wed Aug 15 19:53:24 2018 -0700
     6.2 +++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h	Wed Aug 15 19:53:26 2018 -0700
     6.3 @@ -50,7 +50,7 @@
     6.4      const char *(*GetDeviceName)(Uint16 vendor_id, Uint16 product_id);
     6.5      SDL_bool (*Init)(SDL_Joystick *joystick, hid_device *dev, Uint16 vendor_id, Uint16 product_id, void **context);
     6.6      int (*Rumble)(SDL_Joystick *joystick, hid_device *dev, void *context, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
     6.7 -    void (*Update)(SDL_Joystick *joystick, hid_device *dev, void *context);
     6.8 +    SDL_bool (*Update)(SDL_Joystick *joystick, hid_device *dev, void *context);
     6.9      void (*Quit)(SDL_Joystick *joystick, hid_device *dev, void *context);
    6.10  
    6.11  } SDL_HIDAPI_DeviceDriver;