dinput/tests: Add EnumObjects callback return value test.
[wine.git] / dlls / windows.gaming.input / periodic_effect.c
blob8633a8fb9b91f4ea957646a4b34e4a2369a5f8c4
1 /* WinRT Windows.Gaming.Input implementation
3 * Copyright 2022 RĂ©mi Bernon for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "private.h"
21 #include "provider.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(input);
25 struct periodic_effect
27 IPeriodicForceEffect IPeriodicForceEffect_iface;
28 IWineForceFeedbackEffectImpl *IWineForceFeedbackEffectImpl_inner;
29 LONG ref;
31 PeriodicForceEffectKind kind;
34 static inline struct periodic_effect *impl_from_IPeriodicForceEffect( IPeriodicForceEffect *iface )
36 return CONTAINING_RECORD( iface, struct periodic_effect, IPeriodicForceEffect_iface );
39 static HRESULT WINAPI effect_QueryInterface( IPeriodicForceEffect *iface, REFIID iid, void **out )
41 struct periodic_effect *impl = impl_from_IPeriodicForceEffect( iface );
43 TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out );
45 if (IsEqualGUID( iid, &IID_IUnknown ) ||
46 IsEqualGUID( iid, &IID_IInspectable ) ||
47 IsEqualGUID( iid, &IID_IAgileObject ) ||
48 IsEqualGUID( iid, &IID_IPeriodicForceEffect ))
50 IInspectable_AddRef( (*out = &impl->IPeriodicForceEffect_iface) );
51 return S_OK;
54 return IWineForceFeedbackEffectImpl_QueryInterface( impl->IWineForceFeedbackEffectImpl_inner, iid, out );
57 static ULONG WINAPI effect_AddRef( IPeriodicForceEffect *iface )
59 struct periodic_effect *impl = impl_from_IPeriodicForceEffect( iface );
60 ULONG ref = InterlockedIncrement( &impl->ref );
61 TRACE( "iface %p increasing refcount to %lu.\n", iface, ref );
62 return ref;
65 static ULONG WINAPI effect_Release( IPeriodicForceEffect *iface )
67 struct periodic_effect *impl = impl_from_IPeriodicForceEffect( iface );
68 ULONG ref = InterlockedDecrement( &impl->ref );
70 TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref );
72 if (!ref)
74 /* guard against re-entry if inner releases an outer iface */
75 InterlockedIncrement( &impl->ref );
76 IWineForceFeedbackEffectImpl_Release( impl->IWineForceFeedbackEffectImpl_inner );
77 free( impl );
80 return ref;
83 static HRESULT WINAPI effect_GetIids( IPeriodicForceEffect *iface, ULONG *iid_count, IID **iids )
85 FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids );
86 return E_NOTIMPL;
89 static HRESULT WINAPI effect_GetRuntimeClassName( IPeriodicForceEffect *iface, HSTRING *class_name )
91 return WindowsCreateString( RuntimeClass_Windows_Gaming_Input_ForceFeedback_PeriodicForceEffect,
92 ARRAY_SIZE(RuntimeClass_Windows_Gaming_Input_ForceFeedback_PeriodicForceEffect),
93 class_name );
96 static HRESULT WINAPI effect_GetTrustLevel( IPeriodicForceEffect *iface, TrustLevel *trust_level )
98 FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level );
99 return E_NOTIMPL;
102 static HRESULT WINAPI effect_get_Kind( IPeriodicForceEffect *iface, PeriodicForceEffectKind *kind )
104 struct periodic_effect *impl = impl_from_IPeriodicForceEffect( iface );
105 TRACE( "iface %p, kind %p.\n", iface, kind );
106 *kind = impl->kind;
107 return S_OK;
110 static HRESULT WINAPI effect_SetParameters( IPeriodicForceEffect *iface, Vector3 direction, FLOAT frequency, FLOAT phase,
111 FLOAT bias, TimeSpan duration )
113 struct periodic_effect *impl = impl_from_IPeriodicForceEffect( iface );
114 WineForceFeedbackEffectParameters params =
116 .periodic =
118 .type = WineForceFeedbackEffectType_Periodic_SquareWave + impl->kind,
119 .direction = direction,
120 .frequency = frequency,
121 .phase = phase,
122 .bias = bias,
123 .duration = duration,
124 .repeat_count = 1,
125 .gain = 1.,
129 TRACE( "iface %p, direction %s, frequency %f, phase %f, bias %f, duration %I64u.\n", iface,
130 debugstr_vector3( &direction ), frequency, phase, bias, duration.Duration );
132 return IWineForceFeedbackEffectImpl_put_Parameters( impl->IWineForceFeedbackEffectImpl_inner, params, NULL );
135 static HRESULT WINAPI effect_SetParametersWithEnvelope( IPeriodicForceEffect *iface, Vector3 direction, FLOAT frequency, FLOAT phase, FLOAT bias,
136 FLOAT attack_gain, FLOAT sustain_gain, FLOAT release_gain, TimeSpan start_delay,
137 TimeSpan attack_duration, TimeSpan sustain_duration,
138 TimeSpan release_duration, UINT32 repeat_count )
140 struct periodic_effect *impl = impl_from_IPeriodicForceEffect( iface );
141 WineForceFeedbackEffectParameters params =
143 .periodic =
145 .type = WineForceFeedbackEffectType_Periodic_SquareWave + impl->kind,
146 .direction = direction,
147 .frequency = frequency,
148 .phase = phase,
149 .bias = bias,
150 .duration = {attack_duration.Duration + sustain_duration.Duration + release_duration.Duration},
151 .start_delay = start_delay,
152 .repeat_count = repeat_count,
153 .gain = sustain_gain,
156 WineForceFeedbackEffectEnvelope envelope =
158 .attack_gain = attack_gain,
159 .release_gain = release_gain,
160 .attack_duration = attack_duration,
161 .release_duration = release_duration,
164 TRACE( "iface %p, direction %s, frequency %f, phase %f, bias %f, attack_gain %f, sustain_gain %f, release_gain %f, start_delay %I64u, "
165 "attack_duration %I64u, sustain_duration %I64u, release_duration %I64u, repeat_count %u.\n", iface, debugstr_vector3( &direction ),
166 frequency, phase, bias, attack_gain, sustain_gain, release_gain, start_delay.Duration, attack_duration.Duration, sustain_duration.Duration,
167 release_duration.Duration, repeat_count );
169 return IWineForceFeedbackEffectImpl_put_Parameters( impl->IWineForceFeedbackEffectImpl_inner, params, &envelope );
172 static const struct IPeriodicForceEffectVtbl effect_vtbl =
174 effect_QueryInterface,
175 effect_AddRef,
176 effect_Release,
177 /* IInspectable methods */
178 effect_GetIids,
179 effect_GetRuntimeClassName,
180 effect_GetTrustLevel,
181 /* IPeriodicForceEffect methods */
182 effect_get_Kind,
183 effect_SetParameters,
184 effect_SetParametersWithEnvelope,
187 struct periodic_factory
189 IActivationFactory IActivationFactory_iface;
190 IPeriodicForceEffectFactory IPeriodicForceEffectFactory_iface;
191 LONG ref;
194 static inline struct periodic_factory *impl_from_IActivationFactory( IActivationFactory *iface )
196 return CONTAINING_RECORD( iface, struct periodic_factory, IActivationFactory_iface );
199 static HRESULT WINAPI activation_QueryInterface( IActivationFactory *iface, REFIID iid, void **out )
201 struct periodic_factory *impl = impl_from_IActivationFactory( iface );
203 TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out );
205 if (IsEqualGUID( iid, &IID_IUnknown ) ||
206 IsEqualGUID( iid, &IID_IInspectable ) ||
207 IsEqualGUID( iid, &IID_IAgileObject ) ||
208 IsEqualGUID( iid, &IID_IActivationFactory ))
210 IInspectable_AddRef( (*out = &impl->IActivationFactory_iface) );
211 return S_OK;
214 if (IsEqualGUID( iid, &IID_IPeriodicForceEffectFactory ))
216 IInspectable_AddRef( (*out = &impl->IPeriodicForceEffectFactory_iface) );
217 return S_OK;
220 FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
221 *out = NULL;
222 return E_NOINTERFACE;
225 static ULONG WINAPI activation_AddRef( IActivationFactory *iface )
227 struct periodic_factory *impl = impl_from_IActivationFactory( iface );
228 ULONG ref = InterlockedIncrement( &impl->ref );
229 TRACE( "iface %p increasing refcount to %lu.\n", iface, ref );
230 return ref;
233 static ULONG WINAPI activation_Release( IActivationFactory *iface )
235 struct periodic_factory *impl = impl_from_IActivationFactory( iface );
236 ULONG ref = InterlockedDecrement( &impl->ref );
237 TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref );
238 return ref;
241 static HRESULT WINAPI activation_GetIids( IActivationFactory *iface, ULONG *iid_count, IID **iids )
243 FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids );
244 return E_NOTIMPL;
247 static HRESULT WINAPI activation_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name )
249 FIXME( "iface %p, class_name %p stub!\n", iface, class_name );
250 return E_NOTIMPL;
253 static HRESULT WINAPI activation_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level )
255 FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level );
256 return E_NOTIMPL;
259 static HRESULT WINAPI activation_ActivateInstance( IActivationFactory *iface, IInspectable **instance )
261 FIXME( "iface %p, instance %p stub!\n", iface, instance );
262 return E_NOTIMPL;
265 static const struct IActivationFactoryVtbl activation_vtbl =
267 activation_QueryInterface,
268 activation_AddRef,
269 activation_Release,
270 /* IInspectable methods */
271 activation_GetIids,
272 activation_GetRuntimeClassName,
273 activation_GetTrustLevel,
274 /* IActivationFactory methods */
275 activation_ActivateInstance,
278 DEFINE_IINSPECTABLE( factory, IPeriodicForceEffectFactory, struct periodic_factory, IActivationFactory_iface )
280 static HRESULT WINAPI factory_CreateInstance( IPeriodicForceEffectFactory *iface, enum PeriodicForceEffectKind kind, IForceFeedbackEffect **out )
282 enum WineForceFeedbackEffectType type = WineForceFeedbackEffectType_Periodic + kind;
283 struct periodic_effect *impl;
284 HRESULT hr;
286 TRACE( "iface %p, kind %u, out %p.\n", iface, kind, out );
288 if (!(impl = calloc( 1, sizeof(struct periodic_effect) ))) return E_OUTOFMEMORY;
289 impl->IPeriodicForceEffect_iface.lpVtbl = &effect_vtbl;
290 impl->ref = 1;
291 impl->kind = kind;
293 if (FAILED(hr = force_feedback_effect_create( type, (IInspectable *)&impl->IPeriodicForceEffect_iface, &impl->IWineForceFeedbackEffectImpl_inner )) ||
294 FAILED(hr = IPeriodicForceEffect_QueryInterface( &impl->IPeriodicForceEffect_iface, &IID_IForceFeedbackEffect, (void **)out )))
296 if (impl->IWineForceFeedbackEffectImpl_inner) IWineForceFeedbackEffectImpl_Release( impl->IWineForceFeedbackEffectImpl_inner );
297 free( impl );
298 return hr;
301 IPeriodicForceEffect_Release( &impl->IPeriodicForceEffect_iface );
302 TRACE( "created PeriodicForceEffect %p\n", *out );
303 return S_OK;
306 static const struct IPeriodicForceEffectFactoryVtbl factory_vtbl =
308 factory_QueryInterface,
309 factory_AddRef,
310 factory_Release,
311 /* IInspectable methods */
312 factory_GetIids,
313 factory_GetRuntimeClassName,
314 factory_GetTrustLevel,
315 /* IPeriodicForceEffectFactory methods */
316 factory_CreateInstance,
319 static struct periodic_factory periodic_statics =
321 {&activation_vtbl},
322 {&factory_vtbl},
326 IInspectable *periodic_effect_factory = (IInspectable *)&periodic_statics.IActivationFactory_iface;