mirror of https://github.com/encounter/SDL.git
Use WGI instead of XInput for Windows 10 UWP apps
Fixes https://github.com/libsdl-org/SDL/issues/5017
This commit is contained in:
parent
e04a0221e3
commit
110e4e1334
|
@ -253,6 +253,7 @@
|
||||||
<ClCompile Include="..\src\joystick\virtual\SDL_virtualjoystick.c" />
|
<ClCompile Include="..\src\joystick\virtual\SDL_virtualjoystick.c" />
|
||||||
<ClCompile Include="..\src\joystick\windows\SDL_dinputjoystick.c" />
|
<ClCompile Include="..\src\joystick\windows\SDL_dinputjoystick.c" />
|
||||||
<ClCompile Include="..\src\joystick\windows\SDL_windowsjoystick.c" />
|
<ClCompile Include="..\src\joystick\windows\SDL_windowsjoystick.c" />
|
||||||
|
<ClCompile Include="..\src\joystick\windows\SDL_windows_gaming_input.c" />
|
||||||
<ClCompile Include="..\src\joystick\windows\SDL_xinputjoystick.c" />
|
<ClCompile Include="..\src\joystick\windows\SDL_xinputjoystick.c" />
|
||||||
<ClCompile Include="..\src\loadso\windows\SDL_sysloadso.c" />
|
<ClCompile Include="..\src\loadso\windows\SDL_sysloadso.c" />
|
||||||
<ClCompile Include="..\src\locale\SDL_locale.c" />
|
<ClCompile Include="..\src\locale\SDL_locale.c" />
|
||||||
|
|
|
@ -814,4 +814,9 @@
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\src\joystick\windows\SDL_windows_gaming_input.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -201,8 +201,13 @@ typedef unsigned int uintptr_t;
|
||||||
#define SDL_HAPTIC_DISABLED 1
|
#define SDL_HAPTIC_DISABLED 1
|
||||||
#else
|
#else
|
||||||
#define SDL_JOYSTICK_VIRTUAL 1
|
#define SDL_JOYSTICK_VIRTUAL 1
|
||||||
|
#if (NTDDI_VERSION >= NTDDI_WIN10)
|
||||||
|
#define SDL_JOYSTICK_WGI 1
|
||||||
|
#define SDL_HAPTIC_DISABLED 1
|
||||||
|
#else
|
||||||
#define SDL_JOYSTICK_XINPUT 1
|
#define SDL_JOYSTICK_XINPUT 1
|
||||||
#define SDL_HAPTIC_XINPUT 1
|
#define SDL_HAPTIC_XINPUT 1
|
||||||
|
#endif /* WIN10 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* WinRT doesn't have HIDAPI available */
|
/* WinRT doesn't have HIDAPI available */
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#define COBJMACROS
|
#define COBJMACROS
|
||||||
#include "windows.gaming.input.h"
|
#include "windows.gaming.input.h"
|
||||||
#include <cfgmgr32.h>
|
#include <cfgmgr32.h>
|
||||||
|
#include <roapi.h>
|
||||||
|
|
||||||
|
|
||||||
struct joystick_hwdata
|
struct joystick_hwdata
|
||||||
|
@ -94,6 +95,7 @@ extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16
|
||||||
static SDL_bool
|
static SDL_bool
|
||||||
SDL_IsXInputDevice(Uint16 vendor, Uint16 product)
|
SDL_IsXInputDevice(Uint16 vendor, Uint16 product)
|
||||||
{
|
{
|
||||||
|
#ifdef SDL_JOYSTICK_XINPUT
|
||||||
PRAWINPUTDEVICELIST raw_devices = NULL;
|
PRAWINPUTDEVICELIST raw_devices = NULL;
|
||||||
UINT i, raw_device_count = 0;
|
UINT i, raw_device_count = 0;
|
||||||
LONG vidpid = MAKELONG(vendor, product);
|
LONG vidpid = MAKELONG(vendor, product);
|
||||||
|
@ -191,6 +193,8 @@ SDL_IsXInputDevice(Uint16 vendor, Uint16 product)
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_free(raw_devices);
|
SDL_free(raw_devices);
|
||||||
|
#endif /* SDL_JOYSTICK_XINPUT */
|
||||||
|
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +233,7 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = IUnknown_QueryInterface((IUnknown *)e, &IID_IRawGameController, (void **)&controller);
|
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(e, &IID_IRawGameController, (void **)&controller);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
SDL_JoystickGUID guid;
|
SDL_JoystickGUID guid;
|
||||||
|
@ -247,26 +251,37 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
|
||||||
|
|
||||||
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IRawGameController2, (void **)&controller2);
|
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IRawGameController2, (void **)&controller2);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
|
typedef PCWSTR (WINAPI *WindowsGetStringRawBuffer_t)(HSTRING string, UINT32 *length);
|
||||||
|
typedef HRESULT (WINAPI *WindowsDeleteString_t)(HSTRING string);
|
||||||
|
|
||||||
|
WindowsGetStringRawBuffer_t WindowsGetStringRawBufferFunc = NULL;
|
||||||
|
WindowsDeleteString_t WindowsDeleteStringFunc = NULL;
|
||||||
|
#ifdef __WINRT__
|
||||||
|
WindowsGetStringRawBufferFunc = WindowsGetStringRawBuffer;
|
||||||
|
WindowsDeleteStringFunc = WindowsDeleteString;
|
||||||
|
#else
|
||||||
HMODULE hModule = LoadLibraryA("combase.dll");
|
HMODULE hModule = LoadLibraryA("combase.dll");
|
||||||
if (hModule != NULL) {
|
if (hModule != NULL) {
|
||||||
typedef PCWSTR (WINAPI *WindowsGetStringRawBuffer_t)(HSTRING string, UINT32 *length);
|
WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)GetProcAddress(hModule, "WindowsGetStringRawBuffer");
|
||||||
typedef HRESULT (WINAPI *WindowsDeleteString_t)(HSTRING string);
|
WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString");
|
||||||
|
}
|
||||||
WindowsGetStringRawBuffer_t WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)GetProcAddress(hModule, "WindowsGetStringRawBuffer");
|
#endif /* __WINRT__ */
|
||||||
WindowsDeleteString_t WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString");
|
if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) {
|
||||||
if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) {
|
HSTRING hString;
|
||||||
HSTRING hString;
|
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_get_DisplayName(controller2, &hString);
|
||||||
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_get_DisplayName(controller2, &hString);
|
if (SUCCEEDED(hr)) {
|
||||||
if (SUCCEEDED(hr)) {
|
PCWSTR string = WindowsGetStringRawBufferFunc(hString, NULL);
|
||||||
PCWSTR string = WindowsGetStringRawBufferFunc(hString, NULL);
|
if (string) {
|
||||||
if (string) {
|
name = WIN_StringToUTF8W(string);
|
||||||
name = WIN_StringToUTF8W(string);
|
|
||||||
}
|
|
||||||
WindowsDeleteStringFunc(hString);
|
|
||||||
}
|
}
|
||||||
|
WindowsDeleteStringFunc(hString);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#ifndef __WINRT__
|
||||||
|
if (hModule != NULL) {
|
||||||
FreeLibrary(hModule);
|
FreeLibrary(hModule);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
__x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2);
|
__x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2);
|
||||||
}
|
}
|
||||||
if (!name) {
|
if (!name) {
|
||||||
|
@ -373,7 +388,7 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeRemo
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
__x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller = NULL;
|
__x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller = NULL;
|
||||||
|
|
||||||
hr = IUnknown_QueryInterface((IUnknown *)e, &IID_IRawGameController, (void **)&controller);
|
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(e, &IID_IRawGameController, (void **)&controller);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -424,78 +439,88 @@ static __FIEventHandler_1_Windows__CGaming__CInput__CRawGameController controlle
|
||||||
static int
|
static int
|
||||||
WGI_JoystickInit(void)
|
WGI_JoystickInit(void)
|
||||||
{
|
{
|
||||||
HMODULE hModule;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (FAILED(WIN_CoInitialize())) {
|
if (FAILED(WIN_CoInitialize())) {
|
||||||
return SDL_SetError("CoInitialize() failed");
|
return SDL_SetError("CoInitialize() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
hModule = LoadLibraryA("combase.dll");
|
typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string);
|
||||||
if (hModule != NULL) {
|
typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory);
|
||||||
typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string);
|
|
||||||
typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory);
|
|
||||||
|
|
||||||
|
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL;
|
||||||
|
RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL;
|
||||||
|
#ifdef __WINRT__
|
||||||
|
WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
|
||||||
|
RoGetActivationFactoryFunc = RoGetActivationFactory;
|
||||||
|
#else
|
||||||
|
HMODULE hModule = LoadLibraryA("combase.dll");
|
||||||
|
if (hModule != NULL) {
|
||||||
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference");
|
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference");
|
||||||
RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory");
|
RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory");
|
||||||
if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
|
}
|
||||||
PCWSTR pNamespace;
|
#endif /* __WINRT__ */
|
||||||
HSTRING_HEADER hNamespaceStringHeader;
|
if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
|
||||||
HSTRING hNamespaceString;
|
PCWSTR pNamespace;
|
||||||
|
HSTRING_HEADER hNamespaceStringHeader;
|
||||||
|
HSTRING hNamespaceString;
|
||||||
|
|
||||||
pNamespace = L"Windows.Gaming.Input.RawGameController";
|
pNamespace = L"Windows.Gaming.Input.RawGameController";
|
||||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRawGameControllerStatics, (void **)&wgi.statics);
|
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRawGameControllerStatics, (void **)&wgi.statics);
|
||||||
if (!SUCCEEDED(hr)) {
|
if (!SUCCEEDED(hr)) {
|
||||||
SDL_SetError("Couldn't find IRawGameControllerStatics: 0x%lx", hr);
|
SDL_SetError("Couldn't find IRawGameControllerStatics: 0x%lx", hr);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pNamespace = L"Windows.Gaming.Input.ArcadeStick";
|
|
||||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IArcadeStickStatics, (void **)&wgi.arcade_stick_statics);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
__x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics_QueryInterface(wgi.arcade_stick_statics, &IID_IArcadeStickStatics2, (void **)&wgi.arcade_stick_statics2);
|
|
||||||
} else {
|
|
||||||
SDL_SetError("Couldn't find IID_IArcadeStickStatics: 0x%lx", hr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pNamespace = L"Windows.Gaming.Input.FlightStick";
|
|
||||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IFlightStickStatics, (void **)&wgi.flight_stick_statics);
|
|
||||||
if (!SUCCEEDED(hr)) {
|
|
||||||
SDL_SetError("Couldn't find IID_IFlightStickStatics: 0x%lx", hr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pNamespace = L"Windows.Gaming.Input.Gamepad";
|
|
||||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IGamepadStatics, (void **)&wgi.gamepad_statics);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_QueryInterface(wgi.gamepad_statics, &IID_IGamepadStatics2, (void **)&wgi.gamepad_statics2);
|
|
||||||
} else {
|
|
||||||
SDL_SetError("Couldn't find IGamepadStatics: 0x%lx", hr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pNamespace = L"Windows.Gaming.Input.RacingWheel";
|
|
||||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRacingWheelStatics, (void **)&wgi.racing_wheel_statics);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
__x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics_QueryInterface(wgi.racing_wheel_statics, &IID_IRacingWheelStatics2, (void **)&wgi.racing_wheel_statics2);
|
|
||||||
} else {
|
|
||||||
SDL_SetError("Couldn't find IRacingWheelStatics: 0x%lx", hr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pNamespace = L"Windows.Gaming.Input.ArcadeStick";
|
||||||
|
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IArcadeStickStatics, (void **)&wgi.arcade_stick_statics);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
__x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics_QueryInterface(wgi.arcade_stick_statics, &IID_IArcadeStickStatics2, (void **)&wgi.arcade_stick_statics2);
|
||||||
|
} else {
|
||||||
|
SDL_SetError("Couldn't find IID_IArcadeStickStatics: 0x%lx", hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pNamespace = L"Windows.Gaming.Input.FlightStick";
|
||||||
|
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IFlightStickStatics, (void **)&wgi.flight_stick_statics);
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
SDL_SetError("Couldn't find IID_IFlightStickStatics: 0x%lx", hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pNamespace = L"Windows.Gaming.Input.Gamepad";
|
||||||
|
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IGamepadStatics, (void **)&wgi.gamepad_statics);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_QueryInterface(wgi.gamepad_statics, &IID_IGamepadStatics2, (void **)&wgi.gamepad_statics2);
|
||||||
|
} else {
|
||||||
|
SDL_SetError("Couldn't find IGamepadStatics: 0x%lx", hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pNamespace = L"Windows.Gaming.Input.RacingWheel";
|
||||||
|
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRacingWheelStatics, (void **)&wgi.racing_wheel_statics);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
__x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics_QueryInterface(wgi.racing_wheel_statics, &IID_IRacingWheelStatics2, (void **)&wgi.racing_wheel_statics2);
|
||||||
|
} else {
|
||||||
|
SDL_SetError("Couldn't find IRacingWheelStatics: 0x%lx", hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifndef __WINRT__
|
||||||
|
if (hModule != NULL) {
|
||||||
FreeLibrary(hModule);
|
FreeLibrary(hModule);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (wgi.statics) {
|
if (wgi.statics) {
|
||||||
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_add_RawGameControllerAdded(wgi.statics, &controller_added, &wgi.controller_added_token);
|
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_add_RawGameControllerAdded(wgi.statics, &controller_added, &wgi.controller_added_token);
|
||||||
|
|
Loading…
Reference in New Issue