Generalized the idea of joystick driver priority

Joystick drivers are sorted by priority in the driver list, and higher priority drivers report whether they are handling a device when lower priority drivers want to add it to their device list.

This has been handled ad-hoc with the Windows and HIDAPI drivers, but this formalizes the idea and makes sure that GameInput has the highest priority of the Windows drivers.
This commit is contained in:
Sam Lantinga
2024-02-17 15:41:18 -08:00
parent 7f33464bed
commit f35ede7281
25 changed files with 298 additions and 272 deletions

View File

@@ -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();