windowscodecs: Silence fixme for IID_CMetaBitmapRenderTarget.
[wine.git] / dlls / windows.gaming.input / vector.c
blob954d7df3552f8c4b79ee2f6e93e6fb2ff7c324ec
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
20 #include "private.h"
22 #include "wine/debug.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(combase);
26 struct iterator
28 IIterator_IInspectable IIterator_IInspectable_iface;
29 const GUID *iid;
30 LONG ref;
32 IVectorView_IInspectable *view;
33 UINT32 index;
34 UINT32 size;
37 static inline struct iterator *impl_from_IIterator_IInspectable( IIterator_IInspectable *iface )
39 return CONTAINING_RECORD( iface, struct iterator, IIterator_IInspectable_iface );
42 static HRESULT WINAPI iterator_QueryInterface( IIterator_IInspectable *iface, REFIID iid, void **out )
44 struct iterator *impl = impl_from_IIterator_IInspectable( iface );
46 TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out );
48 if (IsEqualGUID( iid, &IID_IUnknown ) ||
49 IsEqualGUID( iid, &IID_IInspectable ) ||
50 IsEqualGUID( iid, &IID_IAgileObject ) ||
51 IsEqualGUID( iid, impl->iid ))
53 IInspectable_AddRef( (*out = &impl->IIterator_IInspectable_iface) );
54 return S_OK;
57 FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
58 *out = NULL;
59 return E_NOINTERFACE;
62 static ULONG WINAPI iterator_AddRef( IIterator_IInspectable *iface )
64 struct iterator *impl = impl_from_IIterator_IInspectable( iface );
65 ULONG ref = InterlockedIncrement( &impl->ref );
66 TRACE( "iface %p increasing refcount to %lu.\n", iface, ref );
67 return ref;
70 static ULONG WINAPI iterator_Release( IIterator_IInspectable *iface )
72 struct iterator *impl = impl_from_IIterator_IInspectable( iface );
73 ULONG ref = InterlockedDecrement( &impl->ref );
75 TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref );
77 if (!ref)
79 IVectorView_IInspectable_Release( impl->view );
80 free( impl );
83 return ref;
86 static HRESULT WINAPI iterator_GetIids( IIterator_IInspectable *iface, ULONG *iid_count, IID **iids )
88 FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids );
89 return E_NOTIMPL;
92 static HRESULT WINAPI iterator_GetRuntimeClassName( IIterator_IInspectable *iface, HSTRING *class_name )
94 FIXME( "iface %p, class_name %p stub!\n", iface, class_name );
95 return E_NOTIMPL;
98 static HRESULT WINAPI iterator_GetTrustLevel( IIterator_IInspectable *iface, TrustLevel *trust_level )
100 FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level );
101 return E_NOTIMPL;
104 static HRESULT WINAPI iterator_get_Current( IIterator_IInspectable *iface, IInspectable **value )
106 struct iterator *impl = impl_from_IIterator_IInspectable( iface );
107 TRACE( "iface %p, value %p.\n", iface, value );
108 return IVectorView_IInspectable_GetAt( impl->view, impl->index, value );
111 static HRESULT WINAPI iterator_get_HasCurrent( IIterator_IInspectable *iface, boolean *value )
113 struct iterator *impl = impl_from_IIterator_IInspectable( iface );
115 TRACE( "iface %p, value %p.\n", iface, value );
117 *value = impl->index < impl->size;
118 return S_OK;
121 static HRESULT WINAPI iterator_MoveNext( IIterator_IInspectable *iface, boolean *value )
123 struct iterator *impl = impl_from_IIterator_IInspectable( iface );
125 TRACE( "iface %p, value %p.\n", iface, value );
127 if (impl->index < impl->size) impl->index++;
128 return IIterator_IInspectable_get_HasCurrent( iface, value );
131 static HRESULT WINAPI iterator_GetMany( IIterator_IInspectable *iface, UINT32 items_size,
132 IInspectable **items, UINT *count )
134 struct iterator *impl = impl_from_IIterator_IInspectable( iface );
135 TRACE( "iface %p, items_size %u, items %p, count %p.\n", iface, items_size, items, count );
136 return IVectorView_IInspectable_GetMany( impl->view, impl->index, items_size, items, count );
139 static const IIterator_IInspectableVtbl iterator_vtbl =
141 iterator_QueryInterface,
142 iterator_AddRef,
143 iterator_Release,
144 /* IInspectable methods */
145 iterator_GetIids,
146 iterator_GetRuntimeClassName,
147 iterator_GetTrustLevel,
148 /* IIterator<IInspectable*> methods */
149 iterator_get_Current,
150 iterator_get_HasCurrent,
151 iterator_MoveNext,
152 iterator_GetMany,
155 struct vector_view
157 IVectorView_IInspectable IVectorView_IInspectable_iface;
158 IIterable_IInspectable IIterable_IInspectable_iface;
159 struct vector_iids iids;
160 LONG ref;
162 UINT32 size;
163 IInspectable *elements[1];
166 static inline struct vector_view *impl_from_IVectorView_IInspectable( IVectorView_IInspectable *iface )
168 return CONTAINING_RECORD( iface, struct vector_view, IVectorView_IInspectable_iface );
171 static HRESULT WINAPI vector_view_QueryInterface( IVectorView_IInspectable *iface, REFIID iid, void **out )
173 struct vector_view *impl = impl_from_IVectorView_IInspectable( iface );
175 TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out );
177 if (IsEqualGUID( iid, &IID_IUnknown ) ||
178 IsEqualGUID( iid, &IID_IInspectable ) ||
179 IsEqualGUID( iid, &IID_IAgileObject ) ||
180 IsEqualGUID( iid, impl->iids.view ))
182 IInspectable_AddRef( (*out = &impl->IVectorView_IInspectable_iface) );
183 return S_OK;
186 if (IsEqualGUID( iid, impl->iids.iterable ))
188 IInspectable_AddRef( (*out = &impl->IIterable_IInspectable_iface) );
189 return S_OK;
192 FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
193 *out = NULL;
194 return E_NOINTERFACE;
197 static ULONG WINAPI vector_view_AddRef( IVectorView_IInspectable *iface )
199 struct vector_view *impl = impl_from_IVectorView_IInspectable( iface );
200 ULONG ref = InterlockedIncrement( &impl->ref );
201 TRACE( "iface %p increasing refcount to %lu.\n", iface, ref );
202 return ref;
205 static ULONG WINAPI vector_view_Release( IVectorView_IInspectable *iface )
207 struct vector_view *impl = impl_from_IVectorView_IInspectable( iface );
208 ULONG i, ref = InterlockedDecrement( &impl->ref );
210 TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref );
212 if (!ref)
214 for (i = 0; i < impl->size; ++i) IInspectable_Release( impl->elements[i] );
215 free( impl );
218 return ref;
221 static HRESULT WINAPI vector_view_GetIids( IVectorView_IInspectable *iface, ULONG *iid_count, IID **iids )
223 FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids );
224 return E_NOTIMPL;
227 static HRESULT WINAPI vector_view_GetRuntimeClassName( IVectorView_IInspectable *iface, HSTRING *class_name )
229 FIXME( "iface %p, class_name %p stub!\n", iface, class_name );
230 return E_NOTIMPL;
233 static HRESULT WINAPI vector_view_GetTrustLevel( IVectorView_IInspectable *iface, TrustLevel *trust_level )
235 FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level );
236 return E_NOTIMPL;
239 static HRESULT WINAPI vector_view_GetAt( IVectorView_IInspectable *iface, UINT32 index, IInspectable **value )
241 struct vector_view *impl = impl_from_IVectorView_IInspectable( iface );
243 TRACE( "iface %p, index %u, value %p.\n", iface, index, value );
245 *value = NULL;
246 if (index >= impl->size) return E_BOUNDS;
248 IInspectable_AddRef( (*value = impl->elements[index]) );
249 return S_OK;
252 static HRESULT WINAPI vector_view_get_Size( IVectorView_IInspectable *iface, UINT32 *value )
254 struct vector_view *impl = impl_from_IVectorView_IInspectable( iface );
256 TRACE( "iface %p, value %p.\n", iface, value );
258 *value = impl->size;
259 return S_OK;
262 static HRESULT WINAPI vector_view_IndexOf( IVectorView_IInspectable *iface, IInspectable *element,
263 UINT32 *index, BOOLEAN *found )
265 struct vector_view *impl = impl_from_IVectorView_IInspectable( iface );
266 ULONG i;
268 TRACE( "iface %p, element %p, index %p, found %p.\n", iface, element, index, found );
270 for (i = 0; i < impl->size; ++i) if (impl->elements[i] == element) break;
271 if ((*found = (i < impl->size))) *index = i;
272 else *index = 0;
274 return S_OK;
277 static HRESULT WINAPI vector_view_GetMany( IVectorView_IInspectable *iface, UINT32 start_index,
278 UINT32 items_size, IInspectable **items, UINT *count )
280 struct vector_view *impl = impl_from_IVectorView_IInspectable( iface );
281 UINT32 i;
283 TRACE( "iface %p, start_index %u, items_size %u, items %p, count %p.\n",
284 iface, start_index, items_size, items, count );
286 if (start_index >= impl->size) return E_BOUNDS;
288 for (i = start_index; i < impl->size; ++i)
290 if (i - start_index >= items_size) break;
291 IInspectable_AddRef( (items[i - start_index] = impl->elements[i]) );
293 *count = i - start_index;
295 return S_OK;
298 static const struct IVectorView_IInspectableVtbl vector_view_vtbl =
300 vector_view_QueryInterface,
301 vector_view_AddRef,
302 vector_view_Release,
303 /* IInspectable methods */
304 vector_view_GetIids,
305 vector_view_GetRuntimeClassName,
306 vector_view_GetTrustLevel,
307 /* IVectorView<IInspectable*> methods */
308 vector_view_GetAt,
309 vector_view_get_Size,
310 vector_view_IndexOf,
311 vector_view_GetMany,
314 DEFINE_IINSPECTABLE_( iterable_view, IIterable_IInspectable, struct vector_view, view_impl_from_IIterable_IInspectable,
315 IIterable_IInspectable_iface, &impl->IVectorView_IInspectable_iface )
317 static HRESULT WINAPI iterable_view_First( IIterable_IInspectable *iface, IIterator_IInspectable **value )
319 struct vector_view *impl = view_impl_from_IIterable_IInspectable( iface );
320 struct iterator *iter;
322 TRACE( "iface %p, value %p.\n", iface, value );
324 if (!(iter = calloc( 1, sizeof(struct iterator) ))) return E_OUTOFMEMORY;
325 iter->IIterator_IInspectable_iface.lpVtbl = &iterator_vtbl;
326 iter->iid = impl->iids.iterator;
327 iter->ref = 1;
329 IVectorView_IInspectable_AddRef( (iter->view = &impl->IVectorView_IInspectable_iface) );
330 iter->size = impl->size;
332 *value = &iter->IIterator_IInspectable_iface;
333 return S_OK;
336 static const struct IIterable_IInspectableVtbl iterable_view_vtbl =
338 iterable_view_QueryInterface,
339 iterable_view_AddRef,
340 iterable_view_Release,
341 /* IInspectable methods */
342 iterable_view_GetIids,
343 iterable_view_GetRuntimeClassName,
344 iterable_view_GetTrustLevel,
345 /* IIterable<T> methods */
346 iterable_view_First,
349 struct vector
351 IVector_IInspectable IVector_IInspectable_iface;
352 IIterable_IInspectable IIterable_IInspectable_iface;
353 struct vector_iids iids;
354 LONG ref;
356 UINT32 size;
357 UINT32 capacity;
358 IInspectable **elements;
361 static inline struct vector *impl_from_IVector_IInspectable( IVector_IInspectable *iface )
363 return CONTAINING_RECORD( iface, struct vector, IVector_IInspectable_iface );
366 static HRESULT WINAPI vector_QueryInterface( IVector_IInspectable *iface, REFIID iid, void **out )
368 struct vector *impl = impl_from_IVector_IInspectable( iface );
370 TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out );
372 if (IsEqualGUID( iid, &IID_IUnknown ) ||
373 IsEqualGUID( iid, &IID_IInspectable ) ||
374 IsEqualGUID( iid, &IID_IAgileObject ) ||
375 IsEqualGUID( iid, impl->iids.vector ))
377 IInspectable_AddRef( (*out = &impl->IVector_IInspectable_iface) );
378 return S_OK;
381 if (IsEqualGUID( iid, impl->iids.iterable ))
383 IInspectable_AddRef( (*out = &impl->IIterable_IInspectable_iface) );
384 return S_OK;
387 FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
388 *out = NULL;
389 return E_NOINTERFACE;
392 static ULONG WINAPI vector_AddRef( IVector_IInspectable *iface )
394 struct vector *impl = impl_from_IVector_IInspectable( iface );
395 ULONG ref = InterlockedIncrement( &impl->ref );
396 TRACE( "iface %p increasing refcount to %lu.\n", iface, ref );
397 return ref;
400 static ULONG WINAPI vector_Release( IVector_IInspectable *iface )
402 struct vector *impl = impl_from_IVector_IInspectable( iface );
403 ULONG ref = InterlockedDecrement( &impl->ref );
405 TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref );
407 if (!ref)
409 IVector_IInspectable_Clear( iface );
410 free( impl );
413 return ref;
416 static HRESULT WINAPI vector_GetIids( IVector_IInspectable *iface, ULONG *iid_count, IID **iids )
418 FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids );
419 return E_NOTIMPL;
422 static HRESULT WINAPI vector_GetRuntimeClassName( IVector_IInspectable *iface, HSTRING *class_name )
424 FIXME( "iface %p, class_name %p stub!\n", iface, class_name );
425 return E_NOTIMPL;
428 static HRESULT WINAPI vector_GetTrustLevel( IVector_IInspectable *iface, TrustLevel *trust_level )
430 FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level );
431 return E_NOTIMPL;
434 static HRESULT WINAPI vector_GetAt( IVector_IInspectable *iface, UINT32 index, IInspectable **value )
436 struct vector *impl = impl_from_IVector_IInspectable( iface );
438 TRACE( "iface %p, index %u, value %p.\n", iface, index, value );
440 *value = NULL;
441 if (index >= impl->size) return E_BOUNDS;
443 IInspectable_AddRef( (*value = impl->elements[index]) );
444 return S_OK;
447 static HRESULT WINAPI vector_get_Size( IVector_IInspectable *iface, UINT32 *value )
449 struct vector *impl = impl_from_IVector_IInspectable( iface );
450 TRACE( "iface %p, value %p.\n", iface, value );
451 *value = impl->size;
452 return S_OK;
455 static HRESULT WINAPI vector_GetView( IVector_IInspectable *iface, IVectorView_IInspectable **value )
457 struct vector *impl = impl_from_IVector_IInspectable( iface );
458 struct vector_view *view;
459 ULONG i;
461 TRACE( "iface %p, value %p.\n", iface, value );
463 if (!(view = calloc( 1, offsetof( struct vector_view, elements[impl->size] ) ))) return E_OUTOFMEMORY;
464 view->IVectorView_IInspectable_iface.lpVtbl = &vector_view_vtbl;
465 view->IIterable_IInspectable_iface.lpVtbl = &iterable_view_vtbl;
466 view->iids = impl->iids;
467 view->ref = 1;
469 for (i = 0; i < impl->size; ++i) IInspectable_AddRef( (view->elements[view->size++] = impl->elements[i]) );
471 *value = &view->IVectorView_IInspectable_iface;
472 return S_OK;
475 static HRESULT WINAPI vector_IndexOf( IVector_IInspectable *iface, IInspectable *element, UINT32 *index, BOOLEAN *found )
477 struct vector *impl = impl_from_IVector_IInspectable( iface );
478 ULONG i;
480 TRACE( "iface %p, element %p, index %p, found %p.\n", iface, element, index, found );
482 for (i = 0; i < impl->size; ++i) if (impl->elements[i] == element) break;
483 if ((*found = (i < impl->size))) *index = i;
484 else *index = 0;
486 return S_OK;
489 static HRESULT WINAPI vector_SetAt( IVector_IInspectable *iface, UINT32 index, IInspectable *value )
491 struct vector *impl = impl_from_IVector_IInspectable( iface );
493 TRACE( "iface %p, index %u, value %p.\n", iface, index, value );
495 if (index >= impl->size) return E_BOUNDS;
496 IInspectable_Release( impl->elements[index] );
497 IInspectable_AddRef( (impl->elements[index] = value) );
498 return S_OK;
501 static HRESULT WINAPI vector_InsertAt( IVector_IInspectable *iface, UINT32 index, IInspectable *value )
503 struct vector *impl = impl_from_IVector_IInspectable( iface );
504 IInspectable **tmp = impl->elements;
506 TRACE( "iface %p, index %u, value %p.\n", iface, index, value );
508 if (impl->size == impl->capacity)
510 impl->capacity = max( 32, impl->capacity * 3 / 2 );
511 if (!(impl->elements = realloc( impl->elements, impl->capacity * sizeof(*impl->elements) )))
513 impl->elements = tmp;
514 return E_OUTOFMEMORY;
518 memmove( impl->elements + index + 1, impl->elements + index, (impl->size++ - index) * sizeof(*impl->elements) );
519 IInspectable_AddRef( (impl->elements[index] = value) );
520 return S_OK;
523 static HRESULT WINAPI vector_RemoveAt( IVector_IInspectable *iface, UINT32 index )
525 struct vector *impl = impl_from_IVector_IInspectable( iface );
527 TRACE( "iface %p, index %u.\n", iface, index );
529 if (index >= impl->size) return E_BOUNDS;
530 IInspectable_Release( impl->elements[index] );
531 memmove( impl->elements + index, impl->elements + index + 1, (--impl->size - index) * sizeof(*impl->elements) );
532 return S_OK;
535 static HRESULT WINAPI vector_Append( IVector_IInspectable *iface, IInspectable *value )
537 struct vector *impl = impl_from_IVector_IInspectable( iface );
539 TRACE( "iface %p, value %p.\n", iface, value );
541 return IVector_IInspectable_InsertAt( iface, impl->size, value );
544 static HRESULT WINAPI vector_RemoveAtEnd( IVector_IInspectable *iface )
546 struct vector *impl = impl_from_IVector_IInspectable( iface );
548 TRACE( "iface %p.\n", iface );
550 if (impl->size) IInspectable_Release( impl->elements[--impl->size] );
551 return S_OK;
554 static HRESULT WINAPI vector_Clear( IVector_IInspectable *iface )
556 struct vector *impl = impl_from_IVector_IInspectable( iface );
558 TRACE( "iface %p.\n", iface );
560 while (impl->size) IVector_IInspectable_RemoveAtEnd( iface );
561 free( impl->elements );
562 impl->capacity = 0;
563 impl->elements = NULL;
565 return S_OK;
568 static HRESULT WINAPI vector_GetMany( IVector_IInspectable *iface, UINT32 start_index,
569 UINT32 items_size, IInspectable **items, UINT *count )
571 struct vector *impl = impl_from_IVector_IInspectable( iface );
572 UINT32 i;
574 TRACE( "iface %p, start_index %u, items_size %u, items %p, count %p.\n",
575 iface, start_index, items_size, items, count );
577 if (start_index >= impl->size) return E_BOUNDS;
579 for (i = start_index; i < impl->size; ++i)
581 if (i - start_index >= items_size) break;
582 IInspectable_AddRef( (items[i - start_index] = impl->elements[i]) );
584 *count = i - start_index;
586 return S_OK;
589 static HRESULT WINAPI vector_ReplaceAll( IVector_IInspectable *iface, UINT32 count, IInspectable **items )
591 HRESULT hr;
592 ULONG i;
594 TRACE( "iface %p, count %u, items %p.\n", iface, count, items );
596 hr = IVector_IInspectable_Clear( iface );
597 for (i = 0; i < count && SUCCEEDED(hr); ++i) hr = IVector_IInspectable_Append( iface, items[i] );
598 return hr;
601 static const struct IVector_IInspectableVtbl vector_vtbl =
603 vector_QueryInterface,
604 vector_AddRef,
605 vector_Release,
606 /* IInspectable methods */
607 vector_GetIids,
608 vector_GetRuntimeClassName,
609 vector_GetTrustLevel,
610 /* IVector<IInspectable*> methods */
611 vector_GetAt,
612 vector_get_Size,
613 vector_GetView,
614 vector_IndexOf,
615 vector_SetAt,
616 vector_InsertAt,
617 vector_RemoveAt,
618 vector_Append,
619 vector_RemoveAtEnd,
620 vector_Clear,
621 vector_GetMany,
622 vector_ReplaceAll,
625 DEFINE_IINSPECTABLE( iterable, IIterable_IInspectable, struct vector, IVector_IInspectable_iface )
627 static HRESULT WINAPI iterable_First( IIterable_IInspectable *iface, IIterator_IInspectable **value )
629 struct vector *impl = impl_from_IIterable_IInspectable( iface );
630 IIterable_IInspectable *iterable;
631 IVectorView_IInspectable *view;
632 HRESULT hr;
634 TRACE( "iface %p, value %p.\n", iface, value );
636 if (FAILED(hr = IVector_IInspectable_GetView( &impl->IVector_IInspectable_iface, &view ))) return hr;
638 hr = IVectorView_IInspectable_QueryInterface( view, impl->iids.iterable, (void **)&iterable );
639 IVectorView_IInspectable_Release( view );
640 if (FAILED(hr)) return hr;
642 hr = IIterable_IInspectable_First( iterable, value );
643 IIterable_IInspectable_Release( iterable );
644 return hr;
647 static const struct IIterable_IInspectableVtbl iterable_vtbl =
649 iterable_QueryInterface,
650 iterable_AddRef,
651 iterable_Release,
652 /* IInspectable methods */
653 iterable_GetIids,
654 iterable_GetRuntimeClassName,
655 iterable_GetTrustLevel,
656 /* IIterable<T> methods */
657 iterable_First,
660 HRESULT vector_create( const struct vector_iids *iids, void **out )
662 struct vector *impl;
664 TRACE( "iid %s, out %p.\n", debugstr_guid( iids->vector ), out );
666 if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY;
667 impl->IVector_IInspectable_iface.lpVtbl = &vector_vtbl;
668 impl->IIterable_IInspectable_iface.lpVtbl = &iterable_vtbl;
669 impl->iids = *iids;
670 impl->ref = 1;
672 *out = &impl->IVector_IInspectable_iface;
673 TRACE( "created %p\n", *out );
674 return S_OK;