1 /* WinRT Windows.Gaming.Input implementation
3 * Copyright 2021 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
22 #include "wine/debug.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(combase
);
28 IVectorView_IInspectable IVectorView_IInspectable_iface
;
33 IInspectable
*elements
[1];
36 static inline struct vector_view
*impl_from_IVectorView_IInspectable( IVectorView_IInspectable
*iface
)
38 return CONTAINING_RECORD( iface
, struct vector_view
, IVectorView_IInspectable_iface
);
41 static HRESULT WINAPI
vector_view_QueryInterface( IVectorView_IInspectable
*iface
, REFIID iid
, void **out
)
43 struct vector_view
*impl
= impl_from_IVectorView_IInspectable( iface
);
45 TRACE( "iface %p, iid %s, out %p.\n", iface
, debugstr_guid( iid
), out
);
47 if (IsEqualGUID( iid
, &IID_IUnknown
) ||
48 IsEqualGUID( iid
, &IID_IInspectable
) ||
49 IsEqualGUID( iid
, &IID_IAgileObject
) ||
50 IsEqualGUID( iid
, impl
->iid
))
52 IUnknown_AddRef( iface
);
57 WARN( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid
) );
62 static ULONG WINAPI
vector_view_AddRef( IVectorView_IInspectable
*iface
)
64 struct vector_view
*impl
= impl_from_IVectorView_IInspectable( iface
);
65 ULONG ref
= InterlockedIncrement( &impl
->ref
);
66 TRACE( "iface %p increasing refcount to %lu.\n", iface
, ref
);
70 static ULONG WINAPI
vector_view_Release( IVectorView_IInspectable
*iface
)
72 struct vector_view
*impl
= impl_from_IVectorView_IInspectable( iface
);
73 ULONG i
, ref
= InterlockedDecrement( &impl
->ref
);
75 TRACE( "iface %p decreasing refcount to %lu.\n", iface
, ref
);
79 for (i
= 0; i
< impl
->size
; ++i
) IInspectable_Release( impl
->elements
[i
] );
86 static HRESULT WINAPI
vector_view_GetIids( IVectorView_IInspectable
*iface
, ULONG
*iid_count
, IID
**iids
)
88 FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface
, iid_count
, iids
);
92 static HRESULT WINAPI
vector_view_GetRuntimeClassName( IVectorView_IInspectable
*iface
, HSTRING
*class_name
)
94 FIXME( "iface %p, class_name %p stub!\n", iface
, class_name
);
98 static HRESULT WINAPI
vector_view_GetTrustLevel( IVectorView_IInspectable
*iface
, TrustLevel
*trust_level
)
100 FIXME( "iface %p, trust_level %p stub!\n", iface
, trust_level
);
104 static HRESULT WINAPI
vector_view_GetAt( IVectorView_IInspectable
*iface
, UINT32 index
, IInspectable
**value
)
106 struct vector_view
*impl
= impl_from_IVectorView_IInspectable( iface
);
108 TRACE( "iface %p, index %u, value %p.\n", iface
, index
, value
);
111 if (index
>= impl
->size
) return E_BOUNDS
;
113 IInspectable_AddRef( (*value
= impl
->elements
[index
]) );
117 static HRESULT WINAPI
vector_view_get_Size( IVectorView_IInspectable
*iface
, UINT32
*value
)
119 struct vector_view
*impl
= impl_from_IVectorView_IInspectable( iface
);
121 TRACE( "iface %p, value %p.\n", iface
, value
);
127 static HRESULT WINAPI
vector_view_IndexOf( IVectorView_IInspectable
*iface
, IInspectable
*element
,
128 UINT32
*index
, BOOLEAN
*found
)
130 struct vector_view
*impl
= impl_from_IVectorView_IInspectable( iface
);
133 TRACE( "iface %p, element %p, index %p, found %p.\n", iface
, element
, index
, found
);
135 for (i
= 0; i
< impl
->size
; ++i
) if (impl
->elements
[i
] == element
) break;
136 if ((*found
= (i
< impl
->size
))) *index
= i
;
142 static HRESULT WINAPI
vector_view_GetMany( IVectorView_IInspectable
*iface
, UINT32 start_index
,
143 UINT32 items_size
, IInspectable
**items
, UINT
*count
)
145 struct vector_view
*impl
= impl_from_IVectorView_IInspectable( iface
);
148 TRACE( "iface %p, start_index %u, items_size %u, items %p, count %p.\n",
149 iface
, start_index
, items_size
, items
, count
);
151 if (start_index
>= impl
->size
) return E_BOUNDS
;
153 for (i
= start_index
; i
< impl
->size
; ++i
)
155 if (i
- start_index
>= items_size
) break;
156 IInspectable_AddRef( (items
[i
- start_index
] = impl
->elements
[i
]) );
158 *count
= i
- start_index
;
163 static const struct IVectorView_IInspectableVtbl vector_view_vtbl
=
165 vector_view_QueryInterface
,
168 /* IInspectable methods */
170 vector_view_GetRuntimeClassName
,
171 vector_view_GetTrustLevel
,
172 /* IVectorView<IInspectable*> methods */
174 vector_view_get_Size
,
181 IVector_IInspectable IVector_IInspectable_iface
;
183 const GUID
*view_iid
;
188 IInspectable
**elements
;
191 static inline struct vector
*impl_from_IVector_IInspectable( IVector_IInspectable
*iface
)
193 return CONTAINING_RECORD( iface
, struct vector
, IVector_IInspectable_iface
);
196 static HRESULT WINAPI
vector_QueryInterface( IVector_IInspectable
*iface
, REFIID iid
, void **out
)
198 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
200 TRACE( "iface %p, iid %s, out %p.\n", iface
, debugstr_guid( iid
), out
);
202 if (IsEqualGUID( iid
, &IID_IUnknown
) ||
203 IsEqualGUID( iid
, &IID_IInspectable
) ||
204 IsEqualGUID( iid
, &IID_IAgileObject
) ||
205 IsEqualGUID( iid
, impl
->iid
))
207 IUnknown_AddRef( iface
);
212 WARN( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid
) );
214 return E_NOINTERFACE
;
217 static ULONG WINAPI
vector_AddRef( IVector_IInspectable
*iface
)
219 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
220 ULONG ref
= InterlockedIncrement( &impl
->ref
);
221 TRACE( "iface %p increasing refcount to %lu.\n", iface
, ref
);
225 static ULONG WINAPI
vector_Release( IVector_IInspectable
*iface
)
227 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
228 ULONG ref
= InterlockedDecrement( &impl
->ref
);
230 TRACE( "iface %p decreasing refcount to %lu.\n", iface
, ref
);
234 IVector_IInspectable_Clear( iface
);
241 static HRESULT WINAPI
vector_GetIids( IVector_IInspectable
*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
vector_GetRuntimeClassName( IVector_IInspectable
*iface
, HSTRING
*class_name
)
249 FIXME( "iface %p, class_name %p stub!\n", iface
, class_name
);
253 static HRESULT WINAPI
vector_GetTrustLevel( IVector_IInspectable
*iface
, TrustLevel
*trust_level
)
255 FIXME( "iface %p, trust_level %p stub!\n", iface
, trust_level
);
259 static HRESULT WINAPI
vector_GetAt( IVector_IInspectable
*iface
, UINT32 index
, IInspectable
**value
)
261 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
263 TRACE( "iface %p, index %u, value %p.\n", iface
, index
, value
);
266 if (index
>= impl
->size
) return E_BOUNDS
;
268 IInspectable_AddRef( (*value
= impl
->elements
[index
]) );
272 static HRESULT WINAPI
vector_get_Size( IVector_IInspectable
*iface
, UINT32
*value
)
274 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
275 TRACE( "iface %p, value %p.\n", iface
, value
);
280 static HRESULT WINAPI
vector_GetView( IVector_IInspectable
*iface
, IVectorView_IInspectable
**value
)
282 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
283 struct vector_view
*view
;
286 TRACE( "iface %p, value %p.\n", iface
, value
);
288 if (!(view
= calloc( 1, offsetof( struct vector_view
, elements
[impl
->size
] ) ))) return E_OUTOFMEMORY
;
289 view
->IVectorView_IInspectable_iface
.lpVtbl
= &vector_view_vtbl
;
290 view
->iid
= impl
->view_iid
;
293 for (i
= 0; i
< impl
->size
; ++i
) IInspectable_AddRef( (view
->elements
[view
->size
++] = impl
->elements
[i
]) );
295 *value
= &view
->IVectorView_IInspectable_iface
;
299 static HRESULT WINAPI
vector_IndexOf( IVector_IInspectable
*iface
, IInspectable
*element
, UINT32
*index
, BOOLEAN
*found
)
301 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
304 TRACE( "iface %p, element %p, index %p, found %p.\n", iface
, element
, index
, found
);
306 for (i
= 0; i
< impl
->size
; ++i
) if (impl
->elements
[i
] == element
) break;
307 if ((*found
= (i
< impl
->size
))) *index
= i
;
313 static HRESULT WINAPI
vector_SetAt( IVector_IInspectable
*iface
, UINT32 index
, IInspectable
*value
)
315 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
317 TRACE( "iface %p, index %u, value %p.\n", iface
, index
, value
);
319 if (index
>= impl
->size
) return E_BOUNDS
;
320 IInspectable_Release( impl
->elements
[index
] );
321 IInspectable_AddRef( (impl
->elements
[index
] = value
) );
325 static HRESULT WINAPI
vector_InsertAt( IVector_IInspectable
*iface
, UINT32 index
, IInspectable
*value
)
327 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
328 IInspectable
**tmp
= impl
->elements
;
330 TRACE( "iface %p, index %u, value %p.\n", iface
, index
, value
);
332 if (impl
->size
== impl
->capacity
)
334 impl
->capacity
= max( 32, impl
->capacity
* 3 / 2 );
335 if (!(impl
->elements
= realloc( impl
->elements
, impl
->capacity
* sizeof(*impl
->elements
) )))
337 impl
->elements
= tmp
;
338 return E_OUTOFMEMORY
;
342 memmove( impl
->elements
+ index
+ 1, impl
->elements
+ index
, impl
->size
++ * sizeof(*impl
->elements
) );
343 IInspectable_AddRef( (impl
->elements
[index
] = value
) );
347 static HRESULT WINAPI
vector_RemoveAt( IVector_IInspectable
*iface
, UINT32 index
)
349 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
351 TRACE( "iface %p, index %u.\n", iface
, index
);
353 if (index
>= impl
->size
) return E_BOUNDS
;
354 IInspectable_Release( impl
->elements
[index
] );
355 memmove( impl
->elements
+ index
, impl
->elements
+ index
+ 1, --impl
->size
* sizeof(*impl
->elements
) );
359 static HRESULT WINAPI
vector_Append( IVector_IInspectable
*iface
, IInspectable
*value
)
361 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
363 TRACE( "iface %p, value %p.\n", iface
, value
);
365 return IVector_IInspectable_InsertAt( iface
, impl
->size
, value
);
368 static HRESULT WINAPI
vector_RemoveAtEnd( IVector_IInspectable
*iface
)
370 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
372 TRACE( "iface %p.\n", iface
);
374 if (impl
->size
) IInspectable_Release( impl
->elements
[--impl
->size
] );
378 static HRESULT WINAPI
vector_Clear( IVector_IInspectable
*iface
)
380 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
382 TRACE( "iface %p.\n", iface
);
384 while (impl
->size
) IVector_IInspectable_RemoveAtEnd( iface
);
385 free( impl
->elements
);
387 impl
->elements
= NULL
;
392 static HRESULT WINAPI
vector_GetMany( IVector_IInspectable
*iface
, UINT32 start_index
,
393 UINT32 items_size
, IInspectable
**items
, UINT
*count
)
395 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
398 TRACE( "iface %p, start_index %u, items_size %u, items %p, count %p.\n",
399 iface
, start_index
, items_size
, items
, count
);
401 if (start_index
>= impl
->size
) return E_BOUNDS
;
403 for (i
= start_index
; i
< impl
->size
; ++i
)
405 if (i
- start_index
>= items_size
) break;
406 IInspectable_AddRef( (items
[i
- start_index
] = impl
->elements
[i
]) );
408 *count
= i
- start_index
;
413 static HRESULT WINAPI
vector_ReplaceAll( IVector_IInspectable
*iface
, UINT32 count
, IInspectable
**items
)
418 TRACE( "iface %p, count %u, items %p.\n", iface
, count
, items
);
420 hr
= IVector_IInspectable_Clear( iface
);
421 for (i
= 0; i
< count
&& SUCCEEDED(hr
); ++i
) hr
= IVector_IInspectable_Append( iface
, items
[i
] );
425 static const struct IVector_IInspectableVtbl vector_vtbl
=
427 vector_QueryInterface
,
430 /* IInspectable methods */
432 vector_GetRuntimeClassName
,
433 vector_GetTrustLevel
,
434 /* IVector<IInspectable*> methods */
449 HRESULT
vector_create( REFIID iid
, REFIID view_iid
, void **out
)
453 TRACE( "iid %s, out %p.\n", debugstr_guid( iid
), out
);
455 if (!(impl
= calloc( 1, sizeof(*impl
) ))) return E_OUTOFMEMORY
;
456 impl
->IVector_IInspectable_iface
.lpVtbl
= &vector_vtbl
;
458 impl
->view_iid
= view_iid
;
461 *out
= &impl
->IVector_IInspectable_iface
;
462 TRACE( "created %p\n", *out
);