Make sure HID devices can be opened before making them available to the application

This prevents a number of issues where devices are enumerated but not actually able to be opened, like https://github.com/libsdl-org/SDL/issues/5781.

We currently leave the devices open, allowing us to more easily do controller feature detection, protocol negotiation, detect dropped Bluetooth connections, etc. with the expectation that the application is likely to open the controllers shortly.
This commit is contained in:
Sam Lantinga
2022-09-22 18:22:17 -07:00
parent 2857e3c748
commit aa2e2f4843
17 changed files with 811 additions and 1072 deletions

View File

@@ -89,12 +89,6 @@ HIDAPI_DriverGameCube_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *n
return SDL_FALSE;
}
static const char *
HIDAPI_DriverGameCube_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
{
return "Nintendo GameCube Controller";
}
static void
ResetAxisRange(SDL_DriverGameCube_Context *ctx, int joystick_index)
{
@@ -151,18 +145,13 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
SDL_EnableGameCubeAdaptors();
#endif
HIDAPI_SetDeviceName(device, "Nintendo GameCube Controller");
ctx = (SDL_DriverGameCube_Context *)SDL_calloc(1, sizeof(*ctx));
if (!ctx) {
SDL_OutOfMemory();
return SDL_FALSE;
}
device->dev = SDL_hid_open_path(device->path, 0);
if (!device->dev) {
SDL_free(ctx);
SDL_SetError("Couldn't open %s", device->path);
return SDL_FALSE;
}
device->context = ctx;
ctx->joysticks[0] = -1;
@@ -184,8 +173,9 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
} else {
/* This is all that's needed to initialize the device. Really! */
if (SDL_hid_write(device->dev, &initMagic, sizeof(initMagic)) != sizeof(initMagic)) {
SDL_SetError("Couldn't initialize WUP-028");
goto error;
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"HIDAPI_DriverGameCube_InitDevice(): Couldn't initialize WUP-028");
return SDL_FALSE;
}
/* Wait for the adapter to initialize */
@@ -230,22 +220,6 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
SDL_GameControllerButtonReportingHintChanged, ctx);
return SDL_TRUE;
error:
SDL_LockMutex(device->dev_lock);
{
if (device->dev) {
SDL_hid_close(device->dev);
device->dev = NULL;
}
if (device->context) {
SDL_free(device->context);
device->context = NULL;
}
}
SDL_UnlockMutex(device->dev_lock);
return SDL_FALSE;
}
static int
@@ -565,16 +539,6 @@ HIDAPI_DriverGameCube_FreeDevice(SDL_HIDAPI_Device *device)
SDL_GameControllerButtonReportingHintChanged, ctx);
SDL_DelHintCallback(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE,
SDL_JoystickGameCubeRumbleBrakeHintChanged, ctx);
SDL_LockMutex(device->dev_lock);
{
SDL_hid_close(device->dev);
device->dev = NULL;
SDL_free(device->context);
device->context = NULL;
}
SDL_UnlockMutex(device->dev_lock);
}
SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
@@ -585,7 +549,6 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
HIDAPI_DriverGameCube_UnregisterHints,
HIDAPI_DriverGameCube_IsEnabled,
HIDAPI_DriverGameCube_IsSupportedDevice,
HIDAPI_DriverGameCube_GetDeviceName,
HIDAPI_DriverGameCube_InitDevice,
HIDAPI_DriverGameCube_GetDevicePlayerIndex,
HIDAPI_DriverGameCube_SetDevicePlayerIndex,