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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c
index 10345db..44e9b99 100644
--- a/src/joystick/hidapi/SDL_hidapi_ps4.c
+++ b/src/joystick/hidapi/SDL_hidapi_ps4.c
@@ -479,7 +479,7 @@ HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_
SDL_memcpy(&ctx->last_state, packet, sizeof(ctx->last_state));
}
-static void
+static SDL_bool
HIDAPI_DriverPS4_Update(SDL_Joystick *joystick, hid_device *dev, void *context)
{
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context;
@@ -509,6 +509,8 @@ HIDAPI_DriverPS4_Update(SDL_Joystick *joystick, hid_device *dev, void *context)
HIDAPI_DriverPS4_Rumble(joystick, dev, context, 0, 0, 0);
}
}
+
+ return (size >= 0);
}
static void
diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c
index 5f8e0f8..c37ba8f 100644
--- a/src/joystick/hidapi/SDL_hidapi_switch.c
+++ b/src/joystick/hidapi/SDL_hidapi_switch.c
@@ -846,12 +846,13 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
ctx->m_lastFullState = *packet;
}
-static void
+static SDL_bool
HIDAPI_DriverSwitch_Update(SDL_Joystick *joystick, hid_device *dev, void *context)
{
SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)context;
+ int size;
- while (ReadInput(ctx) > 0) {
+ while ((size = ReadInput(ctx)) > 0) {
switch (ctx->m_rgucReadBuffer[0]) {
case k_eSwitchInputReportIDs_SimpleControllerState:
HandleSimpleControllerState(joystick, ctx, (SwitchSimpleStatePacket_t *)&ctx->m_rgucReadBuffer[1]);
@@ -870,6 +871,7 @@ HIDAPI_DriverSwitch_Update(SDL_Joystick *joystick, hid_device *dev, void *contex
HIDAPI_DriverSwitch_Rumble(joystick, dev, context, 0, 0, 0);
}
}
+ return (size >= 0);
}
static void
diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360.c b/src/joystick/hidapi/SDL_hidapi_xbox360.c
index e7e5980..ab4f417 100644
--- a/src/joystick/hidapi/SDL_hidapi_xbox360.c
+++ b/src/joystick/hidapi/SDL_hidapi_xbox360.c
@@ -310,7 +310,7 @@ HIDAPI_DriverXbox360_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev,
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
}
-static void
+static SDL_bool
HIDAPI_DriverXbox360_Update(SDL_Joystick *joystick, hid_device *dev, void *context)
{
SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)context;
@@ -336,6 +336,8 @@ HIDAPI_DriverXbox360_Update(SDL_Joystick *joystick, hid_device *dev, void *conte
HIDAPI_DriverXbox360_Rumble(joystick, dev, context, 0, 0, 0);
}
}
+
+ return (size >= 0);
}
static void
diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c
index 959b281..16fab5a 100644
--- a/src/joystick/hidapi/SDL_hidapi_xboxone.c
+++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c
@@ -308,7 +308,7 @@ HIDAPI_DriverXboxOne_HandleModePacket(SDL_Joystick *joystick, hid_device *dev, S
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[4] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
}
-static void
+static SDL_bool
HIDAPI_DriverXboxOne_Update(SDL_Joystick *joystick, hid_device *dev, void *context)
{
SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)context;
@@ -337,6 +337,8 @@ HIDAPI_DriverXboxOne_Update(SDL_Joystick *joystick, hid_device *dev, void *conte
HIDAPI_DriverXboxOne_Rumble(joystick, dev, context, 0, 0, 0);
}
}
+
+ return (size >= 0);
}
static void
diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c
index 1e9e2bd..6d52224 100644
--- a/src/joystick/hidapi/SDL_hidapijoystick.c
+++ b/src/joystick/hidapi/SDL_hidapijoystick.c
@@ -146,7 +146,7 @@ typedef struct _DEV_BROADCAST_HDR DEV_BROADCAST_HDR;
#define DBT_DEVNODES_CHANGED 0x0007
#define DBT_CONFIGCHANGED 0x0018
#define DBT_DEVICETYPESPECIFIC 0x8005 /* type specific event */
-#define DBT_DEVINSTSTARTED 0x8008 /* device installed and started */
+#define DBT_DEVINSTSTARTED 0x8008 /* device installed and started */
#include <initguid.h>
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
@@ -605,6 +605,7 @@ HIDAPI_AddDevice(struct hid_device_info *info)
return;
}
+#define DEBUG_HIDAPI
#ifdef DEBUG_HIDAPI
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);
#endif
@@ -786,7 +787,15 @@ HIDAPI_JoystickUpdate(SDL_Joystick * joystick)
{
struct joystick_hwdata *hwdata = joystick->hwdata;
SDL_HIDAPI_DeviceDriver *driver = hwdata->driver;
- driver->Update(joystick, hwdata->dev, hwdata->context);
+ if (!driver->Update(joystick, hwdata->dev, hwdata->context)) {
+ SDL_HIDAPI_Device *device;
+ for (device = SDL_HIDAPI_devices; device; device = device->next) {
+ if (device->instance_id == joystick->instance_id) {
+ HIDAPI_DelDevice(device, SDL_TRUE);
+ break;
+ }
+ }
+ }
}
static void
diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h
index fbfd3a3..a21a69d 100644
--- a/src/joystick/hidapi/SDL_hidapijoystick_c.h
+++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h
@@ -50,7 +50,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver
const char *(*GetDeviceName)(Uint16 vendor_id, Uint16 product_id);
SDL_bool (*Init)(SDL_Joystick *joystick, hid_device *dev, Uint16 vendor_id, Uint16 product_id, void **context);
int (*Rumble)(SDL_Joystick *joystick, hid_device *dev, void *context, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
- void (*Update)(SDL_Joystick *joystick, hid_device *dev, void *context);
+ SDL_bool (*Update)(SDL_Joystick *joystick, hid_device *dev, void *context);
void (*Quit)(SDL_Joystick *joystick, hid_device *dev, void *context);
} SDL_HIDAPI_DeviceDriver;