From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/tests/force_feedback.c | 3 +- dlls/windows.gaming.input/constant_effect.c | 117 +++++++++++++++++++- dlls/windows.gaming.input/private.h | 8 ++ 3 files changed, 122 insertions(+), 6 deletions(-)
diff --git a/dlls/dinput/tests/force_feedback.c b/dlls/dinput/tests/force_feedback.c index 806212d966d..e688f575704 100644 --- a/dlls/dinput/tests/force_feedback.c +++ b/dlls/dinput/tests/force_feedback.c @@ -5624,15 +5624,14 @@ static void test_windows_gaming_input(void) pWindowsDeleteString( str );
hr = IActivationFactory_ActivateInstance( activation_factory, &tmp_inspectable ); - todo_wine ok( hr == S_OK, "QueryInterface returned %#lx\n", hr ); IActivationFactory_Release( activation_factory ); - if (hr != S_OK) goto skip_tests;
hr = IInspectable_QueryInterface( tmp_inspectable, &IID_IForceFeedbackEffect, (void **)&effect ); todo_wine ok( hr == S_OK, "QueryInterface returned %#lx\n", hr ); IInspectable_Release( tmp_inspectable ); + if (hr != S_OK) goto skip_tests;
hr = IForceFeedbackEffect_QueryInterface( effect, &IID_IConstantForceEffect, (void **)&constant_effect ); ok( hr == S_OK, "QueryInterface returned %#lx\n", hr ); diff --git a/dlls/windows.gaming.input/constant_effect.c b/dlls/windows.gaming.input/constant_effect.c index a27258dd9bf..a491d49c18c 100644 --- a/dlls/windows.gaming.input/constant_effect.c +++ b/dlls/windows.gaming.input/constant_effect.c @@ -20,10 +20,110 @@ #include "private.h" #include "provider.h"
-#include "wine/debug.h" - WINE_DEFAULT_DEBUG_CHANNEL(input);
+struct constant_effect +{ + IConstantForceEffect IConstantForceEffect_iface; + LONG ref; +}; + +static inline struct constant_effect *impl_from_IConstantForceEffect( IConstantForceEffect *iface ) +{ + return CONTAINING_RECORD( iface, struct constant_effect, IConstantForceEffect_iface ); +} + +static HRESULT WINAPI effect_QueryInterface( IConstantForceEffect *iface, REFIID iid, void **out ) +{ + struct constant_effect *impl = impl_from_IConstantForceEffect( 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_IAgileObject ) || + IsEqualGUID( iid, &IID_IConstantForceEffect )) + { + IInspectable_AddRef( (*out = &impl->IConstantForceEffect_iface) ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI effect_AddRef( IConstantForceEffect *iface ) +{ + struct constant_effect *impl = impl_from_IConstantForceEffect( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI effect_Release( IConstantForceEffect *iface ) +{ + struct constant_effect *impl = impl_from_IConstantForceEffect( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + + if (!ref) free( impl ); + + return ref; +} + +static HRESULT WINAPI effect_GetIids( IConstantForceEffect *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 effect_GetRuntimeClassName( IConstantForceEffect *iface, HSTRING *class_name ) +{ + return WindowsCreateString( RuntimeClass_Windows_Gaming_Input_ForceFeedback_ConstantForceEffect, + ARRAY_SIZE(RuntimeClass_Windows_Gaming_Input_ForceFeedback_ConstantForceEffect), + class_name ); +} + +static HRESULT WINAPI effect_GetTrustLevel( IConstantForceEffect *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI effect_SetParameters( IConstantForceEffect *iface, Vector3 direction, TimeSpan duration ) +{ + FIXME( "iface %p, direction %s, duration %I64u stub!\n", iface, debugstr_vector3( &direction ), duration.Duration ); + return E_NOTIMPL; +} + +static HRESULT WINAPI effect_SetParametersWithEnvelope( IConstantForceEffect *iface, Vector3 direction, FLOAT attack_gain, + FLOAT sustain_gain, FLOAT release_gain, TimeSpan start_delay, + TimeSpan attack_duration, TimeSpan sustain_duration, + TimeSpan release_duration, UINT32 repeat_count ) +{ + FIXME( "iface %p, direction %s, attack_gain %f, sustain_gain %f, release_gain %f, start_delay %I64u, attack_duration %I64u, " + "sustain_duration %I64u, release_duration %I64u, repeat_count %u stub!\n", iface, debugstr_vector3( &direction ), + attack_gain, sustain_gain, release_gain, start_delay.Duration, attack_duration.Duration, sustain_duration.Duration, + release_duration.Duration, repeat_count ); + return E_NOTIMPL; +} + +static const struct IConstantForceEffectVtbl effect_vtbl = +{ + effect_QueryInterface, + effect_AddRef, + effect_Release, + /* IInspectable methods */ + effect_GetIids, + effect_GetRuntimeClassName, + effect_GetTrustLevel, + /* IConstantForceEffect methods */ + effect_SetParameters, + effect_SetParametersWithEnvelope, +}; + struct constant_factory { IActivationFactory IActivationFactory_iface; @@ -91,8 +191,17 @@ static HRESULT WINAPI activation_GetTrustLevel( IActivationFactory *iface, Trust
static HRESULT WINAPI activation_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) { - FIXME( "iface %p, instance %p stub!\n", iface, instance ); - return E_NOTIMPL; + struct constant_effect *impl; + + TRACE( "iface %p, instance %p.\n", iface, instance ); + + if (!(impl = calloc( 1, sizeof(struct constant_effect) ))) return E_OUTOFMEMORY; + impl->IConstantForceEffect_iface.lpVtbl = &effect_vtbl; + impl->ref = 1; + + *instance = (IInspectable *)&impl->IConstantForceEffect_iface; + TRACE( "created ConstantForceEffect %p\n", *instance ); + return S_OK; }
static const struct IActivationFactoryVtbl activation_vtbl = diff --git a/dlls/windows.gaming.input/private.h b/dlls/windows.gaming.input/private.h index 2e97f182e78..9bbaae5554b 100644 --- a/dlls/windows.gaming.input/private.h +++ b/dlls/windows.gaming.input/private.h @@ -31,6 +31,7 @@
#define WIDL_using_Windows_Foundation #define WIDL_using_Windows_Foundation_Collections +#define WIDL_using_Windows_Foundation_Numerics #include "windows.foundation.h" #define WIDL_using_Windows_Devices_Power #define WIDL_using_Windows_Gaming_Input @@ -38,6 +39,7 @@ #define WIDL_using_Windows_Gaming_Input_ForceFeedback #include "windows.gaming.input.custom.h"
+#include "wine/debug.h" #include "wine/list.h"
extern HINSTANCE windows_gaming_input; @@ -111,3 +113,9 @@ extern HRESULT async_operation_boolean_create( IUnknown *invoker, IUnknown *para DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, &impl->base_iface ) #define DEFINE_IINSPECTABLE_OUTER( pfx, iface_type, impl_type, outer_iface ) \ DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, impl->outer_iface ) + +static inline const char *debugstr_vector3( const Vector3 *vector ) +{ + if (!vector) return "(null)"; + return wine_dbg_sprintf( "[%f, %f, %f]", vector->X, vector->Y, vector->Z ); +}