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 IIterator_IInspectable IIterator_IInspectable_iface
;
32 IVectorView_IInspectable
*view
;
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
) );
57 FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid
) );
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
);
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
);
79 IVectorView_IInspectable_Release( impl
->view
);
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
);
92 static HRESULT WINAPI
iterator_GetRuntimeClassName( IIterator_IInspectable
*iface
, HSTRING
*class_name
)
94 FIXME( "iface %p, class_name %p stub!\n", iface
, class_name
);
98 static HRESULT WINAPI
iterator_GetTrustLevel( IIterator_IInspectable
*iface
, TrustLevel
*trust_level
)
100 FIXME( "iface %p, trust_level %p stub!\n", iface
, trust_level
);
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
, BOOL
*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
;
121 static HRESULT WINAPI
iterator_MoveNext( IIterator_IInspectable
*iface
, BOOL
*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
,
144 /* IInspectable methods */
146 iterator_GetRuntimeClassName
,
147 iterator_GetTrustLevel
,
148 /* IIterator<IInspectable*> methods */
149 iterator_get_Current
,
150 iterator_get_HasCurrent
,
157 IVectorView_IInspectable IVectorView_IInspectable_iface
;
158 IIterable_IInspectable IIterable_IInspectable_iface
;
159 struct vector_iids iids
;
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
) );
186 if (IsEqualGUID( iid
, impl
->iids
.iterable
))
188 IInspectable_AddRef( (*out
= &impl
->IIterable_IInspectable_iface
) );
192 FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid
) );
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
);
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
);
214 for (i
= 0; i
< impl
->size
; ++i
) IInspectable_Release( impl
->elements
[i
] );
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
);
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
);
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
);
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
);
246 if (index
>= impl
->size
) return E_BOUNDS
;
248 IInspectable_AddRef( (*value
= impl
->elements
[index
]) );
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
);
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
);
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
;
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
);
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
;
298 static const struct IVectorView_IInspectableVtbl vector_view_vtbl
=
300 vector_view_QueryInterface
,
303 /* IInspectable methods */
305 vector_view_GetRuntimeClassName
,
306 vector_view_GetTrustLevel
,
307 /* IVectorView<IInspectable*> methods */
309 vector_view_get_Size
,
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
;
329 IVectorView_IInspectable_AddRef( (iter
->view
= &impl
->IVectorView_IInspectable_iface
) );
330 iter
->size
= impl
->size
;
332 *value
= &iter
->IIterator_IInspectable_iface
;
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 */
351 IVector_IInspectable IVector_IInspectable_iface
;
352 IIterable_IInspectable IIterable_IInspectable_iface
;
353 struct vector_iids iids
;
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
) );
381 if (IsEqualGUID( iid
, impl
->iids
.iterable
))
383 IInspectable_AddRef( (*out
= &impl
->IIterable_IInspectable_iface
) );
387 FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid
) );
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
);
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
);
409 IVector_IInspectable_Clear( iface
);
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
);
422 static HRESULT WINAPI
vector_GetRuntimeClassName( IVector_IInspectable
*iface
, HSTRING
*class_name
)
424 FIXME( "iface %p, class_name %p stub!\n", iface
, class_name
);
428 static HRESULT WINAPI
vector_GetTrustLevel( IVector_IInspectable
*iface
, TrustLevel
*trust_level
)
430 FIXME( "iface %p, trust_level %p stub!\n", iface
, trust_level
);
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
);
441 if (index
>= impl
->size
) return E_BOUNDS
;
443 IInspectable_AddRef( (*value
= impl
->elements
[index
]) );
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
);
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
;
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
;
469 for (i
= 0; i
< impl
->size
; ++i
) IInspectable_AddRef( (view
->elements
[view
->size
++] = impl
->elements
[i
]) );
471 *value
= &view
->IVectorView_IInspectable_iface
;
475 static HRESULT WINAPI
vector_IndexOf( IVector_IInspectable
*iface
, IInspectable
*element
, UINT32
*index
, BOOLEAN
*found
)
477 struct vector
*impl
= impl_from_IVector_IInspectable( iface
);
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
;
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
) );
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
) );
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
) );
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
] );
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
);
563 impl
->elements
= NULL
;
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
);
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
;
589 static HRESULT WINAPI
vector_ReplaceAll( IVector_IInspectable
*iface
, UINT32 count
, IInspectable
**items
)
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
] );
601 static const struct IVector_IInspectableVtbl vector_vtbl
=
603 vector_QueryInterface
,
606 /* IInspectable methods */
608 vector_GetRuntimeClassName
,
609 vector_GetTrustLevel
,
610 /* IVector<IInspectable*> methods */
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
;
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
);
647 static const struct IIterable_IInspectableVtbl iterable_vtbl
=
649 iterable_QueryInterface
,
652 /* IInspectable methods */
654 iterable_GetRuntimeClassName
,
655 iterable_GetTrustLevel
,
656 /* IIterable<T> methods */
660 HRESULT
vector_create( const struct vector_iids
*iids
, void **out
)
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
;
672 *out
= &impl
->IVector_IInspectable_iface
;
673 TRACE( "created %p\n", *out
);