diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c index 13e549e08..cbb5bd945 100644 --- a/src/joystick/windows/SDL_dinputjoystick.c +++ b/src/joystick/windows/SDL_dinputjoystick.c @@ -698,6 +698,47 @@ SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext) SDL_RawDevListCount = 0; } +typedef struct +{ + Uint16 vendor; + Uint16 product; + Uint16 version; + SDL_bool present; +} EnumJoystickPresentData; + +static BOOL CALLBACK +EnumJoystickPresentCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) +{ + EnumJoystickPresentData *data = (EnumJoystickPresentData *)pContext; + Uint16 vendor = 0; + Uint16 product = 0; + Uint16 version = 0; + + if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) { + vendor = (Uint16)LOWORD(pdidInstance->guidProduct.Data1); + product = (Uint16)HIWORD(pdidInstance->guidProduct.Data1); + if (data->vendor == vendor && data->product == product && data->version == version) { + data->present = SDL_TRUE; + return DIENUM_STOP; + } + } + return DIENUM_CONTINUE; +} + +SDL_bool +SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version) +{ + EnumJoystickPresentData data; + + data.vendor = vendor; + data.product = product; + data.version = version; + data.present = SDL_FALSE; + IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoystickPresentCallback, &data, DIEDFL_ATTACHEDONLY); + + return data.present; +} + static BOOL CALLBACK EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) { @@ -1261,6 +1302,12 @@ SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext) { } +SDL_bool +SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version) +{ + return SDL_FALSE; +} + int SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice) { diff --git a/src/joystick/windows/SDL_dinputjoystick_c.h b/src/joystick/windows/SDL_dinputjoystick_c.h index f647e7a80..2e7e7db70 100644 --- a/src/joystick/windows/SDL_dinputjoystick_c.h +++ b/src/joystick/windows/SDL_dinputjoystick_c.h @@ -22,6 +22,7 @@ extern int SDL_DINPUT_JoystickInit(void); extern void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext); +extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version); extern int SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice); extern int SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); extern void SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick); diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c index df33ead2d..cbfce0efe 100644 --- a/src/joystick/windows/SDL_windows_gaming_input.c +++ b/src/joystick/windows/SDL_windows_gaming_input.c @@ -25,6 +25,7 @@ #include "SDL_endian.h" #include "SDL_events.h" #include "../SDL_sysjoystick.h" +#include "../hidapi/SDL_hidapijoystick_c.h" #include "../../core/windows/SDL_windows.h" #define COBJMACROS @@ -173,16 +174,11 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde Uint16 *guid16 = (Uint16 *)guid.data; __x_ABI_CWindows_CGaming_CInput_CIRawGameController2 *controller2 = NULL; __x_ABI_CWindows_CGaming_CInput_CIGameController *gamecontroller = NULL; + SDL_bool ignore_joystick = SDL_FALSE; __x_ABI_CWindows_CGaming_CInput_CIRawGameController_get_HardwareVendorId(controller, &vendor); __x_ABI_CWindows_CGaming_CInput_CIRawGameController_get_HardwareProductId(controller, &product); - if (SDL_IsXInputDevice(vendor, product)) { - /* This will be handled by the XInput driver */ - __x_ABI_CWindows_CGaming_CInput_CIRawGameController_Release(controller); - return S_OK; - } - hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IRawGameController2, (void **)&controller2); if (SUCCEEDED(hr)) { HSTRING hString; @@ -243,7 +239,25 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde guid.data[14] = 'w'; guid.data[15] = (Uint8)type; - if (SDL_ShouldIgnoreJoystick(name, guid)) { +#ifdef SDL_JOYSTICK_HIDAPI + if (!ignore_joystick && HIDAPI_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)) { + ignore_joystick = SDL_TRUE; + } + + if (!ignore_joystick && SDL_ShouldIgnoreJoystick(name, guid)) { + ignore_joystick = SDL_TRUE; + } + + if (ignore_joystick) { SDL_free(name); } else { /* New device, add it */