Signed-off-by: Rémi Bernon rbernon@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 );