From b24e0e059c1734c3a9d287d0be1450c2b29cc259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Mon, 12 Oct 2020 12:50:32 +0200 Subject: [PATCH 2/9] windows.gaming.input: Implement IGamepadStatics stubs. --- .../windows.gaming.input_main.c | 127 +++++++++++++++++ include/windows.foundation.idl | 11 ++ include/windows.gaming.input.idl | 128 ++++++++++++++++++ loader/wine.inf.in | 1 + 4 files changed, 267 insertions(+) diff --git a/dlls/windows.gaming.input.dll/windows.gaming.input_main.c b/dlls/windows.gaming.input.dll/windows.gaming.input_main.c index 2b6abc4dd84..33c260b27b3 100644 --- a/dlls/windows.gaming.input.dll/windows.gaming.input_main.c +++ b/dlls/windows.gaming.input.dll/windows.gaming.input_main.c @@ -10,6 +10,10 @@ #include "initguid.h" #include "activation.h" +#define WIDL_USING_IVECTORVIEW_1_WINDOWS_GAMING_INPUT_GAMEPAD +#define WIDL_USING_IEVENTHANDLER_1_WINDOWS_GAMING_INPUT_GAMEPAD +#define WIDL_USING_WINDOWS_GAMING_INPUT_IGAMEPAD +#define WIDL_USING_WINDOWS_GAMING_INPUT_IGAMEPADSTATICS #include "windows.foundation.h" #include "windows.gaming.input.h" @@ -27,6 +31,7 @@ static const char *debugstr_hstring(HSTRING hstr) struct windows_gaming_input { IActivationFactory IActivationFactory_iface; + IGamepadStatics IGamepadStatics_iface; LONG ref; }; @@ -35,6 +40,120 @@ 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 gamepad_statics_QueryInterface( + IGamepadStatics *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IAgileObject)) + { + 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 gamepad_statics_AddRef( + IGamepadStatics *iface) +{ + struct windows_gaming_input *impl = impl_from_IGamepadStatics(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + TRACE("iface %p, ref %u.\n", iface, ref); + return ref; +} + +static ULONG STDMETHODCALLTYPE gamepad_statics_Release( + IGamepadStatics *iface) +{ + struct windows_gaming_input *impl = impl_from_IGamepadStatics(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + TRACE("iface %p, ref %u.\n", iface, ref); + return ref; +} + +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) +{ + struct windows_gaming_input *impl = impl_from_IGamepadStatics(iface); + 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 HRESULT STDMETHODCALLTYPE windows_gaming_input_QueryInterface( IActivationFactory *iface, REFIID iid, void **out) { @@ -50,6 +169,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; @@ -117,6 +243,7 @@ static const struct IActivationFactoryVtbl activation_factory_vtbl = static struct windows_gaming_input windows_gaming_input = { {&activation_factory_vtbl}, + {&gamepad_statics_vtbl}, 0 }; diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl index 9b9b40897be..dd613b68b00 100644 --- a/include/windows.foundation.idl +++ b/include/windows.foundation.idl @@ -26,6 +26,11 @@ import "windowscontracts.idl"; /* import "eventtoken.idl"; */ /* import "ivectorchangedeventargs.idl"; */ +typedef struct EventRegistrationToken +{ + __int64 value; +} EventRegistrationToken; + namespace Windows { namespace Foundation { [contract(Windows.Foundation.FoundationContract, 1.0)] @@ -119,6 +124,12 @@ namespace Windows { ] delegate void EventHandler([in] IInspectable *sender, [in] T args); + [ + contract(Windows.Foundation.FoundationContract, 1.0), + uuid(9de1c534-6ae1-11e0-84e1-18a905bcc53f) + ] + delegate void TypedEventHandler([in] TSender sender, [in] TResult args); + namespace Collections { [ diff --git a/include/windows.gaming.input.idl b/include/windows.gaming.input.idl index 575f34ccb58..b5af4e24a66 100644 --- a/include/windows.gaming.input.idl +++ b/include/windows.gaming.input.idl @@ -22,3 +22,131 @@ 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; + interface Windows.Foundation.Collections.IVectorView; + } + } + } +} + +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 *value, [out, retval] EventRegistrationToken* token); + [eventremove] HRESULT GamepadAdded([in] EventRegistrationToken token); + [eventadd] HRESULT GamepadRemoved([in] Windows.Foundation.EventHandler *value, [out, retval] EventRegistrationToken* token); + [eventremove] HRESULT GamepadRemoved([in] EventRegistrationToken token); + [propget] HRESULT Gamepads([out, retval] Windows.Foundation.Collections.IVectorView **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; + } + } + } +} diff --git a/loader/wine.inf.in b/loader/wine.inf.in index 157b146a857..9d738859b81 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -713,6 +713,7 @@ HKLM,%MciExtStr%,"wmx",,"MPEGVideo" HKLM,%MciExtStr%,"wvx",,"MPEGVideo" [Misc] +HKLM,Software\Microsoft\WindowsRuntime\ActivatableClassId\Windows.Gaming.Input.Gamepad,"DllPath",2,"Windows.Gaming.Input.dll" HKLM,Software\Microsoft\WindowsRuntime\ActivatableClassId\Windows.Media.SpeechSynthesis.SpeechSynthesizer,"DllPath",2,"Windows.Media.Speech.dll" HKLM,Software\Borland\Database Engine\Settings\SYSTEM\INIT,SHAREDMEMLOCATION,,9000 HKLM,Software\Clients\Mail,,2,"Native Mail Client" -- 2.28.0