mirror of
https://github.com/Ryujinx/SDL.git
synced 2025-01-09 14:35:39 +00:00
Added WGI gamepad added/removed listeners for RAWINPUT
This fixes WGI correlation on startup when the WGI gamepad list isn't populated yet (cherry picked from commit f047e178b610c6888212c3096c10eb3f64f31a15)
This commit is contained in:
parent
1f7bc08884
commit
f8a0135edf
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#if SDL_JOYSTICK_RAWINPUT
|
#if SDL_JOYSTICK_RAWINPUT
|
||||||
|
|
||||||
|
#include "SDL_atomic.h"
|
||||||
#include "SDL_endian.h"
|
#include "SDL_endian.h"
|
||||||
#include "SDL_events.h"
|
#include "SDL_events.h"
|
||||||
#include "SDL_hints.h"
|
#include "SDL_hints.h"
|
||||||
|
@ -445,8 +446,86 @@ static struct
|
||||||
SDL_bool need_device_list_update;
|
SDL_bool need_device_list_update;
|
||||||
int ref_count;
|
int ref_count;
|
||||||
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics *gamepad_statics;
|
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics *gamepad_statics;
|
||||||
|
EventRegistrationToken gamepad_added_token;
|
||||||
|
EventRegistrationToken gamepad_removed_token;
|
||||||
} wgi_state;
|
} wgi_state;
|
||||||
|
|
||||||
|
typedef struct GamepadDelegate
|
||||||
|
{
|
||||||
|
__FIEventHandler_1_Windows__CGaming__CInput__CGamepad iface;
|
||||||
|
SDL_atomic_t refcount;
|
||||||
|
} GamepadDelegate;
|
||||||
|
|
||||||
|
static const IID IID_IEventHandler_Gamepad = { 0x8a7639ee, 0x624a, 0x501a, { 0xbb, 0x53, 0x56, 0x2d, 0x1e, 0xc1, 0x1b, 0x52 } };
|
||||||
|
|
||||||
|
static HRESULT STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_QueryInterface(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This, REFIID riid, void **ppvObject)
|
||||||
|
{
|
||||||
|
if (ppvObject == NULL) {
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppvObject = NULL;
|
||||||
|
if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &IID_IAgileObject) || WIN_IsEqualIID(riid, &IID_IEventHandler_Gamepad)) {
|
||||||
|
*ppvObject = This;
|
||||||
|
__FIEventHandler_1_Windows__CGaming__CInput__CGamepad_AddRef(This);
|
||||||
|
return S_OK;
|
||||||
|
} else if (WIN_IsEqualIID(riid, &IID_IMarshal)) {
|
||||||
|
/* This seems complicated. Let's hope it doesn't happen. */
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
} else {
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_AddRef(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This)
|
||||||
|
{
|
||||||
|
GamepadDelegate *self = (GamepadDelegate *)This;
|
||||||
|
return SDL_AtomicAdd(&self->refcount, 1) + 1UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_Release(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This)
|
||||||
|
{
|
||||||
|
GamepadDelegate *self = (GamepadDelegate *)This;
|
||||||
|
int rc = SDL_AtomicAdd(&self->refcount, -1) - 1;
|
||||||
|
/* Should never free the static delegate objects */
|
||||||
|
SDL_assert(rc > 0);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_InvokeAdded(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This, IInspectable *sender, __x_ABI_CWindows_CGaming_CInput_CIGamepad *e)
|
||||||
|
{
|
||||||
|
wgi_state.need_device_list_update = SDL_TRUE;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_InvokeRemoved(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This, IInspectable *sender, __x_ABI_CWindows_CGaming_CInput_CIGamepad *e)
|
||||||
|
{
|
||||||
|
wgi_state.need_device_list_update = SDL_TRUE;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __FIEventHandler_1_Windows__CGaming__CInput__CGamepadVtbl gamepad_added_vtbl = {
|
||||||
|
IEventHandler_CGamepadVtbl_QueryInterface,
|
||||||
|
IEventHandler_CGamepadVtbl_AddRef,
|
||||||
|
IEventHandler_CGamepadVtbl_Release,
|
||||||
|
IEventHandler_CGamepadVtbl_InvokeAdded
|
||||||
|
};
|
||||||
|
static GamepadDelegate gamepad_added = {
|
||||||
|
{ &gamepad_added_vtbl },
|
||||||
|
{ 1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static __FIEventHandler_1_Windows__CGaming__CInput__CGamepadVtbl gamepad_removed_vtbl = {
|
||||||
|
IEventHandler_CGamepadVtbl_QueryInterface,
|
||||||
|
IEventHandler_CGamepadVtbl_AddRef,
|
||||||
|
IEventHandler_CGamepadVtbl_Release,
|
||||||
|
IEventHandler_CGamepadVtbl_InvokeRemoved
|
||||||
|
};
|
||||||
|
static GamepadDelegate gamepad_removed = {
|
||||||
|
{ &gamepad_removed_vtbl },
|
||||||
|
{ 1 }
|
||||||
|
};
|
||||||
|
|
||||||
static void RAWINPUT_MarkWindowsGamingInputSlotUsed(WindowsGamingInputGamepadState *wgi_slot, RAWINPUT_DeviceContext *ctx)
|
static void RAWINPUT_MarkWindowsGamingInputSlotUsed(WindowsGamingInputGamepadState *wgi_slot, RAWINPUT_DeviceContext *ctx)
|
||||||
{
|
{
|
||||||
wgi_slot->used = SDL_TRUE;
|
wgi_slot->used = SDL_TRUE;
|
||||||
|
@ -568,7 +647,6 @@ static void RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wgi_state.need_device_list_update = SDL_TRUE;
|
|
||||||
wgi_state.ref_count++;
|
wgi_state.ref_count++;
|
||||||
if (!wgi_state.initialized) {
|
if (!wgi_state.initialized) {
|
||||||
static const IID SDL_IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } };
|
static const IID SDL_IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } };
|
||||||
|
@ -600,6 +678,20 @@ static void RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, (void **)&wgi_state.gamepad_statics);
|
RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, (void **)&wgi_state.gamepad_statics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wgi_state.gamepad_statics) {
|
||||||
|
wgi_state.need_device_list_update = SDL_TRUE;
|
||||||
|
|
||||||
|
hr = __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_add_GamepadAdded(wgi_state.gamepad_statics, &gamepad_added.iface, &wgi_state.gamepad_added_token);
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
SDL_SetError("add_GamepadAdded() failed: 0x%lx\n", hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_add_GamepadRemoved(wgi_state.gamepad_statics, &gamepad_removed.iface, &wgi_state.gamepad_removed_token);
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
SDL_SetError("add_GamepadRemoved() failed: 0x%lx\n", hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -647,7 +739,6 @@ static SDL_bool RAWINPUT_GuessWindowsGamingInputSlot(const WindowsMatchState *st
|
||||||
|
|
||||||
static void RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
|
static void RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
|
||||||
{
|
{
|
||||||
wgi_state.need_device_list_update = SDL_TRUE;
|
|
||||||
--wgi_state.ref_count;
|
--wgi_state.ref_count;
|
||||||
if (!wgi_state.ref_count && wgi_state.initialized) {
|
if (!wgi_state.ref_count && wgi_state.initialized) {
|
||||||
int ii;
|
int ii;
|
||||||
|
@ -660,6 +751,8 @@ static void RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
|
||||||
}
|
}
|
||||||
wgi_state.per_gamepad_count = 0;
|
wgi_state.per_gamepad_count = 0;
|
||||||
if (wgi_state.gamepad_statics) {
|
if (wgi_state.gamepad_statics) {
|
||||||
|
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_remove_GamepadAdded(wgi_state.gamepad_statics, wgi_state.gamepad_added_token);
|
||||||
|
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_remove_GamepadRemoved(wgi_state.gamepad_statics, wgi_state.gamepad_removed_token);
|
||||||
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(wgi_state.gamepad_statics);
|
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(wgi_state.gamepad_statics);
|
||||||
wgi_state.gamepad_statics = NULL;
|
wgi_state.gamepad_statics = NULL;
|
||||||
}
|
}
|
||||||
|
@ -921,9 +1014,6 @@ SDL_bool RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 ve
|
||||||
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
|
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
|
||||||
xinput_device_change = SDL_TRUE;
|
xinput_device_change = SDL_TRUE;
|
||||||
#endif
|
#endif
|
||||||
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
|
|
||||||
wgi_state.need_device_list_update = SDL_TRUE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
device = SDL_RAWINPUT_devices;
|
device = SDL_RAWINPUT_devices;
|
||||||
while (device) {
|
while (device) {
|
||||||
|
|
|
@ -214,46 +214,6 @@ static SDL_bool SDL_IsXInputDevice(Uint16 vendor, Uint16 product)
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct RawGameControllerDelegate
|
|
||||||
{
|
|
||||||
__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController iface;
|
|
||||||
SDL_atomic_t refcount;
|
|
||||||
} RawGameControllerDelegate;
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_QueryInterface(__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController *This, REFIID riid, void **ppvObject)
|
|
||||||
{
|
|
||||||
if (ppvObject == NULL) {
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ppvObject = NULL;
|
|
||||||
if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &IID_IAgileObject) || WIN_IsEqualIID(riid, &IID_IEventHandler_RawGameController)) {
|
|
||||||
*ppvObject = This;
|
|
||||||
__x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_AddRef(This);
|
|
||||||
return S_OK;
|
|
||||||
} else if (WIN_IsEqualIID(riid, &IID_IMarshal)) {
|
|
||||||
/* This seems complicated. Let's hope it doesn't happen. */
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
} else {
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_AddRef(__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController *This)
|
|
||||||
{
|
|
||||||
RawGameControllerDelegate *self = (RawGameControllerDelegate *)This;
|
|
||||||
return SDL_AtomicAdd(&self->refcount, 1) + 1UL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_Release(__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController *This)
|
|
||||||
{
|
|
||||||
RawGameControllerDelegate *self = (RawGameControllerDelegate *)This;
|
|
||||||
int rc = SDL_AtomicAdd(&self->refcount, -1) - 1;
|
|
||||||
/* Should never free the static delegate objects */
|
|
||||||
SDL_assert(rc > 0);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void WGI_LoadRawGameControllerStatics()
|
static void WGI_LoadRawGameControllerStatics()
|
||||||
{
|
{
|
||||||
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL;
|
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL;
|
||||||
|
@ -384,6 +344,46 @@ static SDL_JoystickType GetGameControllerType(__x_ABI_CWindows_CGaming_CInput_CI
|
||||||
return SDL_JOYSTICK_TYPE_UNKNOWN;
|
return SDL_JOYSTICK_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct RawGameControllerDelegate
|
||||||
|
{
|
||||||
|
__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController iface;
|
||||||
|
SDL_atomic_t refcount;
|
||||||
|
} RawGameControllerDelegate;
|
||||||
|
|
||||||
|
static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_QueryInterface(__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController *This, REFIID riid, void **ppvObject)
|
||||||
|
{
|
||||||
|
if (ppvObject == NULL) {
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppvObject = NULL;
|
||||||
|
if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &IID_IAgileObject) || WIN_IsEqualIID(riid, &IID_IEventHandler_RawGameController)) {
|
||||||
|
*ppvObject = This;
|
||||||
|
__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController_AddRef(This);
|
||||||
|
return S_OK;
|
||||||
|
} else if (WIN_IsEqualIID(riid, &IID_IMarshal)) {
|
||||||
|
/* This seems complicated. Let's hope it doesn't happen. */
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
} else {
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_AddRef(__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController *This)
|
||||||
|
{
|
||||||
|
RawGameControllerDelegate *self = (RawGameControllerDelegate *)This;
|
||||||
|
return SDL_AtomicAdd(&self->refcount, 1) + 1UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_Release(__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController *This)
|
||||||
|
{
|
||||||
|
RawGameControllerDelegate *self = (RawGameControllerDelegate *)This;
|
||||||
|
int rc = SDL_AtomicAdd(&self->refcount, -1) - 1;
|
||||||
|
/* Should never free the static delegate objects */
|
||||||
|
SDL_assert(rc > 0);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdded(__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController *This, IInspectable *sender, __x_ABI_CWindows_CGaming_CInput_CIRawGameController *e)
|
static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdded(__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController *This, IInspectable *sender, __x_ABI_CWindows_CGaming_CInput_CIRawGameController *e)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
Loading…
Reference in a new issue