[PATCH 2/6] windows.gaming.input: Implement IGamepadStatics_get_Gamepads.
Rémi Bernon
rbernon at codeweavers.com
Thu Mar 10 03:38:40 CST 2022
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/dinput/tests/joystick8.c | 1 +
dlls/windows.gaming.input/gamepad.c | 82 +++++++++++++++++++++++------
2 files changed, 68 insertions(+), 15 deletions(-)
diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c
index e74e76482f9..c4cfceeee3e 100644
--- a/dlls/dinput/tests/joystick8.c
+++ b/dlls/dinput/tests/joystick8.c
@@ -3356,6 +3356,7 @@ static void test_windows_gaming_input(void)
ok( hr == S_OK, "get_Gamepads returned %#lx\n", hr );
hr = IVectorView_Gamepad_get_Size( gamepads_view, &size );
ok( hr == S_OK, "get_Size returned %#lx\n", hr );
+ todo_wine /* but Wine currently intentionally does */
ok( size == 0, "got size %u\n", size );
IVectorView_Gamepad_Release( gamepads_view );
IGamepadStatics_Release( gamepad_statics );
diff --git a/dlls/windows.gaming.input/gamepad.c b/dlls/windows.gaming.input/gamepad.c
index 172ca74e3f6..70c9f4cd792 100644
--- a/dlls/windows.gaming.input/gamepad.c
+++ b/dlls/windows.gaming.input/gamepad.c
@@ -24,6 +24,36 @@
WINE_DEFAULT_DEBUG_CHANNEL(input);
+static CRITICAL_SECTION gamepad_cs;
+static CRITICAL_SECTION_DEBUG gamepad_cs_debug =
+{
+ 0, 0, &gamepad_cs,
+ { &gamepad_cs_debug.ProcessLocksList, &gamepad_cs_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": gamepad_cs") }
+};
+static CRITICAL_SECTION gamepad_cs = { &gamepad_cs_debug, -1, 0, 0, 0, 0 };
+
+static IVector_Gamepad *gamepads;
+
+static HRESULT init_gamepads(void)
+{
+ static const struct vector_iids iids =
+ {
+ .vector = &IID_IVector_Gamepad,
+ .view = &IID_IVectorView_Gamepad,
+ .iterable = &IID_IIterable_Gamepad,
+ .iterator = &IID_IIterator_Gamepad,
+ };
+ HRESULT hr;
+
+ EnterCriticalSection( &gamepad_cs );
+ if (gamepads) hr = S_OK;
+ else hr = vector_create( &iids, (void **)&gamepads );
+ LeaveCriticalSection( &gamepad_cs );
+
+ return hr;
+}
+
struct gamepad
{
IGameControllerImpl IGameControllerImpl_iface;
@@ -118,13 +148,19 @@ static HRESULT WINAPI controller_Initialize( IGameControllerImpl *iface, IGameCo
IGameControllerProvider *provider )
{
struct gamepad *impl = impl_from_IGameControllerImpl( iface );
+ HRESULT hr;
TRACE( "iface %p, outer %p, provider %p.\n", iface, outer, provider );
impl->IGameController_outer = outer;
IGameControllerProvider_AddRef( (impl->provider = provider) );
- return S_OK;
+ EnterCriticalSection( &gamepad_cs );
+ if (SUCCEEDED(hr = init_gamepads()))
+ hr = IVector_Gamepad_Append( gamepads, &impl->IGamepad_iface );
+ LeaveCriticalSection( &gamepad_cs );
+
+ return hr;
}
static const struct IGameControllerImplVtbl controller_vtbl =
@@ -341,23 +377,14 @@ static HRESULT WINAPI statics_remove_GamepadRemoved( IGamepadStatics *iface, Eve
static HRESULT WINAPI statics_get_Gamepads( IGamepadStatics *iface, IVectorView_Gamepad **value )
{
- static const struct vector_iids iids =
- {
- .vector = &IID_IVector_Gamepad,
- .view = &IID_IVectorView_Gamepad,
- .iterable = &IID_IIterable_Gamepad,
- .iterator = &IID_IIterator_Gamepad,
- };
- IVector_Gamepad *gamepads;
HRESULT hr;
TRACE( "iface %p, value %p.\n", iface, value );
- if (SUCCEEDED(hr = vector_create( &iids, (void **)&gamepads )))
- {
+ EnterCriticalSection( &gamepad_cs );
+ if (SUCCEEDED(hr = init_gamepads()))
hr = IVector_Gamepad_GetView( gamepads, value );
- IVector_Gamepad_Release( gamepads );
- }
+ LeaveCriticalSection( &gamepad_cs );
return hr;
}
@@ -440,8 +467,33 @@ static HRESULT WINAPI controller_factory_OnGameControllerAdded( ICustomGameContr
static HRESULT WINAPI controller_factory_OnGameControllerRemoved( ICustomGameControllerFactory *iface, IGameController *value )
{
- FIXME( "iface %p, value %p stub!\n", iface, value );
- return E_NOTIMPL;
+ IGamepad *gamepad;
+ BOOLEAN found;
+ UINT32 index;
+ HRESULT hr;
+
+ TRACE( "iface %p, value %p.\n", iface, value );
+
+ if (FAILED(hr = IGameController_QueryInterface( value, &IID_IGamepad, (void **)&gamepad )))
+ return hr;
+
+ EnterCriticalSection( &gamepad_cs );
+ if (SUCCEEDED(hr = init_gamepads()))
+ {
+ if (FAILED(hr = IVector_Gamepad_IndexOf( gamepads, gamepad, &index, &found )) || !found)
+ WARN( "Could not find gamepad %p, hr %#lx!\n", gamepad, hr );
+ else
+ hr = IVector_Gamepad_RemoveAt( gamepads, index );
+ }
+ LeaveCriticalSection( &gamepad_cs );
+
+ if (FAILED(hr))
+ WARN( "Failed to remove gamepad %p, hr %#lx!\n", gamepad, hr );
+ else if (found)
+ TRACE( "Removed gamepad %p.\n", gamepad );
+ IGamepad_Release( gamepad );
+
+ return S_OK;
}
static const struct ICustomGameControllerFactoryVtbl controller_factory_vtbl =
--
2.35.1
More information about the wine-devel
mailing list