userenv/tests: Enable compilation with long types.
[wine.git] / dlls / windows.gaming.input / vector.c
blob441c13dab4cc19362ba9749550bc93bc40e6fe71
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 vector_view
28 IVectorView_IInspectable IVectorView_IInspectable_iface;
29 const GUID *iid;
30 LONG ref;
32 UINT32 size;
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 );
53 *out = iface;
54 return S_OK;
57 WARN( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
58 *out = NULL;
59 return E_NOINTERFACE;
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 );
67 return 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 );
77 if (!ref)
79 for (i = 0; i < impl->size; ++i) IInspectable_Release( impl->elements[i] );
80 free( impl );
83 return ref;
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 );
89 return E_NOTIMPL;
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 );
95 return E_NOTIMPL;
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 );
101 return E_NOTIMPL;
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 );
110 *value = NULL;
111 if (index >= impl->size) return E_BOUNDS;
113 IInspectable_AddRef( (*value = impl->elements[index]) );
114 return S_OK;
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 );
123 *value = impl->size;
124 return S_OK;
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 );
131 ULONG i;
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;
137 else *index = 0;
139 return S_OK;
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 );
146 UINT32 i;
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;
160 return S_OK;
163 static const struct IVectorView_IInspectableVtbl vector_view_vtbl =
165 vector_view_QueryInterface,
166 vector_view_AddRef,
167 vector_view_Release,
168 /* IInspectable methods */
169 vector_view_GetIids,
170 vector_view_GetRuntimeClassName,
171 vector_view_GetTrustLevel,
172 /* IVectorView<IInspectable*> methods */
173 vector_view_GetAt,
174 vector_view_get_Size,
175 vector_view_IndexOf,
176 vector_view_GetMany,
179 struct vector
181 IVector_IInspectable IVector_IInspectable_iface;
182 const GUID *iid;
183 const GUID *view_iid;
184 LONG ref;
186 UINT32 size;
187 UINT32 capacity;
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 );
208 *out = iface;
209 return S_OK;
212 WARN( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
213 *out = NULL;
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 );
222 return 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 );
232 if (!ref)
234 IVector_IInspectable_Clear( iface );
235 free( impl );
238 return ref;
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 );
244 return E_NOTIMPL;
247 static HRESULT WINAPI vector_GetRuntimeClassName( IVector_IInspectable *iface, HSTRING *class_name )
249 FIXME( "iface %p, class_name %p stub!\n", iface, class_name );
250 return E_NOTIMPL;
253 static HRESULT WINAPI vector_GetTrustLevel( IVector_IInspectable *iface, TrustLevel *trust_level )
255 FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level );
256 return E_NOTIMPL;
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 );
265 *value = NULL;
266 if (index >= impl->size) return E_BOUNDS;
268 IInspectable_AddRef( (*value = impl->elements[index]) );
269 return S_OK;
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 );
276 *value = impl->size;
277 return S_OK;
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;
284 ULONG i;
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;
291 view->ref = 1;
293 for (i = 0; i < impl->size; ++i) IInspectable_AddRef( (view->elements[view->size++] = impl->elements[i]) );
295 *value = &view->IVectorView_IInspectable_iface;
296 return S_OK;
299 static HRESULT WINAPI vector_IndexOf( IVector_IInspectable *iface, IInspectable *element, UINT32 *index, BOOLEAN *found )
301 struct vector *impl = impl_from_IVector_IInspectable( iface );
302 ULONG i;
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;
308 else *index = 0;
310 return S_OK;
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) );
322 return S_OK;
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) );
344 return S_OK;
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) );
356 return S_OK;
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] );
375 return S_OK;
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 );
386 impl->capacity = 0;
387 impl->elements = NULL;
389 return S_OK;
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 );
396 UINT32 i;
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;
410 return S_OK;
413 static HRESULT WINAPI vector_ReplaceAll( IVector_IInspectable *iface, UINT32 count, IInspectable **items )
415 HRESULT hr;
416 ULONG i;
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] );
422 return hr;
425 static const struct IVector_IInspectableVtbl vector_vtbl =
427 vector_QueryInterface,
428 vector_AddRef,
429 vector_Release,
430 /* IInspectable methods */
431 vector_GetIids,
432 vector_GetRuntimeClassName,
433 vector_GetTrustLevel,
434 /* IVector<IInspectable*> methods */
435 vector_GetAt,
436 vector_get_Size,
437 vector_GetView,
438 vector_IndexOf,
439 vector_SetAt,
440 vector_InsertAt,
441 vector_RemoveAt,
442 vector_Append,
443 vector_RemoveAtEnd,
444 vector_Clear,
445 vector_GetMany,
446 vector_ReplaceAll,
449 HRESULT vector_create( REFIID iid, REFIID view_iid, void **out )
451 struct vector *impl;
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;
457 impl->iid = iid;
458 impl->view_iid = view_iid;
459 impl->ref = 1;
461 *out = &impl->IVector_IInspectable_iface;
462 TRACE( "created %p\n", *out );
463 return S_OK;