Skip to content

Commit

Permalink
Don't use the WGI driver if another driver is already handling the jo…
Browse files Browse the repository at this point in the history
…ystick
  • Loading branch information
slouken committed Apr 23, 2020
1 parent 6ca7f51 commit 4727f79
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 7 deletions.
47 changes: 47 additions & 0 deletions src/joystick/windows/SDL_dinputjoystick.c
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down
1 change: 1 addition & 0 deletions src/joystick/windows/SDL_dinputjoystick_c.h
Expand Up @@ -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);
Expand Down
28 changes: 21 additions & 7 deletions src/joystick/windows/SDL_windows_gaming_input.c
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit 4727f79

Please sign in to comment.