diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index c1c1a3843..1e0ca4466 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -49,16 +49,16 @@ #endif static SDL_JoystickDriver *SDL_joystick_drivers[] = { -#ifdef SDL_JOYSTICK_HIDAPI /* Before WINDOWS_ driver, as WINDOWS wants to check if this driver is handling things */ +#ifdef SDL_JOYSTICK_HIDAPI /* Highest priority driver for supported devices */ &SDL_HIDAPI_JoystickDriver, #endif -#ifdef SDL_JOYSTICK_RAWINPUT /* Before WINDOWS_ driver, as WINDOWS wants to check if this driver is handling things */ - &SDL_RAWINPUT_JoystickDriver, -#endif -#ifdef SDL_JOYSTICK_GAMEINPUT /* Before WINDOWS_ driver, as GameInput takes priority over XInputOnGameInput for GDK platforms */ +#ifdef SDL_JOYSTICK_GAMEINPUT /* Higher priority than other Windows drivers */ &SDL_GAMEINPUT_JoystickDriver, #endif -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) /* Before WGI driver, as WGI wants to check if this driver is handling things */ +#ifdef SDL_JOYSTICK_RAWINPUT + &SDL_RAWINPUT_JoystickDriver, +#endif +#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) &SDL_WINDOWS_JoystickDriver, #endif #ifdef SDL_JOYSTICK_WGI @@ -659,6 +659,29 @@ SDL_bool SDL_JoysticksOpened(void) return opened; } +SDL_bool SDL_JoystickHandledByAnotherDriver(struct SDL_JoystickDriver *driver, Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + int i; + SDL_bool result = SDL_FALSE; + + SDL_LockJoysticks(); + { + for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) { + if (driver == SDL_joystick_drivers[i]) { + /* Higher priority drivers do not have this device */ + break; + } + if (SDL_joystick_drivers[i]->IsDevicePresent(vendor_id, product_id, version, name)) { + result = SDL_TRUE; + break; + } + } + } + SDL_UnlockJoysticks(); + + return result; +} + SDL_JoystickID *SDL_GetJoysticks(int *count) { int i, num_joysticks, device_index; diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index 3004bb148..0f00d180b 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/src/joystick/SDL_joystick_c.h @@ -54,6 +54,9 @@ extern void SDL_AssertJoysticksLocked(void) SDL_ASSERT_CAPABILITY(SDL_joystick_l /* Function to return whether there are any joysticks opened by the application */ extern SDL_bool SDL_JoysticksOpened(void); +/* Function to determine whether a device is currently detected by this driver */ +extern SDL_bool SDL_JoystickHandledByAnotherDriver(struct SDL_JoystickDriver *driver, Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name); + /* Function to standardize the name for a controller This should be freed with SDL_free() when no longer needed */ diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 739d6973d..d3d8e71de 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -158,6 +158,9 @@ typedef struct SDL_JoystickDriver /* Function to cause any queued joystick insertions to be processed */ void (*Detect)(void); + /* Function to determine whether a device is currently detected by this driver */ + SDL_bool (*IsDevicePresent)(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name); + /* Function to get the device-dependent name of a joystick */ const char *(*GetDeviceName)(int device_index); diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c index 0d2972f5e..fe085a749 100644 --- a/src/joystick/android/SDL_sysjoystick.c +++ b/src/joystick/android/SDL_sysjoystick.c @@ -321,12 +321,9 @@ int Android_AddJoystick(int device_id, const char *name, const char *desc, int v goto done; } -#ifdef SDL_JOYSTICK_HIDAPI - if (HIDAPI_IsDevicePresent(vendor_id, product_id, 0, name)) { - /* The HIDAPI driver is taking care of this device */ + if (SDL_JoystickHandledByAnotherDriver(&SDL_ANDROID_JoystickDriver, vendor_id, product_id, 0, name)) { goto done; } -#endif #ifdef DEBUG_JOYSTICK SDL_Log("Joystick: %s, descriptor %s, vendor = 0x%.4x, product = 0x%.4x, %d axes, %d hats\n", name, desc, vendor_id, product_id, naxes, nhats); @@ -482,6 +479,12 @@ static void ANDROID_JoystickDetect(void) } } +static SDL_bool ANDROID_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + /* We don't override any other drivers */ + return SDL_FALSE; +} + static SDL_joylist_item *GetJoystickByDevIndex(int device_index) { SDL_joylist_item *item = SDL_joylist; @@ -646,6 +649,7 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver = { ANDROID_JoystickInit, ANDROID_JoystickGetCount, ANDROID_JoystickDetect, + ANDROID_JoystickIsDevicePresent, ANDROID_JoystickGetDeviceName, ANDROID_JoystickGetDevicePath, ANDROID_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/apple/SDL_mfijoystick.m b/src/joystick/apple/SDL_mfijoystick.m index 9f43a6e63..c497fc606 100644 --- a/src/joystick/apple/SDL_mfijoystick.m +++ b/src/joystick/apple/SDL_mfijoystick.m @@ -879,6 +879,12 @@ static void IOS_JoystickDetect(void) { } +static SDL_bool IOS_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + /* We don't override any other drivers through this method */ + return SDL_FALSE; +} + static const char *IOS_JoystickGetDeviceName(int device_index) { SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index); @@ -2079,6 +2085,7 @@ SDL_JoystickDriver SDL_IOS_JoystickDriver = { IOS_JoystickInit, IOS_JoystickGetCount, IOS_JoystickDetect, + IOS_JoystickIsDevicePresent, IOS_JoystickGetDeviceName, IOS_JoystickGetDevicePath, IOS_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/bsd/SDL_bsdjoystick.c b/src/joystick/bsd/SDL_bsdjoystick.c index 647015c47..c5c924594 100644 --- a/src/joystick/bsd/SDL_bsdjoystick.c +++ b/src/joystick/bsd/SDL_bsdjoystick.c @@ -427,15 +427,8 @@ static int MaybeAddDevice(const char *path) name = SDL_CreateJoystickName(di.udi_vendorNo, di.udi_productNo, di.udi_vendor, di.udi_product); guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, di.udi_vendor, di.udi_product, 0, 0); -#ifdef SDL_JOYSTICK_HIDAPI - if (HIDAPI_IsDevicePresent(di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, name)) { - /* The HIDAPI driver is taking care of this device */ - SDL_free(name); - FreeHwData(hw); - return -1; - } -#endif - if (SDL_ShouldIgnoreJoystick(name, guid)) { + if (SDL_ShouldIgnoreJoystick(name, guid) || + SDL_JoystickHandledByAnotherDriver(&SDL_BSD_JoystickDriver, di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, name)) { SDL_free(name); FreeHwData(hw); return -1; @@ -516,6 +509,12 @@ static void BSD_JoystickDetect(void) { } +static SDL_bool BSD_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + /* We don't override any other drivers */ + return SDL_FALSE; +} + static SDL_joylist_item *GetJoystickByDevIndex(int device_index) { SDL_joylist_item *item = SDL_joylist; @@ -848,6 +847,7 @@ SDL_JoystickDriver SDL_BSD_JoystickDriver = { BSD_JoystickInit, BSD_JoystickGetCount, BSD_JoystickDetect, + BSD_JoystickIsDevicePresent, BSD_JoystickGetDeviceName, BSD_JoystickGetDevicePath, BSD_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/darwin/SDL_iokitjoystick.c b/src/joystick/darwin/SDL_iokitjoystick.c index 9900ecf44..99c9565fd 100644 --- a/src/joystick/darwin/SDL_iokitjoystick.c +++ b/src/joystick/darwin/SDL_iokitjoystick.c @@ -490,12 +490,9 @@ static SDL_bool GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice) SDL_free(name); } -#ifdef SDL_JOYSTICK_HIDAPI - if (HIDAPI_IsDevicePresent(vendor, product, version, pDevice->product)) { - /* The HIDAPI driver is taking care of this device */ + if (SDL_JoystickHandledByAnotherDriver(&SDL_DARWIN_JoystickDriver, vendor, product, version, pDevice->product)) { return SDL_FALSE; } -#endif pDevice->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, (Uint16)vendor, (Uint16)product, (Uint16)version, manufacturer_string, product_string, 0, 0); pDevice->steam_virtual_gamepad_slot = GetSteamVirtualGamepadSlot((Uint16)vendor, (Uint16)product, product_string); @@ -714,13 +711,19 @@ static void DARWIN_JoystickDetect(void) } } -const char *DARWIN_JoystickGetDeviceName(int device_index) +static SDL_bool DARWIN_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + /* We don't override any other drivers */ + return SDL_FALSE; +} + +static const char *DARWIN_JoystickGetDeviceName(int device_index) { recDevice *device = GetDeviceForIndex(device_index); return device ? device->product : "UNKNOWN"; } -const char *DARWIN_JoystickGetDevicePath(int device_index) +static const char *DARWIN_JoystickGetDevicePath(int device_index) { return NULL; } @@ -1063,6 +1066,7 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver = { DARWIN_JoystickInit, DARWIN_JoystickGetCount, DARWIN_JoystickDetect, + DARWIN_JoystickIsDevicePresent, DARWIN_JoystickGetDeviceName, DARWIN_JoystickGetDevicePath, DARWIN_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/dummy/SDL_sysjoystick.c b/src/joystick/dummy/SDL_sysjoystick.c index 0d6a850d2..933875750 100644 --- a/src/joystick/dummy/SDL_sysjoystick.c +++ b/src/joystick/dummy/SDL_sysjoystick.c @@ -41,6 +41,11 @@ static void DUMMY_JoystickDetect(void) { } +static SDL_bool DUMMY_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + return SDL_FALSE; +} + static const char *DUMMY_JoystickGetDeviceName(int device_index) { return NULL; @@ -128,6 +133,7 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver = { DUMMY_JoystickInit, DUMMY_JoystickGetCount, DUMMY_JoystickDetect, + DUMMY_JoystickIsDevicePresent, DUMMY_JoystickGetDeviceName, DUMMY_JoystickGetDevicePath, DUMMY_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/emscripten/SDL_sysjoystick.c b/src/joystick/emscripten/SDL_sysjoystick.c index a9be05618..e4a5603a9 100644 --- a/src/joystick/emscripten/SDL_sysjoystick.c +++ b/src/joystick/emscripten/SDL_sysjoystick.c @@ -259,6 +259,12 @@ static void EMSCRIPTEN_JoystickDetect(void) { } +static SDL_bool EMSCRIPTEN_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + /* We don't override any other drivers */ + return SDL_FALSE; +} + static const char *EMSCRIPTEN_JoystickGetDeviceName(int device_index) { return JoystickByDeviceIndex(device_index)->name; @@ -414,6 +420,7 @@ SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver = { EMSCRIPTEN_JoystickInit, EMSCRIPTEN_JoystickGetCount, EMSCRIPTEN_JoystickDetect, + EMSCRIPTEN_JoystickIsDevicePresent, EMSCRIPTEN_JoystickGetDeviceName, EMSCRIPTEN_JoystickGetDevicePath, EMSCRIPTEN_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/gdk/SDL_gameinputjoystick.c b/src/joystick/gdk/SDL_gameinputjoystick.c index 230f5c96f..c90635e66 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick.c +++ b/src/joystick/gdk/SDL_gameinputjoystick.c @@ -24,11 +24,6 @@ #if defined(SDL_JOYSTICK_GAMEINPUT) && SDL_JOYSTICK_GAMEINPUT -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - /* Public APIs: GAMEINPUT_Joystick... */ /* Private APIs: GAMEINPUT_InternalJoystick... */ @@ -38,6 +33,8 @@ typedef struct GAMEINPUT_InternalDevice { IGameInputDevice *device; const char *deviceName; /* this is a constant string literal */ + Uint16 vendor; + Uint16 product; SDL_JoystickGUID joystickGuid; /* generated by SDL. */ SDL_JoystickID instanceId; /* generated by SDL. */ int playerIndex; @@ -71,6 +68,10 @@ static int GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) GAMEINPUT_InternalDevice **devicelist = NULL; GAMEINPUT_InternalDevice *elem = NULL; const GameInputDeviceInfo *devinfo = NULL; + Uint16 bus = SDL_HARDWARE_BUS_USB; + Uint16 vendor = 0; + Uint16 product = 0; + Uint16 version = 0; char tmpbuff[4]; int idx = 0; @@ -96,33 +97,34 @@ static int GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) return SDL_OutOfMemory(); } - /* generate a device name */ - for (idx = 0; idx < APP_LOCAL_DEVICE_ID_SIZE; ++idx) { - SDL_snprintf(tmpbuff, SDL_arraysize(tmpbuff), "%02hhX", devinfo->deviceId.value[idx]); - SDL_strlcat(elem->devicePath, tmpbuff, SDL_arraysize(tmpbuff)); - } - devicelist = (GAMEINPUT_InternalDevice **)SDL_realloc(g_GameInputList.devices, sizeof(elem) * (g_GameInputList.count + 1LL)); if (!devicelist) { SDL_free(elem); return SDL_OutOfMemory(); } + /* generate a device name */ + for (idx = 0; idx < APP_LOCAL_DEVICE_ID_SIZE; ++idx) { + SDL_snprintf(tmpbuff, SDL_arraysize(tmpbuff), "%02hhX", devinfo->deviceId.value[idx]); + SDL_strlcat(elem->devicePath, tmpbuff, SDL_arraysize(tmpbuff)); + } + if (devinfo->capabilities & GameInputDeviceCapabilityWireless) { + bus = SDL_HARDWARE_BUS_BLUETOOTH; + } else { + bus = SDL_HARDWARE_BUS_USB; + } + vendor = devinfo->vendorId; + product = devinfo->productId; + version = (devinfo->major << 8) | devinfo->minor; + g_GameInputList.devices = devicelist; IGameInputDevice_AddRef(pDevice); elem->device = pDevice; elem->deviceName = "GameInput Gamepad"; + elem->vendor = vendor; + elem->product = product; elem->supportedRumbleMotors = devinfo->supportedRumbleMotors; - elem->joystickGuid = SDL_CreateJoystickGUID( - SDL_HARDWARE_BUS_BLUETOOTH, - USB_VENDOR_MICROSOFT, - USB_PRODUCT_XBOX_SERIES_X_BLE, - 1, - "GameInput", - "Gamepad", - 'g', - 0 - ); + elem->joystickGuid = SDL_CreateJoystickGUID(bus, vendor, product, version, "GameInput", "Gamepad", 'g', 0); elem->instanceId = SDL_GetNextObjectID(); g_GameInputList.devices[g_GameInputList.count] = elem; @@ -274,6 +276,20 @@ static void GAMEINPUT_JoystickDetect(void) } } +static SDL_bool GAMEINPUT_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + int idx = 0; + GAMEINPUT_InternalDevice *elem = NULL; + + for (idx = 0; idx < g_GameInputList.count; ++idx) { + elem = g_GameInputList.devices[idx]; + if (elem && vendor_id == elem->vendor && product_id == elem->product) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + static const char *GAMEINPUT_JoystickGetDeviceName(int device_index) { GAMEINPUT_InternalDevice *elem = GAMEINPUT_InternalFindByIndex(device_index); @@ -312,7 +328,7 @@ static int GAMEINPUT_JoystickGetDevicePlayerIndex(int device_index) * you're meant to assign some index to a player yourself. * * GameMaker, for example, seems to do this in the order of plugging in. - * + * * Sorry for the trouble! */ GAMEINPUT_InternalDevice *elem = GAMEINPUT_InternalFindByIndex(device_index); @@ -566,6 +582,7 @@ SDL_JoystickDriver SDL_GAMEINPUT_JoystickDriver = GAMEINPUT_JoystickInit, GAMEINPUT_JoystickGetCount, GAMEINPUT_JoystickDetect, + GAMEINPUT_JoystickIsDevicePresent, GAMEINPUT_JoystickGetDeviceName, GAMEINPUT_JoystickGetDevicePath, GAMEINPUT_JoystickGetDeviceSteamVirtualGamepadSlot, @@ -586,9 +603,4 @@ SDL_JoystickDriver SDL_GAMEINPUT_JoystickDriver = }; -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif - #endif /* defined(SDL_JOYSTICK_GAMEINPUT) && SDL_JOYSTICK_GAMEINPUT */ diff --git a/src/joystick/haiku/SDL_haikujoystick.cc b/src/joystick/haiku/SDL_haikujoystick.cc index 77961036e..db40918c0 100644 --- a/src/joystick/haiku/SDL_haikujoystick.cc +++ b/src/joystick/haiku/SDL_haikujoystick.cc @@ -91,6 +91,12 @@ extern "C" { } + static SDL_bool HAIKU_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) + { + /* We don't override any other drivers */ + return SDL_FALSE; + } + static const char *HAIKU_JoystickGetDeviceName(int device_index) { return SDL_joyname[device_index]; @@ -293,6 +299,7 @@ extern "C" HAIKU_JoystickInit, HAIKU_JoystickGetCount, HAIKU_JoystickDetect, + HAIKU_JoystickIsDevicePresent, HAIKU_JoystickGetDeviceName, HAIKU_JoystickGetDevicePath, HAIKU_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index e0a9adb59..0fadbe4aa 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -1699,6 +1699,7 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver = { HIDAPI_JoystickInit, HIDAPI_JoystickGetCount, HIDAPI_JoystickDetect, + HIDAPI_IsDevicePresent, HIDAPI_JoystickGetDeviceName, HIDAPI_JoystickGetDevicePath, HIDAPI_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c index 0c8573a1a..17935745b 100644 --- a/src/joystick/linux/SDL_sysjoystick.c +++ b/src/joystick/linux/SDL_sysjoystick.c @@ -310,14 +310,11 @@ static int IsJoystick(const char *path, int fd, char **name_return, Uint16 *vend return 0; } -#ifdef SDL_JOYSTICK_HIDAPI if (!IsVirtualJoystick(inpid.vendor, inpid.product, inpid.version, name) && - HIDAPI_IsDevicePresent(inpid.vendor, inpid.product, inpid.version, name)) { - /* The HIDAPI driver is taking care of this device */ + SDL_JoystickHandledByAnotherDriver(&SDL_LINUX_JoystickDriver, inpid.vendor, inpid.product, inpid.version, name)) { SDL_free(name); return 0; } -#endif FixupDeviceInfoForMapping(fd, &inpid); @@ -987,6 +984,12 @@ static void LINUX_JoystickDetect(void) SDL_UpdateSteamControllers(); } +static SDL_bool LINUX_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + /* We don't override any other drivers */ + return SDL_FALSE; +} + static int LINUX_JoystickInit(void) { const char *devices = SDL_GetHint(SDL_HINT_JOYSTICK_DEVICE); @@ -2686,6 +2689,7 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver = { LINUX_JoystickInit, LINUX_JoystickGetCount, LINUX_JoystickDetect, + LINUX_JoystickIsDevicePresent, LINUX_JoystickGetDeviceName, LINUX_JoystickGetDevicePath, LINUX_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/n3ds/SDL_sysjoystick.c b/src/joystick/n3ds/SDL_sysjoystick.c index 863a1c174..271b2627f 100644 --- a/src/joystick/n3ds/SDL_sysjoystick.c +++ b/src/joystick/n3ds/SDL_sysjoystick.c @@ -226,6 +226,12 @@ static void N3DS_JoystickDetect(void) { } +static SDL_bool N3DS_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + /* We don't override any other drivers */ + return SDL_FALSE; +} + static const char *N3DS_JoystickGetDevicePath(int device_index) { return NULL; @@ -266,26 +272,27 @@ static int N3DS_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int } SDL_JoystickDriver SDL_N3DS_JoystickDriver = { - .Init = N3DS_JoystickInit, - .GetCount = N3DS_JoystickGetCount, - .Detect = N3DS_JoystickDetect, - .GetDeviceName = N3DS_JoystickGetDeviceName, - .GetDevicePath = N3DS_JoystickGetDevicePath, - .GetDeviceSteamVirtualGamepadSlot = N3DS_JoystickGetDeviceSteamVirtualGamepadSlot, - .GetDevicePlayerIndex = N3DS_JoystickGetDevicePlayerIndex, - .SetDevicePlayerIndex = N3DS_JoystickSetDevicePlayerIndex, - .GetDeviceGUID = N3DS_JoystickGetDeviceGUID, - .GetDeviceInstanceID = N3DS_JoystickGetDeviceInstanceID, - .Open = N3DS_JoystickOpen, - .Rumble = N3DS_JoystickRumble, - .RumbleTriggers = N3DS_JoystickRumbleTriggers, - .SetLED = N3DS_JoystickSetLED, - .SendEffect = N3DS_JoystickSendEffect, - .SetSensorsEnabled = N3DS_JoystickSetSensorsEnabled, - .Update = N3DS_JoystickUpdate, - .Close = N3DS_JoystickClose, - .Quit = N3DS_JoystickQuit, - .GetGamepadMapping = N3DS_JoystickGetGamepadMapping + N3DS_JoystickInit, + N3DS_JoystickGetCount, + N3DS_JoystickDetect, + N3DS_JoystickIsDevicePresent, + N3DS_JoystickGetDeviceName, + N3DS_JoystickGetDevicePath, + N3DS_JoystickGetDeviceSteamVirtualGamepadSlot, + N3DS_JoystickGetDevicePlayerIndex, + N3DS_JoystickSetDevicePlayerIndex, + N3DS_JoystickGetDeviceGUID, + N3DS_JoystickGetDeviceInstanceID, + N3DS_JoystickOpen, + N3DS_JoystickRumble, + N3DS_JoystickRumbleTriggers, + N3DS_JoystickSetLED, + N3DS_JoystickSendEffect, + N3DS_JoystickSetSensorsEnabled, + N3DS_JoystickUpdate, + N3DS_JoystickClose, + N3DS_JoystickQuit, + N3DS_JoystickGetGamepadMapping }; #endif /* SDL_JOYSTICK_N3DS */ diff --git a/src/joystick/ps2/SDL_sysjoystick.c b/src/joystick/ps2/SDL_sysjoystick.c index ad264584e..cf54852f1 100644 --- a/src/joystick/ps2/SDL_sysjoystick.c +++ b/src/joystick/ps2/SDL_sysjoystick.c @@ -140,6 +140,12 @@ static void PS2_JoystickDetect() { } +static SDL_bool PS2_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + /* We don't override any other drivers */ + return SDL_FALSE; +} + /* Function to get the device-dependent name of a joystick */ static const char *PS2_JoystickGetDeviceName(int index) { @@ -341,6 +347,7 @@ SDL_JoystickDriver SDL_PS2_JoystickDriver = { PS2_JoystickInit, PS2_JoystickGetCount, PS2_JoystickDetect, + PS2_JoystickIsDevicePresent, PS2_JoystickGetDeviceName, PS2_JoystickGetDevicePath, PS2_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/psp/SDL_sysjoystick.c b/src/joystick/psp/SDL_sysjoystick.c index 2ae252865..31cbb8a71 100644 --- a/src/joystick/psp/SDL_sysjoystick.c +++ b/src/joystick/psp/SDL_sysjoystick.c @@ -105,6 +105,12 @@ static void PSP_JoystickDetect(void) { } +static SDL_bool PSP_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + /* We don't override any other drivers */ + return SDL_FALSE; +} + /* Function to get the device-dependent name of a joystick */ static const char *PSP_JoystickGetDeviceName(int device_index) { @@ -251,6 +257,7 @@ SDL_JoystickDriver SDL_PSP_JoystickDriver = { PSP_JoystickInit, PSP_JoystickGetCount, PSP_JoystickDetect, + PSP_JoystickIsDevicePresent, PSP_JoystickGetDeviceName, PSP_JoystickGetDevicePath, PSP_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/virtual/SDL_virtualjoystick.c b/src/joystick/virtual/SDL_virtualjoystick.c index 526ec24cc..6c014673f 100644 --- a/src/joystick/virtual/SDL_virtualjoystick.c +++ b/src/joystick/virtual/SDL_virtualjoystick.c @@ -353,6 +353,12 @@ static void VIRTUAL_JoystickDetect(void) { } +static SDL_bool VIRTUAL_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + /* We don't override any other drivers... or do we? */ + return SDL_FALSE; +} + static const char *VIRTUAL_JoystickGetDeviceName(int device_index) { joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index); @@ -749,6 +755,7 @@ SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver = { VIRTUAL_JoystickInit, VIRTUAL_JoystickGetCount, VIRTUAL_JoystickDetect, + VIRTUAL_JoystickIsDevicePresent, VIRTUAL_JoystickGetDeviceName, VIRTUAL_JoystickGetDevicePath, VIRTUAL_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/vita/SDL_sysjoystick.c b/src/joystick/vita/SDL_sysjoystick.c index 35ec7ebdd..58fef1788 100644 --- a/src/joystick/vita/SDL_sysjoystick.c +++ b/src/joystick/vita/SDL_sysjoystick.c @@ -101,7 +101,7 @@ static int calc_bezier_y(float t) * Joystick 0 should be the system default joystick. * It should return number of joysticks, or -1 on an unrecoverable fatal error. */ -int VITA_JoystickInit(void) +static int VITA_JoystickInit(void) { int i; SceCtrlPortInfo myPortInfo; @@ -139,22 +139,28 @@ int VITA_JoystickInit(void) return SDL_numjoysticks; } -int VITA_JoystickGetCount() +static int VITA_JoystickGetCount() { return SDL_numjoysticks; } -void VITA_JoystickDetect() +static void VITA_JoystickDetect() { } +static SDL_bool VITA_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + /* We don't override any other drivers */ + return SDL_FALSE; +} + /* Function to perform the mapping from device index to the instance id for this index */ -SDL_JoystickID VITA_JoystickGetDeviceInstanceID(int device_index) +static SDL_JoystickID VITA_JoystickGetDeviceInstanceID(int device_index) { return device_index + 1; } -const char *VITA_JoystickGetDeviceName(int index) +static const char *VITA_JoystickGetDeviceName(int index) { if (index == 0) { return "PSVita Controller"; @@ -176,7 +182,7 @@ const char *VITA_JoystickGetDeviceName(int index) return NULL; } -const char *VITA_JoystickGetDevicePath(int index) +static const char *VITA_JoystickGetDevicePath(int index) { return NULL; } @@ -200,7 +206,7 @@ static void VITA_JoystickSetDevicePlayerIndex(int device_index, int player_index This should fill the nbuttons and naxes fields of the joystick structure. It returns 0, or -1 if there is an error. */ -int VITA_JoystickOpen(SDL_Joystick *joystick, int device_index) +static int VITA_JoystickOpen(SDL_Joystick *joystick, int device_index) { joystick->nbuttons = SDL_arraysize(ext_button_map); joystick->naxes = 6; @@ -309,16 +315,16 @@ static void VITA_JoystickUpdate(SDL_Joystick *joystick) } /* Function to close a joystick after use */ -void VITA_JoystickClose(SDL_Joystick *joystick) +static void VITA_JoystickClose(SDL_Joystick *joystick) { } /* Function to perform any system-specific joystick related cleanup */ -void VITA_JoystickQuit(void) +static void VITA_JoystickQuit(void) { } -SDL_JoystickGUID VITA_JoystickGetDeviceGUID(int device_index) +static SDL_JoystickGUID VITA_JoystickGetDeviceGUID(int device_index) { /* the GUID is just the name for now */ const char *name = VITA_JoystickGetDeviceName(device_index); @@ -378,6 +384,7 @@ SDL_JoystickDriver SDL_VITA_JoystickDriver = { VITA_JoystickInit, VITA_JoystickGetCount, VITA_JoystickDetect, + VITA_JoystickIsDevicePresent, VITA_JoystickGetDeviceName, VITA_JoystickGetDevicePath, VITA_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c index 150f59be2..08d9fdebc 100644 --- a/src/joystick/windows/SDL_dinputjoystick.c +++ b/src/joystick/windows/SDL_dinputjoystick.c @@ -516,13 +516,7 @@ static BOOL CALLBACK EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInsta CHECK(!SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)); -#ifdef SDL_JOYSTICK_HIDAPI - CHECK(!HIDAPI_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)); -#endif - -#ifdef SDL_JOYSTICK_RAWINPUT - CHECK(!RAWINPUT_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)); -#endif + CHECK(!SDL_JoystickHandledByAnotherDriver(&SDL_WINDOWS_JoystickDriver, vendor, product, version, pNewJoystick->joystickname)); WINDOWS_AddJoystickDevice(pNewJoystick); pNewJoystick = NULL; diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c index 671e3a376..e59df1d97 100644 --- a/src/joystick/windows/SDL_rawinputjoystick.c +++ b/src/joystick/windows/SDL_rawinputjoystick.c @@ -886,10 +886,7 @@ static void RAWINPUT_AddDevice(HANDLE hDevice) CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, dev_name, &size) != (UINT)-1); /* Only take XInput-capable devices */ CHECK(SDL_strstr(dev_name, "IG_") != NULL); -#ifdef SDL_JOYSTICK_HIDAPI - /* Don't take devices handled by HIDAPI */ - CHECK(!HIDAPI_IsDevicePresent((Uint16)rdi.hid.dwVendorId, (Uint16)rdi.hid.dwProductId, (Uint16)rdi.hid.dwVersionNumber, "")); -#endif + CHECK(!SDL_JoystickHandledByAnotherDriver(&SDL_RAWINPUT_JoystickDriver, (Uint16)rdi.hid.dwVendorId, (Uint16)rdi.hid.dwProductId, (Uint16)rdi.hid.dwVersionNumber, "")); device = (SDL_RAWINPUT_Device *)SDL_calloc(1, sizeof(SDL_RAWINPUT_Device)); CHECK(device); device->hDevice = hDevice; @@ -1062,42 +1059,6 @@ SDL_bool RAWINPUT_IsEnabled() return SDL_RAWINPUT_inited && !SDL_RAWINPUT_remote_desktop; } -SDL_bool RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) -{ - SDL_RAWINPUT_Device *device; - - /* If we're being asked about a device, that means another API just detected one, so rescan */ -#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT - xinput_device_change = SDL_TRUE; -#endif - - device = SDL_RAWINPUT_devices; - while (device) { - if (vendor_id == device->vendor_id && product_id == device->product_id) { - return SDL_TRUE; - } - - /* The Xbox 360 wireless controller shows up as product 0 in WGI. - Try to match it to a Raw Input device via name or known product ID. */ - if (vendor_id == device->vendor_id && product_id == 0 && - ((name && SDL_strstr(device->name, name) != NULL) || - (device->vendor_id == USB_VENDOR_MICROSOFT && - device->product_id == USB_PRODUCT_XBOX360_XUSB_CONTROLLER))) { - return SDL_TRUE; - } - - /* The Xbox One controller shows up as a hardcoded raw input VID/PID */ - if (name && SDL_strcmp(name, "Xbox One Game Controller") == 0 && - device->vendor_id == USB_VENDOR_MICROSOFT && - device->product_id == USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER) { - return SDL_TRUE; - } - - device = device->next; - } - return SDL_FALSE; -} - static void RAWINPUT_PostUpdate(void) { #ifdef SDL_JOYSTICK_RAWINPUT_MATCHING @@ -1181,6 +1142,42 @@ static void RAWINPUT_JoystickDetect(void) RAWINPUT_PostUpdate(); } +static SDL_bool RAWINPUT_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + SDL_RAWINPUT_Device *device; + + /* If we're being asked about a device, that means another API just detected one, so rescan */ +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + xinput_device_change = SDL_TRUE; +#endif + + device = SDL_RAWINPUT_devices; + while (device) { + if (vendor_id == device->vendor_id && product_id == device->product_id) { + return SDL_TRUE; + } + + /* The Xbox 360 wireless controller shows up as product 0 in WGI. + Try to match it to a Raw Input device via name or known product ID. */ + if (vendor_id == device->vendor_id && product_id == 0 && + ((name && SDL_strstr(device->name, name) != NULL) || + (device->vendor_id == USB_VENDOR_MICROSOFT && + device->product_id == USB_PRODUCT_XBOX360_XUSB_CONTROLLER))) { + return SDL_TRUE; + } + + /* The Xbox One controller shows up as a hardcoded raw input VID/PID */ + if (name && SDL_strcmp(name, "Xbox One Game Controller") == 0 && + device->vendor_id == USB_VENDOR_MICROSOFT && + device->product_id == USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER) { + return SDL_TRUE; + } + + device = device->next; + } + return SDL_FALSE; +} + static SDL_RAWINPUT_Device *RAWINPUT_GetDeviceByIndex(int device_index) { SDL_RAWINPUT_Device *device = SDL_RAWINPUT_devices; @@ -2206,6 +2203,7 @@ SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver = { RAWINPUT_JoystickInit, RAWINPUT_JoystickGetCount, RAWINPUT_JoystickDetect, + RAWINPUT_JoystickIsDevicePresent, RAWINPUT_JoystickGetDeviceName, RAWINPUT_JoystickGetDevicePath, RAWINPUT_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/windows/SDL_rawinputjoystick_c.h b/src/joystick/windows/SDL_rawinputjoystick_c.h index d4f9e79fb..510bc8ae3 100644 --- a/src/joystick/windows/SDL_rawinputjoystick_c.h +++ b/src/joystick/windows/SDL_rawinputjoystick_c.h @@ -24,9 +24,6 @@ /* Return true if the RawInput driver is enabled */ extern SDL_bool RAWINPUT_IsEnabled(); -/* Return true if a RawInput device is present and supported as a joystick */ -extern SDL_bool RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name); - /* Registers for input events */ extern int RAWINPUT_RegisterNotifications(HWND hWnd); extern int RAWINPUT_UnregisterNotifications(); diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c index 61e8b2c41..af788cd92 100644 --- a/src/joystick/windows/SDL_windows_gaming_input.c +++ b/src/joystick/windows/SDL_windows_gaming_input.c @@ -106,114 +106,8 @@ DEFINE_GUID(IID___x_ABI_CWindows_CGaming_CInput_CIRawGameController2, 0x43c0c035 DEFINE_GUID(IID___x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics, 0xeb8d0792, 0xe95a, 0x4b19, 0xaf, 0xc7, 0x0a, 0x59, 0xf8, 0xbf, 0x75, 0x9e); extern SDL_bool SDL_XINPUT_Enabled(void); -extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version); -static SDL_bool SDL_IsXInputDevice(Uint16 vendor, Uint16 product) -{ -#if defined(SDL_JOYSTICK_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT) - PRAWINPUTDEVICELIST raw_devices = NULL; - UINT i, raw_device_count = 0; - LONG vidpid = MAKELONG(vendor, product); - - /* XInput and RawInput backends will pick up XInput-compatible devices */ - if (!SDL_XINPUT_Enabled() -#ifdef SDL_JOYSTICK_RAWINPUT - && !RAWINPUT_IsEnabled() -#endif - ) { - return SDL_FALSE; - } - - /* Go through RAWINPUT (WinXP and later) to find HID devices. */ - if ((GetRawInputDeviceList(NULL, &raw_device_count, sizeof(RAWINPUTDEVICELIST)) == -1) || (!raw_device_count)) { - return SDL_FALSE; /* oh well. */ - } - - raw_devices = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * raw_device_count); - if (!raw_devices) { - return SDL_FALSE; - } - - raw_device_count = GetRawInputDeviceList(raw_devices, &raw_device_count, sizeof(RAWINPUTDEVICELIST)); - if (raw_device_count == (UINT)-1) { - SDL_free(raw_devices); - raw_devices = NULL; - return SDL_FALSE; /* oh well. */ - } - - for (i = 0; i < raw_device_count; i++) { - RID_DEVICE_INFO rdi; - char devName[MAX_PATH] = { 0 }; - UINT rdiSize = sizeof(rdi); - UINT nameSize = SDL_arraysize(devName); - DEVINST devNode; - char devVidPidString[32]; - int j; - - rdi.cbSize = sizeof(rdi); - - if ((raw_devices[i].dwType != RIM_TYPEHID) || - (GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) == ((UINT)-1)) || - (GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) == ((UINT)-1)) || - (SDL_strstr(devName, "IG_") == NULL)) { - /* Skip non-XInput devices */ - continue; - } - - /* First check for a simple VID/PID match. This will work for Xbox 360 controllers. */ - if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == vidpid) { - SDL_free(raw_devices); - return SDL_TRUE; - } - - /* For Xbox One controllers, Microsoft doesn't propagate the VID/PID down to the HID stack. - * We'll have to walk the device tree upwards searching for a match for our VID/PID. */ - - /* Make sure the device interface string is something we know how to parse */ - /* Example: \\?\HID#VID_045E&PID_02FF&IG_00#9&2c203035&2&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} */ - if ((SDL_strstr(devName, "\\\\?\\") != devName) || (SDL_strstr(devName, "#{") == NULL)) { - continue; - } - - /* Unescape the backslashes in the string and terminate before the GUID portion */ - for (j = 0; devName[j] != '\0'; j++) { - if (devName[j] == '#') { - if (devName[j + 1] == '{') { - devName[j] = '\0'; - break; - } else { - devName[j] = '\\'; - } - } - } - - /* We'll be left with a string like this: \\?\HID\VID_045E&PID_02FF&IG_00\9&2c203035&2&0000 - * Simply skip the \\?\ prefix and we'll have a properly formed device instance ID */ - if (CM_Locate_DevNodeA(&devNode, &devName[4], CM_LOCATE_DEVNODE_NORMAL) != CR_SUCCESS) { - continue; - } - - (void)SDL_snprintf(devVidPidString, sizeof(devVidPidString), "VID_%04X&PID_%04X", vendor, product); - - while (CM_Get_Parent(&devNode, devNode, 0) == CR_SUCCESS) { - char deviceId[MAX_DEVICE_ID_LEN]; - - if ((CM_Get_Device_IDA(devNode, deviceId, SDL_arraysize(deviceId), 0) == CR_SUCCESS) && - (SDL_strstr(deviceId, devVidPidString) != NULL)) { - /* The VID/PID matched a parent device */ - SDL_free(raw_devices); - return SDL_TRUE; - } - } - } - - SDL_free(raw_devices); -#endif /* SDL_JOYSTICK_XINPUT || SDL_JOYSTICK_RAWINPUT */ - - return SDL_FALSE; -} - static void WGI_LoadRawGameControllerStatics() { HRESULT hr; @@ -448,23 +342,7 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde name = SDL_strdup(""); } -#ifdef SDL_JOYSTICK_HIDAPI - if (!ignore_joystick && HIDAPI_IsDevicePresent(vendor, product, version, name)) { - ignore_joystick = SDL_TRUE; - } -#endif - -#ifdef SDL_JOYSTICK_RAWINPUT - if (!ignore_joystick && RAWINPUT_IsDevicePresent(vendor, product, version, name)) { - ignore_joystick = SDL_TRUE; - } -#endif - - if (!ignore_joystick && SDL_DINPUT_JoystickPresent(vendor, product, version)) { - ignore_joystick = SDL_TRUE; - } - - if (!ignore_joystick && SDL_IsXInputDevice(vendor, product)) { + if (!ignore_joystick && SDL_JoystickHandledByAnotherDriver(&SDL_WGI_JoystickDriver, vendor, product, version, name)) { ignore_joystick = SDL_TRUE; } @@ -684,6 +562,12 @@ static void WGI_JoystickDetect(void) { } +static SDL_bool WGI_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + /* We don't override any other drivers */ + return SDL_FALSE; +} + static const char *WGI_JoystickGetDeviceName(int device_index) { return wgi.controllers[device_index].name; @@ -1009,6 +893,7 @@ SDL_JoystickDriver SDL_WGI_JoystickDriver = { WGI_JoystickInit, WGI_JoystickGetCount, WGI_JoystickDetect, + WGI_JoystickIsDevicePresent, WGI_JoystickGetDeviceName, WGI_JoystickGetDevicePath, WGI_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/windows/SDL_windowsjoystick.c b/src/joystick/windows/SDL_windowsjoystick.c index 0aa33797a..415f1d99b 100644 --- a/src/joystick/windows/SDL_windowsjoystick.c +++ b/src/joystick/windows/SDL_windowsjoystick.c @@ -579,6 +579,17 @@ void WINDOWS_JoystickDetect(void) } } +static SDL_bool WINDOWS_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + if (SDL_DINPUT_JoystickPresent(vendor_id, product_id, version)) { + return SDL_TRUE; + } + if (SDL_XINPUT_JoystickPresent(vendor_id, product_id, version)) { + return SDL_TRUE; + } + return SDL_FALSE; +} + static const char *WINDOWS_JoystickGetDeviceName(int device_index) { JoyStick_DeviceData *device = SYS_Joystick; @@ -788,6 +799,7 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver = { WINDOWS_JoystickInit, WINDOWS_JoystickGetCount, WINDOWS_JoystickDetect, + WINDOWS_JoystickIsDevicePresent, WINDOWS_JoystickGetDeviceName, WINDOWS_JoystickGetDevicePath, WINDOWS_JoystickGetDeviceSteamVirtualGamepadSlot, diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c index d16c7803d..09739eb7c 100644 --- a/src/joystick/windows/SDL_xinputjoystick.c +++ b/src/joystick/windows/SDL_xinputjoystick.c @@ -97,6 +97,13 @@ static SDL_bool GetXInputDeviceInfo(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Ui SDL_XINPUT_CAPABILITIES_EX capabilities; if (!XINPUTGETCAPABILITIESEX || XINPUTGETCAPABILITIESEX(1, userid, 0, &capabilities) != ERROR_SUCCESS) { + /* Use a generic VID/PID representing an XInput controller */ + if (pVID) { + *pVID = USB_VENDOR_MICROSOFT; + } + if (pPID) { + *pPID = USB_PRODUCT_XBOX360_XUSB_CONTROLLER; + } return SDL_FALSE; } @@ -199,22 +206,10 @@ static void AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pC return; } -#ifdef SDL_JOYSTICK_HIDAPI - /* Since we're guessing about the VID/PID, use a hard-coded VID/PID to represent XInput */ - if (HIDAPI_IsDevicePresent(USB_VENDOR_MICROSOFT, USB_PRODUCT_XBOX360_XUSB_CONTROLLER, version, pNewJoystick->joystickname)) { - /* The HIDAPI driver is taking care of this device */ + if (SDL_JoystickHandledByAnotherDriver(&SDL_WINDOWS_JoystickDriver, vendor, product, version, pNewJoystick->joystickname)) { SDL_free(pNewJoystick); return; } -#endif - -#ifdef SDL_JOYSTICK_RAWINPUT - if (RAWINPUT_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)) { - /* The RAWINPUT driver is taking care of this device */ - SDL_free(pNewJoystick); - return; - } -#endif WINDOWS_AddJoystickDevice(pNewJoystick); } @@ -237,6 +232,29 @@ void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext) } } +SDL_bool SDL_XINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version) +{ + int iuserid; + + if (!s_bXInputEnabled) { + return SDL_FALSE; + } + + /* iterate in reverse, so these are in the final list in ascending numeric order. */ + for (iuserid = 0; iuserid < XUSER_MAX_COUNT; ++iuserid) { + const Uint8 userid = (Uint8)iuserid; + Uint16 slot_vendor; + Uint16 slot_product; + Uint16 slot_version; + if (GetXInputDeviceInfo(userid, &slot_vendor, &slot_product, &slot_version)) { + if (vendor == slot_vendor && product == slot_product && version == slot_version) { + return SDL_TRUE; + } + } + } + return SDL_FALSE; +} + int SDL_XINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice) { const Uint8 userId = joystickdevice->XInputUserId; @@ -420,6 +438,11 @@ void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext) { } +SDL_bool SDL_XINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version) +{ + return SDL_FALSE; +} + int SDL_XINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice) { return SDL_Unsupported(); diff --git a/src/joystick/windows/SDL_xinputjoystick_c.h b/src/joystick/windows/SDL_xinputjoystick_c.h index 8973f8b7c..b244ced3b 100644 --- a/src/joystick/windows/SDL_xinputjoystick_c.h +++ b/src/joystick/windows/SDL_xinputjoystick_c.h @@ -30,6 +30,7 @@ extern "C" { extern SDL_bool SDL_XINPUT_Enabled(void); extern int SDL_XINPUT_JoystickInit(void); extern void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext); +extern SDL_bool SDL_XINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version); extern int SDL_XINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice); extern int SDL_XINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); extern void SDL_XINPUT_JoystickUpdate(SDL_Joystick *joystick);