[PATCH 2/5] windows.gaming.input: Implement IRawGameControllerStatics_FromGameController.

Rémi Bernon rbernon at codeweavers.com
Tue Mar 8 03:55:23 CST 2022


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/windows.gaming.input/controller.c | 16 +++++++++++++--
 dlls/windows.gaming.input/main.c       |  7 +++----
 dlls/windows.gaming.input/manager.c    | 27 +++++++++++++++++++++++---
 dlls/windows.gaming.input/private.h    |  2 +-
 4 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/dlls/windows.gaming.input/controller.c b/dlls/windows.gaming.input/controller.c
index 27c5d6ebd32..94343c0927d 100644
--- a/dlls/windows.gaming.input/controller.c
+++ b/dlls/windows.gaming.input/controller.c
@@ -174,8 +174,20 @@ static HRESULT WINAPI statics_get_RawGameControllers( IRawGameControllerStatics
 static HRESULT WINAPI statics_FromGameController( IRawGameControllerStatics *iface, IGameController *game_controller,
                                                   IRawGameController **value )
 {
-    FIXME( "iface %p, game_controller %p, value %p stub!\n", iface, game_controller, value );
-    return E_NOTIMPL;
+    struct controller_statics *impl = impl_from_IRawGameControllerStatics( iface );
+    IGameController *controller;
+    HRESULT hr;
+
+    TRACE( "iface %p, game_controller %p, value %p.\n", iface, game_controller, value );
+
+    hr = IGameControllerFactoryManagerStatics2_TryGetFactoryControllerFromGameController( manager_factory, &impl->ICustomGameControllerFactory_iface,
+                                                                                          game_controller, &controller );
+    if (FAILED(hr)) return hr;
+
+    hr = IGameController_QueryInterface( controller, &IID_IRawGameController, (void **)value );
+    IGameController_Release( controller );
+
+    return hr;
 }
 
 static const struct IRawGameControllerStaticsVtbl statics_vtbl =
diff --git a/dlls/windows.gaming.input/main.c b/dlls/windows.gaming.input/main.c
index e71043fcb0f..c5b7f19c987 100644
--- a/dlls/windows.gaming.input/main.c
+++ b/dlls/windows.gaming.input/main.c
@@ -169,7 +169,7 @@ HRESULT WINAPI DllGetActivationFactory( HSTRING class_str, IActivationFactory **
 {
     static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
     const WCHAR *buffer = WindowsGetStringRawBuffer( class_str, NULL );
-    HRESULT hr = S_OK;
+    HRESULT hr = REGDB_E_CLASSNOTREG;
 
     TRACE( "class %s, factory %p.\n", debugstr_w(buffer), factory );
 
@@ -182,10 +182,9 @@ HRESULT WINAPI DllGetActivationFactory( HSTRING class_str, IActivationFactory **
     if (!wcscmp( buffer, RuntimeClass_Windows_Gaming_Input_Gamepad ))
         hr = ICustomGameControllerFactory_QueryInterface( gamepad_factory, &IID_IActivationFactory, (void **)factory );
     if (!wcscmp( buffer, RuntimeClass_Windows_Gaming_Input_Custom_GameControllerFactoryManager ))
-        IActivationFactory_AddRef( (*factory = manager_factory) );
+        hr = IGameControllerFactoryManagerStatics2_QueryInterface( manager_factory, &IID_IActivationFactory, (void **)factory );
 
-    if (SUCCEEDED(hr) && *factory) return S_OK;
-    return REGDB_E_CLASSNOTREG;
+    return hr;
 }
 
 BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved )
diff --git a/dlls/windows.gaming.input/manager.c b/dlls/windows.gaming.input/manager.c
index 15388f7df5d..33f2a3c3df9 100644
--- a/dlls/windows.gaming.input/manager.c
+++ b/dlls/windows.gaming.input/manager.c
@@ -370,8 +370,29 @@ statics2_TryGetFactoryControllerFromGameController( IGameControllerFactoryManage
                                                     ICustomGameControllerFactory *factory,
                                                     IGameController *controller, IGameController **value )
 {
-    FIXME( "iface %p, factory %p, controller %p, value %p stub!\n", iface, factory, controller, value );
-    return E_NOTIMPL;
+    struct controller *entry, *other;
+    BOOL found = FALSE;
+
+    TRACE( "iface %p, factory %p, controller %p, value %p.\n", iface, factory, controller, value );
+
+    EnterCriticalSection( &manager_cs );
+
+    LIST_FOR_EACH_ENTRY( entry, &controller_list, struct controller, entry )
+        if ((found = &entry->IGameController_iface == controller)) break;
+
+    if (!found) WARN( "Failed to find controller %p\n", controller );
+    else
+    {
+        LIST_FOR_EACH_ENTRY( other, &controller_list, struct controller, entry )
+            if ((found = entry->provider == other->provider && other->factory == factory)) break;
+        if (!found) WARN( "Failed to find controller %p, factory %p\n", controller, factory );
+        else IGameController_AddRef( (*value = &other->IGameController_iface) );
+    }
+
+    LeaveCriticalSection( &manager_cs );
+
+    if (!found) return E_FAIL;
+    return S_OK;
 }
 
 static const struct IGameControllerFactoryManagerStatics2Vtbl statics2_vtbl =
@@ -395,7 +416,7 @@ static struct manager_statics manager_statics =
     1,
 };
 
-IActivationFactory *manager_factory = &manager_statics.IActivationFactory_iface;
+IGameControllerFactoryManagerStatics2 *manager_factory = &manager_statics.IGameControllerFactoryManagerStatics2_iface;
 
 static HRESULT controller_create( ICustomGameControllerFactory *factory, IGameControllerProvider *provider,
                                   struct controller **out )
diff --git a/dlls/windows.gaming.input/private.h b/dlls/windows.gaming.input/private.h
index 27dbdb8416c..56d03abad44 100644
--- a/dlls/windows.gaming.input/private.h
+++ b/dlls/windows.gaming.input/private.h
@@ -39,7 +39,7 @@
 extern HINSTANCE windows_gaming_input;
 extern ICustomGameControllerFactory *controller_factory;
 extern ICustomGameControllerFactory *gamepad_factory;
-extern IActivationFactory *manager_factory;
+extern IGameControllerFactoryManagerStatics2 *manager_factory;
 
 extern HRESULT vector_create( REFIID iid, REFIID view_iid, void **out );
 
-- 
2.35.1




More information about the wine-devel mailing list