Skip to content

Commit

Permalink
Remove the HIDAPI device if we get a read error from it
Browse files Browse the repository at this point in the history
This fixes detecting PS4 controller disconnect on Mac OS X, where there isn't any device removed notification
  • Loading branch information
slouken committed Aug 16, 2018
1 parent dfbd7f6 commit 5190201
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 8 deletions.
4 changes: 3 additions & 1 deletion src/joystick/hidapi/SDL_hidapi_ps4.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions src/joystick/hidapi/SDL_hidapi_switch.c
Expand Up @@ -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]);
Expand All @@ -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
Expand Down
4 changes: 3 additions & 1 deletion src/joystick/hidapi/SDL_hidapi_xbox360.c
Expand Up @@ -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;
Expand All @@ -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
Expand Down
4 changes: 3 additions & 1 deletion src/joystick/hidapi/SDL_hidapi_xboxone.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
13 changes: 11 additions & 2 deletions src/joystick/hidapi/SDL_hidapijoystick.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/joystick/hidapi/SDL_hidapijoystick_c.h
Expand Up @@ -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;
Expand Down

0 comments on commit 5190201

Please sign in to comment.