From 21c8a30906e656729854e8bf899ba44750f215ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Mon, 22 Mar 2021 11:17:32 +0100 Subject: [PATCH] windows.gaming.input: Implement IRawGameControllerStatics stubs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RĂ©mi Bernon Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/windows.gaming.input/main.c | 116 ++++++++++++++++ dlls/windows.gaming.input/tests/input.c | 173 ++++++++++++++++++++++++ 2 files changed, 289 insertions(+) diff --git a/dlls/windows.gaming.input/main.c b/dlls/windows.gaming.input/main.c index 545a7acdbaf..8a79d77858e 100644 --- a/dlls/windows.gaming.input/main.c +++ b/dlls/windows.gaming.input/main.c @@ -174,6 +174,7 @@ struct windows_gaming_input { IActivationFactory IActivationFactory_iface; IGamepadStatics IGamepadStatics_iface; + IRawGameControllerStatics IRawGameControllerStatics_iface; LONG ref; }; @@ -187,6 +188,11 @@ static inline struct windows_gaming_input *impl_from_IGamepadStatics(IGamepadSta return CONTAINING_RECORD(iface, struct windows_gaming_input, IGamepadStatics_iface); } +static inline struct windows_gaming_input *impl_from_IRawGameControllerStatics(IRawGameControllerStatics *iface) +{ + return CONTAINING_RECORD(iface, struct windows_gaming_input, IRawGameControllerStatics_iface); +} + static HRESULT STDMETHODCALLTYPE windows_gaming_input_QueryInterface( IActivationFactory *iface, REFIID iid, void **out) { @@ -211,6 +217,13 @@ static HRESULT STDMETHODCALLTYPE windows_gaming_input_QueryInterface( return S_OK; } + if (IsEqualGUID(iid, &IID_IRawGameControllerStatics)) + { + IUnknown_AddRef(iface); + *out = &impl->IRawGameControllerStatics_iface; + return S_OK; + } + FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); *out = NULL; return E_NOINTERFACE; @@ -375,10 +388,113 @@ static const struct IGamepadStaticsVtbl gamepad_statics_vtbl = gamepad_statics_get_Gamepads, }; +static HRESULT STDMETHODCALLTYPE raw_game_controller_statics_QueryInterface( + IRawGameControllerStatics *iface, REFIID iid, void **out) +{ + struct windows_gaming_input *impl = impl_from_IRawGameControllerStatics(iface); + return windows_gaming_input_QueryInterface(&impl->IActivationFactory_iface, iid, out); +} + +static ULONG STDMETHODCALLTYPE raw_game_controller_statics_AddRef( + IRawGameControllerStatics *iface) +{ + struct windows_gaming_input *impl = impl_from_IRawGameControllerStatics(iface); + return windows_gaming_input_AddRef(&impl->IActivationFactory_iface); +} + +static ULONG STDMETHODCALLTYPE raw_game_controller_statics_Release( + IRawGameControllerStatics *iface) +{ + struct windows_gaming_input *impl = impl_from_IRawGameControllerStatics(iface); + return windows_gaming_input_Release(&impl->IActivationFactory_iface); +} + +static HRESULT STDMETHODCALLTYPE raw_game_controller_statics_GetIids( + IRawGameControllerStatics *iface, ULONG *iid_count, IID **iids) +{ + FIXME("iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE raw_game_controller_statics_GetRuntimeClassName( + IRawGameControllerStatics *iface, HSTRING *class_name) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE raw_game_controller_statics_GetTrustLevel( + IRawGameControllerStatics *iface, TrustLevel *trust_level) +{ + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE raw_game_controller_statics_add_RawGameControllerAdded( + IRawGameControllerStatics *iface, IEventHandler_RawGameController *value, EventRegistrationToken* token) +{ + FIXME("iface %p, value %p, token %p stub!\n", iface, value, token); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE raw_game_controller_statics_remove_RawGameControllerAdded( + IRawGameControllerStatics *iface, EventRegistrationToken token) +{ + FIXME("iface %p, token %#I64x stub!\n", iface, token.value); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE raw_game_controller_statics_add_RawGameControllerRemoved( + IRawGameControllerStatics *iface, IEventHandler_RawGameController *value, EventRegistrationToken* token) +{ + FIXME("iface %p, value %p, token %p stub!\n", iface, value, token); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE raw_game_controller_statics_remove_RawGameControllerRemoved( + IRawGameControllerStatics *iface, EventRegistrationToken token) +{ + FIXME("iface %p, token %#I64x stub!\n", iface, token.value); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE raw_game_controller_statics_get_RawGameControllers( + IRawGameControllerStatics *iface, IVectorView_RawGameController **value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE raw_game_controller_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; +} + +static const struct IRawGameControllerStaticsVtbl raw_game_controller_statics_vtbl = +{ + raw_game_controller_statics_QueryInterface, + raw_game_controller_statics_AddRef, + raw_game_controller_statics_Release, + /* IInspectable methods */ + raw_game_controller_statics_GetIids, + raw_game_controller_statics_GetRuntimeClassName, + raw_game_controller_statics_GetTrustLevel, + /* IRawGameControllerStatics methods */ + raw_game_controller_statics_add_RawGameControllerAdded, + raw_game_controller_statics_remove_RawGameControllerAdded, + raw_game_controller_statics_add_RawGameControllerRemoved, + raw_game_controller_statics_remove_RawGameControllerRemoved, + raw_game_controller_statics_get_RawGameControllers, + raw_game_controller_statics_FromGameController, +}; + static struct windows_gaming_input windows_gaming_input = { {&activation_factory_vtbl}, {&gamepad_statics_vtbl}, + {&raw_game_controller_statics_vtbl}, 1 }; diff --git a/dlls/windows.gaming.input/tests/input.c b/dlls/windows.gaming.input/tests/input.c index 9462f3a4ed7..2f0cb1a1553 100644 --- a/dlls/windows.gaming.input/tests/input.c +++ b/dlls/windows.gaming.input/tests/input.c @@ -214,6 +214,178 @@ static void test_Gamepad(void) pRoUninitialize(); } +struct controller_event_handler +{ + IEventHandler_RawGameController IEventHandler_RawGameController_iface; + LONG ref; +}; + +static inline struct controller_event_handler *impl_from_IEventHandler_RawGameController(IEventHandler_RawGameController *iface) +{ + return CONTAINING_RECORD(iface, struct controller_event_handler, IEventHandler_RawGameController_iface); +} + +static HRESULT STDMETHODCALLTYPE controller_event_handler_QueryInterface( + IEventHandler_RawGameController *iface, REFIID iid, void **out) +{ + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IEventHandler_RawGameController)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + trace("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE controller_event_handler_AddRef( + IEventHandler_RawGameController *iface) +{ + struct controller_event_handler *impl = impl_from_IEventHandler_RawGameController(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + return ref; +} + +static ULONG STDMETHODCALLTYPE controller_event_handler_Release( + IEventHandler_RawGameController *iface) +{ + struct controller_event_handler *impl = impl_from_IEventHandler_RawGameController(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + return ref; +} + +static HRESULT STDMETHODCALLTYPE controller_event_handler_Invoke( + IEventHandler_RawGameController *iface, IInspectable *sender, IRawGameController *args) +{ + trace("iface %p, sender %p, args %p\n", iface, sender, args); + return S_OK; +} + +static const IEventHandler_RawGameControllerVtbl controller_event_handler_vtbl = +{ + controller_event_handler_QueryInterface, + controller_event_handler_AddRef, + controller_event_handler_Release, + /*** IEventHandler methods ***/ + controller_event_handler_Invoke, +}; + +static void test_RawGameController(void) +{ + static const WCHAR *controller_name = L"Windows.Gaming.Input.RawGameController"; + + struct controller_event_handler controller_event_handler; + EventRegistrationToken token; + IVectorView_RawGameController *controllers = NULL; + IActivationFactory *factory = NULL; + IRawGameControllerStatics *controller_statics = NULL; + IInspectable *inspectable = NULL, *tmp_inspectable = NULL; + IAgileObject *agile_object = NULL, *tmp_agile_object = NULL; + IRawGameController *controller; + BOOLEAN found; + HSTRING str; + HRESULT hr; + ULONG size; + + controller_event_handler.IEventHandler_RawGameController_iface.lpVtbl = &controller_event_handler_vtbl; + + hr = pRoInitialize(RO_INIT_MULTITHREADED); + ok(hr == S_OK || hr == S_FALSE, "RoInitialize failed, hr %#x\n", hr); + + hr = pWindowsCreateString(controller_name, wcslen(controller_name), &str); + ok(hr == S_OK, "WindowsCreateString failed, hr %#x\n", hr); + + hr = pRoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG), "RoGetActivationFactory failed, hr %#x\n", hr); + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip("%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w(controller_name)); + return; + } + + hr = IActivationFactory_QueryInterface(factory, &IID_IInspectable, (void **)&inspectable); + ok(hr == S_OK, "IActivationFactory_QueryInterface IID_IInspectable failed, hr %#x\n", hr); + + hr = IActivationFactory_QueryInterface(factory, &IID_IAgileObject, (void **)&agile_object); + ok(hr == S_OK, "IActivationFactory_QueryInterface IID_IAgileObject failed, hr %#x\n", hr); + + hr = IActivationFactory_QueryInterface(factory, &IID_IRawGameControllerStatics, (void **)&controller_statics); + ok(hr == S_OK, "IActivationFactory_QueryInterface IID_IRawGameControllerStatics failed, hr %#x\n", hr); + + hr = IRawGameControllerStatics_QueryInterface(controller_statics, &IID_IInspectable, (void **)&tmp_inspectable); + ok(hr == S_OK, "IRawGameControllerStatics_QueryInterface IID_IInspectable failed, hr %#x\n", hr); + ok(tmp_inspectable == inspectable, "IRawGameControllerStatics_QueryInterface IID_IInspectable returned %p, expected %p\n", tmp_inspectable, inspectable); + IInspectable_Release(tmp_inspectable); + + hr = IRawGameControllerStatics_QueryInterface(controller_statics, &IID_IAgileObject, (void **)&tmp_agile_object); + ok(hr == S_OK, "IRawGameControllerStatics_QueryInterface IID_IAgileObject failed, hr %#x\n", hr); + ok(tmp_agile_object == agile_object, "IRawGameControllerStatics_QueryInterface IID_IAgileObject returned %p, expected %p\n", tmp_agile_object, agile_object); + IAgileObject_Release(tmp_agile_object); + + hr = IRawGameControllerStatics_get_RawGameControllers(controller_statics, &controllers); + todo_wine ok(hr == S_OK, "IRawGameControllerStatics_get_RawGameControllers failed, hr %#x\n", hr); + if (FAILED(hr)) goto done; + + hr = IVectorView_RawGameController_QueryInterface(controllers, &IID_IInspectable, (void **)&tmp_inspectable); + ok(hr == S_OK, "IVectorView_RawGameController_QueryInterface failed, hr %#x\n", hr); + ok(tmp_inspectable != inspectable, "IVectorView_RawGameController_QueryInterface returned %p, expected %p\n", tmp_inspectable, inspectable); + IInspectable_Release(tmp_inspectable); + + hr = IVectorView_RawGameController_QueryInterface(controllers, &IID_IAgileObject, (void **)&tmp_agile_object); + ok(hr == S_OK, "IVectorView_RawGameController_QueryInterface failed, hr %#x\n", hr); + ok(tmp_agile_object != agile_object, "IVectorView_RawGameController_QueryInterface IID_IAgileObject returned agile_object\n"); + IAgileObject_Release(tmp_agile_object); + + size = 0xdeadbeef; + hr = IVectorView_RawGameController_get_Size(controllers, &size); + ok(hr == S_OK, "IVectorView_RawGameController_get_Size failed, hr %#x\n", hr); + ok(size != 0xdeadbeef, "IVectorView_RawGameController_get_Size returned %u\n", size); + + controller = (IRawGameController *)0xdeadbeef; + hr = IVectorView_RawGameController_GetAt(controllers, size, &controller); + ok(hr == E_BOUNDS, "IVectorView_RawGameController_GetAt failed, hr %#x\n", hr); + ok(controller == NULL, "IVectorView_RawGameController_GetAt returned %p\n", controller); + + size = 0xdeadbeef; + found = TRUE; + controller = (IRawGameController *)0xdeadbeef; + hr = IVectorView_RawGameController_IndexOf(controllers, controller, &size, &found); + ok(hr == S_OK, "IVectorView_RawGameController_IndexOf failed, hr %#x\n", hr); + ok(size == 0 && found == FALSE, "IVectorView_RawGameController_IndexOf returned size %d, found %d\n", size, found); + + IVectorView_RawGameController_Release(controllers); + +done: + token.value = 0xdeadbeef; + hr = IRawGameControllerStatics_add_RawGameControllerAdded(controller_statics, &controller_event_handler.IEventHandler_RawGameController_iface, &token); + todo_wine ok(hr == S_OK, "IRawGameControllerStatics_add_RawGameControllerAdded failed, hr %#x\n", hr); + todo_wine ok(token.value != 0xdeadbeef, "IRawGameControllerStatics_add_RawGameControllerAdded returned token %#I64x\n", token.value); + + hr = IRawGameControllerStatics_remove_RawGameControllerAdded(controller_statics, token); + todo_wine ok(hr == S_OK, "IRawGameControllerStatics_add_RawGameControllerAdded failed, hr %#x\n", hr); + + token.value = 0xdeadbeef; + IRawGameControllerStatics_add_RawGameControllerRemoved(controller_statics, &controller_event_handler.IEventHandler_RawGameController_iface, &token); + todo_wine ok(hr == S_OK, "IRawGameControllerStatics_add_RawGameControllerRemoved failed, hr %#x\n", hr); + todo_wine ok(token.value != 0xdeadbeef, "IRawGameControllerStatics_add_RawGameControllerRemoved returned token %#I64x\n", token.value); + + hr = IRawGameControllerStatics_remove_RawGameControllerRemoved(controller_statics, token); + todo_wine ok(hr == S_OK, "IRawGameControllerStatics_add_RawGameControllerAdded failed, hr %#x\n", hr); + + IRawGameControllerStatics_Release(controller_statics); + + IAgileObject_Release(agile_object); + IInspectable_Release(inspectable); + IActivationFactory_Release(factory); + + pWindowsDeleteString(str); + + pRoUninitialize(); +} + START_TEST(input) { HMODULE combase; @@ -240,4 +412,5 @@ START_TEST(input) #undef LOAD_FUNCPTR test_Gamepad(); + test_RawGameController(); }