Or with a static factory, as Windows.Input.Gamepad for instance.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windows.media.speech/tests/statics.c | 3 +-- tools/widl/register.c | 1 + 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.media.speech/tests/statics.c b/dlls/windows.media.speech/tests/statics.c index 8454729f9c3..9faa49dfc5d 100644 --- a/dlls/windows.media.speech/tests/statics.c +++ b/dlls/windows.media.speech/tests/statics.c @@ -136,8 +136,7 @@ static void test_VoiceInformation(void) ok(SUCCEEDED(hr), "WindowsCreateString failed, hr %#x\n", hr);
hr = pRoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory); - todo_wine ok(hr == REGDB_E_CLASSNOTREG, "RoGetActivationFactory returned unexpected hr %#x\n", hr); - if (SUCCEEDED(hr)) IActivationFactory_Release(factory); + ok(hr == REGDB_E_CLASSNOTREG, "RoGetActivationFactory returned unexpected hr %#x\n", hr);
pWindowsDeleteString(str);
diff --git a/tools/widl/register.c b/tools/widl/register.c index 76bfc3c715c..e13d8451f9e 100644 --- a/tools/widl/register.c +++ b/tools/widl/register.c @@ -194,6 +194,7 @@ static void write_runtimeclasses_registry( const statement_list_t *stmts ) { if (stmt->type != STMT_TYPE) continue; if (type_get_type((type = stmt->u.type)) != TYPE_RUNTIMECLASS) continue; + if (!get_attrp(type->attrs, ATTR_ACTIVATABLE) && !get_attrp(type->attrs, ATTR_STATIC)) continue; put_str( indent, "ForceRemove %s\n", format_namespace( type->namespace, "", ".", type->name, NULL ) ); put_str( indent++, "{\n" ); put_str( indent, "val 'DllPath' = s '%%MODULE%%'\n" );
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- include/Makefile.in | 1 + include/eventtoken.idl | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 include/eventtoken.idl
diff --git a/include/Makefile.in b/include/Makefile.in index d3494dde7a0..6c98f6d6c8b 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -283,6 +283,7 @@ SOURCES = \ errors.h \ errrec.idl \ evcode.h \ + eventtoken.idl \ evntprov.h \ evntrace.h \ evr.idl \ diff --git a/include/eventtoken.idl b/include/eventtoken.idl new file mode 100644 index 00000000000..0d27615a4ad --- /dev/null +++ b/include/eventtoken.idl @@ -0,0 +1,23 @@ +/* + * Copyright 2021 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +struct EventRegistrationToken +{ + __int64 value; +}; +typedef struct EventRegistrationToken EventRegistrationToken;
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- include/windows.gaming.input.idl | 153 +++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 include/windows.gaming.input.idl
diff --git a/include/windows.gaming.input.idl b/include/windows.gaming.input.idl new file mode 100644 index 00000000000..1da22408eeb --- /dev/null +++ b/include/windows.gaming.input.idl @@ -0,0 +1,153 @@ +/* + * Copyright 2021 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef __WIDL__ +#pragma winrt ns_prefix +#endif + +import "eventtoken.idl"; +import "inspectable.idl"; +import "windows.foundation.idl"; + +namespace Windows { + namespace Gaming { + namespace Input { + typedef enum GamepadButtons GamepadButtons; + typedef struct GamepadReading GamepadReading; + typedef struct GamepadVibration GamepadVibration; + interface IGameController; + interface IGameControllerBatteryInfo; + interface IGamepad; + interface IGamepad2; + interface IGamepadStatics; + interface IGamepadStatics2; + runtimeclass Gamepad; + } + } +} + +namespace Windows { + namespace Gaming { + namespace Input { + declare { + interface Windows.Foundation.EventHandler<Windows.Gaming.Input.Gamepad*>; + interface Windows.Foundation.Collections.IVectorView<Gamepad*>; + } + } + } +} + +namespace Windows { + namespace Gaming { + namespace Input { + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + flags + ] + enum GamepadButtons + { + None = 0x0, + Menu = 0x1, + View = 0x2, + A = 0x4, + B = 0x8, + X = 0x10, + Y = 0x20, + DPadUp = 0x40, + DPadDown = 0x80, + DPadLeft = 0x100, + DPadRight = 0x200, + LeftShoulder = 0x400, + RightShoulder = 0x800, + LeftThumbstick = 0x1000, + RightThumbstick = 0x2000, + [contract(Windows.Foundation.UniversalApiContract, 3.0)] + Paddle1 = 0x4000, + [contract(Windows.Foundation.UniversalApiContract, 3.0)] + Paddle2 = 0x8000, + [contract(Windows.Foundation.UniversalApiContract, 3.0)] + Paddle3 = 0x10000, + [contract(Windows.Foundation.UniversalApiContract, 3.0)] + Paddle4 = 0x20000 + }; + + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + struct GamepadReading + { + UINT64 Timestamp; + Windows.Gaming.Input.GamepadButtons Buttons; + DOUBLE LeftTrigger; + DOUBLE RightTrigger; + DOUBLE LeftThumbstickX; + DOUBLE LeftThumbstickY; + DOUBLE RightThumbstickX; + DOUBLE RightThumbstickY; + }; + + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + struct GamepadVibration + { + DOUBLE LeftMotor; + DOUBLE RightMotor; + DOUBLE LeftTrigger; + DOUBLE RightTrigger; + }; + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Gaming.Input.Gamepad), + uuid(bc7bb43c-0a69-3903-9e9d-a50f86a45de5) + ] + interface IGamepad : IInspectable + requires Windows.Gaming.Input.IGameController + { + [propget] HRESULT Vibration([out, retval] Windows.Gaming.Input.GamepadVibration* value); + [propput] HRESULT Vibration([in] Windows.Gaming.Input.GamepadVibration value); + HRESULT GetCurrentReading([out, retval] Windows.Gaming.Input.GamepadReading* value); + } + + [ + object, + uuid(8bbce529-d49c-39e9-9560-e47dde96b7c8) + ] + interface IGamepadStatics : IInspectable + { + [eventadd] HRESULT GamepadAdded([in] Windows.Foundation.EventHandler<Gamepad*> *value, [out, retval] EventRegistrationToken* token); + [eventremove] HRESULT GamepadAdded([in] EventRegistrationToken token); + [eventadd] HRESULT GamepadRemoved([in] Windows.Foundation.EventHandler<Gamepad*> *value, [out, retval] EventRegistrationToken* token); + [eventremove] HRESULT GamepadRemoved([in] EventRegistrationToken token); + [propget] HRESULT Gamepads([out, retval] Windows.Foundation.Collections.IVectorView<Gamepad*> **value); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile), + static(Windows.Gaming.Input.IGamepadStatics, Windows.Foundation.UniversalApiContract, 1.0), + static(Windows.Gaming.Input.IGamepadStatics2, Windows.Foundation.UniversalApiContract, 4.0), + threading(both) + ] + runtimeclass Gamepad + { + [default] interface Windows.Gaming.Input.IGamepad; + interface Windows.Gaming.Input.IGameController; + [contract(Windows.Foundation.UniversalApiContract, 3.0)] interface Windows.Gaming.Input.IGamepad2; + [contract(Windows.Foundation.UniversalApiContract, 4.0)] interface Windows.Gaming.Input.IGameControllerBatteryInfo; + } + } + } +}
Signed-off-by: Jacek Caban jacek@codeweavers.com
Looks like I missed the include/Makefile.in when splitting the patch though, but I see make_makefiles is automatically adding it.
I guess I'm not supposed to include the change then?
On 17.03.2021 17:17, Rémi Bernon wrote:
Looks like I missed the include/Makefile.in when splitting the patch though, but I see make_makefiles is automatically adding it.
I guess I'm not supposed to include the change then?
Yes, you don't need to include include/Makefile.in part (but I don't think it's a problem if you do).
Jacek
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- configure.ac | 2 + dlls/windows.gaming.input/Makefile.in | 9 + dlls/windows.gaming.input/classes.idl | 23 +++ dlls/windows.gaming.input/main.c | 159 ++++++++++++++++++ dlls/windows.gaming.input/tests/Makefile.in | 5 + dlls/windows.gaming.input/tests/statics.c | 150 +++++++++++++++++ .../windows.gaming.input.spec | 3 + include/Makefile.in | 1 + 8 files changed, 352 insertions(+) create mode 100644 dlls/windows.gaming.input/Makefile.in create mode 100644 dlls/windows.gaming.input/classes.idl create mode 100644 dlls/windows.gaming.input/main.c create mode 100644 dlls/windows.gaming.input/tests/Makefile.in create mode 100644 dlls/windows.gaming.input/tests/statics.c create mode 100644 dlls/windows.gaming.input/windows.gaming.input.spec
diff --git a/configure.ac b/configure.ac index 8c092fb020c..6c2e9fa57ad 100644 --- a/configure.ac +++ b/configure.ac @@ -3801,6 +3801,8 @@ WINE_CONFIG_MAKEFILE(dlls/win32s16.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/win87em.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/winaspi.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/windebug.dll16,enable_win16) +WINE_CONFIG_MAKEFILE(dlls/windows.gaming.input) +WINE_CONFIG_MAKEFILE(dlls/windows.gaming.input/tests) WINE_CONFIG_MAKEFILE(dlls/windows.media.speech) WINE_CONFIG_MAKEFILE(dlls/windows.media.speech/tests) WINE_CONFIG_MAKEFILE(dlls/windowscodecs) diff --git a/dlls/windows.gaming.input/Makefile.in b/dlls/windows.gaming.input/Makefile.in new file mode 100644 index 00000000000..1673eaabaa7 --- /dev/null +++ b/dlls/windows.gaming.input/Makefile.in @@ -0,0 +1,9 @@ +MODULE = windows.gaming.input.dll +IMPORTS = combase uuid + +EXTRADLLFLAGS = -mno-cygwin + +C_SRCS = \ + main.c + +IDL_SRCS = classes.idl diff --git a/dlls/windows.gaming.input/classes.idl b/dlls/windows.gaming.input/classes.idl new file mode 100644 index 00000000000..c9cb91e3182 --- /dev/null +++ b/dlls/windows.gaming.input/classes.idl @@ -0,0 +1,23 @@ +/* + * Runtime Classes for windows.gaming.input.dll + * + * Copyright 2021 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma makedep register + +#include "windows.gaming.input.idl" diff --git a/dlls/windows.gaming.input/main.c b/dlls/windows.gaming.input/main.c new file mode 100644 index 00000000000..05ef844893b --- /dev/null +++ b/dlls/windows.gaming.input/main.c @@ -0,0 +1,159 @@ +/* WinRT Windows.Gaming.Input implementation + * + * Copyright 2021 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winstring.h" +#include "wine/debug.h" +#include "objbase.h" + +#include "initguid.h" +#include "activation.h" + +#include "windows.foundation.h" +#include "windows.gaming.input.h" + +WINE_DEFAULT_DEBUG_CHANNEL(input); + +static const char *debugstr_hstring(HSTRING hstr) +{ + const WCHAR *str; + UINT32 len; + if (hstr && !((ULONG_PTR)hstr >> 16)) return "(invalid)"; + str = WindowsGetStringRawBuffer(hstr, &len); + return wine_dbgstr_wn(str, len); +} + +struct windows_gaming_input +{ + IActivationFactory IActivationFactory_iface; + LONG ref; +}; + +static inline struct windows_gaming_input *impl_from_IActivationFactory(IActivationFactory *iface) +{ + return CONTAINING_RECORD(iface, struct windows_gaming_input, IActivationFactory_iface); +} + +static HRESULT STDMETHODCALLTYPE windows_gaming_input_QueryInterface( + IActivationFactory *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IInspectable) || + IsEqualGUID(iid, &IID_IAgileObject) || + IsEqualGUID(iid, &IID_IActivationFactory)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE windows_gaming_input_AddRef( + IActivationFactory *iface) +{ + struct windows_gaming_input *impl = impl_from_IActivationFactory(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + TRACE("iface %p, ref %u.\n", iface, ref); + return ref; +} + +static ULONG STDMETHODCALLTYPE windows_gaming_input_Release( + IActivationFactory *iface) +{ + struct windows_gaming_input *impl = impl_from_IActivationFactory(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + TRACE("iface %p, ref %u.\n", iface, ref); + return ref; +} + +static HRESULT STDMETHODCALLTYPE windows_gaming_input_GetIids( + IActivationFactory *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 windows_gaming_input_GetRuntimeClassName( + IActivationFactory *iface, HSTRING *class_name) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE windows_gaming_input_GetTrustLevel( + IActivationFactory *iface, TrustLevel *trust_level) +{ + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE windows_gaming_input_ActivateInstance( + IActivationFactory *iface, IInspectable **instance) +{ + FIXME("iface %p, instance %p stub!\n", iface, instance); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl activation_factory_vtbl = +{ + windows_gaming_input_QueryInterface, + windows_gaming_input_AddRef, + windows_gaming_input_Release, + /* IInspectable methods */ + windows_gaming_input_GetIids, + windows_gaming_input_GetRuntimeClassName, + windows_gaming_input_GetTrustLevel, + /* IActivationFactory methods */ + windows_gaming_input_ActivateInstance, +}; + +static struct windows_gaming_input windows_gaming_input = +{ + {&activation_factory_vtbl}, + 1 +}; + +HRESULT WINAPI DllCanUnloadNow(void) +{ + return S_FALSE; +} + +HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **out) +{ + FIXME("clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid), debugstr_guid(riid), out); + return CLASS_E_CLASSNOTAVAILABLE; +} + +HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **factory) +{ + TRACE("classid %s, factory %p.\n", debugstr_hstring(classid), factory); + *factory = &windows_gaming_input.IActivationFactory_iface; + IUnknown_AddRef(*factory); + return S_OK; +} diff --git a/dlls/windows.gaming.input/tests/Makefile.in b/dlls/windows.gaming.input/tests/Makefile.in new file mode 100644 index 00000000000..08c8368e883 --- /dev/null +++ b/dlls/windows.gaming.input/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = windows.gaming.input.dll +IMPORTS = uuid + +C_SRCS = \ + statics.c diff --git a/dlls/windows.gaming.input/tests/statics.c b/dlls/windows.gaming.input/tests/statics.c new file mode 100644 index 00000000000..8144a3fb8e8 --- /dev/null +++ b/dlls/windows.gaming.input/tests/statics.c @@ -0,0 +1,150 @@ +/* + * Copyright 2021 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winstring.h" + +#include "initguid.h" +#include "roapi.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Gaming_Input +#include "windows.gaming.input.h" + +#include "wine/test.h" + +static HRESULT (WINAPI *pRoActivateInstance)(HSTRING, IInspectable **); +static HRESULT (WINAPI *pRoGetActivationFactory)(HSTRING, REFIID, void **); +static HRESULT (WINAPI *pRoInitialize)(RO_INIT_TYPE); +static void (WINAPI *pRoUninitialize)(void); +static HRESULT (WINAPI *pWindowsCreateString)(LPCWSTR, UINT32, HSTRING *); +static HRESULT (WINAPI *pWindowsDeleteString)(HSTRING); + +static void test_Gamepad(void) +{ + static const WCHAR *gamepad_name = L"Windows.Gaming.Input.Gamepad"; + + IVectorView_Gamepad *gamepads = NULL; + IActivationFactory *factory = NULL; + IGamepadStatics *gamepad_statics = NULL; + IInspectable *inspectable = NULL, *tmp_inspectable = NULL; + IAgileObject *agile_object = NULL, *tmp_agile_object = NULL; + HSTRING str; + HRESULT hr; + ULONG rc, size; + + hr = pRoInitialize(RO_INIT_MULTITHREADED); + ok(SUCCEEDED(hr), "RoInitialize failed, hr %#x\n", hr); + + hr = pWindowsCreateString(gamepad_name, wcslen(gamepad_name), &str); + ok(SUCCEEDED(hr), "WindowsCreateString failed, hr %#x\n", hr); + + hr = pRoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory); + ok(SUCCEEDED(hr) || 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(gamepad_name)); + return; + } + + hr = IActivationFactory_QueryInterface(factory, &IID_IInspectable, (void **)&inspectable); + ok(SUCCEEDED(hr), "IActivationFactory_QueryInterface IID_IInspectable failed, hr %#x\n", hr); + + hr = IActivationFactory_QueryInterface(factory, &IID_IAgileObject, (void **)&agile_object); + ok(SUCCEEDED(hr), "IActivationFactory_QueryInterface IID_IAgileObject failed, hr %#x\n", hr); + + hr = IActivationFactory_QueryInterface(factory, &IID_IGamepadStatics, (void **)&gamepad_statics); + todo_wine ok(SUCCEEDED(hr), "IActivationFactory_QueryInterface IID_IGamepadStatics failed, hr %#x\n", hr); + if (FAILED(hr)) goto done; + + hr = IGamepadStatics_QueryInterface(gamepad_statics, &IID_IInspectable, (void **)&tmp_inspectable); + ok(SUCCEEDED(hr), "IGamepadStatics_QueryInterface IID_IInspectable failed, hr %#x\n", hr); + ok(tmp_inspectable == inspectable, "IGamepadStatics_QueryInterface IID_IInspectable returned %p, expected %p\n", tmp_inspectable, inspectable); + IInspectable_Release(tmp_inspectable); + + hr = IGamepadStatics_QueryInterface(gamepad_statics, &IID_IAgileObject, (void **)&tmp_agile_object); + ok(SUCCEEDED(hr), "IGamepadStatics_QueryInterface IID_IAgileObject failed, hr %#x\n", hr); + ok(tmp_agile_object == agile_object, "IGamepadStatics_QueryInterface IID_IAgileObject returned %p, expected %p\n", tmp_agile_object, agile_object); + IAgileObject_Release(tmp_agile_object); + + hr = IGamepadStatics_get_Gamepads(gamepad_statics, &gamepads); + ok(SUCCEEDED(hr), "IGamepadStatics_get_Gamepads failed, hr %#x\n", hr); + + hr = IVectorView_Gamepad_QueryInterface(gamepads, &IID_IInspectable, (void **)&tmp_inspectable); + ok(SUCCEEDED(hr), "IVectorView_Gamepad_QueryInterface failed, hr %#x\n", hr); + ok(tmp_inspectable != inspectable, "IVectorView_Gamepad_QueryInterface returned %p, expected %p\n", tmp_inspectable, inspectable); + IInspectable_Release(tmp_inspectable); + + hr = IVectorView_Gamepad_QueryInterface(gamepads, &IID_IAgileObject, (void **)&tmp_agile_object); + ok(SUCCEEDED(hr), "IVectorView_Gamepad_QueryInterface failed, hr %#x\n", hr); + ok(tmp_agile_object != agile_object, "IVectorView_Gamepad_QueryInterface IID_IAgileObject returned agile_object\n"); + IAgileObject_Release(tmp_agile_object); + + size = 0xdeadbeef; + hr = IVectorView_Gamepad_get_Size(gamepads, &size); + ok(SUCCEEDED(hr), "IVectorView_Gamepad_QueryInterface failed, hr %#x\n", hr); + todo_wine ok(size != 0xdeadbeef, "IVectorView_Gamepad_get_Size returned %u\n", size); + + rc = IVectorView_Gamepad_Release(gamepads); + todo_wine ok(rc == 1, "IVectorView_Gamepad_Release returned unexpected refcount %d\n", rc); + + IGamepadStatics_Release(gamepad_statics); + +done: + IAgileObject_Release(agile_object); + IInspectable_Release(inspectable); + IActivationFactory_Release(factory); + + pWindowsDeleteString(str); + + pRoUninitialize(); +} + +START_TEST(statics) +{ + HMODULE combase; + + if (!(combase = LoadLibraryW(L"combase.dll"))) + { + win_skip("Failed to load combase.dll, skipping tests\n"); + return; + } + +#define LOAD_FUNCPTR(x) \ + if (!(p##x = (void*)GetProcAddress(combase, #x))) \ + { \ + win_skip("Failed to find %s in combase.dll, skipping tests.\n", #x); \ + return; \ + } + + LOAD_FUNCPTR(RoActivateInstance); + LOAD_FUNCPTR(RoGetActivationFactory); + LOAD_FUNCPTR(RoInitialize); + LOAD_FUNCPTR(RoUninitialize); + LOAD_FUNCPTR(WindowsCreateString); + LOAD_FUNCPTR(WindowsDeleteString); +#undef LOAD_FUNCPTR + + test_Gamepad(); +} diff --git a/dlls/windows.gaming.input/windows.gaming.input.spec b/dlls/windows.gaming.input/windows.gaming.input.spec new file mode 100644 index 00000000000..20a8bfa98ea --- /dev/null +++ b/dlls/windows.gaming.input/windows.gaming.input.spec @@ -0,0 +1,3 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetActivationFactory(ptr ptr) +@ stdcall -private DllGetClassObject(ptr ptr ptr) diff --git a/include/Makefile.in b/include/Makefile.in index 6c98f6d6c8b..1c80421ef6f 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -750,6 +750,7 @@ SOURCES = \ windns.h \ windows.foundation.collections.idl \ windows.foundation.idl \ + windows.gaming.input.idl \ windows.h \ windows.media.speechsynthesis.idl \ windowscontracts.idl \
- size = 0xdeadbeef;
- hr = IVectorView_Gamepad_get_Size(gamepads, &size);
- ok(SUCCEEDED(hr), "IVectorView_Gamepad_QueryInterface failed, hr %#x\n", hr);
- todo_wine ok(size != 0xdeadbeef, "IVectorView_Gamepad_get_Size returned %u\n", size);
- rc = IVectorView_Gamepad_Release(gamepads);
- todo_wine ok(rc == 1, "IVectorView_Gamepad_Release returned unexpected refcount %d\n", rc);
There's a typo in the message here and the refcount test could probably be dropped as I dropped the others. Compared to windows.media.speechsynthesis tests, refcount for these classes isn't always the same on the testbot Windows VMs, so it didn't seem very relevant to keep the tests.
However, I've got more tests to send with GamepadAdded/Removed event handlers as well as RawGameController runtimeclass, so unless there's some other changes to make elsewhere I'd rather not resend this series just for that.
Cheers,
On 17.03.2021 14:33, Rémi Bernon wrote:
+ size = 0xdeadbeef; + hr = IVectorView_Gamepad_get_Size(gamepads, &size); + ok(SUCCEEDED(hr), "IVectorView_Gamepad_QueryInterface failed, hr %#x\n", hr); + todo_wine ok(size != 0xdeadbeef, "IVectorView_Gamepad_get_Size returned %u\n", size);
+ rc = IVectorView_Gamepad_Release(gamepads); + todo_wine ok(rc == 1, "IVectorView_Gamepad_Release returned unexpected refcount %d\n", rc);
There's a typo in the message here and the refcount test could probably be dropped as I dropped the others. Compared to windows.media.speechsynthesis tests, refcount for these classes isn't always the same on the testbot Windows VMs, so it didn't seem very relevant to keep the tests.
Yes, tests for exact ref count values are very rarely interesting and it would be better to drop them.
However, I've got more tests to send with GamepadAdded/Removed event handlers as well as RawGameController runtimeclass, so unless there's some other changes to make elsewhere I'd rather not resend this series just for that.
There are some things that I would find nice to change. I didn't want to reject speech patches just for that, but since it's becoming a template, it's worth mentioning:
- Testing for the exact (usually S_OK) value instead of SUCCEED() in ok() macros is generally better. It's more strict and catches cases where we should return things like S_FALSE instead.
- I would call tests something like input.c instead. We will never have more test files for most of those DLLs, so if we need some 'non-statics' tests in the future, it would be good if they fit the existing file.
Thanks,
Jacek
On 3/17/21 2:52 PM, Jacek Caban wrote:
On 17.03.2021 14:33, Rémi Bernon wrote:
+ size = 0xdeadbeef; + hr = IVectorView_Gamepad_get_Size(gamepads, &size); + ok(SUCCEEDED(hr), "IVectorView_Gamepad_QueryInterface failed, hr %#x\n", hr); + todo_wine ok(size != 0xdeadbeef, "IVectorView_Gamepad_get_Size returned %u\n", size);
+ rc = IVectorView_Gamepad_Release(gamepads); + todo_wine ok(rc == 1, "IVectorView_Gamepad_Release returned unexpected refcount %d\n", rc);
There's a typo in the message here and the refcount test could probably be dropped as I dropped the others. Compared to windows.media.speechsynthesis tests, refcount for these classes isn't always the same on the testbot Windows VMs, so it didn't seem very relevant to keep the tests.
Yes, tests for exact ref count values are very rarely interesting and it would be better to drop them.
However, I've got more tests to send with GamepadAdded/Removed event handlers as well as RawGameController runtimeclass, so unless there's some other changes to make elsewhere I'd rather not resend this series just for that.
There are some things that I would find nice to change. I didn't want to reject speech patches just for that, but since it's becoming a template, it's worth mentioning:
- Testing for the exact (usually S_OK) value instead of SUCCEED() in
ok() macros is generally better. It's more strict and catches cases where we should return things like S_FALSE instead.
- I would call tests something like input.c instead. We will never have
more test files for most of those DLLs, so if we need some 'non-statics' tests in the future, it would be good if they fit the existing file.
Thanks,
Jacek
Right, works for me. If the widl and include changes are good, I can resend the last 4 patches later with the test changes (and clean the speech tests accordingly to make them consistent).
On 17.03.2021 15:05, Rémi Bernon wrote:
On 3/17/21 2:52 PM, Jacek Caban wrote:
On 17.03.2021 14:33, Rémi Bernon wrote:
+ size = 0xdeadbeef; + hr = IVectorView_Gamepad_get_Size(gamepads, &size); + ok(SUCCEEDED(hr), "IVectorView_Gamepad_QueryInterface failed, hr %#x\n", hr); + todo_wine ok(size != 0xdeadbeef, "IVectorView_Gamepad_get_Size returned %u\n", size);
+ rc = IVectorView_Gamepad_Release(gamepads); + todo_wine ok(rc == 1, "IVectorView_Gamepad_Release returned unexpected refcount %d\n", rc);
There's a typo in the message here and the refcount test could probably be dropped as I dropped the others. Compared to windows.media.speechsynthesis tests, refcount for these classes isn't always the same on the testbot Windows VMs, so it didn't seem very relevant to keep the tests.
Yes, tests for exact ref count values are very rarely interesting and it would be better to drop them.
However, I've got more tests to send with GamepadAdded/Removed event handlers as well as RawGameController runtimeclass, so unless there's some other changes to make elsewhere I'd rather not resend this series just for that.
There are some things that I would find nice to change. I didn't want to reject speech patches just for that, but since it's becoming a template, it's worth mentioning:
- Testing for the exact (usually S_OK) value instead of SUCCEED() in
ok() macros is generally better. It's more strict and catches cases where we should return things like S_FALSE instead.
- I would call tests something like input.c instead. We will never
have more test files for most of those DLLs, so if we need some 'non-statics' tests in the future, it would be good if they fit the existing file.
Thanks,
Jacek
Right, works for me. If the widl and include changes are good, I can resend the last 4 patches later with the test changes (and clean the speech tests accordingly to make them consistent).
Sounds good to me.
Jacek
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windows.gaming.input/main.c | 113 ++++++++++++++++++++++ dlls/windows.gaming.input/tests/statics.c | 8 +- 2 files changed, 117 insertions(+), 4 deletions(-)
diff --git a/dlls/windows.gaming.input/main.c b/dlls/windows.gaming.input/main.c index 05ef844893b..50d73a1adf4 100644 --- a/dlls/windows.gaming.input/main.c +++ b/dlls/windows.gaming.input/main.c @@ -29,7 +29,10 @@ #include "initguid.h" #include "activation.h"
+#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections #include "windows.foundation.h" +#define WIDL_using_Windows_Gaming_Input #include "windows.gaming.input.h"
WINE_DEFAULT_DEBUG_CHANNEL(input); @@ -46,6 +49,7 @@ static const char *debugstr_hstring(HSTRING hstr) struct windows_gaming_input { IActivationFactory IActivationFactory_iface; + IGamepadStatics IGamepadStatics_iface; LONG ref; };
@@ -54,9 +58,16 @@ static inline struct windows_gaming_input *impl_from_IActivationFactory(IActivat return CONTAINING_RECORD(iface, struct windows_gaming_input, IActivationFactory_iface); }
+static inline struct windows_gaming_input *impl_from_IGamepadStatics(IGamepadStatics *iface) +{ + return CONTAINING_RECORD(iface, struct windows_gaming_input, IGamepadStatics_iface); +} + static HRESULT STDMETHODCALLTYPE windows_gaming_input_QueryInterface( IActivationFactory *iface, REFIID iid, void **out) { + struct windows_gaming_input *impl = impl_from_IActivationFactory(iface); + TRACE("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out);
if (IsEqualGUID(iid, &IID_IUnknown) || @@ -69,6 +80,13 @@ static HRESULT STDMETHODCALLTYPE windows_gaming_input_QueryInterface( return S_OK; }
+ if (IsEqualGUID(iid, &IID_IGamepadStatics)) + { + IUnknown_AddRef(iface); + *out = &impl->IGamepadStatics_iface; + return S_OK; + } + FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); *out = NULL; return E_NOINTERFACE; @@ -133,9 +151,104 @@ static const struct IActivationFactoryVtbl activation_factory_vtbl = windows_gaming_input_ActivateInstance, };
+static HRESULT STDMETHODCALLTYPE gamepad_statics_QueryInterface( + IGamepadStatics *iface, REFIID iid, void **out) +{ + struct windows_gaming_input *impl = impl_from_IGamepadStatics(iface); + return windows_gaming_input_QueryInterface(&impl->IActivationFactory_iface, iid, out); +} + +static ULONG STDMETHODCALLTYPE gamepad_statics_AddRef( + IGamepadStatics *iface) +{ + struct windows_gaming_input *impl = impl_from_IGamepadStatics(iface); + return windows_gaming_input_AddRef(&impl->IActivationFactory_iface); +} + +static ULONG STDMETHODCALLTYPE gamepad_statics_Release( + IGamepadStatics *iface) +{ + struct windows_gaming_input *impl = impl_from_IGamepadStatics(iface); + return windows_gaming_input_Release(&impl->IActivationFactory_iface); +} + +static HRESULT STDMETHODCALLTYPE gamepad_statics_GetIids( + IGamepadStatics *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 gamepad_statics_GetRuntimeClassName( + IGamepadStatics *iface, HSTRING *class_name) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE gamepad_statics_GetTrustLevel( + IGamepadStatics *iface, TrustLevel *trust_level) +{ + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE gamepad_statics_add_GamepadAdded( + IGamepadStatics *iface, IEventHandler_Gamepad *value, EventRegistrationToken* token) +{ + FIXME("iface %p, value %p, token %p stub!\n", iface, value, token); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE gamepad_statics_remove_GamepadAdded( + IGamepadStatics *iface, EventRegistrationToken token) +{ + FIXME("iface %p, token %#I64x stub!\n", iface, token.value); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE gamepad_statics_add_GamepadRemoved( + IGamepadStatics *iface, IEventHandler_Gamepad *value, EventRegistrationToken* token) +{ + FIXME("iface %p, value %p, token %p stub!\n", iface, value, token); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE gamepad_statics_remove_GamepadRemoved( + IGamepadStatics *iface, EventRegistrationToken token) +{ + FIXME("iface %p, token %#I64x stub!\n", iface, token.value); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE gamepad_statics_get_Gamepads( + IGamepadStatics *iface, IVectorView_Gamepad **value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + return E_NOTIMPL; +} + +static const struct IGamepadStaticsVtbl gamepad_statics_vtbl = +{ + gamepad_statics_QueryInterface, + gamepad_statics_AddRef, + gamepad_statics_Release, + /* IInspectable methods */ + gamepad_statics_GetIids, + gamepad_statics_GetRuntimeClassName, + gamepad_statics_GetTrustLevel, + /* IGamepadStatics methods */ + gamepad_statics_add_GamepadAdded, + gamepad_statics_remove_GamepadAdded, + gamepad_statics_add_GamepadRemoved, + gamepad_statics_remove_GamepadRemoved, + gamepad_statics_get_Gamepads, +}; + static struct windows_gaming_input windows_gaming_input = { {&activation_factory_vtbl}, + {&gamepad_statics_vtbl}, 1 };
diff --git a/dlls/windows.gaming.input/tests/statics.c b/dlls/windows.gaming.input/tests/statics.c index 8144a3fb8e8..de04bdf4cf3 100644 --- a/dlls/windows.gaming.input/tests/statics.c +++ b/dlls/windows.gaming.input/tests/statics.c @@ -75,8 +75,7 @@ static void test_Gamepad(void) ok(SUCCEEDED(hr), "IActivationFactory_QueryInterface IID_IAgileObject failed, hr %#x\n", hr);
hr = IActivationFactory_QueryInterface(factory, &IID_IGamepadStatics, (void **)&gamepad_statics); - todo_wine ok(SUCCEEDED(hr), "IActivationFactory_QueryInterface IID_IGamepadStatics failed, hr %#x\n", hr); - if (FAILED(hr)) goto done; + ok(SUCCEEDED(hr), "IActivationFactory_QueryInterface IID_IGamepadStatics failed, hr %#x\n", hr);
hr = IGamepadStatics_QueryInterface(gamepad_statics, &IID_IInspectable, (void **)&tmp_inspectable); ok(SUCCEEDED(hr), "IGamepadStatics_QueryInterface IID_IInspectable failed, hr %#x\n", hr); @@ -89,7 +88,8 @@ static void test_Gamepad(void) IAgileObject_Release(tmp_agile_object);
hr = IGamepadStatics_get_Gamepads(gamepad_statics, &gamepads); - ok(SUCCEEDED(hr), "IGamepadStatics_get_Gamepads failed, hr %#x\n", hr); + todo_wine ok(SUCCEEDED(hr), "IGamepadStatics_get_Gamepads failed, hr %#x\n", hr); + if (FAILED(hr)) goto done;
hr = IVectorView_Gamepad_QueryInterface(gamepads, &IID_IInspectable, (void **)&tmp_inspectable); ok(SUCCEEDED(hr), "IVectorView_Gamepad_QueryInterface failed, hr %#x\n", hr); @@ -109,9 +109,9 @@ static void test_Gamepad(void) rc = IVectorView_Gamepad_Release(gamepads); todo_wine ok(rc == 1, "IVectorView_Gamepad_Release returned unexpected refcount %d\n", rc);
+done: IGamepadStatics_Release(gamepad_statics);
-done: IAgileObject_Release(agile_object); IInspectable_Release(inspectable); IActivationFactory_Release(factory);
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windows.gaming.input/main.c | 126 +++++++++++++++++++++- dlls/windows.gaming.input/tests/statics.c | 6 +- 2 files changed, 126 insertions(+), 6 deletions(-)
diff --git a/dlls/windows.gaming.input/main.c b/dlls/windows.gaming.input/main.c index 50d73a1adf4..5e349d98fab 100644 --- a/dlls/windows.gaming.input/main.c +++ b/dlls/windows.gaming.input/main.c @@ -46,6 +46,126 @@ static const char *debugstr_hstring(HSTRING hstr) return wine_dbgstr_wn(str, len); }
+struct gamepad_vector +{ + IVectorView_Gamepad IVectorView_Gamepad_iface; + LONG ref; +}; + +static inline struct gamepad_vector *impl_from_IVectorView_Gamepad(IVectorView_Gamepad *iface) +{ + return CONTAINING_RECORD(iface, struct gamepad_vector, IVectorView_Gamepad_iface); +} + +static HRESULT STDMETHODCALLTYPE vector_view_gamepad_QueryInterface( + IVectorView_Gamepad *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IInspectable) || + IsEqualGUID(iid, &IID_IAgileObject) || + IsEqualGUID(iid, &IID_IVectorView_Gamepad)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE vector_view_gamepad_AddRef( + IVectorView_Gamepad *iface) +{ + struct gamepad_vector *impl = impl_from_IVectorView_Gamepad(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + TRACE("iface %p, ref %u.\n", iface, ref); + return ref; +} + +static ULONG STDMETHODCALLTYPE vector_view_gamepad_Release( + IVectorView_Gamepad *iface) +{ + struct gamepad_vector *impl = impl_from_IVectorView_Gamepad(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + TRACE("iface %p, ref %u.\n", iface, ref); + return ref; +} + +static HRESULT STDMETHODCALLTYPE vector_view_gamepad_GetIids( + IVectorView_Gamepad *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 vector_view_gamepad_GetRuntimeClassName( + IVectorView_Gamepad *iface, HSTRING *class_name) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE vector_view_gamepad_GetTrustLevel( + IVectorView_Gamepad *iface, TrustLevel *trust_level) +{ + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE vector_view_gamepad_GetAt( + IVectorView_Gamepad *iface, ULONG index, IGamepad **value) +{ + FIXME("iface %p, index %#x, value %p stub!\n", iface, index, value); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE vector_view_gamepad_get_Size( + IVectorView_Gamepad *iface, ULONG *value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE vector_view_gamepad_IndexOf( + IVectorView_Gamepad *iface, IGamepad *element, ULONG *index, BOOLEAN *value) +{ + FIXME("iface %p, element %p, index %p, value %p stub!\n", iface, element, index, value); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE vector_view_gamepad_GetMany( + IVectorView_Gamepad *iface, ULONG start_index, IGamepad **items, UINT *value) +{ + FIXME("iface %p, start_index %#x, items %p, value %p stub!\n", iface, start_index, items, value); + return E_NOTIMPL; +} + +static const struct IVectorView_GamepadVtbl vector_view_gamepad_vtbl = +{ + vector_view_gamepad_QueryInterface, + vector_view_gamepad_AddRef, + vector_view_gamepad_Release, + /* IInspectable methods */ + vector_view_gamepad_GetIids, + vector_view_gamepad_GetRuntimeClassName, + vector_view_gamepad_GetTrustLevel, + /* IVectorView<VoiceInformation> methods */ + vector_view_gamepad_GetAt, + vector_view_gamepad_get_Size, + vector_view_gamepad_IndexOf, + vector_view_gamepad_GetMany, +}; + +static struct gamepad_vector gamepads = +{ + {&vector_view_gamepad_vtbl}, + 0 +}; + struct windows_gaming_input { IActivationFactory IActivationFactory_iface; @@ -224,8 +344,10 @@ static HRESULT STDMETHODCALLTYPE gamepad_statics_remove_GamepadRemoved( static HRESULT STDMETHODCALLTYPE gamepad_statics_get_Gamepads( IGamepadStatics *iface, IVectorView_Gamepad **value) { - FIXME("iface %p, value %p stub!\n", iface, value); - return E_NOTIMPL; + TRACE("iface %p, value %p.\n", iface, value); + *value = &gamepads.IVectorView_Gamepad_iface; + IVectorView_Gamepad_AddRef(*value); + return S_OK; }
static const struct IGamepadStaticsVtbl gamepad_statics_vtbl = diff --git a/dlls/windows.gaming.input/tests/statics.c b/dlls/windows.gaming.input/tests/statics.c index de04bdf4cf3..699cf6fc9f7 100644 --- a/dlls/windows.gaming.input/tests/statics.c +++ b/dlls/windows.gaming.input/tests/statics.c @@ -88,8 +88,7 @@ static void test_Gamepad(void) IAgileObject_Release(tmp_agile_object);
hr = IGamepadStatics_get_Gamepads(gamepad_statics, &gamepads); - todo_wine ok(SUCCEEDED(hr), "IGamepadStatics_get_Gamepads failed, hr %#x\n", hr); - if (FAILED(hr)) goto done; + ok(SUCCEEDED(hr), "IGamepadStatics_get_Gamepads failed, hr %#x\n", hr);
hr = IVectorView_Gamepad_QueryInterface(gamepads, &IID_IInspectable, (void **)&tmp_inspectable); ok(SUCCEEDED(hr), "IVectorView_Gamepad_QueryInterface failed, hr %#x\n", hr); @@ -103,13 +102,12 @@ static void test_Gamepad(void)
size = 0xdeadbeef; hr = IVectorView_Gamepad_get_Size(gamepads, &size); - ok(SUCCEEDED(hr), "IVectorView_Gamepad_QueryInterface failed, hr %#x\n", hr); + todo_wine ok(SUCCEEDED(hr), "IVectorView_Gamepad_QueryInterface failed, hr %#x\n", hr); todo_wine ok(size != 0xdeadbeef, "IVectorView_Gamepad_get_Size returned %u\n", size);
rc = IVectorView_Gamepad_Release(gamepads); todo_wine ok(rc == 1, "IVectorView_Gamepad_Release returned unexpected refcount %d\n", rc);
-done: IGamepadStatics_Release(gamepad_statics);
IAgileObject_Release(agile_object);
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windows.gaming.input/main.c | 11 +++++++---- dlls/windows.gaming.input/tests/statics.c | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/dlls/windows.gaming.input/main.c b/dlls/windows.gaming.input/main.c index 5e349d98fab..b1ba55f9018 100644 --- a/dlls/windows.gaming.input/main.c +++ b/dlls/windows.gaming.input/main.c @@ -120,28 +120,31 @@ static HRESULT STDMETHODCALLTYPE vector_view_gamepad_GetAt( IVectorView_Gamepad *iface, ULONG index, IGamepad **value) { FIXME("iface %p, index %#x, value %p stub!\n", iface, index, value); - return E_NOTIMPL; + return S_OK; }
static HRESULT STDMETHODCALLTYPE vector_view_gamepad_get_Size( IVectorView_Gamepad *iface, ULONG *value) { FIXME("iface %p, value %p stub!\n", iface, value); - return E_NOTIMPL; + *value = 0; + return S_OK; }
static HRESULT STDMETHODCALLTYPE vector_view_gamepad_IndexOf( IVectorView_Gamepad *iface, IGamepad *element, ULONG *index, BOOLEAN *value) { FIXME("iface %p, element %p, index %p, value %p stub!\n", iface, element, index, value); - return E_NOTIMPL; + *value = FALSE; + return S_OK; }
static HRESULT STDMETHODCALLTYPE vector_view_gamepad_GetMany( IVectorView_Gamepad *iface, ULONG start_index, IGamepad **items, UINT *value) { FIXME("iface %p, start_index %#x, items %p, value %p stub!\n", iface, start_index, items, value); - return E_NOTIMPL; + *value = 0; + return S_OK; }
static const struct IVectorView_GamepadVtbl vector_view_gamepad_vtbl = diff --git a/dlls/windows.gaming.input/tests/statics.c b/dlls/windows.gaming.input/tests/statics.c index 699cf6fc9f7..f381a015fe7 100644 --- a/dlls/windows.gaming.input/tests/statics.c +++ b/dlls/windows.gaming.input/tests/statics.c @@ -102,8 +102,8 @@ static void test_Gamepad(void)
size = 0xdeadbeef; hr = IVectorView_Gamepad_get_Size(gamepads, &size); - todo_wine ok(SUCCEEDED(hr), "IVectorView_Gamepad_QueryInterface failed, hr %#x\n", hr); - todo_wine ok(size != 0xdeadbeef, "IVectorView_Gamepad_get_Size returned %u\n", size); + ok(SUCCEEDED(hr), "IVectorView_Gamepad_QueryInterface failed, hr %#x\n", hr); + ok(size != 0xdeadbeef, "IVectorView_Gamepad_get_Size returned %u\n", size);
rc = IVectorView_Gamepad_Release(gamepads); todo_wine ok(rc == 1, "IVectorView_Gamepad_Release returned unexpected refcount %d\n", rc);