[PATCH 2/4] windows.gaming.input: Implement CreateGameController for Gamepad runtimeclass.

Rémi Bernon rbernon at codeweavers.com
Wed Mar 9 02:47:58 CST 2022


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/windows.gaming.input/gamepad.c | 195 +++++++++++++++++++++++++++-
 1 file changed, 193 insertions(+), 2 deletions(-)

diff --git a/dlls/windows.gaming.input/gamepad.c b/dlls/windows.gaming.input/gamepad.c
index 50008541281..3fdf852ac1f 100644
--- a/dlls/windows.gaming.input/gamepad.c
+++ b/dlls/windows.gaming.input/gamepad.c
@@ -18,11 +18,190 @@
  */
 
 #include "private.h"
+#include "provider.h"
 
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(input);
 
+struct gamepad
+{
+    IGameControllerImpl IGameControllerImpl_iface;
+    IGameControllerInputSink IGameControllerInputSink_iface;
+    IGamepad IGamepad_iface;
+    IGameController *IGameController_outer;
+    LONG ref;
+
+    IGameControllerProvider *provider;
+};
+
+static inline struct gamepad *impl_from_IGameControllerImpl( IGameControllerImpl *iface )
+{
+    return CONTAINING_RECORD( iface, struct gamepad, IGameControllerImpl_iface );
+}
+
+static HRESULT WINAPI controller_QueryInterface( IGameControllerImpl *iface, REFIID iid, void **out )
+{
+    struct gamepad *impl = impl_from_IGameControllerImpl( iface );
+
+    TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out );
+
+    if (IsEqualGUID( iid, &IID_IUnknown ) ||
+        IsEqualGUID( iid, &IID_IInspectable ) ||
+        IsEqualGUID( iid, &IID_IGameControllerImpl ))
+    {
+        IInspectable_AddRef( (*out = &impl->IGameControllerImpl_iface) );
+        return S_OK;
+    }
+
+    if (IsEqualGUID( iid, &IID_IGameControllerInputSink ))
+    {
+        IInspectable_AddRef( (*out = &impl->IGameControllerInputSink_iface) );
+        return S_OK;
+    }
+
+    if (IsEqualGUID( iid, &IID_IGamepad ))
+    {
+        IInspectable_AddRef( (*out = &impl->IGamepad_iface) );
+        return S_OK;
+    }
+
+    WARN( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
+    *out = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI controller_AddRef( IGameControllerImpl *iface )
+{
+    struct gamepad *impl = impl_from_IGameControllerImpl( iface );
+    ULONG ref = InterlockedIncrement( &impl->ref );
+    TRACE( "iface %p increasing refcount to %lu.\n", iface, ref );
+    return ref;
+}
+
+static ULONG WINAPI controller_Release( IGameControllerImpl *iface )
+{
+    struct gamepad *impl = impl_from_IGameControllerImpl( iface );
+    ULONG ref = InterlockedDecrement( &impl->ref );
+
+    TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref );
+
+    if (!ref)
+    {
+        IGameControllerProvider_Release( impl->provider );
+        free( impl );
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI controller_GetIids( IGameControllerImpl *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 WINAPI controller_GetRuntimeClassName( IGameControllerImpl *iface, HSTRING *class_name )
+{
+    return WindowsCreateString( RuntimeClass_Windows_Gaming_Input_Gamepad,
+                                ARRAY_SIZE(RuntimeClass_Windows_Gaming_Input_Gamepad),
+                                class_name );
+}
+
+static HRESULT WINAPI controller_GetTrustLevel( IGameControllerImpl *iface, TrustLevel *trust_level )
+{
+    FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level );
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI controller_Initialize( IGameControllerImpl *iface, IGameController *outer,
+                                             IGameControllerProvider *provider )
+{
+    struct gamepad *impl = impl_from_IGameControllerImpl( iface );
+
+    TRACE( "iface %p, outer %p, provider %p.\n", iface, outer, provider );
+
+    impl->IGameController_outer = outer;
+    IGameControllerProvider_AddRef( (impl->provider = provider) );
+
+    return S_OK;
+}
+
+static const struct IGameControllerImplVtbl controller_vtbl =
+{
+    controller_QueryInterface,
+    controller_AddRef,
+    controller_Release,
+    /* IInspectable methods */
+    controller_GetIids,
+    controller_GetRuntimeClassName,
+    controller_GetTrustLevel,
+    /* IGameControllerImpl methods */
+    controller_Initialize,
+};
+
+DEFINE_IINSPECTABLE_OUTER( input_sink, IGameControllerInputSink, struct gamepad, IGameController_outer )
+
+static HRESULT WINAPI input_sink_OnInputResumed( IGameControllerInputSink *iface, UINT64 timestamp )
+{
+    FIXME( "iface %p, timestamp %I64u stub!\n", iface, timestamp );
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI input_sink_OnInputSuspended( IGameControllerInputSink *iface, UINT64 timestamp )
+{
+    FIXME( "iface %p, timestamp %I64u stub!\n", iface, timestamp );
+    return E_NOTIMPL;
+}
+
+static const struct IGameControllerInputSinkVtbl input_sink_vtbl =
+{
+    input_sink_QueryInterface,
+    input_sink_AddRef,
+    input_sink_Release,
+    /* IInspectable methods */
+    input_sink_GetIids,
+    input_sink_GetRuntimeClassName,
+    input_sink_GetTrustLevel,
+    /* IGameControllerInputSink methods */
+    input_sink_OnInputResumed,
+    input_sink_OnInputSuspended,
+};
+
+DEFINE_IINSPECTABLE_OUTER( gamepad, IGamepad, struct gamepad, IGameController_outer )
+
+static HRESULT WINAPI gamepad_get_Vibration( IGamepad *iface, struct GamepadVibration *value )
+{
+    FIXME( "iface %p, value %p stub!\n", iface, value );
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI gamepad_put_Vibration( IGamepad *iface, struct GamepadVibration value )
+{
+    FIXME( "iface %p, value %p stub!\n", iface, &value );
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI gamepad_GetCurrentReading( IGamepad *iface, struct GamepadReading *value )
+{
+    FIXME( "iface %p, value %p stub!\n", iface, value );
+    return E_NOTIMPL;}
+
+static const struct IGamepadVtbl gamepad_vtbl =
+{
+    gamepad_QueryInterface,
+    gamepad_AddRef,
+    gamepad_Release,
+    /* IInspectable methods */
+    gamepad_GetIids,
+    gamepad_GetRuntimeClassName,
+    gamepad_GetTrustLevel,
+    /* IGamepad methods */
+    gamepad_get_Vibration,
+    gamepad_put_Vibration,
+    gamepad_GetCurrentReading,
+};
+
 struct gamepad_statics
 {
     IActivationFactory IActivationFactory_iface;
@@ -232,8 +411,20 @@ DEFINE_IINSPECTABLE( controller_factory, ICustomGameControllerFactory, struct ga
 static HRESULT WINAPI controller_factory_CreateGameController( ICustomGameControllerFactory *iface, IGameControllerProvider *provider,
                                                                IInspectable **value )
 {
-    FIXME( "iface %p, provider %p, value %p stub!\n", iface, provider, value );
-    return E_NOTIMPL;
+    struct gamepad *impl;
+
+    TRACE( "iface %p, provider %p, value %p.\n", iface, provider, value );
+
+    if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY;
+    impl->IGameControllerImpl_iface.lpVtbl = &controller_vtbl;
+    impl->IGameControllerInputSink_iface.lpVtbl = &input_sink_vtbl;
+    impl->IGamepad_iface.lpVtbl = &gamepad_vtbl;
+    impl->ref = 1;
+
+    TRACE( "created Gamepad %p\n", impl );
+
+    *value = (IInspectable *)&impl->IGameControllerImpl_iface;
+    return S_OK;
 }
 
 static HRESULT WINAPI controller_factory_OnGameControllerAdded( ICustomGameControllerFactory *iface, IGameController *value )
-- 
2.35.1




More information about the wine-devel mailing list