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
23 WINE_DEFAULT_DEBUG_CHANNEL(input
);
25 struct periodic_effect
27 IPeriodicForceEffect IPeriodicForceEffect_iface
;
28 IWineForceFeedbackEffectImpl
*IWineForceFeedbackEffectImpl_inner
;
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
) );
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
);
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
);
74 /* guard against re-entry if inner releases an outer iface */
75 InterlockedIncrement( &impl
->ref
);
76 IWineForceFeedbackEffectImpl_Release( impl
->IWineForceFeedbackEffectImpl_inner
);
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
);
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
),
96 static HRESULT WINAPI
effect_GetTrustLevel( IPeriodicForceEffect
*iface
, TrustLevel
*trust_level
)
98 FIXME( "iface %p, trust_level %p stub!\n", iface
, trust_level
);
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
);
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
=
118 .type
= WineForceFeedbackEffectType_Periodic_SquareWave
+ impl
->kind
,
119 .direction
= direction
,
120 .frequency
= frequency
,
123 .duration
= duration
,
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
=
145 .type
= WineForceFeedbackEffectType_Periodic_SquareWave
+ impl
->kind
,
146 .direction
= direction
,
147 .frequency
= frequency
,
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
,
177 /* IInspectable methods */
179 effect_GetRuntimeClassName
,
180 effect_GetTrustLevel
,
181 /* IPeriodicForceEffect methods */
183 effect_SetParameters
,
184 effect_SetParametersWithEnvelope
,
187 struct periodic_factory
189 IActivationFactory IActivationFactory_iface
;
190 IPeriodicForceEffectFactory IPeriodicForceEffectFactory_iface
;
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
) );
214 if (IsEqualGUID( iid
, &IID_IPeriodicForceEffectFactory
))
216 IInspectable_AddRef( (*out
= &impl
->IPeriodicForceEffectFactory_iface
) );
220 FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid
) );
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
);
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
);
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
);
247 static HRESULT WINAPI
activation_GetRuntimeClassName( IActivationFactory
*iface
, HSTRING
*class_name
)
249 FIXME( "iface %p, class_name %p stub!\n", iface
, class_name
);
253 static HRESULT WINAPI
activation_GetTrustLevel( IActivationFactory
*iface
, TrustLevel
*trust_level
)
255 FIXME( "iface %p, trust_level %p stub!\n", iface
, trust_level
);
259 static HRESULT WINAPI
activation_ActivateInstance( IActivationFactory
*iface
, IInspectable
**instance
)
261 FIXME( "iface %p, instance %p stub!\n", iface
, instance
);
265 static const struct IActivationFactoryVtbl activation_vtbl
=
267 activation_QueryInterface
,
270 /* IInspectable methods */
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
;
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
;
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
);
301 IPeriodicForceEffect_Release( &impl
->IPeriodicForceEffect_iface
);
302 TRACE( "created PeriodicForceEffect %p\n", *out
);
306 static const struct IPeriodicForceEffectFactoryVtbl factory_vtbl
=
308 factory_QueryInterface
,
311 /* IInspectable methods */
313 factory_GetRuntimeClassName
,
314 factory_GetTrustLevel
,
315 /* IPeriodicForceEffectFactory methods */
316 factory_CreateInstance
,
319 static struct periodic_factory periodic_statics
=
326 IInspectable
*periodic_effect_factory
= (IInspectable
*)&periodic_statics
.IActivationFactory_iface
;