dinput/tests: Use separate statements instead of the comma operator.
[wine.git] / dlls / dinput / tests / force_feedback.c
blob696546ee49dbffc318e964a2b5dfb9334be4abae
1 /*
2 * Copyright 2022 RĂ©mi Bernon for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define DIRECTINPUT_VERSION 0x0800
21 #include <stdarg.h>
22 #include <stddef.h>
23 #include <stdint.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
30 #define COBJMACROS
31 #include "dinput.h"
32 #include "dinputd.h"
33 #include "roapi.h"
34 #include "unknwn.h"
35 #include "winstring.h"
37 #include "wine/hid.h"
39 #include "dinput_test.h"
41 #define WIDL_using_Windows_Foundation
42 #define WIDL_using_Windows_Foundation_Collections
43 #define WIDL_using_Windows_Foundation_Numerics
44 #include "windows.foundation.h"
45 #define WIDL_using_Windows_Devices_Haptics
46 #define WIDL_using_Windows_Gaming_Input
47 #define WIDL_using_Windows_Gaming_Input_ForceFeedback
48 #include "windows.gaming.input.h"
49 #include "windows.gaming.input.forcefeedback.h"
50 #undef Size
52 static HRESULT (WINAPI *pRoGetActivationFactory)( HSTRING, REFIID, void** );
53 static HRESULT (WINAPI *pRoInitialize)( RO_INIT_TYPE );
54 static HRESULT (WINAPI *pWindowsCreateString)( const WCHAR*, UINT32, HSTRING* );
55 static HRESULT (WINAPI *pWindowsDeleteString)( HSTRING str );
56 static const WCHAR* (WINAPI *pWindowsGetStringRawBuffer)( HSTRING, UINT32* );
58 static BOOL load_combase_functions(void)
60 HMODULE combase = GetModuleHandleW( L"combase.dll" );
62 #define LOAD_FUNC(m, f) if (!(p ## f = (void *)GetProcAddress( m, #f ))) goto failed;
63 LOAD_FUNC( combase, RoGetActivationFactory );
64 LOAD_FUNC( combase, RoInitialize );
65 LOAD_FUNC( combase, WindowsCreateString );
66 LOAD_FUNC( combase, WindowsDeleteString );
67 LOAD_FUNC( combase, WindowsGetStringRawBuffer );
68 #undef LOAD_FUNC
70 return TRUE;
72 failed:
73 win_skip("Failed to load combase.dll functions, skipping tests\n");
74 return FALSE;
77 struct check_objects_todos
79 BOOL type;
80 BOOL guid;
81 BOOL usage;
82 BOOL name;
85 struct check_objects_params
87 DWORD version;
88 UINT index;
89 UINT expect_count;
90 const DIDEVICEOBJECTINSTANCEW *expect_objs;
91 const struct check_objects_todos *todo_objs;
92 BOOL todo_extra;
95 static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *args )
97 static const DIDEVICEOBJECTINSTANCEW unexpected_obj = {0};
98 static const struct check_objects_todos todo_none = {0};
99 struct check_objects_params *params = args;
100 const DIDEVICEOBJECTINSTANCEW *exp = params->expect_objs + params->index;
101 const struct check_objects_todos *todo;
103 if (!params->todo_objs) todo = &todo_none;
104 else todo = params->todo_objs + params->index;
106 todo_wine_if( params->todo_extra && params->index >= params->expect_count )
107 ok( params->index < params->expect_count, "unexpected extra object\n" );
108 if (params->index >= params->expect_count) return DIENUM_STOP;
110 winetest_push_context( "obj[%d]", params->index );
112 ok( params->index < params->expect_count, "unexpected extra object\n" );
113 if (params->index >= params->expect_count) exp = &unexpected_obj;
115 check_member( *obj, *exp, "%lu", dwSize );
116 todo_wine_if( todo->guid )
117 check_member_guid( *obj, *exp, guidType );
118 todo_wine_if( params->version < 0x700 && (obj->dwType & DIDFT_BUTTON) )
119 check_member( *obj, *exp, "%#lx", dwOfs );
120 todo_wine_if( todo->type )
121 check_member( *obj, *exp, "%#lx", dwType );
122 check_member( *obj, *exp, "%#lx", dwFlags );
123 if (!localized) todo_wine_if( todo->name ) check_member_wstr( *obj, *exp, tszName );
124 check_member( *obj, *exp, "%lu", dwFFMaxForce );
125 check_member( *obj, *exp, "%lu", dwFFForceResolution );
126 check_member( *obj, *exp, "%u", wCollectionNumber );
127 check_member( *obj, *exp, "%u", wDesignatorIndex );
128 check_member( *obj, *exp, "%#04x", wUsagePage );
129 todo_wine_if( todo->usage )
130 check_member( *obj, *exp, "%#04x", wUsage );
131 check_member( *obj, *exp, "%#lx", dwDimension );
132 check_member( *obj, *exp, "%#04x", wExponent );
133 check_member( *obj, *exp, "%u", wReportId );
135 winetest_pop_context();
137 params->index++;
138 return DIENUM_CONTINUE;
141 struct check_effects_params
143 UINT index;
144 UINT expect_count;
145 const DIEFFECTINFOW *expect_effects;
148 static BOOL CALLBACK check_effects( const DIEFFECTINFOW *effect, void *args )
150 static const DIEFFECTINFOW unexpected_effect = {0};
151 struct check_effects_params *params = args;
152 const DIEFFECTINFOW *exp = params->expect_effects + params->index;
154 winetest_push_context( "effect[%d]", params->index );
156 ok( params->index < params->expect_count, "unexpected extra object\n" );
157 if (params->index >= params->expect_count) exp = &unexpected_effect;
159 check_member( *effect, *exp, "%lu", dwSize );
160 check_member_guid( *effect, *exp, guid );
161 check_member( *effect, *exp, "%#lx", dwEffType );
162 check_member( *effect, *exp, "%#lx", dwStaticParams );
163 check_member( *effect, *exp, "%#lx", dwDynamicParams );
164 check_member_wstr( *effect, *exp, tszName );
166 winetest_pop_context();
167 params->index++;
169 return DIENUM_CONTINUE;
172 static BOOL CALLBACK check_effect_count( const DIEFFECTINFOW *effect, void *args )
174 DWORD *count = args;
175 *count = *count + 1;
176 return DIENUM_CONTINUE;
179 static BOOL CALLBACK check_no_created_effect_objects( IDirectInputEffect *effect, void *context )
181 ok( 0, "unexpected effect %p\n", effect );
182 return DIENUM_CONTINUE;
185 struct check_created_effect_params
187 IDirectInputEffect *expect_effect;
188 DWORD count;
191 static BOOL CALLBACK check_created_effect_objects( IDirectInputEffect *effect, void *context )
193 struct check_created_effect_params *params = context;
194 ULONG ref;
196 ok( effect == params->expect_effect, "got effect %p, expected %p\n", effect, params->expect_effect );
197 params->count++;
199 IDirectInputEffect_AddRef( effect );
200 ref = IDirectInputEffect_Release( effect );
201 ok( ref == 1, "got ref %lu, expected 1\n", ref );
202 return DIENUM_CONTINUE;
205 static BOOL CALLBACK enum_device_count( const DIDEVICEINSTANCEW *devinst, void *context )
207 DWORD *count = context;
208 *count = *count + 1;
209 return DIENUM_CONTINUE;
212 static void check_dinput_devices( DWORD version, DIDEVICEINSTANCEW *devinst )
214 IDirectInput8W *di8;
215 IDirectInputW *di;
216 ULONG count;
217 HRESULT hr;
219 if (version >= 0x800)
221 hr = DirectInput8Create( instance, version, &IID_IDirectInput8W, (void **)&di8, NULL );
222 ok( hr == DI_OK, "DirectInput8Create returned %#lx\n", hr );
224 hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_ALL, NULL, NULL, DIEDFL_ALLDEVICES );
225 ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#lx\n", hr );
226 hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_ALL, enum_device_count, &count, 0xdeadbeef );
227 ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#lx\n", hr );
228 hr = IDirectInput8_EnumDevices( di8, 0xdeadbeef, enum_device_count, &count, DIEDFL_ALLDEVICES );
229 ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#lx\n", hr );
231 count = 0;
232 hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_ALL, enum_device_count, &count, DIEDFL_ALLDEVICES );
233 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
234 ok( count == 3, "got count %lu, expected 0\n", count );
235 count = 0;
236 hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_DEVICE, enum_device_count, &count, DIEDFL_ALLDEVICES );
237 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
238 ok( count == 0, "got count %lu, expected 0\n", count );
239 count = 0;
240 hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_POINTER, enum_device_count, &count,
241 DIEDFL_INCLUDEALIASES | DIEDFL_INCLUDEPHANTOMS | DIEDFL_INCLUDEHIDDEN );
242 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
243 todo_wine
244 ok( count == 3, "got count %lu, expected 3\n", count );
245 count = 0;
246 hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_KEYBOARD, enum_device_count, &count,
247 DIEDFL_INCLUDEALIASES | DIEDFL_INCLUDEPHANTOMS | DIEDFL_INCLUDEHIDDEN );
248 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
249 todo_wine
250 ok( count == 3, "got count %lu, expected 3\n", count );
251 count = 0;
252 hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_GAMECTRL, enum_device_count, &count,
253 DIEDFL_INCLUDEALIASES | DIEDFL_INCLUDEPHANTOMS | DIEDFL_INCLUDEHIDDEN );
254 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
255 ok( count == 1, "got count %lu, expected 1\n", count );
257 count = 0;
258 hr = IDirectInput8_EnumDevices( di8, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_ALLDEVICES );
259 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
260 ok( count == 1, "got count %lu, expected 1\n", count );
262 count = 0;
263 hr = IDirectInput8_EnumDevices( di8, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_FORCEFEEDBACK );
264 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
265 if (IsEqualGUID( &devinst->guidFFDriver, &GUID_NULL )) ok( count == 0, "got count %lu, expected 0\n", count );
266 else ok( count == 1, "got count %lu, expected 1\n", count );
268 count = 0;
269 hr = IDirectInput8_EnumDevices( di8, (devinst->dwDevType & 0xff) + 1, enum_device_count, &count, DIEDFL_ALLDEVICES );
270 if ((devinst->dwDevType & 0xff) != DI8DEVTYPE_SUPPLEMENTAL) ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
271 else ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#lx\n", hr );
272 ok( count == 0, "got count %lu, expected 0\n", count );
274 else
276 hr = DirectInputCreateEx( instance, version, &IID_IDirectInput2W, (void **)&di, NULL );
277 ok( hr == DI_OK, "DirectInputCreateEx returned %#lx\n", hr );
279 hr = IDirectInput_EnumDevices( di, 0, NULL, NULL, DIEDFL_ALLDEVICES );
280 ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#lx\n", hr );
281 hr = IDirectInput_EnumDevices( di, 0, enum_device_count, &count, 0xdeadbeef );
282 ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#lx\n", hr );
283 hr = IDirectInput_EnumDevices( di, 0xdeadbeef, enum_device_count, &count, DIEDFL_ALLDEVICES );
284 ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#lx\n", hr );
285 hr = IDirectInput_EnumDevices( di, 0, enum_device_count, &count, DIEDFL_INCLUDEHIDDEN );
286 ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#lx\n", hr );
288 count = 0;
289 hr = IDirectInput_EnumDevices( di, 0, enum_device_count, &count, DIEDFL_ALLDEVICES );
290 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
291 ok( count == 3, "got count %lu, expected 0\n", count );
292 count = 0;
293 hr = IDirectInput_EnumDevices( di, DIDEVTYPE_DEVICE, enum_device_count, &count, DIEDFL_ALLDEVICES );
294 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
295 ok( count == 0, "got count %lu, expected 0\n", count );
296 count = 0;
297 hr = IDirectInput_EnumDevices( di, DIDEVTYPE_MOUSE, enum_device_count, &count,
298 DIEDFL_INCLUDEALIASES | DIEDFL_INCLUDEPHANTOMS );
299 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
300 todo_wine
301 ok( count == 3, "got count %lu, expected 3\n", count );
302 count = 0;
303 hr = IDirectInput_EnumDevices( di, DIDEVTYPE_KEYBOARD, enum_device_count, &count,
304 DIEDFL_INCLUDEALIASES | DIEDFL_INCLUDEPHANTOMS );
305 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
306 todo_wine
307 ok( count == 3, "got count %lu, expected 3\n", count );
308 count = 0;
309 hr = IDirectInput_EnumDevices( di, DIDEVTYPE_JOYSTICK, enum_device_count, &count,
310 DIEDFL_INCLUDEALIASES | DIEDFL_INCLUDEPHANTOMS );
311 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
312 ok( count == 1, "got count %lu, expected 1\n", count );
314 count = 0;
315 hr = IDirectInput_EnumDevices( di, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_ALLDEVICES );
316 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
317 ok( count == 1, "got count %lu, expected 1\n", count );
319 count = 0;
320 hr = IDirectInput_EnumDevices( di, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_FORCEFEEDBACK );
321 ok( hr == DI_OK, "EnumDevices returned: %#lx\n", hr );
322 if (IsEqualGUID( &devinst->guidFFDriver, &GUID_NULL )) ok( count == 0, "got count %lu, expected 0\n", count );
323 else ok( count == 1, "got count %lu, expected 1\n", count );
325 hr = IDirectInput_EnumDevices( di, 0x14, enum_device_count, &count, DIEDFL_ALLDEVICES );
326 ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#lx\n", hr );
330 static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file, DWORD version )
332 struct hid_expect expect_download[] =
334 /* set periodic */
336 .code = IOCTL_HID_WRITE_REPORT,
337 .report_id = 5,
338 .report_len = 2,
339 .report_buf = {0x05,0x19},
341 /* set envelope */
343 .code = IOCTL_HID_WRITE_REPORT,
344 .report_id = 6,
345 .report_len = 7,
346 .report_buf = {0x06,0x19,0x4c,0x02,0x00,0x04,0x00},
348 /* update effect */
350 .code = IOCTL_HID_WRITE_REPORT,
351 .report_id = 3,
352 .report_len = 11,
353 .report_buf = {0x03,0x01,0x01,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
355 /* start command when DIEP_START is set */
357 .code = IOCTL_HID_WRITE_REPORT,
358 .report_id = 2,
359 .report_len = 4,
360 .report_buf = {0x02,0x01,0x01,0x01},
363 struct hid_expect expect_download_0[] =
365 /* set periodic */
367 .code = IOCTL_HID_WRITE_REPORT,
368 .report_id = 5,
369 .report_len = 2,
370 .report_buf = {0x05,0x00},
372 /* set envelope */
374 .code = IOCTL_HID_WRITE_REPORT,
375 .report_id = 6,
376 .report_len = 7,
377 .report_buf = {0x06,0x00,0x00,0x00,0x00,0x00,0x00},
379 /* update effect */
381 .code = IOCTL_HID_WRITE_REPORT,
382 .report_id = 3,
383 .report_len = 11,
384 .report_buf = {0x03,0x01,0x02,0x08,0x01,0x00,0x00,0x00,0x01,0x3f,0x00},
387 struct hid_expect expect_download_1[] =
389 /* set periodic */
391 .code = IOCTL_HID_WRITE_REPORT,
392 .report_id = 5,
393 .report_len = 2,
394 .report_buf = {0x05,0x00},
396 /* update effect */
398 .code = IOCTL_HID_WRITE_REPORT,
399 .report_id = 3,
400 .report_len = 11,
401 .report_buf = {0x03,0x01,0x02,0x08,0x01,0x00,0x00,0x00,0x01,0x3f,0x00},
404 struct hid_expect expect_download_2[] =
406 /* set periodic */
408 .code = IOCTL_HID_WRITE_REPORT,
409 .report_id = 5,
410 .report_len = 2,
411 .report_buf = {0x05,0x19},
413 /* set envelope */
415 .code = IOCTL_HID_WRITE_REPORT,
416 .report_id = 6,
417 .report_len = 7,
418 .report_buf = {0x06,0x19,0x4c,0x02,0x00,0x04,0x00},
420 /* update effect */
422 .code = IOCTL_HID_WRITE_REPORT,
423 .report_id = 3,
424 .report_len = 11,
425 .report_buf = {0x03,0x01,0x02,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
428 struct hid_expect expect_download_3[] =
430 /* set periodic */
432 .code = IOCTL_HID_WRITE_REPORT,
433 .report_id = 5,
434 .report_len = 2,
435 .report_buf = {0x05,0x19},
437 /* set envelope */
439 .code = IOCTL_HID_WRITE_REPORT,
440 .report_id = 6,
441 .report_len = 7,
442 .report_buf = {0x06,0x19,0x4c,0x01,0x00,0x04,0x00},
444 /* update effect */
446 .code = IOCTL_HID_WRITE_REPORT,
447 .report_id = 3,
448 .report_len = 11,
449 .report_buf = {0x03,0x01,0x02,0x08,0xff,0xff,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
452 struct hid_expect expect_download_4[] =
454 /* set periodic */
456 .code = IOCTL_HID_WRITE_REPORT,
457 .report_id = 5,
458 .report_len = 2,
459 .report_buf = {0x05,0x19},
461 /* update effect */
463 .code = IOCTL_HID_WRITE_REPORT,
464 .report_id = 3,
465 .report_len = 11,
466 .report_buf = {0x03,0x01,0x02,0x08,0xff,0xff,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
469 struct hid_expect expect_update[] =
471 /* update effect */
473 .code = IOCTL_HID_WRITE_REPORT,
474 .report_id = 3,
475 .report_len = 11,
476 .report_buf = {0x03, 0x01, 0x02, 0x08, 0xff, 0xff, version >= 0x700 ? 0x06 : 0x00, 0x00, 0x01, 0x55, 0xd5},
479 struct hid_expect expect_set_envelope[] =
481 /* set envelope */
483 .code = IOCTL_HID_WRITE_REPORT,
484 .report_id = 6,
485 .report_len = 7,
486 .report_buf = {0x06, 0x19, 0x4c, 0x01, 0x00, 0x04, 0x00},
489 struct hid_expect expect_start =
491 .code = IOCTL_HID_WRITE_REPORT,
492 .report_id = 2,
493 .report_len = 4,
494 .report_buf = {0x02, 0x01, 0x01, 0x01},
496 struct hid_expect expect_start_solo =
498 .code = IOCTL_HID_WRITE_REPORT,
499 .report_id = 2,
500 .report_len = 4,
501 .report_buf = {0x02, 0x01, 0x02, 0x01},
503 struct hid_expect expect_start_0 =
505 .code = IOCTL_HID_WRITE_REPORT,
506 .report_id = 2,
507 .report_len = 4,
508 .report_buf = {0x02, 0x01, 0x01, 0x00},
510 struct hid_expect expect_start_4 =
512 .code = IOCTL_HID_WRITE_REPORT,
513 .report_id = 2,
514 .report_len = 4,
515 .report_buf = {0x02, 0x01, 0x01, 0x04},
517 struct hid_expect expect_stop =
519 .code = IOCTL_HID_WRITE_REPORT,
520 .report_id = 2,
521 .report_len = 4,
522 .report_buf = {0x02, 0x01, 0x03, 0x00},
524 struct hid_expect expect_unload[] =
527 .code = IOCTL_HID_WRITE_REPORT,
528 .report_id = 2,
529 .report_len = 4,
530 .report_buf = {0x02,0x01,0x03,0x00},
532 /* device reset, when unloaded from Unacquire */
534 .code = IOCTL_HID_WRITE_REPORT,
535 .report_id = 1,
536 .report_len = 2,
537 .report_buf = {1,0x01},
540 struct hid_expect expect_acquire[] =
543 .code = IOCTL_HID_WRITE_REPORT,
544 .report_id = 1,
545 .report_len = 2,
546 .report_buf = {1, 0x01},
549 .code = IOCTL_HID_WRITE_REPORT,
550 .report_id = 8,
551 .report_len = 2,
552 .report_buf = {8, 0x19},
555 struct hid_expect expect_reset[] =
558 .code = IOCTL_HID_WRITE_REPORT,
559 .report_id = 1,
560 .report_len = 2,
561 .report_buf = {1, 0x01},
564 static const DWORD expect_axes_init[2] = {0};
565 const DIEFFECT expect_desc_init =
567 .dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5),
568 .dwTriggerButton = -1,
569 .rgdwAxes = (void *)expect_axes_init,
571 static const DWORD expect_axes[3] =
573 DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR,
574 DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR,
575 DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR,
577 static const LONG expect_directions[3] =
579 +3000,
580 -6000,
583 static const DIENVELOPE expect_envelope =
585 .dwSize = sizeof(DIENVELOPE),
586 .dwAttackLevel = 1000,
587 .dwAttackTime = 2000,
588 .dwFadeLevel = 3000,
589 .dwFadeTime = 4000,
591 static const DIPERIODIC expect_periodic =
593 .dwMagnitude = 1000,
594 .lOffset = 2000,
595 .dwPhase = 3000,
596 .dwPeriod = 4000,
598 const DIEFFECT expect_desc =
600 .dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5),
601 .dwFlags = DIEFF_SPHERICAL | DIEFF_OBJECTIDS,
602 .dwDuration = 1000,
603 .dwSamplePeriod = 2000,
604 .dwGain = 3000,
605 .dwTriggerButton = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER,
606 .dwTriggerRepeatInterval = 5000,
607 .cAxes = 3,
608 .rgdwAxes = (void *)expect_axes,
609 .rglDirection = (void *)expect_directions,
610 .lpEnvelope = (void *)&expect_envelope,
611 .cbTypeSpecificParams = sizeof(DIPERIODIC),
612 .lpvTypeSpecificParams = (void *)&expect_periodic,
613 .dwStartDelay = 6000,
615 static const LONG expect_directions_0[3] = {0};
616 static const DIENVELOPE expect_envelope_0 = {.dwSize = sizeof(DIENVELOPE)};
617 static const DIPERIODIC expect_periodic_0 = {0};
618 const DIEFFECT expect_desc_0 =
620 .dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5),
621 .dwFlags = DIEFF_SPHERICAL | DIEFF_OBJECTIDS,
622 .dwDuration = 1000,
623 .dwTriggerButton = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER,
624 .cAxes = 3,
625 .rgdwAxes = (void *)expect_axes,
626 .rglDirection = (void *)expect_directions_0,
627 .lpEnvelope = (void *)&expect_envelope_0,
628 .cbTypeSpecificParams = sizeof(DIPERIODIC),
629 .lpvTypeSpecificParams = (void *)&expect_periodic_0,
631 struct check_created_effect_params check_params = {0};
632 IDirectInputEffect *effect;
633 DIPERIODIC periodic = {0};
634 DIENVELOPE envelope = {0};
635 LONG directions[4] = {0};
636 DIEFFECT desc = {0};
637 DWORD axes[4] = {0};
638 ULONG i, ref, flags;
639 HRESULT hr;
640 GUID guid;
642 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Sine, NULL, NULL, NULL );
643 ok( hr == E_POINTER, "CreateEffect returned %#lx\n", hr );
644 hr = IDirectInputDevice8_CreateEffect( device, NULL, NULL, &effect, NULL );
645 ok( hr == E_POINTER, "CreateEffect returned %#lx\n", hr );
646 hr = IDirectInputDevice8_CreateEffect( device, &GUID_NULL, NULL, &effect, NULL );
647 ok( hr == DIERR_DEVICENOTREG, "CreateEffect returned %#lx\n", hr );
649 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Sine, NULL, &effect, NULL );
650 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
651 if (hr != DI_OK) return;
653 hr = IDirectInputDevice8_EnumCreatedEffectObjects( device, check_no_created_effect_objects, effect, 0xdeadbeef );
654 ok( hr == DIERR_INVALIDPARAM, "EnumCreatedEffectObjects returned %#lx\n", hr );
655 check_params.expect_effect = effect;
656 hr = IDirectInputDevice8_EnumCreatedEffectObjects( device, check_created_effect_objects, &check_params, 0 );
657 ok( hr == DI_OK, "EnumCreatedEffectObjects returned %#lx\n", hr );
658 ok( check_params.count == 1, "got count %lu, expected 1\n", check_params.count );
660 hr = IDirectInputEffect_Initialize( effect, NULL, version, &GUID_Sine );
661 ok( hr == DIERR_INVALIDPARAM, "Initialize returned %#lx\n", hr );
662 hr = IDirectInputEffect_Initialize( effect, instance, 0x800 - (version - 0x700), &GUID_Sine );
663 if (version == 0x800)
665 todo_wine
666 ok( hr == DIERR_BETADIRECTINPUTVERSION, "Initialize returned %#lx\n", hr );
668 else
670 todo_wine
671 ok( hr == DIERR_OLDDIRECTINPUTVERSION, "Initialize returned %#lx\n", hr );
673 hr = IDirectInputEffect_Initialize( effect, instance, 0, &GUID_Sine );
674 todo_wine
675 ok( hr == DIERR_NOTINITIALIZED, "Initialize returned %#lx\n", hr );
676 hr = IDirectInputEffect_Initialize( effect, instance, version, NULL );
677 ok( hr == E_POINTER, "Initialize returned %#lx\n", hr );
679 hr = IDirectInputEffect_Initialize( effect, instance, version, &GUID_NULL );
680 ok( hr == DIERR_DEVICENOTREG, "Initialize returned %#lx\n", hr );
681 hr = IDirectInputEffect_Initialize( effect, instance, version, &GUID_Sine );
682 ok( hr == DI_OK, "Initialize returned %#lx\n", hr );
683 hr = IDirectInputEffect_Initialize( effect, instance, version, &GUID_Square );
684 ok( hr == DI_OK, "Initialize returned %#lx\n", hr );
686 hr = IDirectInputEffect_GetEffectGuid( effect, NULL );
687 ok( hr == E_POINTER, "GetEffectGuid returned %#lx\n", hr );
688 hr = IDirectInputEffect_GetEffectGuid( effect, &guid );
689 ok( hr == DI_OK, "GetEffectGuid returned %#lx\n", hr );
690 ok( IsEqualGUID( &guid, &GUID_Square ), "got guid %s, expected %s\n", debugstr_guid( &guid ),
691 debugstr_guid( &GUID_Square ) );
693 hr = IDirectInputEffect_GetParameters( effect, NULL, 0 );
694 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
695 hr = IDirectInputEffect_GetParameters( effect, NULL, DIEP_DURATION );
696 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
697 hr = IDirectInputEffect_GetParameters( effect, &desc, 0 );
698 ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#lx\n", hr );
699 desc.dwSize = sizeof(DIEFFECT_DX5) + 2;
700 hr = IDirectInputEffect_GetParameters( effect, &desc, 0 );
701 ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#lx\n", hr );
702 desc.dwSize = sizeof(DIEFFECT_DX5);
703 hr = IDirectInputEffect_GetParameters( effect, &desc, 0 );
704 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
705 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_STARTDELAY );
706 ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#lx\n", hr );
707 desc.dwSize = sizeof(DIEFFECT_DX6);
708 hr = IDirectInputEffect_GetParameters( effect, &desc, 0 );
709 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
711 set_hid_expect( file, expect_reset, sizeof(expect_reset) );
712 hr = IDirectInputDevice8_Unacquire( device );
713 ok( hr == DI_OK, "Unacquire returned: %#lx\n", hr );
714 set_hid_expect( file, NULL, 0 );
715 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DURATION );
716 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
717 set_hid_expect( file, expect_acquire, sizeof(expect_acquire) );
718 hr = IDirectInputDevice8_Acquire( device );
719 ok( hr == DI_OK, "Acquire returned: %#lx\n", hr );
720 wait_hid_expect( file, 100 ); /* device gain reports are written asynchronously */
722 desc.dwDuration = 0xdeadbeef;
723 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DURATION );
724 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
725 check_member( desc, expect_desc_init, "%lu", dwDuration );
726 memset( &desc, 0xcd, sizeof(desc) );
727 desc.dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5);
728 desc.dwFlags = 0;
729 desc.dwStartDelay = 0xdeadbeef;
730 flags = DIEP_GAIN | DIEP_SAMPLEPERIOD | DIEP_TRIGGERREPEATINTERVAL |
731 (version >= 0x700 ? DIEP_STARTDELAY : 0);
732 hr = IDirectInputEffect_GetParameters( effect, &desc, flags );
733 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
734 check_member( desc, expect_desc_init, "%lu", dwSamplePeriod );
735 check_member( desc, expect_desc_init, "%lu", dwGain );
736 if (version >= 0x700) check_member( desc, expect_desc_init, "%lu", dwStartDelay );
737 else ok( desc.dwStartDelay == 0xdeadbeef, "got dwStartDelay %#lx\n", desc.dwStartDelay );
738 check_member( desc, expect_desc_init, "%lu", dwTriggerRepeatInterval );
740 memset( &desc, 0xcd, sizeof(desc) );
741 desc.dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5);
742 desc.dwFlags = 0;
743 desc.lpEnvelope = NULL;
744 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_ENVELOPE );
745 ok( hr == E_POINTER, "GetParameters returned %#lx\n", hr );
746 desc.lpEnvelope = &envelope;
747 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_ENVELOPE );
748 ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#lx\n", hr );
749 envelope.dwSize = sizeof(DIENVELOPE);
750 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_ENVELOPE );
751 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
753 desc.dwFlags = 0;
754 desc.cAxes = 0;
755 desc.rgdwAxes = NULL;
756 desc.rglDirection = NULL;
757 desc.lpEnvelope = NULL;
758 desc.cbTypeSpecificParams = 0;
759 desc.lpvTypeSpecificParams = NULL;
760 hr = IDirectInputEffect_GetParameters( effect, &desc, version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5 );
761 ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#lx\n", hr );
762 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_TRIGGERBUTTON );
763 ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#lx\n", hr );
764 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_AXES );
765 ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#lx\n", hr );
766 desc.dwFlags = DIEFF_OBJECTOFFSETS;
767 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
768 ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#lx\n", hr );
769 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_TRIGGERBUTTON );
770 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
771 check_member( desc, expect_desc_init, "%#lx", dwTriggerButton );
772 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_AXES );
773 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
774 check_member( desc, expect_desc_init, "%lu", cAxes );
775 desc.dwFlags = DIEFF_OBJECTIDS;
776 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
777 ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#lx\n", hr );
778 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_TRIGGERBUTTON );
779 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
780 check_member( desc, expect_desc_init, "%#lx", dwTriggerButton );
781 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_AXES );
782 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
783 check_member( desc, expect_desc_init, "%lu", cAxes );
784 desc.dwFlags |= DIEFF_CARTESIAN;
785 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
786 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
787 ok( desc.dwFlags == DIEFF_OBJECTIDS, "got flags %#lx, expected %#x\n", desc.dwFlags, DIEFF_OBJECTIDS );
788 desc.dwFlags |= DIEFF_POLAR;
789 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
790 ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#lx\n", hr );
791 ok( desc.dwFlags == DIEFF_OBJECTIDS, "got flags %#lx, expected %#x\n", desc.dwFlags, DIEFF_OBJECTIDS );
792 desc.dwFlags |= DIEFF_SPHERICAL;
793 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
794 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
795 check_member( desc, expect_desc_init, "%lu", cAxes );
796 ok( desc.dwFlags == DIEFF_OBJECTIDS, "got flags %#lx, expected %#x\n", desc.dwFlags, DIEFF_OBJECTIDS );
798 desc.dwFlags |= DIEFF_SPHERICAL;
799 desc.cAxes = 2;
800 desc.rgdwAxes = axes;
801 desc.rglDirection = directions;
802 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_AXES | DIEP_DIRECTION );
803 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
804 check_member( desc, expect_desc_init, "%lu", cAxes );
805 check_member( desc, expect_desc_init, "%lu", rgdwAxes[0] );
806 check_member( desc, expect_desc_init, "%lu", rgdwAxes[1] );
807 check_member( desc, expect_desc_init, "%p", rglDirection );
808 ok( desc.dwFlags == DIEFF_OBJECTIDS, "got flags %#lx, expected %#x\n", desc.dwFlags, DIEFF_OBJECTIDS );
810 desc.dwFlags |= DIEFF_SPHERICAL;
811 desc.lpEnvelope = &envelope;
812 desc.cbTypeSpecificParams = sizeof(periodic);
813 desc.lpvTypeSpecificParams = &periodic;
814 hr = IDirectInputEffect_GetParameters( effect, &desc, version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5 );
815 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
816 check_member( desc, expect_desc_init, "%lu", dwDuration );
817 check_member( desc, expect_desc_init, "%lu", dwSamplePeriod );
818 check_member( desc, expect_desc_init, "%lu", dwGain );
819 check_member( desc, expect_desc_init, "%#lx", dwTriggerButton );
820 check_member( desc, expect_desc_init, "%lu", dwTriggerRepeatInterval );
821 check_member( desc, expect_desc_init, "%lu", cAxes );
822 check_member( desc, expect_desc_init, "%lu", rgdwAxes[0] );
823 check_member( desc, expect_desc_init, "%lu", rgdwAxes[1] );
824 check_member( desc, expect_desc_init, "%p", rglDirection );
825 check_member( desc, expect_desc_init, "%p", lpEnvelope );
826 check_member( desc, expect_desc_init, "%lu", cbTypeSpecificParams );
827 if (version >= 0x700) check_member( desc, expect_desc_init, "%lu", dwStartDelay );
828 else ok( desc.dwStartDelay == 0xcdcdcdcd, "got dwStartDelay %#lx\n", desc.dwStartDelay );
830 set_hid_expect( file, expect_reset, sizeof(expect_reset) );
831 hr = IDirectInputDevice8_Unacquire( device );
832 ok( hr == DI_OK, "Unacquire returned: %#lx\n", hr );
833 set_hid_expect( file, NULL, 0 );
834 hr = IDirectInputEffect_Download( effect );
835 ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "Download returned %#lx\n", hr );
836 set_hid_expect( file, expect_acquire, sizeof(expect_acquire) );
837 hr = IDirectInputDevice8_Acquire( device );
838 ok( hr == DI_OK, "Acquire returned: %#lx\n", hr );
839 wait_hid_expect( file, 100 ); /* device gain reports are written asynchronously */
841 hr = IDirectInputEffect_Download( effect );
842 ok( hr == DIERR_INCOMPLETEEFFECT, "Download returned %#lx\n", hr );
843 hr = IDirectInputEffect_Unload( effect );
844 ok( hr == DI_NOEFFECT, "Unload returned %#lx\n", hr );
846 hr = IDirectInputEffect_SetParameters( effect, NULL, DIEP_NODOWNLOAD );
847 ok( hr == E_POINTER, "SetParameters returned %#lx\n", hr );
848 memset( &desc, 0, sizeof(desc) );
849 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_NODOWNLOAD );
850 ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#lx\n", hr );
851 desc.dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5);
852 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_NODOWNLOAD );
853 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
855 set_hid_expect( file, expect_reset, sizeof(expect_reset) );
856 hr = IDirectInputDevice8_Unacquire( device );
857 ok( hr == DI_OK, "Unacquire returned: %#lx\n", hr );
858 set_hid_expect( file, NULL, 0 );
859 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, DIEP_DURATION );
860 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
861 set_hid_expect( file, expect_acquire, sizeof(expect_acquire) );
862 hr = IDirectInputDevice8_Acquire( device );
863 ok( hr == DI_OK, "Acquire returned: %#lx\n", hr );
864 wait_hid_expect( file, 100 ); /* device gain reports are written asynchronously */
866 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, DIEP_DURATION | DIEP_NODOWNLOAD );
867 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
869 desc.dwTriggerButton = -1;
870 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DURATION );
871 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
872 check_member( desc, expect_desc, "%lu", dwDuration );
873 check_member( desc, expect_desc_init, "%lu", dwSamplePeriod );
874 check_member( desc, expect_desc_init, "%lu", dwGain );
875 check_member( desc, expect_desc_init, "%#lx", dwTriggerButton );
876 check_member( desc, expect_desc_init, "%lu", dwTriggerRepeatInterval );
877 check_member( desc, expect_desc_init, "%lu", cAxes );
878 check_member( desc, expect_desc_init, "%p", rglDirection );
879 check_member( desc, expect_desc_init, "%p", lpEnvelope );
880 check_member( desc, expect_desc_init, "%lu", cbTypeSpecificParams );
881 check_member( desc, expect_desc_init, "%lu", dwStartDelay );
883 hr = IDirectInputEffect_Download( effect );
884 ok( hr == DIERR_INCOMPLETEEFFECT, "Download returned %#lx\n", hr );
885 hr = IDirectInputEffect_Unload( effect );
886 ok( hr == DI_NOEFFECT, "Unload returned %#lx\n", hr );
888 flags = DIEP_GAIN | DIEP_SAMPLEPERIOD | DIEP_TRIGGERREPEATINTERVAL | DIEP_NODOWNLOAD;
889 if (version >= 0x700) flags |= DIEP_STARTDELAY;
890 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, flags );
891 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
892 desc.dwDuration = 0;
893 flags = DIEP_DURATION | DIEP_GAIN | DIEP_SAMPLEPERIOD | DIEP_TRIGGERREPEATINTERVAL;
894 if (version >= 0x700) flags |= DIEP_STARTDELAY;
895 hr = IDirectInputEffect_GetParameters( effect, &desc, flags );
896 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
897 check_member( desc, expect_desc, "%lu", dwDuration );
898 check_member( desc, expect_desc, "%lu", dwSamplePeriod );
899 check_member( desc, expect_desc, "%lu", dwGain );
900 check_member( desc, expect_desc_init, "%#lx", dwTriggerButton );
901 check_member( desc, expect_desc, "%lu", dwTriggerRepeatInterval );
902 check_member( desc, expect_desc_init, "%lu", cAxes );
903 check_member( desc, expect_desc_init, "%p", rglDirection );
904 check_member( desc, expect_desc_init, "%p", lpEnvelope );
905 check_member( desc, expect_desc_init, "%lu", cbTypeSpecificParams );
906 if (version >= 0x700) check_member( desc, expect_desc, "%lu", dwStartDelay );
907 else ok( desc.dwStartDelay == 0, "got dwStartDelay %#lx\n", desc.dwStartDelay );
909 hr = IDirectInputEffect_Download( effect );
910 ok( hr == DIERR_INCOMPLETEEFFECT, "Download returned %#lx\n", hr );
911 hr = IDirectInputEffect_Unload( effect );
912 ok( hr == DI_NOEFFECT, "Unload returned %#lx\n", hr );
914 desc.lpEnvelope = NULL;
915 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_ENVELOPE | DIEP_NODOWNLOAD );
916 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
917 desc.lpEnvelope = &envelope;
918 envelope.dwSize = 0;
919 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_ENVELOPE | DIEP_NODOWNLOAD );
920 ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#lx\n", hr );
922 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, DIEP_ENVELOPE | DIEP_NODOWNLOAD );
923 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
925 desc.lpEnvelope = &envelope;
926 envelope.dwSize = sizeof(DIENVELOPE);
927 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_ENVELOPE );
928 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
929 check_member( envelope, expect_envelope, "%lu", dwAttackLevel );
930 check_member( envelope, expect_envelope, "%lu", dwAttackTime );
931 check_member( envelope, expect_envelope, "%lu", dwFadeLevel );
932 check_member( envelope, expect_envelope, "%lu", dwFadeTime );
934 hr = IDirectInputEffect_Download( effect );
935 ok( hr == DIERR_INCOMPLETEEFFECT, "Download returned %#lx\n", hr );
936 hr = IDirectInputEffect_Unload( effect );
937 ok( hr == DI_NOEFFECT, "Unload returned %#lx\n", hr );
939 desc.dwFlags = 0;
940 desc.cAxes = 0;
941 desc.rgdwAxes = NULL;
942 desc.rglDirection = NULL;
943 desc.lpEnvelope = NULL;
944 desc.cbTypeSpecificParams = 0;
945 desc.lpvTypeSpecificParams = NULL;
946 flags = version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5;
947 hr = IDirectInputEffect_SetParameters( effect, &desc, flags | DIEP_NODOWNLOAD );
948 ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#lx\n", hr );
949 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_TRIGGERBUTTON | DIEP_NODOWNLOAD );
950 ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#lx\n", hr );
951 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_AXES | DIEP_NODOWNLOAD );
952 ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#lx\n", hr );
954 desc.dwFlags = DIEFF_OBJECTOFFSETS;
955 desc.cAxes = 1;
956 desc.rgdwAxes = axes;
957 desc.rgdwAxes[0] = DIJOFS_X;
958 desc.dwTriggerButton = DIJOFS_BUTTON( 1 );
959 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_DIRECTION | DIEP_NODOWNLOAD );
960 ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#lx\n", hr );
961 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, DIEP_AXES | DIEP_TRIGGERBUTTON | DIEP_NODOWNLOAD );
962 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
963 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_AXES | DIEP_TRIGGERBUTTON | DIEP_NODOWNLOAD );
964 ok( hr == DIERR_ALREADYINITIALIZED, "SetParameters returned %#lx\n", hr );
966 desc.cAxes = 0;
967 desc.dwFlags = DIEFF_OBJECTIDS;
968 desc.rgdwAxes = axes;
969 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_AXES | DIEP_TRIGGERBUTTON );
970 ok( hr == DIERR_MOREDATA, "GetParameters returned %#lx\n", hr );
971 check_member( desc, expect_desc, "%lu", cAxes );
972 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_AXES | DIEP_TRIGGERBUTTON );
973 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
974 check_member( desc, expect_desc, "%#lx", dwTriggerButton );
975 check_member( desc, expect_desc, "%lu", cAxes );
976 check_member( desc, expect_desc, "%lu", rgdwAxes[0] );
977 check_member( desc, expect_desc, "%lu", rgdwAxes[1] );
978 check_member( desc, expect_desc, "%lu", rgdwAxes[2] );
980 desc.dwFlags = DIEFF_OBJECTOFFSETS;
981 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_AXES | DIEP_TRIGGERBUTTON );
982 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
983 ok( desc.dwTriggerButton == 0x30, "got %#lx expected %#x\n", desc.dwTriggerButton, 0x30 );
984 ok( desc.rgdwAxes[0] == 8, "got %#lx expected %#x\n", desc.rgdwAxes[0], 8 );
985 ok( desc.rgdwAxes[1] == 0, "got %#lx expected %#x\n", desc.rgdwAxes[1], 0 );
986 ok( desc.rgdwAxes[2] == 4, "got %#lx expected %#x\n", desc.rgdwAxes[2], 4 );
988 hr = IDirectInputEffect_Download( effect );
989 ok( hr == DIERR_INCOMPLETEEFFECT, "Download returned %#lx\n", hr );
990 hr = IDirectInputEffect_Unload( effect );
991 ok( hr == DI_NOEFFECT, "Unload returned %#lx\n", hr );
993 desc.dwFlags = DIEFF_CARTESIAN;
994 desc.cAxes = 0;
995 desc.rglDirection = directions;
996 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_DIRECTION | DIEP_NODOWNLOAD );
997 ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#lx\n", hr );
998 desc.cAxes = 3;
999 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_DIRECTION | DIEP_NODOWNLOAD );
1000 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1001 desc.dwFlags = DIEFF_POLAR;
1002 desc.cAxes = 3;
1003 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_DIRECTION | DIEP_NODOWNLOAD );
1004 ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#lx\n", hr );
1006 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, DIEP_DIRECTION | DIEP_NODOWNLOAD );
1007 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1009 desc.dwFlags = DIEFF_SPHERICAL;
1010 desc.cAxes = 1;
1011 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1012 ok( hr == DIERR_MOREDATA, "GetParameters returned %#lx\n", hr );
1013 ok( desc.dwFlags == DIEFF_SPHERICAL, "got flags %#lx, expected %#x\n", desc.dwFlags, DIEFF_SPHERICAL );
1014 check_member( desc, expect_desc, "%lu", cAxes );
1015 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1016 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
1017 check_member( desc, expect_desc, "%lu", cAxes );
1018 ok( desc.rglDirection[0] == 3000, "got rglDirection[0] %ld expected %d\n", desc.rglDirection[0], 3000 );
1019 ok( desc.rglDirection[1] == 30000, "got rglDirection[1] %ld expected %d\n", desc.rglDirection[1], 30000 );
1020 ok( desc.rglDirection[2] == 0, "got rglDirection[2] %ld expected %d\n", desc.rglDirection[2], 0 );
1021 desc.dwFlags = DIEFF_CARTESIAN;
1022 desc.cAxes = 2;
1023 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1024 ok( hr == DIERR_MOREDATA, "GetParameters returned %#lx\n", hr );
1025 ok( desc.dwFlags == DIEFF_CARTESIAN, "got flags %#lx, expected %#x\n", desc.dwFlags, DIEFF_CARTESIAN );
1026 check_member( desc, expect_desc, "%lu", cAxes );
1027 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1028 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
1029 check_member( desc, expect_desc, "%lu", cAxes );
1030 ok( desc.rglDirection[0] == 4330, "got rglDirection[0] %ld expected %d\n", desc.rglDirection[0], 4330 );
1031 ok( desc.rglDirection[1] == 2500, "got rglDirection[1] %ld expected %d\n", desc.rglDirection[1], 2500 );
1032 ok( desc.rglDirection[2] == -8660, "got rglDirection[2] %ld expected %d\n", desc.rglDirection[2], -8660 );
1033 desc.dwFlags = DIEFF_POLAR;
1034 desc.cAxes = 3;
1035 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1036 ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#lx\n", hr );
1038 hr = IDirectInputEffect_Download( effect );
1039 ok( hr == DIERR_INCOMPLETEEFFECT, "Download returned %#lx\n", hr );
1040 hr = IDirectInputEffect_Unload( effect );
1041 ok( hr == DI_NOEFFECT, "Unload returned %#lx\n", hr );
1043 desc.cbTypeSpecificParams = 0;
1044 desc.lpvTypeSpecificParams = &periodic;
1045 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_TYPESPECIFICPARAMS | DIEP_NODOWNLOAD );
1046 ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#lx\n", hr );
1047 desc.cbTypeSpecificParams = sizeof(DIPERIODIC);
1048 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_TYPESPECIFICPARAMS | DIEP_NODOWNLOAD );
1049 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1050 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, DIEP_TYPESPECIFICPARAMS | DIEP_NODOWNLOAD );
1051 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1053 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_TYPESPECIFICPARAMS );
1054 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
1055 check_member( periodic, expect_periodic, "%lu", dwMagnitude );
1056 check_member( periodic, expect_periodic, "%ld", lOffset );
1057 check_member( periodic, expect_periodic, "%lu", dwPhase );
1058 check_member( periodic, expect_periodic, "%lu", dwPeriod );
1060 hr = IDirectInputEffect_Start( effect, 1, DIES_NODOWNLOAD );
1061 ok( hr == DIERR_NOTDOWNLOADED, "Start returned %#lx\n", hr );
1062 hr = IDirectInputEffect_Stop( effect );
1063 ok( hr == DIERR_NOTDOWNLOADED, "Stop returned %#lx\n", hr );
1065 set_hid_expect( file, expect_download, 3 * sizeof(struct hid_expect) );
1066 hr = IDirectInputEffect_Download( effect );
1067 ok( hr == DI_OK, "Download returned %#lx\n", hr );
1068 set_hid_expect( file, NULL, 0 );
1070 hr = IDirectInputEffect_Download( effect );
1071 ok( hr == DI_NOEFFECT, "Download returned %#lx\n", hr );
1073 hr = IDirectInputEffect_Start( effect, 1, 0xdeadbeef );
1074 ok( hr == DIERR_INVALIDPARAM, "Start returned %#lx\n", hr );
1076 set_hid_expect( file, &expect_start_solo, sizeof(expect_start_solo) );
1077 hr = IDirectInputEffect_Start( effect, 1, DIES_SOLO );
1078 ok( hr == DI_OK, "Start returned %#lx\n", hr );
1079 set_hid_expect( file, NULL, 0 );
1081 set_hid_expect( file, &expect_stop, sizeof(expect_stop) );
1082 hr = IDirectInputEffect_Stop( effect );
1083 ok( hr == DI_OK, "Stop returned %#lx\n", hr );
1084 set_hid_expect( file, NULL, 0 );
1086 set_hid_expect( file, &expect_start, sizeof(expect_start) );
1087 hr = IDirectInputEffect_Start( effect, 1, 0 );
1088 ok( hr == DI_OK, "Start returned %#lx\n", hr );
1089 set_hid_expect( file, NULL, 0 );
1091 set_hid_expect( file, &expect_start_4, sizeof(expect_start_4) );
1092 hr = IDirectInputEffect_Start( effect, 4, 0 );
1093 ok( hr == DI_OK, "Start returned %#lx\n", hr );
1094 set_hid_expect( file, NULL, 0 );
1096 set_hid_expect( file, &expect_start_0, sizeof(expect_start_4) );
1097 hr = IDirectInputEffect_Start( effect, 0, 0 );
1098 ok( hr == DI_OK, "Start returned %#lx\n", hr );
1099 set_hid_expect( file, NULL, 0 );
1101 set_hid_expect( file, expect_unload, sizeof(struct hid_expect) );
1102 hr = IDirectInputEffect_Unload( effect );
1103 ok( hr == DI_OK, "Unload returned %#lx\n", hr );
1104 set_hid_expect( file, NULL, 0 );
1106 set_hid_expect( file, expect_download, 4 * sizeof(struct hid_expect) );
1107 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, DIEP_START );
1108 ok( hr == DI_OK, "SetParameters returned %#lx\n", hr );
1109 set_hid_expect( file, NULL, 0 );
1111 set_hid_expect( file, expect_unload, sizeof(struct hid_expect) );
1112 hr = IDirectInputEffect_Unload( effect );
1113 ok( hr == DI_OK, "Unload returned %#lx\n", hr );
1114 set_hid_expect( file, NULL, 0 );
1116 set_hid_expect( file, expect_download, 3 * sizeof(struct hid_expect) );
1117 hr = IDirectInputEffect_Download( effect );
1118 ok( hr == DI_OK, "Download returned %#lx\n", hr );
1119 set_hid_expect( file, NULL, 0 );
1121 set_hid_expect( file, expect_unload, 2 * sizeof(struct hid_expect) );
1122 hr = IDirectInputDevice8_Unacquire( device );
1123 ok( hr == DI_OK, "Unacquire returned: %#lx\n", hr );
1124 set_hid_expect( file, NULL, 0 );
1126 hr = IDirectInputEffect_Start( effect, 1, DIES_NODOWNLOAD );
1127 ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "Start returned %#lx\n", hr );
1128 hr = IDirectInputEffect_Stop( effect );
1129 ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "Stop returned %#lx\n", hr );
1131 set_hid_expect( file, expect_acquire, sizeof(expect_acquire) );
1132 hr = IDirectInputDevice8_Acquire( device );
1133 ok( hr == DI_OK, "Acquire returned: %#lx\n", hr );
1134 wait_hid_expect( file, 100 ); /* device gain reports are written asynchronously */
1136 hr = IDirectInputEffect_Unload( effect );
1137 ok( hr == DI_NOEFFECT, "Unload returned %#lx\n", hr );
1139 ref = IDirectInputEffect_Release( effect );
1140 ok( ref == 0, "Release returned %ld\n", ref );
1142 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Sine, NULL, &effect, NULL );
1143 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1145 desc.dwFlags = DIEFF_POLAR | DIEFF_OBJECTIDS;
1146 desc.cAxes = 2;
1147 desc.rgdwAxes[0] = DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR;
1148 desc.rgdwAxes[1] = DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR;
1149 desc.rglDirection[0] = 3000;
1150 desc.rglDirection[1] = 0;
1151 desc.rglDirection[2] = 0;
1152 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_AXES | DIEP_DIRECTION | DIEP_NODOWNLOAD );
1153 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1154 desc.rglDirection[0] = 0;
1156 desc.dwFlags = DIEFF_SPHERICAL;
1157 desc.cAxes = 1;
1158 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1159 ok( hr == DIERR_MOREDATA, "GetParameters returned %#lx\n", hr );
1160 ok( desc.dwFlags == DIEFF_SPHERICAL, "got flags %#lx, expected %#x\n", desc.dwFlags, DIEFF_SPHERICAL );
1161 ok( desc.cAxes == 2, "got cAxes %lu expected 2\n", desc.cAxes );
1162 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1163 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
1164 ok( desc.cAxes == 2, "got cAxes %lu expected 2\n", desc.cAxes );
1165 ok( desc.rglDirection[0] == 30000, "got rglDirection[0] %ld expected %d\n", desc.rglDirection[0], 30000 );
1166 ok( desc.rglDirection[1] == 0, "got rglDirection[1] %ld expected %d\n", desc.rglDirection[1], 0 );
1167 ok( desc.rglDirection[2] == 0, "got rglDirection[2] %ld expected %d\n", desc.rglDirection[2], 0 );
1169 desc.dwFlags = DIEFF_CARTESIAN;
1170 desc.cAxes = 1;
1171 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1172 ok( hr == DIERR_MOREDATA, "GetParameters returned %#lx\n", hr );
1173 ok( desc.dwFlags == DIEFF_CARTESIAN, "got flags %#lx, expected %#x\n", desc.dwFlags, DIEFF_CARTESIAN );
1174 ok( desc.cAxes == 2, "got cAxes %lu expected 2\n", desc.cAxes );
1175 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1176 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
1177 ok( desc.cAxes == 2, "got cAxes %lu expected 2\n", desc.cAxes );
1178 ok( desc.rglDirection[0] == 5000, "got rglDirection[0] %ld expected %d\n", desc.rglDirection[0], 5000 );
1179 ok( desc.rglDirection[1] == -8660, "got rglDirection[1] %ld expected %d\n", desc.rglDirection[1], -8660 );
1180 ok( desc.rglDirection[2] == 0, "got rglDirection[2] %ld expected %d\n", desc.rglDirection[2], 0 );
1182 desc.dwFlags = DIEFF_POLAR;
1183 desc.cAxes = 1;
1184 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1185 ok( hr == DIERR_MOREDATA, "GetParameters returned %#lx\n", hr );
1186 ok( desc.dwFlags == DIEFF_POLAR, "got flags %#lx, expected %#x\n", desc.dwFlags, DIEFF_POLAR );
1187 ok( desc.cAxes == 2, "got cAxes %lu expected 2\n", desc.cAxes );
1188 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1189 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
1190 ok( desc.cAxes == 2, "got cAxes %lu expected 2\n", desc.cAxes );
1191 ok( desc.rglDirection[0] == 3000, "got rglDirection[0] %ld expected %d\n", desc.rglDirection[0], 3000 );
1192 ok( desc.rglDirection[1] == 0, "got rglDirection[1] %ld expected %d\n", desc.rglDirection[1], 0 );
1193 ok( desc.rglDirection[2] == 0, "got rglDirection[2] %ld expected %d\n", desc.rglDirection[2], 0 );
1195 ref = IDirectInputEffect_Release( effect );
1196 ok( ref == 0, "Release returned %ld\n", ref );
1198 for (i = 1; i < 4; i++)
1200 struct hid_expect expect_directions[] =
1202 /* set periodic */
1204 .code = IOCTL_HID_WRITE_REPORT,
1205 .report_id = 5,
1206 .report_len = 2,
1207 .report_buf = {0x05,0x19},
1209 /* set envelope */
1211 .code = IOCTL_HID_WRITE_REPORT,
1212 .report_id = 6,
1213 .report_len = 7,
1214 .report_buf = {0x06,0x19,0x4c,0x02,0x00,0x04,0x00},
1216 /* update effect */
1217 {0},
1218 /* effect control */
1220 .code = IOCTL_HID_WRITE_REPORT,
1221 .report_id = 2,
1222 .report_len = 4,
1223 .report_buf = {0x02,0x01,0x03,0x00},
1226 struct hid_expect expect_spherical =
1228 .code = IOCTL_HID_WRITE_REPORT,
1229 .report_id = 3,
1230 .report_len = 11,
1231 .report_buf = { 0x03, 0x01, 0x02, 0x08, 0x01, 0x00, version >= 0x700 ? 0x06 : 0x00, 0x00, 0x01,
1232 i >= 2 ? 0x55 : 0, i >= 3 ? 0x1c : 0 },
1234 struct hid_expect expect_cartesian =
1236 .code = IOCTL_HID_WRITE_REPORT,
1237 .report_id = 3,
1238 .report_len = 11,
1239 .report_buf = {0x03, 0x01, 0x02, 0x08, 0x01, 0x00, version >= 0x700 ? 0x06 : 0x00, 0x00,
1240 0x01, i >= 2 ? 0x63 : 0, i >= 3 ? 0x1d : 0},
1242 struct hid_expect expect_polar =
1244 .code = IOCTL_HID_WRITE_REPORT,
1245 .report_id = 3,
1246 .report_len = 11,
1247 .report_buf = {0x03, 0x01, 0x02, 0x08, 0x01, 0x00, version >= 0x700 ? 0x06 : 0x00, 0x00,
1248 0x01, i >= 2 ? 0x3f : 0, i >= 3 ? 0x00 : 0},
1251 winetest_push_context( "%lu axes", i );
1252 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Sine, NULL, &effect, NULL );
1253 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1255 desc.dwFlags = DIEFF_OBJECTIDS;
1256 desc.cAxes = i;
1257 desc.rgdwAxes[0] = DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR;
1258 desc.rgdwAxes[1] = DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR;
1259 desc.rgdwAxes[2] = DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR;
1260 desc.rglDirection[0] = 0;
1261 desc.rglDirection[1] = 0;
1262 desc.rglDirection[2] = 0;
1263 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_AXES | DIEP_NODOWNLOAD );
1264 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1266 desc.dwFlags = DIEFF_CARTESIAN;
1267 desc.cAxes = i == 3 ? 2 : 3;
1268 desc.rglDirection[0] = 1000;
1269 desc.rglDirection[1] = 2000;
1270 desc.rglDirection[2] = 3000;
1271 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_DIRECTION | DIEP_NODOWNLOAD );
1272 ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#lx\n", hr );
1273 desc.cAxes = i;
1274 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_DIRECTION | DIEP_NODOWNLOAD );
1275 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1277 desc.dwFlags = DIEFF_SPHERICAL;
1278 desc.cAxes = i;
1279 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1280 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
1281 desc.cAxes = 3;
1282 memset( desc.rglDirection, 0xcd, 3 * sizeof(LONG) );
1283 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1284 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
1285 ok( desc.cAxes == i, "got cAxes %lu expected 2\n", desc.cAxes );
1286 if (i == 1)
1288 ok( desc.rglDirection[0] == 0, "got rglDirection[0] %ld expected %d\n", desc.rglDirection[0], 0 );
1289 ok( desc.rglDirection[1] == 0xcdcdcdcd, "got rglDirection[1] %ld expected %d\n",
1290 desc.rglDirection[1], 0xcdcdcdcd );
1291 ok( desc.rglDirection[2] == 0xcdcdcdcd, "got rglDirection[2] %ld expected %d\n",
1292 desc.rglDirection[2], 0xcdcdcdcd );
1294 else
1296 ok( desc.rglDirection[0] == 6343, "got rglDirection[0] %ld expected %d\n",
1297 desc.rglDirection[0], 6343 );
1298 if (i == 2)
1300 ok( desc.rglDirection[1] == 0, "got rglDirection[1] %ld expected %d\n",
1301 desc.rglDirection[1], 0 );
1302 ok( desc.rglDirection[2] == 0xcdcdcdcd, "got rglDirection[2] %ld expected %d\n",
1303 desc.rglDirection[2], 0xcdcdcdcd );
1305 else
1307 ok( desc.rglDirection[1] == 5330, "got rglDirection[1] %ld expected %d\n",
1308 desc.rglDirection[1], 5330 );
1309 ok( desc.rglDirection[2] == 0, "got rglDirection[2] %ld expected %d\n",
1310 desc.rglDirection[2], 0 );
1314 desc.dwFlags = DIEFF_CARTESIAN;
1315 desc.cAxes = i;
1316 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1317 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
1318 desc.cAxes = 3;
1319 memset( desc.rglDirection, 0xcd, 3 * sizeof(LONG) );
1320 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1321 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
1322 ok( desc.cAxes == i, "got cAxes %lu expected 2\n", desc.cAxes );
1323 ok( desc.rglDirection[0] == 1000, "got rglDirection[0] %ld expected %d\n", desc.rglDirection[0], 1000 );
1324 if (i == 1)
1325 ok( desc.rglDirection[1] == 0xcdcdcdcd, "got rglDirection[1] %ld expected %d\n",
1326 desc.rglDirection[1], 0xcdcdcdcd );
1327 else
1328 ok( desc.rglDirection[1] == 2000, "got rglDirection[1] %ld expected %d\n",
1329 desc.rglDirection[1], 2000 );
1330 if (i <= 2)
1331 ok( desc.rglDirection[2] == 0xcdcdcdcd, "got rglDirection[2] %ld expected %d\n",
1332 desc.rglDirection[2], 0xcdcdcdcd );
1333 else
1334 ok( desc.rglDirection[2] == 3000, "got rglDirection[2] %ld expected %d\n",
1335 desc.rglDirection[2], 3000 );
1337 desc.dwFlags = DIEFF_POLAR;
1338 desc.cAxes = 1;
1339 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1340 if (i != 2) ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#lx\n", hr );
1341 else ok( hr == DIERR_MOREDATA, "GetParameters returned %#lx\n", hr );
1342 desc.cAxes = 3;
1343 memset( desc.rglDirection, 0xcd, 3 * sizeof(LONG) );
1344 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
1345 if (i != 2) ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#lx\n", hr );
1346 else
1348 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
1349 ok( desc.cAxes == i, "got cAxes %lu expected 2\n", desc.cAxes );
1350 ok( desc.rglDirection[0] == 15343, "got rglDirection[0] %ld expected %d\n",
1351 desc.rglDirection[0], 15343 );
1352 ok( desc.rglDirection[1] == 0, "got rglDirection[1] %ld expected %d\n", desc.rglDirection[1], 0 );
1353 ok( desc.rglDirection[2] == 0xcdcdcdcd, "got rglDirection[2] %ld expected %d\n",
1354 desc.rglDirection[2], 0xcdcdcdcd );
1357 ref = IDirectInputEffect_Release( effect );
1358 ok( ref == 0, "Release returned %ld\n", ref );
1360 desc = expect_desc;
1361 desc.dwFlags = DIEFF_SPHERICAL | DIEFF_OBJECTIDS;
1362 desc.cAxes = i;
1363 desc.rgdwAxes = axes;
1364 desc.rglDirection = directions;
1365 desc.rglDirection[0] = 3000;
1366 desc.rglDirection[1] = 4000;
1367 desc.rglDirection[2] = 5000;
1368 flags = version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5;
1369 expect_directions[2] = expect_spherical;
1370 set_hid_expect( file, expect_directions, sizeof(expect_directions) );
1371 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Sine, &desc, &effect, NULL );
1372 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1373 ref = IDirectInputEffect_Release( effect );
1374 ok( ref == 0, "Release returned %ld\n", ref );
1375 set_hid_expect( file, NULL, 0 );
1377 desc = expect_desc;
1378 desc.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTIDS;
1379 desc.cAxes = i;
1380 desc.rgdwAxes = axes;
1381 desc.rglDirection = directions;
1382 desc.rglDirection[0] = 6000;
1383 desc.rglDirection[1] = 7000;
1384 desc.rglDirection[2] = 8000;
1385 flags = version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5;
1386 expect_directions[2] = expect_cartesian;
1387 set_hid_expect( file, expect_directions, sizeof(expect_directions) );
1388 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Sine, &desc, &effect, NULL );
1389 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1390 ref = IDirectInputEffect_Release( effect );
1391 ok( ref == 0, "Release returned %ld\n", ref );
1392 set_hid_expect( file, NULL, 0 );
1394 if (i == 2)
1396 desc = expect_desc;
1397 desc.dwFlags = DIEFF_POLAR | DIEFF_OBJECTIDS;
1398 desc.cAxes = i;
1399 desc.rgdwAxes = axes;
1400 desc.rglDirection = directions;
1401 desc.rglDirection[0] = 9000;
1402 desc.rglDirection[1] = 10000;
1403 desc.rglDirection[2] = 11000;
1404 flags = version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5;
1405 expect_directions[2] = expect_polar;
1406 set_hid_expect( file, expect_directions, sizeof(expect_directions) );
1407 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Sine, &desc, &effect, NULL );
1408 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1409 ref = IDirectInputEffect_Release( effect );
1410 ok( ref == 0, "Release returned %ld\n", ref );
1411 set_hid_expect( file, NULL, 0 );
1414 winetest_pop_context();
1417 /* zero-ed effect parameters are sent */
1419 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Sine, NULL, &effect, NULL );
1420 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1422 set_hid_expect( file, expect_download_0, sizeof(expect_download_0) );
1423 flags = version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5;
1424 hr = IDirectInputEffect_SetParameters( effect, &expect_desc_0, flags );
1425 ok( hr == DI_OK, "SetParameters returned %#lx\n", hr );
1426 set_hid_expect( file, NULL, 0 );
1428 set_hid_expect( file, &expect_stop, sizeof(expect_stop) );
1429 ref = IDirectInputEffect_Release( effect );
1430 ok( ref == 0, "Release returned %ld\n", ref );
1431 set_hid_expect( file, NULL, 0 );
1433 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Sine, NULL, &effect, NULL );
1434 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1436 set_hid_expect( file, expect_download_1, sizeof(expect_download_1) );
1437 flags = version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5;
1438 hr = IDirectInputEffect_SetParameters( effect, &expect_desc_0, (flags & ~DIEP_ENVELOPE) );
1439 ok( hr == DI_OK, "SetParameters returned %#lx\n", hr );
1440 set_hid_expect( file, NULL, 0 );
1442 set_hid_expect( file, &expect_stop, sizeof(expect_stop) );
1443 ref = IDirectInputEffect_Release( effect );
1444 ok( ref == 0, "Release returned %ld\n", ref );
1445 set_hid_expect( file, NULL, 0 );
1447 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Sine, NULL, &effect, NULL );
1448 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1451 set_hid_expect( file, expect_download_2, sizeof(expect_download_2) );
1452 flags = version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5;
1453 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, flags );
1454 ok( hr == DI_OK, "SetParameters returned %#lx\n", hr );
1455 set_hid_expect( file, NULL, 0 );
1456 desc = expect_desc;
1457 desc.dwDuration = INFINITE;
1458 desc.dwTriggerButton = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER;
1459 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_NODOWNLOAD | DIEP_DURATION | DIEP_TRIGGERBUTTON );
1460 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1461 set_hid_expect( file, expect_update, sizeof(expect_update) );
1462 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, 0 );
1463 ok( hr == DI_OK, "SetParameters returned %#lx\n", hr );
1464 wait_hid_expect( file, 100 ); /* these updates are sent asynchronously */
1465 desc = expect_desc;
1466 desc.dwDuration = INFINITE;
1467 desc.dwTriggerButton = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER;
1468 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_NODOWNLOAD | DIEP_DURATION | DIEP_TRIGGERBUTTON );
1469 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1470 set_hid_expect( file, expect_update, sizeof(expect_update) );
1471 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, 0 );
1472 ok( hr == DI_OK, "SetParameters returned %#lx\n", hr );
1473 wait_hid_expect( file, 100 ); /* these updates are sent asynchronously */
1475 desc = expect_desc;
1476 desc.lpEnvelope = &envelope;
1477 desc.lpEnvelope->dwAttackTime = 1000;
1478 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_NODOWNLOAD | DIEP_ENVELOPE );
1479 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1480 set_hid_expect( file, expect_set_envelope, sizeof(expect_set_envelope) );
1481 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, 0 );
1482 ok( hr == DI_OK, "SetParameters returned %#lx\n", hr );
1483 wait_hid_expect( file, 100 ); /* these updates are sent asynchronously */
1485 set_hid_expect( file, &expect_stop, sizeof(expect_stop) );
1486 hr = IDirectInputEffect_Unload( effect );
1487 ok( hr == DI_OK, "Unload returned %#lx\n", hr );
1488 set_hid_expect( file, NULL, 0 );
1490 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, DIEP_NODOWNLOAD );
1491 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1492 set_hid_expect( file, expect_download_3, sizeof(expect_download_3) );
1493 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, 0 );
1494 ok( hr == DI_OK, "SetParameters returned %#lx\n", hr );
1495 wait_hid_expect( file, 100 ); /* these updates are sent asynchronously */
1497 set_hid_expect( file, &expect_stop, sizeof(expect_stop) );
1498 hr = IDirectInputEffect_Unload( effect );
1499 ok( hr == DI_OK, "Unload returned %#lx\n", hr );
1500 set_hid_expect( file, NULL, 0 );
1502 desc = expect_desc;
1503 desc.lpEnvelope = NULL;
1504 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_NODOWNLOAD | DIEP_ENVELOPE );
1505 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1506 set_hid_expect( file, expect_download_4, sizeof(expect_download_4) );
1507 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, 0 );
1508 ok( hr == DI_OK, "SetParameters returned %#lx\n", hr );
1509 wait_hid_expect( file, 100 ); /* these updates are sent asynchronously */
1511 set_hid_expect( file, &expect_stop, sizeof(expect_stop) );
1512 ref = IDirectInputEffect_Release( effect );
1513 ok( ref == 0, "Release returned %ld\n", ref );
1514 set_hid_expect( file, NULL, 0 );
1516 set_hid_expect( file, expect_reset, sizeof(expect_reset) );
1517 hr = IDirectInputDevice8_Unacquire( device );
1518 ok( hr == DI_OK, "Acquire returned: %#lx\n", hr );
1519 set_hid_expect( file, NULL, 0 );
1520 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Sine, &expect_desc, &effect, NULL );
1521 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1522 ref = IDirectInputEffect_Release( effect );
1523 ok( ref == 0, "Release returned %ld\n", ref );
1524 set_hid_expect( file, expect_acquire, sizeof(expect_acquire) );
1525 hr = IDirectInputDevice8_Acquire( device );
1526 ok( hr == DI_OK, "Acquire returned: %#lx\n", hr );
1527 wait_hid_expect( file, 100 ); /* device gain reports are written asynchronously */
1530 static void test_condition_effect( IDirectInputDevice8W *device, HANDLE file, DWORD version )
1532 struct hid_expect expect_create[] =
1534 /* set condition */
1536 .code = IOCTL_HID_WRITE_REPORT,
1537 .report_id = 7,
1538 .report_len = 8,
1539 .report_buf = {0x07,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
1541 /* set condition */
1543 .code = IOCTL_HID_WRITE_REPORT,
1544 .report_id = 7,
1545 .report_len = 8,
1546 .report_buf = {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
1548 /* update effect */
1550 .code = IOCTL_HID_WRITE_REPORT,
1551 .report_id = 3,
1552 .report_len = 11,
1553 .report_buf = {0x03,0x01,0x03,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0x00},
1556 struct hid_expect expect_create_1[] =
1558 /* set condition */
1560 .code = IOCTL_HID_WRITE_REPORT,
1561 .report_id = 7,
1562 .report_len = 8,
1563 .report_buf = {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
1565 /* update effect */
1567 .code = IOCTL_HID_WRITE_REPORT,
1568 .report_id = 3,
1569 .report_len = 11,
1570 .report_buf = {0x03,0x01,0x03,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x3f,0x00},
1573 struct hid_expect expect_create_2[] =
1575 /* set condition */
1577 .code = IOCTL_HID_WRITE_REPORT,
1578 .report_id = 7,
1579 .report_len = 8,
1580 .report_buf = {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
1582 /* update effect */
1584 .code = IOCTL_HID_WRITE_REPORT,
1585 .report_id = 3,
1586 .report_len = 11,
1587 .report_buf = {0x03,0x01,0x03,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xf1},
1590 struct hid_expect expect_create_3[] =
1592 /* set condition */
1594 .code = IOCTL_HID_WRITE_REPORT,
1595 .report_id = 7,
1596 .report_len = 8,
1597 .report_buf = {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
1599 /* update effect */
1601 .code = IOCTL_HID_WRITE_REPORT,
1602 .report_id = 3,
1603 .report_len = 11,
1604 .report_buf = {0x03,0x01,0x03,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0x00},
1607 struct hid_expect expect_destroy =
1609 .code = IOCTL_HID_WRITE_REPORT,
1610 .report_id = 2,
1611 .report_len = 4,
1612 .report_buf = {0x02, 0x01, 0x03, 0x00},
1614 static const DWORD expect_axes[3] =
1616 DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR,
1617 DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR,
1618 DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR,
1620 static const LONG expect_directions[3] = {
1621 +3000,
1625 static const DIENVELOPE expect_envelope =
1627 .dwSize = sizeof(DIENVELOPE),
1628 .dwAttackLevel = 1000,
1629 .dwAttackTime = 2000,
1630 .dwFadeLevel = 3000,
1631 .dwFadeTime = 4000,
1633 static const DICONDITION expect_condition[3] =
1636 .lOffset = -500,
1637 .lPositiveCoefficient = 2000,
1638 .lNegativeCoefficient = -3000,
1639 .dwPositiveSaturation = -4000,
1640 .dwNegativeSaturation = -5000,
1641 .lDeadBand = 6000,
1644 .lOffset = 6000,
1645 .lPositiveCoefficient = 5000,
1646 .lNegativeCoefficient = -4000,
1647 .dwPositiveSaturation = 3000,
1648 .dwNegativeSaturation = 2000,
1649 .lDeadBand = 1000,
1652 .lOffset = -7000,
1653 .lPositiveCoefficient = -8000,
1654 .lNegativeCoefficient = 9000,
1655 .dwPositiveSaturation = 10000,
1656 .dwNegativeSaturation = 11000,
1657 .lDeadBand = -12000,
1660 const DIEFFECT expect_desc =
1662 .dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5),
1663 .dwFlags = DIEFF_SPHERICAL | DIEFF_OBJECTIDS,
1664 .dwDuration = 1000,
1665 .dwSamplePeriod = 2000,
1666 .dwGain = 3000,
1667 .dwTriggerButton = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER,
1668 .dwTriggerRepeatInterval = 5000,
1669 .cAxes = 2,
1670 .rgdwAxes = (void *)expect_axes,
1671 .rglDirection = (void *)expect_directions,
1672 .lpEnvelope = (void *)&expect_envelope,
1673 .cbTypeSpecificParams = 2 * sizeof(DICONDITION),
1674 .lpvTypeSpecificParams = (void *)expect_condition,
1675 .dwStartDelay = 6000,
1677 struct check_created_effect_params check_params = {0};
1678 DIENVELOPE envelope = {.dwSize = sizeof(DIENVELOPE)};
1679 DICONDITION condition[2] = {{0}};
1680 IDirectInputEffect *effect;
1681 LONG directions[4] = {0};
1682 DWORD axes[4] = {0};
1683 DIEFFECT desc =
1685 .dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5),
1686 .dwFlags = DIEFF_SPHERICAL | DIEFF_OBJECTIDS,
1687 .cAxes = 4,
1688 .rgdwAxes = axes,
1689 .rglDirection = directions,
1690 .lpEnvelope = &envelope,
1691 .cbTypeSpecificParams = 2 * sizeof(DICONDITION),
1692 .lpvTypeSpecificParams = condition,
1694 HRESULT hr;
1695 ULONG ref;
1696 GUID guid;
1698 set_hid_expect( file, expect_create, sizeof(expect_create) );
1699 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, &expect_desc, &effect, NULL );
1700 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1701 set_hid_expect( file, NULL, 0 );
1703 check_params.expect_effect = effect;
1704 hr = IDirectInputDevice8_EnumCreatedEffectObjects( device, check_created_effect_objects, &check_params, 0 );
1705 ok( hr == DI_OK, "EnumCreatedEffectObjects returned %#lx\n", hr );
1706 ok( check_params.count == 1, "got count %lu, expected 1\n", check_params.count );
1708 hr = IDirectInputEffect_GetEffectGuid( effect, &guid );
1709 ok( hr == DI_OK, "GetEffectGuid returned %#lx\n", hr );
1710 ok( IsEqualGUID( &guid, &GUID_Spring ), "got guid %s, expected %s\n", debugstr_guid( &guid ),
1711 debugstr_guid( &GUID_Spring ) );
1713 hr = IDirectInputEffect_GetParameters( effect, &desc, version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5 );
1714 ok( hr == DI_OK, "GetParameters returned %#lx\n", hr );
1715 check_member( desc, expect_desc, "%lu", dwDuration );
1716 check_member( desc, expect_desc, "%lu", dwSamplePeriod );
1717 check_member( desc, expect_desc, "%lu", dwGain );
1718 check_member( desc, expect_desc, "%#lx", dwTriggerButton );
1719 check_member( desc, expect_desc, "%lu", dwTriggerRepeatInterval );
1720 check_member( desc, expect_desc, "%lu", cAxes );
1721 check_member( desc, expect_desc, "%#lx", rgdwAxes[0] );
1722 check_member( desc, expect_desc, "%#lx", rgdwAxes[1] );
1723 check_member( desc, expect_desc, "%ld", rglDirection[0] );
1724 check_member( desc, expect_desc, "%ld", rglDirection[1] );
1725 check_member( desc, expect_desc, "%lu", cbTypeSpecificParams );
1726 if (version >= 0x700) check_member( desc, expect_desc, "%lu", dwStartDelay );
1727 else ok( desc.dwStartDelay == 0, "got dwStartDelay %#lx\n", desc.dwStartDelay );
1728 check_member( envelope, expect_envelope, "%lu", dwAttackLevel );
1729 check_member( envelope, expect_envelope, "%lu", dwAttackTime );
1730 check_member( envelope, expect_envelope, "%lu", dwFadeLevel );
1731 check_member( envelope, expect_envelope, "%lu", dwFadeTime );
1732 check_member( condition[0], expect_condition[0], "%ld", lOffset );
1733 check_member( condition[0], expect_condition[0], "%ld", lPositiveCoefficient );
1734 check_member( condition[0], expect_condition[0], "%ld", lNegativeCoefficient );
1735 check_member( condition[0], expect_condition[0], "%lu", dwPositiveSaturation );
1736 check_member( condition[0], expect_condition[0], "%lu", dwNegativeSaturation );
1737 check_member( condition[0], expect_condition[0], "%ld", lDeadBand );
1738 check_member( condition[1], expect_condition[1], "%ld", lOffset );
1739 check_member( condition[1], expect_condition[1], "%ld", lPositiveCoefficient );
1740 check_member( condition[1], expect_condition[1], "%ld", lNegativeCoefficient );
1741 check_member( condition[1], expect_condition[1], "%lu", dwPositiveSaturation );
1742 check_member( condition[1], expect_condition[1], "%lu", dwNegativeSaturation );
1743 check_member( condition[1], expect_condition[1], "%ld", lDeadBand );
1745 set_hid_expect( file, &expect_destroy, sizeof(expect_destroy) );
1746 ref = IDirectInputEffect_Release( effect );
1747 ok( ref == 0, "Release returned %ld\n", ref );
1748 set_hid_expect( file, NULL, 0 );
1750 desc = expect_desc;
1751 desc.cAxes = 1;
1752 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, &desc, &effect, NULL );
1753 ok( hr == DIERR_INVALIDPARAM, "CreateEffect returned %#lx\n", hr );
1754 desc.cbTypeSpecificParams = 1 * sizeof(DICONDITION);
1755 desc.lpvTypeSpecificParams = (void *)&expect_condition[1];
1756 set_hid_expect( file, expect_create_1, sizeof(expect_create_1) );
1757 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, &desc, &effect, NULL );
1758 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1759 set_hid_expect( file, NULL, 0 );
1761 set_hid_expect( file, &expect_destroy, sizeof(expect_destroy) );
1762 ref = IDirectInputEffect_Release( effect );
1763 ok( ref == 0, "Release returned %ld\n", ref );
1764 set_hid_expect( file, NULL, 0 );
1766 desc = expect_desc;
1767 desc.cAxes = 3;
1768 desc.rglDirection = directions;
1769 desc.rglDirection[0] = +3000;
1770 desc.rglDirection[1] = -2000;
1771 desc.rglDirection[2] = +1000;
1772 desc.cbTypeSpecificParams = 1 * sizeof(DICONDITION);
1773 desc.lpvTypeSpecificParams = (void *)&expect_condition[1];
1774 set_hid_expect( file, expect_create_2, sizeof(expect_create_2) );
1775 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, &desc, &effect, NULL );
1776 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1777 set_hid_expect( file, NULL, 0 );
1779 set_hid_expect( file, &expect_destroy, sizeof(expect_destroy) );
1780 ref = IDirectInputEffect_Release( effect );
1781 ok( ref == 0, "Release returned %ld\n", ref );
1782 set_hid_expect( file, NULL, 0 );
1784 desc = expect_desc;
1785 desc.cAxes = 2;
1786 desc.rgdwAxes = axes;
1787 desc.rgdwAxes[0] = DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR;
1788 desc.rgdwAxes[1] = DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR;
1789 desc.rglDirection = directions;
1790 desc.rglDirection[0] = +3000;
1791 desc.rglDirection[1] = -2000;
1792 desc.cbTypeSpecificParams = 1 * sizeof(DICONDITION);
1793 desc.lpvTypeSpecificParams = (void *)&expect_condition[1];
1794 set_hid_expect( file, expect_create_3, sizeof(expect_create_3) );
1795 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, &desc, &effect, NULL );
1796 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1797 set_hid_expect( file, NULL, 0 );
1799 set_hid_expect( file, &expect_destroy, sizeof(expect_destroy) );
1800 ref = IDirectInputEffect_Release( effect );
1801 ok( ref == 0, "Release returned %ld\n", ref );
1802 set_hid_expect( file, NULL, 0 );
1804 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, NULL, &effect, NULL );
1805 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
1806 desc = expect_desc;
1807 desc.cAxes = 0;
1808 desc.cbTypeSpecificParams = 1 * sizeof(DICONDITION);
1809 desc.lpvTypeSpecificParams = (void *)&expect_condition[0];
1810 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_TYPESPECIFICPARAMS | DIEP_NODOWNLOAD );
1811 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1812 desc.cbTypeSpecificParams = 0 * sizeof(DICONDITION);
1813 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_TYPESPECIFICPARAMS );
1814 ok( hr == DIERR_MOREDATA, "SetParameters returned %#lx\n", hr );
1815 ok( desc.cbTypeSpecificParams == 1 * sizeof(DICONDITION), "got %lu\n", desc.cbTypeSpecificParams );
1816 desc.cbTypeSpecificParams = 0 * sizeof(DICONDITION);
1817 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_TYPESPECIFICPARAMS | DIEP_NODOWNLOAD );
1818 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
1819 desc.cbTypeSpecificParams = 0 * sizeof(DICONDITION);
1820 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_TYPESPECIFICPARAMS );
1821 ok( hr == DI_OK, "SetParameters returned %#lx\n", hr );
1822 ok( desc.cbTypeSpecificParams == 0 * sizeof(DICONDITION), "got %lu\n", desc.cbTypeSpecificParams );
1823 ref = IDirectInputEffect_Release( effect );
1824 ok( ref == 0, "Release returned %ld\n", ref );
1827 static BOOL test_force_feedback_joystick( DWORD version )
1829 #include "psh_hid_macros.h"
1830 const unsigned char report_descriptor[] =
1832 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
1833 USAGE(1, HID_USAGE_GENERIC_JOYSTICK),
1834 COLLECTION(1, Application),
1835 USAGE(1, HID_USAGE_GENERIC_JOYSTICK),
1836 COLLECTION(1, Report),
1837 REPORT_ID(1, 1),
1839 USAGE(1, HID_USAGE_GENERIC_X),
1840 USAGE(1, HID_USAGE_GENERIC_Y),
1841 USAGE(1, HID_USAGE_GENERIC_Z),
1842 LOGICAL_MINIMUM(1, 0),
1843 LOGICAL_MAXIMUM(1, 0x7f),
1844 PHYSICAL_MINIMUM(1, 0),
1845 PHYSICAL_MAXIMUM(1, 0x7f),
1846 REPORT_SIZE(1, 8),
1847 REPORT_COUNT(1, 3),
1848 INPUT(1, Data|Var|Abs),
1850 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON),
1851 USAGE_MINIMUM(1, 1),
1852 USAGE_MAXIMUM(1, 2),
1853 LOGICAL_MINIMUM(1, 0),
1854 LOGICAL_MAXIMUM(1, 1),
1855 PHYSICAL_MINIMUM(1, 0),
1856 PHYSICAL_MAXIMUM(1, 1),
1857 REPORT_SIZE(1, 1),
1858 REPORT_COUNT(1, 2),
1859 INPUT(1, Data|Var|Abs),
1860 REPORT_COUNT(1, 6),
1861 INPUT(1, Cnst|Var|Abs),
1862 END_COLLECTION,
1864 USAGE_PAGE(1, HID_USAGE_PAGE_PID),
1865 USAGE(1, PID_USAGE_STATE_REPORT),
1866 COLLECTION(1, Report),
1867 REPORT_ID(1, 2),
1869 USAGE(1, PID_USAGE_DEVICE_PAUSED),
1870 USAGE(1, PID_USAGE_ACTUATORS_ENABLED),
1871 USAGE(1, PID_USAGE_SAFETY_SWITCH),
1872 USAGE(1, PID_USAGE_ACTUATOR_OVERRIDE_SWITCH),
1873 USAGE(1, PID_USAGE_ACTUATOR_POWER),
1874 LOGICAL_MINIMUM(1, 0),
1875 LOGICAL_MAXIMUM(1, 1),
1876 PHYSICAL_MINIMUM(1, 0),
1877 PHYSICAL_MAXIMUM(1, 1),
1878 REPORT_SIZE(1, 1),
1879 REPORT_COUNT(1, 5),
1880 INPUT(1, Data|Var|Abs),
1881 REPORT_COUNT(1, 3),
1882 INPUT(1, Cnst|Var|Abs),
1884 USAGE(1, PID_USAGE_EFFECT_PLAYING),
1885 LOGICAL_MINIMUM(1, 0),
1886 LOGICAL_MAXIMUM(1, 1),
1887 PHYSICAL_MINIMUM(1, 0),
1888 PHYSICAL_MAXIMUM(1, 1),
1889 REPORT_SIZE(1, 1),
1890 REPORT_COUNT(1, 1),
1891 INPUT(1, Data|Var|Abs),
1893 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
1894 LOGICAL_MAXIMUM(1, 0x7f),
1895 LOGICAL_MINIMUM(1, 0x00),
1896 REPORT_SIZE(1, 7),
1897 REPORT_COUNT(1, 1),
1898 INPUT(1, Data|Var|Abs),
1899 END_COLLECTION,
1901 USAGE_PAGE(1, HID_USAGE_PAGE_PID),
1902 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT),
1903 COLLECTION(1, Report),
1904 REPORT_ID(1, 1),
1906 USAGE(1, PID_USAGE_DEVICE_CONTROL),
1907 COLLECTION(1, Logical),
1908 USAGE(1, PID_USAGE_DC_DEVICE_RESET),
1909 LOGICAL_MINIMUM(1, 1),
1910 LOGICAL_MAXIMUM(1, 2),
1911 PHYSICAL_MINIMUM(1, 1),
1912 PHYSICAL_MAXIMUM(1, 2),
1913 REPORT_SIZE(1, 8),
1914 REPORT_COUNT(1, 1),
1915 OUTPUT(1, Data|Ary|Abs),
1916 END_COLLECTION,
1917 END_COLLECTION,
1919 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT),
1920 COLLECTION(1, Report),
1921 REPORT_ID(1, 2),
1923 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
1924 LOGICAL_MINIMUM(1, 0),
1925 LOGICAL_MAXIMUM(1, 0x7f),
1926 PHYSICAL_MINIMUM(1, 0),
1927 PHYSICAL_MAXIMUM(1, 0x7f),
1928 REPORT_SIZE(1, 8),
1929 REPORT_COUNT(1, 1),
1930 OUTPUT(1, Data|Var|Abs),
1932 USAGE(1, PID_USAGE_EFFECT_OPERATION),
1933 COLLECTION(1, NamedArray),
1934 USAGE(1, PID_USAGE_OP_EFFECT_START),
1935 USAGE(1, PID_USAGE_OP_EFFECT_START_SOLO),
1936 USAGE(1, PID_USAGE_OP_EFFECT_STOP),
1937 LOGICAL_MINIMUM(1, 1),
1938 LOGICAL_MAXIMUM(1, 3),
1939 PHYSICAL_MINIMUM(1, 1),
1940 PHYSICAL_MAXIMUM(1, 3),
1941 REPORT_SIZE(1, 8),
1942 REPORT_COUNT(1, 1),
1943 OUTPUT(1, Data|Ary|Abs),
1944 END_COLLECTION,
1946 USAGE(1, PID_USAGE_LOOP_COUNT),
1947 LOGICAL_MINIMUM(1, 0),
1948 LOGICAL_MAXIMUM(1, 0x7f),
1949 PHYSICAL_MINIMUM(1, 0),
1950 PHYSICAL_MAXIMUM(1, 0x7f),
1951 REPORT_SIZE(1, 8),
1952 REPORT_COUNT(1, 1),
1953 OUTPUT(1, Data|Var|Abs),
1954 END_COLLECTION,
1956 USAGE(1, PID_USAGE_SET_EFFECT_REPORT),
1957 COLLECTION(1, Report),
1958 REPORT_ID(1, 3),
1960 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
1961 LOGICAL_MINIMUM(1, 0),
1962 LOGICAL_MAXIMUM(1, 0x7f),
1963 PHYSICAL_MINIMUM(1, 0),
1964 PHYSICAL_MAXIMUM(1, 0x7f),
1965 REPORT_SIZE(1, 8),
1966 REPORT_COUNT(1, 1),
1967 OUTPUT(1, Data|Var|Abs),
1969 USAGE(1, PID_USAGE_EFFECT_TYPE),
1970 COLLECTION(1, NamedArray),
1971 USAGE(1, PID_USAGE_ET_SQUARE),
1972 USAGE(1, PID_USAGE_ET_SINE),
1973 USAGE(1, PID_USAGE_ET_SPRING),
1974 LOGICAL_MINIMUM(1, 1),
1975 LOGICAL_MAXIMUM(1, 3),
1976 PHYSICAL_MINIMUM(1, 1),
1977 PHYSICAL_MAXIMUM(1, 3),
1978 REPORT_SIZE(1, 8),
1979 REPORT_COUNT(1, 1),
1980 OUTPUT(1, Data|Ary|Abs),
1981 END_COLLECTION,
1983 USAGE(1, PID_USAGE_AXES_ENABLE),
1984 COLLECTION(1, Logical),
1985 USAGE(4, (HID_USAGE_PAGE_GENERIC << 16)|HID_USAGE_GENERIC_X),
1986 USAGE(4, (HID_USAGE_PAGE_GENERIC << 16)|HID_USAGE_GENERIC_Y),
1987 USAGE(4, (HID_USAGE_PAGE_GENERIC << 16)|HID_USAGE_GENERIC_Z),
1988 LOGICAL_MINIMUM(1, 0),
1989 LOGICAL_MAXIMUM(1, 1),
1990 PHYSICAL_MINIMUM(1, 0),
1991 PHYSICAL_MAXIMUM(1, 1),
1992 REPORT_SIZE(1, 1),
1993 REPORT_COUNT(1, 3),
1994 OUTPUT(1, Data|Var|Abs),
1995 END_COLLECTION,
1996 USAGE(1, PID_USAGE_DIRECTION_ENABLE),
1997 REPORT_COUNT(1, 1),
1998 OUTPUT(1, Data|Var|Abs),
1999 REPORT_COUNT(1, 4),
2000 OUTPUT(1, Cnst|Var|Abs),
2002 USAGE(1, PID_USAGE_DURATION),
2003 USAGE(1, PID_USAGE_START_DELAY),
2004 UNIT(2, 0x1003), /* Eng Lin:Time */
2005 UNIT_EXPONENT(1, -3), /* 10^-3 */
2006 LOGICAL_MINIMUM(1, 0),
2007 LOGICAL_MAXIMUM(2, 0x7fff),
2008 PHYSICAL_MINIMUM(1, 0),
2009 PHYSICAL_MAXIMUM(2, 0x7fff),
2010 REPORT_SIZE(1, 16),
2011 REPORT_COUNT(1, 2),
2012 OUTPUT(1, Data|Var|Abs),
2013 UNIT(1, 0),
2014 UNIT_EXPONENT(1, 0),
2016 USAGE(1, PID_USAGE_TRIGGER_BUTTON),
2017 LOGICAL_MINIMUM(1, 1),
2018 LOGICAL_MAXIMUM(1, 0x08),
2019 PHYSICAL_MINIMUM(1, 1),
2020 PHYSICAL_MAXIMUM(1, 0x08),
2021 REPORT_SIZE(1, 8),
2022 REPORT_COUNT(1, 1),
2023 OUTPUT(1, Data|Var|Abs),
2025 USAGE(1, PID_USAGE_DIRECTION),
2026 COLLECTION(1, Logical),
2027 USAGE(4, (HID_USAGE_PAGE_ORDINAL << 16)|1),
2028 USAGE(4, (HID_USAGE_PAGE_ORDINAL << 16)|2),
2029 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
2030 UNIT_EXPONENT(1, -2), /* 10^-2 */
2031 LOGICAL_MINIMUM(1, 0),
2032 LOGICAL_MAXIMUM(2, 0x00ff),
2033 PHYSICAL_MINIMUM(1, 0),
2034 PHYSICAL_MAXIMUM(4, 0x00008ca0),
2035 UNIT(1, 0),
2036 REPORT_SIZE(1, 8),
2037 REPORT_COUNT(1, 2),
2038 OUTPUT(1, Data|Var|Abs),
2039 UNIT_EXPONENT(1, 0),
2040 UNIT(1, 0),
2041 END_COLLECTION,
2042 END_COLLECTION,
2044 USAGE(1, PID_USAGE_SET_PERIODIC_REPORT),
2045 COLLECTION(1, Logical),
2046 REPORT_ID(1, 5),
2048 USAGE(1, PID_USAGE_MAGNITUDE),
2049 LOGICAL_MINIMUM(1, 0),
2050 LOGICAL_MAXIMUM(2, 0x00ff),
2051 PHYSICAL_MINIMUM(1, 0),
2052 PHYSICAL_MAXIMUM(2, 0x2710),
2053 REPORT_SIZE(1, 8),
2054 REPORT_COUNT(1, 1),
2055 OUTPUT(1, Data|Var|Abs),
2056 END_COLLECTION,
2058 USAGE(1, PID_USAGE_SET_ENVELOPE_REPORT),
2059 COLLECTION(1, Logical),
2060 REPORT_ID(1, 6),
2062 USAGE(1, PID_USAGE_ATTACK_LEVEL),
2063 USAGE(1, PID_USAGE_FADE_LEVEL),
2064 LOGICAL_MINIMUM(1, 0),
2065 LOGICAL_MAXIMUM(2, 0x00ff),
2066 PHYSICAL_MINIMUM(1, 0),
2067 PHYSICAL_MAXIMUM(2, 0x2710),
2068 REPORT_SIZE(1, 8),
2069 REPORT_COUNT(1, 2),
2070 OUTPUT(1, Data|Var|Abs),
2072 USAGE(1, PID_USAGE_ATTACK_TIME),
2073 USAGE(1, PID_USAGE_FADE_TIME),
2074 UNIT(2, 0x1003), /* Eng Lin:Time */
2075 UNIT_EXPONENT(1, -3), /* 10^-3 */
2076 LOGICAL_MINIMUM(1, 0),
2077 LOGICAL_MAXIMUM(2, 0x7fff),
2078 PHYSICAL_MINIMUM(1, 0),
2079 PHYSICAL_MAXIMUM(2, 0x7fff),
2080 REPORT_SIZE(1, 16),
2081 REPORT_COUNT(1, 2),
2082 OUTPUT(1, Data|Var|Abs),
2083 PHYSICAL_MAXIMUM(1, 0),
2084 UNIT_EXPONENT(1, 0),
2085 UNIT(1, 0),
2086 END_COLLECTION,
2089 USAGE(1, PID_USAGE_SET_CONDITION_REPORT),
2090 COLLECTION(1, Logical),
2091 REPORT_ID(1, 7),
2093 USAGE(1, PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET),
2094 COLLECTION(1, Logical),
2095 USAGE(4, (HID_USAGE_PAGE_ORDINAL << 16)|1),
2096 USAGE(4, (HID_USAGE_PAGE_ORDINAL << 16)|2),
2097 LOGICAL_MINIMUM(1, 0),
2098 LOGICAL_MAXIMUM(1, 1),
2099 PHYSICAL_MINIMUM(1, 0),
2100 PHYSICAL_MAXIMUM(1, 1),
2101 REPORT_SIZE(1, 2),
2102 REPORT_COUNT(1, 2),
2103 OUTPUT(1, Data|Var|Abs),
2104 END_COLLECTION,
2105 REPORT_SIZE(1, 4),
2106 REPORT_COUNT(1, 1),
2107 OUTPUT(1, Cnst|Var|Abs),
2109 USAGE(1, PID_USAGE_CP_OFFSET),
2110 LOGICAL_MINIMUM(1, 0x80),
2111 LOGICAL_MAXIMUM(1, 0x7f),
2112 PHYSICAL_MINIMUM(2, 0xd8f0),
2113 PHYSICAL_MAXIMUM(2, 0x2710),
2114 REPORT_SIZE(1, 8),
2115 REPORT_COUNT(1, 1),
2116 OUTPUT(1, Data|Var|Abs),
2118 USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT),
2119 USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT),
2120 LOGICAL_MINIMUM(1, 0x80),
2121 LOGICAL_MAXIMUM(1, 0x7f),
2122 PHYSICAL_MINIMUM(2, 0xd8f0),
2123 PHYSICAL_MAXIMUM(2, 0x2710),
2124 REPORT_SIZE(1, 8),
2125 REPORT_COUNT(1, 2),
2126 OUTPUT(1, Data|Var|Abs),
2128 USAGE(1, PID_USAGE_POSITIVE_SATURATION),
2129 USAGE(1, PID_USAGE_NEGATIVE_SATURATION),
2130 LOGICAL_MINIMUM(1, 0),
2131 LOGICAL_MAXIMUM(2, 0x00ff),
2132 PHYSICAL_MINIMUM(1, 0),
2133 PHYSICAL_MAXIMUM(2, 0x2710),
2134 REPORT_SIZE(1, 8),
2135 REPORT_COUNT(1, 2),
2136 OUTPUT(1, Data|Var|Abs),
2138 USAGE(1, PID_USAGE_DEAD_BAND),
2139 LOGICAL_MINIMUM(1, 0),
2140 LOGICAL_MAXIMUM(2, 0x00ff),
2141 PHYSICAL_MINIMUM(1, 0),
2142 PHYSICAL_MAXIMUM(2, 0x2710),
2143 REPORT_SIZE(1, 8),
2144 REPORT_COUNT(1, 1),
2145 OUTPUT(1, Data|Var|Abs),
2146 END_COLLECTION,
2149 USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT),
2150 COLLECTION(1, Logical),
2151 REPORT_ID(1, 8),
2153 USAGE(1, PID_USAGE_DEVICE_GAIN),
2154 LOGICAL_MINIMUM(1, 0),
2155 LOGICAL_MAXIMUM(2, 0x00ff),
2156 PHYSICAL_MINIMUM(1, 0),
2157 PHYSICAL_MAXIMUM(2, 0x2710),
2158 REPORT_SIZE(1, 8),
2159 REPORT_COUNT(1, 1),
2160 OUTPUT(1, Data|Var|Abs),
2161 END_COLLECTION,
2162 END_COLLECTION,
2164 C_ASSERT(sizeof(report_descriptor) < MAX_HID_DESCRIPTOR_LEN);
2165 #include "pop_hid_macros.h"
2167 struct hid_device_desc desc =
2169 .use_report_id = TRUE,
2170 .caps =
2172 .InputReportByteLength = 5,
2173 .OutputReportByteLength = 11,
2175 .attributes = default_attributes,
2177 const DIDEVCAPS expect_caps =
2179 .dwSize = sizeof(DIDEVCAPS),
2180 .dwFlags = DIDC_FORCEFEEDBACK | DIDC_ATTACHED | DIDC_EMULATED | DIDC_STARTDELAY |
2181 DIDC_FFFADE | DIDC_FFATTACK | DIDC_DEADBAND | DIDC_SATURATION,
2182 .dwDevType = version >= 0x800 ? DIDEVTYPE_HID | (DI8DEVTYPEJOYSTICK_LIMITED << 8) | DI8DEVTYPE_JOYSTICK
2183 : DIDEVTYPE_HID | (DIDEVTYPEJOYSTICK_UNKNOWN << 8) | DIDEVTYPE_JOYSTICK,
2184 .dwAxes = 3,
2185 .dwButtons = 2,
2186 .dwFFSamplePeriod = 1000000,
2187 .dwFFMinTimeResolution = 1000000,
2188 .dwHardwareRevision = 1,
2189 .dwFFDriverVersion = 1,
2191 struct hid_expect expect_acquire[] =
2194 .code = IOCTL_HID_WRITE_REPORT,
2195 .report_id = 1,
2196 .report_len = 2,
2197 .report_buf = {1, 0x01},
2200 .code = IOCTL_HID_WRITE_REPORT,
2201 .report_id = 8,
2202 .report_len = 2,
2203 .report_buf = {8, 0x19},
2206 struct hid_expect expect_reset[] =
2209 .code = IOCTL_HID_WRITE_REPORT,
2210 .report_id = 1,
2211 .report_len = 2,
2212 .report_buf = {1, 0x01},
2215 struct hid_expect expect_set_device_gain_1 =
2217 .code = IOCTL_HID_WRITE_REPORT,
2218 .report_id = 8,
2219 .report_len = 2,
2220 .report_buf = {8, 0x19},
2222 struct hid_expect expect_set_device_gain_2 =
2224 .code = IOCTL_HID_WRITE_REPORT,
2225 .report_id = 8,
2226 .report_len = 2,
2227 .report_buf = {8, 0x33},
2230 const DIDEVICEINSTANCEW expect_devinst =
2232 .dwSize = sizeof(DIDEVICEINSTANCEW),
2233 .guidInstance = expect_guid_product,
2234 .guidProduct = expect_guid_product,
2235 .dwDevType = version >= 0x800 ? DIDEVTYPE_HID | (DI8DEVTYPEJOYSTICK_LIMITED << 8) | DI8DEVTYPE_JOYSTICK
2236 : DIDEVTYPE_HID | (DIDEVTYPEJOYSTICK_UNKNOWN << 8) | DIDEVTYPE_JOYSTICK,
2237 .tszInstanceName = L"Wine Test",
2238 .tszProductName = L"Wine Test",
2239 .guidFFDriver = IID_IDirectInputPIDDriver,
2240 .wUsagePage = HID_USAGE_PAGE_GENERIC,
2241 .wUsage = HID_USAGE_GENERIC_JOYSTICK,
2243 const DIDEVICEOBJECTINSTANCEW expect_objects_5[] =
2246 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2247 .guidType = GUID_XAxis,
2248 .dwType = DIDFT_ABSAXIS|DIDFT_MAKEINSTANCE(0)|DIDFT_FFACTUATOR,
2249 .dwFlags = DIDOI_ASPECTPOSITION|DIDOI_FFACTUATOR,
2250 .tszName = L"X Axis",
2251 .wCollectionNumber = 1,
2252 .wUsagePage = HID_USAGE_PAGE_GENERIC,
2253 .wUsage = HID_USAGE_GENERIC_X,
2254 .wReportId = 1,
2257 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2258 .guidType = GUID_YAxis,
2259 .dwOfs = 0x4,
2260 .dwType = DIDFT_ABSAXIS|DIDFT_MAKEINSTANCE(1)|DIDFT_FFACTUATOR,
2261 .dwFlags = DIDOI_ASPECTPOSITION|DIDOI_FFACTUATOR,
2262 .tszName = L"Y Axis",
2263 .wCollectionNumber = 1,
2264 .wUsagePage = HID_USAGE_PAGE_GENERIC,
2265 .wUsage = HID_USAGE_GENERIC_Y,
2266 .wReportId = 1,
2269 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2270 .guidType = GUID_ZAxis,
2271 .dwOfs = 0x8,
2272 .dwType = DIDFT_ABSAXIS|DIDFT_MAKEINSTANCE(2)|DIDFT_FFACTUATOR,
2273 .dwFlags = DIDOI_ASPECTPOSITION|DIDOI_FFACTUATOR,
2274 .tszName = L"Z Axis",
2275 .wCollectionNumber = 1,
2276 .wUsagePage = HID_USAGE_PAGE_GENERIC,
2277 .wUsage = HID_USAGE_GENERIC_Z,
2278 .wReportId = 1,
2281 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2282 .guidType = GUID_Button,
2283 .dwOfs = 0x30,
2284 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(0)|DIDFT_FFEFFECTTRIGGER,
2285 .dwFlags = DIDOI_FFEFFECTTRIGGER,
2286 .tszName = L"Button 0",
2287 .wCollectionNumber = 1,
2288 .wUsagePage = HID_USAGE_PAGE_BUTTON,
2289 .wUsage = 0x1,
2290 .wReportId = 1,
2293 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2294 .guidType = GUID_Button,
2295 .dwOfs = 0x31,
2296 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(1)|DIDFT_FFEFFECTTRIGGER,
2297 .dwFlags = DIDOI_FFEFFECTTRIGGER,
2298 .tszName = L"Button 1",
2299 .wCollectionNumber = 1,
2300 .wUsagePage = HID_USAGE_PAGE_BUTTON,
2301 .wUsage = 0x2,
2302 .wReportId = 1,
2305 const DIDEVICEOBJECTINSTANCEW expect_objects[] =
2308 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2309 .guidType = GUID_ZAxis,
2310 .dwType = DIDFT_ABSAXIS|DIDFT_MAKEINSTANCE(2)|DIDFT_FFACTUATOR,
2311 .dwFlags = DIDOI_ASPECTPOSITION|DIDOI_FFACTUATOR,
2312 .tszName = L"Z Axis",
2313 .wCollectionNumber = 1,
2314 .wUsagePage = HID_USAGE_PAGE_GENERIC,
2315 .wUsage = HID_USAGE_GENERIC_Z,
2316 .wReportId = 1,
2319 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2320 .guidType = GUID_YAxis,
2321 .dwOfs = 0x4,
2322 .dwType = DIDFT_ABSAXIS|DIDFT_MAKEINSTANCE(1)|DIDFT_FFACTUATOR,
2323 .dwFlags = DIDOI_ASPECTPOSITION|DIDOI_FFACTUATOR,
2324 .tszName = L"Y Axis",
2325 .wCollectionNumber = 1,
2326 .wUsagePage = HID_USAGE_PAGE_GENERIC,
2327 .wUsage = HID_USAGE_GENERIC_Y,
2328 .wReportId = 1,
2331 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2332 .guidType = GUID_XAxis,
2333 .dwOfs = 0x8,
2334 .dwType = DIDFT_ABSAXIS|DIDFT_MAKEINSTANCE(0)|DIDFT_FFACTUATOR,
2335 .dwFlags = DIDOI_ASPECTPOSITION|DIDOI_FFACTUATOR,
2336 .tszName = L"X Axis",
2337 .wCollectionNumber = 1,
2338 .wUsagePage = HID_USAGE_PAGE_GENERIC,
2339 .wUsage = HID_USAGE_GENERIC_X,
2340 .wReportId = 1,
2343 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2344 .guidType = GUID_Button,
2345 .dwOfs = version >= 0x800 ? 0x68 : 0x10,
2346 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(0)|DIDFT_FFEFFECTTRIGGER,
2347 .dwFlags = DIDOI_FFEFFECTTRIGGER,
2348 .tszName = L"Button 0",
2349 .wCollectionNumber = 1,
2350 .wUsagePage = HID_USAGE_PAGE_BUTTON,
2351 .wUsage = 0x1,
2352 .wReportId = 1,
2355 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2356 .guidType = GUID_Button,
2357 .dwOfs = version >= 0x800 ? 0x69 : 0x11,
2358 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(1)|DIDFT_FFEFFECTTRIGGER,
2359 .dwFlags = DIDOI_FFEFFECTTRIGGER,
2360 .tszName = L"Button 1",
2361 .wCollectionNumber = 1,
2362 .wUsagePage = HID_USAGE_PAGE_BUTTON,
2363 .wUsage = 0x2,
2364 .wReportId = 1,
2367 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2368 .guidType = GUID_Unknown,
2369 .dwOfs = version >= 0x800 ? 0x70 : 0,
2370 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(12)|DIDFT_OUTPUT,
2371 .dwFlags = 0x80008000,
2372 .tszName = L"DC Device Reset",
2373 .wCollectionNumber = 4,
2374 .wUsagePage = HID_USAGE_PAGE_PID,
2375 .wUsage = PID_USAGE_DC_DEVICE_RESET,
2376 .wReportId = 1,
2379 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2380 .guidType = GUID_Unknown,
2381 .dwOfs = version >= 0x800 ? 0x10 : 0,
2382 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(13)|DIDFT_OUTPUT,
2383 .dwFlags = 0x80008000,
2384 .tszName = L"Effect Block Index",
2385 .wCollectionNumber = 5,
2386 .wUsagePage = HID_USAGE_PAGE_PID,
2387 .wUsage = PID_USAGE_EFFECT_BLOCK_INDEX,
2388 .wReportId = 2,
2391 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2392 .guidType = GUID_Unknown,
2393 .dwOfs = version >= 0x800 ? 0x71 : 0,
2394 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(14)|DIDFT_OUTPUT,
2395 .dwFlags = 0x80008000,
2396 .tszName = L"Op Effect Start",
2397 .wCollectionNumber = 6,
2398 .wUsagePage = HID_USAGE_PAGE_PID,
2399 .wUsage = PID_USAGE_OP_EFFECT_START,
2400 .wReportId = 2,
2403 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2404 .guidType = GUID_Unknown,
2405 .dwOfs = version >= 0x800 ? 0x72 : 0,
2406 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(15)|DIDFT_OUTPUT,
2407 .dwFlags = 0x80008000,
2408 .tszName = L"Op Effect Start Solo",
2409 .wCollectionNumber = 6,
2410 .wUsagePage = HID_USAGE_PAGE_PID,
2411 .wUsage = PID_USAGE_OP_EFFECT_START_SOLO,
2412 .wReportId = 2,
2415 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2416 .guidType = GUID_Unknown,
2417 .dwOfs = version >= 0x800 ? 0x73 : 0,
2418 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(16)|DIDFT_OUTPUT,
2419 .dwFlags = 0x80008000,
2420 .tszName = L"Op Effect Stop",
2421 .wCollectionNumber = 6,
2422 .wUsagePage = HID_USAGE_PAGE_PID,
2423 .wUsage = PID_USAGE_OP_EFFECT_STOP,
2424 .wReportId = 2,
2427 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2428 .guidType = GUID_Unknown,
2429 .dwOfs = version >= 0x800 ? 0x14 : 0,
2430 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(17)|DIDFT_OUTPUT,
2431 .dwFlags = 0x80008000,
2432 .tszName = L"Loop Count",
2433 .wCollectionNumber = 5,
2434 .wUsagePage = HID_USAGE_PAGE_PID,
2435 .wUsage = PID_USAGE_LOOP_COUNT,
2436 .wReportId = 2,
2439 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2440 .guidType = GUID_Unknown,
2441 .dwOfs = version >= 0x800 ? 0x18 : 0,
2442 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(18)|DIDFT_OUTPUT,
2443 .dwFlags = 0x80008000,
2444 .tszName = L"Effect Block Index",
2445 .wCollectionNumber = 7,
2446 .wUsagePage = HID_USAGE_PAGE_PID,
2447 .wUsage = PID_USAGE_EFFECT_BLOCK_INDEX,
2448 .wReportId = 3,
2451 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2452 .guidType = GUID_Unknown,
2453 .dwOfs = version >= 0x800 ? 0x74 : 0,
2454 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(19)|DIDFT_OUTPUT,
2455 .dwFlags = 0x80008000,
2456 .tszName = L"ET Square",
2457 .wCollectionNumber = 8,
2458 .wUsagePage = HID_USAGE_PAGE_PID,
2459 .wUsage = PID_USAGE_ET_SQUARE,
2460 .wReportId = 3,
2463 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2464 .guidType = GUID_Unknown,
2465 .dwOfs = version >= 0x800 ? 0x75 : 0,
2466 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(20)|DIDFT_OUTPUT,
2467 .dwFlags = 0x80008000,
2468 .tszName = L"ET Sine",
2469 .wCollectionNumber = 8,
2470 .wUsagePage = HID_USAGE_PAGE_PID,
2471 .wUsage = PID_USAGE_ET_SINE,
2472 .wReportId = 3,
2475 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2476 .guidType = GUID_Unknown,
2477 .dwOfs = version >= 0x800 ? 0x76 : 0,
2478 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(21)|DIDFT_OUTPUT,
2479 .dwFlags = 0x80008000,
2480 .tszName = L"ET Spring",
2481 .wCollectionNumber = 8,
2482 .wUsagePage = HID_USAGE_PAGE_PID,
2483 .wUsage = PID_USAGE_ET_SPRING,
2484 .wReportId = 3,
2487 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2488 .guidType = GUID_Unknown,
2489 .dwOfs = version >= 0x800 ? 0x77 : 0,
2490 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(22)|DIDFT_OUTPUT,
2491 .dwFlags = 0x80008000,
2492 .tszName = L"Z Axis",
2493 .wCollectionNumber = 9,
2494 .wUsagePage = HID_USAGE_PAGE_GENERIC,
2495 .wUsage = HID_USAGE_GENERIC_Z,
2496 .wReportId = 3,
2499 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2500 .guidType = GUID_Unknown,
2501 .dwOfs = version >= 0x800 ? 0x78 : 0,
2502 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(23)|DIDFT_OUTPUT,
2503 .dwFlags = 0x80008000,
2504 .tszName = L"Y Axis",
2505 .wCollectionNumber = 9,
2506 .wUsagePage = HID_USAGE_PAGE_GENERIC,
2507 .wUsage = HID_USAGE_GENERIC_Y,
2508 .wReportId = 3,
2511 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2512 .guidType = GUID_Unknown,
2513 .dwOfs = version >= 0x800 ? 0x79 : 0,
2514 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(24)|DIDFT_OUTPUT,
2515 .dwFlags = 0x80008000,
2516 .tszName = L"X Axis",
2517 .wCollectionNumber = 9,
2518 .wUsagePage = HID_USAGE_PAGE_GENERIC,
2519 .wUsage = HID_USAGE_GENERIC_X,
2520 .wReportId = 3,
2523 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2524 .guidType = GUID_Unknown,
2525 .dwOfs = version >= 0x800 ? 0x7a : 0,
2526 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(25)|DIDFT_OUTPUT,
2527 .dwFlags = 0x80008000,
2528 .tszName = L"Direction Enable",
2529 .wCollectionNumber = 7,
2530 .wUsagePage = HID_USAGE_PAGE_PID,
2531 .wUsage = PID_USAGE_DIRECTION_ENABLE,
2532 .wReportId = 3,
2535 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2536 .guidType = GUID_Unknown,
2537 .dwOfs = version >= 0x800 ? 0x1c : 0,
2538 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(26)|DIDFT_OUTPUT,
2539 .dwFlags = 0x80008000,
2540 .tszName = L"Start Delay",
2541 .wCollectionNumber = 7,
2542 .wUsagePage = HID_USAGE_PAGE_PID,
2543 .wUsage = PID_USAGE_START_DELAY,
2544 .wReportId = 3,
2545 .dwDimension = 0x1003,
2546 .wExponent = -3,
2549 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2550 .guidType = GUID_Unknown,
2551 .dwOfs = version >= 0x800 ? 0x20 : 0,
2552 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(27)|DIDFT_OUTPUT,
2553 .dwFlags = 0x80008000,
2554 .tszName = L"Duration",
2555 .wCollectionNumber = 7,
2556 .wUsagePage = HID_USAGE_PAGE_PID,
2557 .wUsage = PID_USAGE_DURATION,
2558 .wReportId = 3,
2559 .dwDimension = 0x1003,
2560 .wExponent = -3,
2563 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2564 .guidType = GUID_Unknown,
2565 .dwOfs = version >= 0x800 ? 0x24 : 0,
2566 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(28)|DIDFT_OUTPUT,
2567 .dwFlags = 0x80008000,
2568 .tszName = L"Trigger Button",
2569 .wCollectionNumber = 7,
2570 .wUsagePage = HID_USAGE_PAGE_PID,
2571 .wUsage = PID_USAGE_TRIGGER_BUTTON,
2572 .wReportId = 3,
2575 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2576 .guidType = GUID_Unknown,
2577 .dwOfs = version >= 0x800 ? 0x28 : 0,
2578 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(29)|DIDFT_OUTPUT,
2579 .dwFlags = 0x80008000,
2580 .tszName = L"Unknown 29",
2581 .wCollectionNumber = 10,
2582 .wUsagePage = HID_USAGE_PAGE_ORDINAL,
2583 .wUsage = 2,
2584 .wReportId = 3,
2585 .wExponent = -2,
2588 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2589 .guidType = GUID_Unknown,
2590 .dwOfs = version >= 0x800 ? 0x2c : 0,
2591 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(30)|DIDFT_OUTPUT,
2592 .dwFlags = 0x80008000,
2593 .tszName = L"Unknown 30",
2594 .wCollectionNumber = 10,
2595 .wUsagePage = HID_USAGE_PAGE_ORDINAL,
2596 .wUsage = 1,
2597 .wReportId = 3,
2598 .wExponent = -2,
2601 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2602 .guidType = GUID_Unknown,
2603 .dwOfs = version >= 0x800 ? 0x30 : 0,
2604 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(31)|DIDFT_OUTPUT,
2605 .dwFlags = 0x80008000,
2606 .tszName = L"Magnitude",
2607 .wCollectionNumber = 11,
2608 .wUsagePage = HID_USAGE_PAGE_PID,
2609 .wUsage = PID_USAGE_MAGNITUDE,
2610 .wReportId = 5,
2613 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2614 .guidType = GUID_Unknown,
2615 .dwOfs = version >= 0x800 ? 0x34 : 0,
2616 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(32)|DIDFT_OUTPUT,
2617 .dwFlags = 0x80008000,
2618 .tszName = L"Fade Level",
2619 .wCollectionNumber = 12,
2620 .wUsagePage = HID_USAGE_PAGE_PID,
2621 .wUsage = PID_USAGE_FADE_LEVEL,
2622 .wReportId = 6,
2625 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2626 .guidType = GUID_Unknown,
2627 .dwOfs = version >= 0x800 ? 0x38 : 0,
2628 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(33)|DIDFT_OUTPUT,
2629 .dwFlags = 0x80008000,
2630 .tszName = L"Attack Level",
2631 .wCollectionNumber = 12,
2632 .wUsagePage = HID_USAGE_PAGE_PID,
2633 .wUsage = PID_USAGE_ATTACK_LEVEL,
2634 .wReportId = 6,
2637 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2638 .guidType = GUID_Unknown,
2639 .dwOfs = version >= 0x800 ? 0x3c : 0,
2640 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(34)|DIDFT_OUTPUT,
2641 .dwFlags = 0x80008000,
2642 .tszName = L"Fade Time",
2643 .wCollectionNumber = 12,
2644 .wUsagePage = HID_USAGE_PAGE_PID,
2645 .wUsage = PID_USAGE_FADE_TIME,
2646 .wReportId = 6,
2647 .dwDimension = 0x1003,
2648 .wExponent = -3,
2651 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2652 .guidType = GUID_Unknown,
2653 .dwOfs = version >= 0x800 ? 0x40 : 0,
2654 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(35)|DIDFT_OUTPUT,
2655 .dwFlags = 0x80008000,
2656 .tszName = L"Attack Time",
2657 .wCollectionNumber = 12,
2658 .wUsagePage = HID_USAGE_PAGE_PID,
2659 .wUsage = PID_USAGE_ATTACK_TIME,
2660 .wReportId = 6,
2661 .dwDimension = 0x1003,
2662 .wExponent = -3,
2665 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2666 .guidType = GUID_Unknown,
2667 .dwOfs = version >= 0x800 ? 0x44 : 0,
2668 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(36)|DIDFT_OUTPUT,
2669 .dwFlags = 0x80008000,
2670 .tszName = L"Unknown 36",
2671 .wCollectionNumber = 14,
2672 .wUsagePage = HID_USAGE_PAGE_ORDINAL,
2673 .wUsage = 2,
2674 .wReportId = 7,
2677 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2678 .guidType = GUID_Unknown,
2679 .dwOfs = version >= 0x800 ? 0x48 : 0,
2680 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(37)|DIDFT_OUTPUT,
2681 .dwFlags = 0x80008000,
2682 .tszName = L"Unknown 37",
2683 .wCollectionNumber = 14,
2684 .wUsagePage = HID_USAGE_PAGE_ORDINAL,
2685 .wUsage = 1,
2686 .wReportId = 7,
2689 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2690 .guidType = GUID_Unknown,
2691 .dwOfs = version >= 0x800 ? 0x4c : 0,
2692 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(38)|DIDFT_OUTPUT,
2693 .dwFlags = 0x80008000,
2694 .tszName = L"CP Offset",
2695 .wCollectionNumber = 13,
2696 .wUsagePage = HID_USAGE_PAGE_PID,
2697 .wUsage = PID_USAGE_CP_OFFSET,
2698 .wReportId = 7,
2701 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2702 .guidType = GUID_Unknown,
2703 .dwOfs = version >= 0x800 ? 0x50 : 0,
2704 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(39)|DIDFT_OUTPUT,
2705 .dwFlags = 0x80008000,
2706 .tszName = L"Negative Coefficient",
2707 .wCollectionNumber = 13,
2708 .wUsagePage = HID_USAGE_PAGE_PID,
2709 .wUsage = PID_USAGE_NEGATIVE_COEFFICIENT,
2710 .wReportId = 7,
2713 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2714 .guidType = GUID_Unknown,
2715 .dwOfs = version >= 0x800 ? 0x54 : 0,
2716 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(40)|DIDFT_OUTPUT,
2717 .dwFlags = 0x80008000,
2718 .tszName = L"Positive Coefficient",
2719 .wCollectionNumber = 13,
2720 .wUsagePage = HID_USAGE_PAGE_PID,
2721 .wUsage = PID_USAGE_POSITIVE_COEFFICIENT,
2722 .wReportId = 7,
2725 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2726 .guidType = GUID_Unknown,
2727 .dwOfs = version >= 0x800 ? 0x58 : 0,
2728 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(41)|DIDFT_OUTPUT,
2729 .dwFlags = 0x80008000,
2730 .tszName = L"Negative Saturation",
2731 .wCollectionNumber = 13,
2732 .wUsagePage = HID_USAGE_PAGE_PID,
2733 .wUsage = PID_USAGE_NEGATIVE_SATURATION,
2734 .wReportId = 7,
2737 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2738 .guidType = GUID_Unknown,
2739 .dwOfs = version >= 0x800 ? 0x5c : 0,
2740 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(42)|DIDFT_OUTPUT,
2741 .dwFlags = 0x80008000,
2742 .tszName = L"Positive Saturation",
2743 .wCollectionNumber = 13,
2744 .wUsagePage = HID_USAGE_PAGE_PID,
2745 .wUsage = PID_USAGE_POSITIVE_SATURATION,
2746 .wReportId = 7,
2749 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2750 .guidType = GUID_Unknown,
2751 .dwOfs = version >= 0x800 ? 0x60 : 0,
2752 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(43)|DIDFT_OUTPUT,
2753 .dwFlags = 0x80008000,
2754 .tszName = L"Dead Band",
2755 .wCollectionNumber = 13,
2756 .wUsagePage = HID_USAGE_PAGE_PID,
2757 .wUsage = PID_USAGE_DEAD_BAND,
2758 .wReportId = 7,
2761 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2762 .guidType = GUID_Unknown,
2763 .dwOfs = version >= 0x800 ? 0x64 : 0,
2764 .dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(44)|DIDFT_OUTPUT,
2765 .dwFlags = 0x80008000,
2766 .tszName = L"Device Gain",
2767 .wCollectionNumber = 15,
2768 .wUsagePage = HID_USAGE_PAGE_PID,
2769 .wUsage = PID_USAGE_DEVICE_GAIN,
2770 .wReportId = 8,
2773 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2774 .guidType = GUID_Unknown,
2775 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(0),
2776 .tszName = L"Collection 0 - Joystick",
2777 .wUsagePage = HID_USAGE_PAGE_GENERIC,
2778 .wUsage = HID_USAGE_GENERIC_JOYSTICK,
2781 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2782 .guidType = GUID_Unknown,
2783 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(1),
2784 .tszName = L"Collection 1 - Joystick",
2785 .wUsagePage = HID_USAGE_PAGE_GENERIC,
2786 .wUsage = HID_USAGE_GENERIC_JOYSTICK,
2789 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2790 .guidType = GUID_Unknown,
2791 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(2),
2792 .tszName = L"Collection 2 - PID State Report",
2793 .wUsagePage = HID_USAGE_PAGE_PID,
2794 .wUsage = PID_USAGE_STATE_REPORT,
2797 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2798 .guidType = GUID_Unknown,
2799 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(3),
2800 .tszName = L"Collection 3 - PID Device Control Report",
2801 .wUsagePage = HID_USAGE_PAGE_PID,
2802 .wUsage = PID_USAGE_DEVICE_CONTROL_REPORT,
2805 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2806 .guidType = GUID_Unknown,
2807 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(4),
2808 .tszName = L"Collection 4 - PID Device Control",
2809 .wCollectionNumber = 3,
2810 .wUsagePage = HID_USAGE_PAGE_PID,
2811 .wUsage = PID_USAGE_DEVICE_CONTROL,
2814 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2815 .guidType = GUID_Unknown,
2816 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(5),
2817 .tszName = L"Collection 5 - Effect Operation Report",
2818 .wUsagePage = HID_USAGE_PAGE_PID,
2819 .wUsage = PID_USAGE_EFFECT_OPERATION_REPORT,
2822 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2823 .guidType = GUID_Unknown,
2824 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(6),
2825 .tszName = L"Collection 6 - Effect Operation",
2826 .wCollectionNumber = 5,
2827 .wUsagePage = HID_USAGE_PAGE_PID,
2828 .wUsage = PID_USAGE_EFFECT_OPERATION,
2831 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2832 .guidType = GUID_Unknown,
2833 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(7),
2834 .tszName = L"Collection 7 - Set Effect Report",
2835 .wUsagePage = HID_USAGE_PAGE_PID,
2836 .wUsage = PID_USAGE_SET_EFFECT_REPORT,
2839 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2840 .guidType = GUID_Unknown,
2841 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(8),
2842 .tszName = L"Collection 8 - Effect Type",
2843 .wCollectionNumber = 7,
2844 .wUsagePage = HID_USAGE_PAGE_PID,
2845 .wUsage = PID_USAGE_EFFECT_TYPE,
2848 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2849 .guidType = GUID_Unknown,
2850 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(9),
2851 .tszName = L"Collection 9 - Axes Enable",
2852 .wCollectionNumber = 7,
2853 .wUsagePage = HID_USAGE_PAGE_PID,
2854 .wUsage = PID_USAGE_AXES_ENABLE,
2857 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2858 .guidType = GUID_Unknown,
2859 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(10),
2860 .tszName = L"Collection 10 - Direction",
2861 .wCollectionNumber = 7,
2862 .wUsagePage = HID_USAGE_PAGE_PID,
2863 .wUsage = PID_USAGE_DIRECTION,
2866 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2867 .guidType = GUID_Unknown,
2868 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(11),
2869 .tszName = L"Collection 11 - Set Periodic Report",
2870 .wUsagePage = HID_USAGE_PAGE_PID,
2871 .wUsage = PID_USAGE_SET_PERIODIC_REPORT,
2874 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2875 .guidType = GUID_Unknown,
2876 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(12),
2877 .tszName = L"Collection 12 - Set Envelope Report",
2878 .wUsagePage = HID_USAGE_PAGE_PID,
2879 .wUsage = PID_USAGE_SET_ENVELOPE_REPORT,
2882 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2883 .guidType = GUID_Unknown,
2884 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(13),
2885 .tszName = L"Collection 13 - Set Condition Report",
2886 .wUsagePage = HID_USAGE_PAGE_PID,
2887 .wUsage = PID_USAGE_SET_CONDITION_REPORT,
2890 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2891 .guidType = GUID_Unknown,
2892 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(14),
2893 .tszName = L"Collection 14 - Type Specific Block Offset",
2894 .wCollectionNumber = 13,
2895 .wUsagePage = HID_USAGE_PAGE_PID,
2896 .wUsage = PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET,
2899 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
2900 .guidType = GUID_Unknown,
2901 .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(15),
2902 .tszName = L"Collection 15 - Device Gain Report",
2903 .wUsagePage = HID_USAGE_PAGE_PID,
2904 .wUsage = PID_USAGE_DEVICE_GAIN_REPORT,
2907 const DIEFFECTINFOW expect_effects[] =
2910 .dwSize = sizeof(DIEFFECTINFOW),
2911 .guid = GUID_Square,
2912 .dwEffType = DIEFT_PERIODIC | DIEFT_STARTDELAY | DIEFT_FFFADE | DIEFT_FFATTACK,
2913 .dwStaticParams = DIEP_AXES | DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_STARTDELAY |
2914 DIEP_DURATION | DIEP_TRIGGERBUTTON | DIEP_ENVELOPE,
2915 .dwDynamicParams = DIEP_AXES | DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_STARTDELAY |
2916 DIEP_DURATION | DIEP_TRIGGERBUTTON | DIEP_ENVELOPE,
2917 .tszName = L"GUID_Square",
2920 .dwSize = sizeof(DIEFFECTINFOW),
2921 .guid = GUID_Sine,
2922 .dwEffType = DIEFT_PERIODIC | DIEFT_STARTDELAY | DIEFT_FFFADE | DIEFT_FFATTACK,
2923 .dwStaticParams = DIEP_AXES | DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_STARTDELAY |
2924 DIEP_DURATION | DIEP_TRIGGERBUTTON | DIEP_ENVELOPE,
2925 .dwDynamicParams = DIEP_AXES | DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_STARTDELAY |
2926 DIEP_DURATION | DIEP_TRIGGERBUTTON | DIEP_ENVELOPE,
2927 .tszName = L"GUID_Sine",
2930 .dwSize = sizeof(DIEFFECTINFOW),
2931 .guid = GUID_Spring,
2932 .dwEffType = DIEFT_CONDITION | DIEFT_STARTDELAY | DIEFT_DEADBAND | DIEFT_SATURATION,
2933 .dwStaticParams = DIEP_AXES | DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_STARTDELAY |
2934 DIEP_DURATION,
2935 .dwDynamicParams = DIEP_AXES | DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_STARTDELAY |
2936 DIEP_DURATION,
2937 .tszName = L"GUID_Spring",
2941 struct check_objects_todos todo_objects_5[ARRAY_SIZE(expect_objects_5)] =
2943 {.guid = TRUE, .type = TRUE, .usage = TRUE, .name = TRUE},
2944 {0},
2945 {.guid = TRUE, .type = TRUE, .usage = TRUE, .name = TRUE},
2947 struct check_objects_params check_objects_params =
2949 .version = version,
2950 .expect_count = version < 0x700 ? ARRAY_SIZE(expect_objects_5) : ARRAY_SIZE(expect_objects),
2951 .expect_objs = version < 0x700 ? expect_objects_5 : expect_objects,
2952 .todo_objs = version < 0x700 ? todo_objects_5 : NULL,
2953 .todo_extra = version < 0x700 ? TRUE : FALSE,
2955 struct check_effects_params check_effects_params =
2957 .expect_count = ARRAY_SIZE(expect_effects),
2958 .expect_effects = expect_effects,
2960 DIPROPDWORD prop_dword =
2962 .diph =
2964 .dwSize = sizeof(DIPROPDWORD),
2965 .dwHeaderSize = sizeof(DIPROPHEADER),
2966 .dwHow = DIPH_DEVICE,
2969 DIPROPGUIDANDPATH prop_guid_path =
2971 .diph =
2973 .dwSize = sizeof(DIPROPGUIDANDPATH),
2974 .dwHeaderSize = sizeof(DIPROPHEADER),
2975 .dwHow = DIPH_DEVICE,
2978 DIDEVICEINSTANCEW devinst = {.dwSize = sizeof(DIDEVICEINSTANCEW)};
2979 IDirectInputDevice8W *device = NULL;
2980 DIDEVICEOBJECTDATA objdata = {0};
2981 DIEFFECTINFOW effectinfo = {0};
2982 DIEFFESCAPE escape = {0};
2983 DIDEVCAPS caps = {0};
2984 char buffer[1024];
2985 ULONG res, ref;
2986 HANDLE file;
2987 HRESULT hr;
2988 HWND hwnd;
2990 winetest_push_context( "%#lx", version );
2991 cleanup_registry_keys();
2993 desc.report_descriptor_len = sizeof(report_descriptor);
2994 memcpy( desc.report_descriptor_buf, report_descriptor, sizeof(report_descriptor) );
2995 fill_context( desc.context, ARRAY_SIZE(desc.context) );
2997 if (!hid_device_start( &desc, 1 )) goto done;
2998 if (FAILED(hr = dinput_test_create_device( version, &devinst, &device ))) goto done;
3000 check_dinput_devices( version, &devinst );
3002 hr = IDirectInputDevice8_GetDeviceInfo( device, &devinst );
3003 ok( hr == DI_OK, "GetDeviceInfo returned %#lx\n", hr );
3004 check_member( devinst, expect_devinst, "%lu", dwSize );
3005 todo_wine
3006 check_member_guid( devinst, expect_devinst, guidInstance );
3007 check_member_guid( devinst, expect_devinst, guidProduct );
3008 check_member( devinst, expect_devinst, "%#lx", dwDevType );
3009 check_member_wstr( devinst, expect_devinst, tszInstanceName );
3010 check_member_wstr( devinst, expect_devinst, tszProductName );
3011 check_member_guid( devinst, expect_devinst, guidFFDriver );
3012 check_member( devinst, expect_devinst, "%04x", wUsagePage );
3013 check_member( devinst, expect_devinst, "%04x", wUsage );
3015 caps.dwSize = sizeof(DIDEVCAPS);
3016 hr = IDirectInputDevice8_GetCapabilities( device, &caps );
3017 ok( hr == DI_OK, "GetCapabilities returned %#lx\n", hr );
3018 check_member( caps, expect_caps, "%lu", dwSize );
3019 check_member( caps, expect_caps, "%#lx", dwFlags );
3020 check_member( caps, expect_caps, "%#lx", dwDevType );
3021 check_member( caps, expect_caps, "%lu", dwAxes );
3022 check_member( caps, expect_caps, "%lu", dwButtons );
3023 check_member( caps, expect_caps, "%lu", dwPOVs );
3024 check_member( caps, expect_caps, "%lu", dwFFSamplePeriod );
3025 check_member( caps, expect_caps, "%lu", dwFFMinTimeResolution );
3026 check_member( caps, expect_caps, "%lu", dwFirmwareRevision );
3027 check_member( caps, expect_caps, "%lu", dwHardwareRevision );
3028 check_member( caps, expect_caps, "%lu", dwFFDriverVersion );
3030 prop_dword.dwData = 0xdeadbeef;
3031 hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFGAIN, &prop_dword.diph );
3032 ok( hr == DI_OK, "GetProperty DIPROP_FFGAIN returned %#lx\n", hr );
3033 ok( prop_dword.dwData == 10000, "got %lu expected %u\n", prop_dword.dwData, 10000 );
3035 hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFLOAD, &prop_dword.diph );
3036 ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr );
3038 hr = IDirectInputDevice8_EnumObjects( device, check_objects, &check_objects_params, DIDFT_ALL );
3039 ok( hr == DI_OK, "EnumObjects returned %#lx\n", hr );
3040 ok( check_objects_params.index >= check_objects_params.expect_count, "missing %u objects\n",
3041 check_objects_params.expect_count - check_objects_params.index );
3043 res = 0;
3044 hr = IDirectInputDevice8_EnumEffects( device, check_effect_count, &res, 0xfe );
3045 ok( hr == DI_OK, "EnumEffects returned %#lx\n", hr );
3046 ok( res == 0, "got %lu expected %u\n", res, 0 );
3047 res = 0;
3048 hr = IDirectInputDevice8_EnumEffects( device, check_effect_count, &res, DIEFT_PERIODIC );
3049 ok( hr == DI_OK, "EnumEffects returned %#lx\n", hr );
3050 ok( res == 2, "got %lu expected %u\n", res, 2 );
3051 hr = IDirectInputDevice8_EnumEffects( device, check_effects, &check_effects_params, DIEFT_ALL );
3052 ok( hr == DI_OK, "EnumEffects returned %#lx\n", hr );
3053 ok( check_effects_params.index >= check_effects_params.expect_count, "missing %u effects\n",
3054 check_effects_params.expect_count - check_effects_params.index );
3056 effectinfo.dwSize = sizeof(DIEFFECTINFOW);
3057 hr = IDirectInputDevice8_GetEffectInfo( device, &effectinfo, &GUID_Sine );
3058 ok( hr == DI_OK, "GetEffectInfo returned %#lx\n", hr );
3059 check_member_guid( effectinfo, expect_effects[1], guid );
3060 check_member( effectinfo, expect_effects[1], "%#lx", dwEffType );
3061 check_member( effectinfo, expect_effects[1], "%#lx", dwStaticParams );
3062 check_member( effectinfo, expect_effects[1], "%#lx", dwDynamicParams );
3063 check_member_wstr( effectinfo, expect_effects[1], tszName );
3065 hr = IDirectInputDevice8_SetDataFormat( device, &c_dfDIJoystick2 );
3066 ok( hr == DI_OK, "SetDataFormat returned: %#lx\n", hr );
3068 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GUIDANDPATH, &prop_guid_path.diph );
3069 ok( hr == DI_OK, "GetProperty DIPROP_GUIDANDPATH returned %#lx\n", hr );
3071 file = CreateFileW( prop_guid_path.wszPath, FILE_READ_ACCESS | FILE_WRITE_ACCESS,
3072 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
3073 FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL );
3074 ok( file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError() );
3076 hwnd = CreateWindowW( L"static", L"dinput", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 10, 10, 200, 200,
3077 NULL, NULL, NULL, NULL );
3079 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE );
3080 ok( hr == DI_OK, "SetCooperativeLevel returned: %#lx\n", hr );
3082 prop_dword.diph.dwHow = DIPH_BYUSAGE;
3083 prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC );
3084 prop_dword.dwData = DIPROPAUTOCENTER_ON;
3085 hr = IDirectInputDevice8_SetProperty( device, DIPROP_AUTOCENTER, &prop_dword.diph );
3086 ok( hr == DIERR_UNSUPPORTED, "SetProperty DIPROP_AUTOCENTER returned %#lx\n", hr );
3087 prop_dword.diph.dwHow = DIPH_DEVICE;
3088 prop_dword.diph.dwObj = 0;
3089 hr = IDirectInputDevice8_SetProperty( device, DIPROP_AUTOCENTER, &prop_dword.diph );
3090 ok( hr == DI_OK, "SetProperty DIPROP_AUTOCENTER returned %#lx\n", hr );
3092 hr = IDirectInputDevice8_Acquire( device );
3093 ok( hr == DI_OK, "Acquire returned: %#lx\n", hr );
3095 prop_dword.dwData = 0xdeadbeef;
3096 hr = IDirectInputDevice8_SetProperty( device, DIPROP_FFGAIN, &prop_dword.diph );
3097 ok( hr == DIERR_INVALIDPARAM, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr );
3098 prop_dword.dwData = 1000;
3099 hr = IDirectInputDevice8_SetProperty( device, DIPROP_FFGAIN, &prop_dword.diph );
3100 ok( hr == DI_OK, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr );
3102 prop_dword.dwData = 0xdeadbeef;
3103 hr = IDirectInputDevice8_SetProperty( device, DIPROP_FFLOAD, &prop_dword.diph );
3104 ok( hr == DIERR_READONLY, "SetProperty DIPROP_FFLOAD returned %#lx\n", hr );
3105 hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFLOAD, &prop_dword.diph );
3106 ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr );
3107 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
3108 ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "GetForceFeedbackState returned %#lx\n", hr );
3109 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_RESET );
3110 ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "SendForceFeedbackCommand returned %#lx\n", hr );
3112 escape.dwSize = sizeof(DIEFFESCAPE);
3113 escape.dwCommand = 0;
3114 escape.lpvInBuffer = buffer;
3115 escape.cbInBuffer = 10;
3116 escape.lpvOutBuffer = buffer + 10;
3117 escape.cbOutBuffer = 10;
3118 hr = IDirectInputDevice8_Escape( device, &escape );
3119 todo_wine
3120 ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "Escape returned: %#lx\n", hr );
3122 hr = IDirectInputDevice8_Unacquire( device );
3123 ok( hr == DI_OK, "Unacquire returned: %#lx\n", hr );
3124 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND | DISCL_EXCLUSIVE );
3125 ok( hr == DI_OK, "SetCooperativeLevel returned: %#lx\n", hr );
3126 prop_dword.dwData = DIPROPAUTOCENTER_ON;
3127 hr = IDirectInputDevice8_SetProperty( device, DIPROP_AUTOCENTER, &prop_dword.diph );
3128 ok( hr == DI_OK, "SetProperty DIPROP_AUTOCENTER returned %#lx\n", hr );
3130 set_hid_expect( file, expect_acquire, sizeof(expect_acquire) );
3131 hr = IDirectInputDevice8_Acquire( device );
3132 ok( hr == DI_OK, "Acquire returned: %#lx\n", hr );
3133 wait_hid_expect( file, 100 ); /* device gain reports are written asynchronously */
3135 set_hid_expect( file, &expect_set_device_gain_2, sizeof(expect_set_device_gain_2) );
3136 prop_dword.dwData = 2000;
3137 hr = IDirectInputDevice8_SetProperty( device, DIPROP_FFGAIN, &prop_dword.diph );
3138 ok( hr == DI_OK, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr );
3139 wait_hid_expect( file, 100 ); /* device gain reports are written asynchronously */
3141 set_hid_expect( file, &expect_set_device_gain_1, sizeof(expect_set_device_gain_1) );
3142 prop_dword.dwData = 1000;
3143 hr = IDirectInputDevice8_SetProperty( device, DIPROP_FFGAIN, &prop_dword.diph );
3144 ok( hr == DI_OK, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr );
3145 wait_hid_expect( file, 100 ); /* device gain reports are written asynchronously */
3147 hr = IDirectInputDevice8_Escape( device, &escape );
3148 todo_wine
3149 ok( hr == DIERR_UNSUPPORTED, "Escape returned: %#lx\n", hr );
3151 prop_dword.dwData = 0xdeadbeef;
3152 hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFLOAD, &prop_dword.diph );
3153 todo_wine
3154 ok( hr == 0x80040301, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr );
3155 res = 0xdeadbeef;
3156 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
3157 todo_wine
3158 ok( hr == 0x80040301, "GetForceFeedbackState returned %#lx\n", hr );
3160 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, 0xdeadbeef );
3161 ok( hr == DIERR_INVALIDPARAM, "SendForceFeedbackCommand returned %#lx\n", hr );
3163 set_hid_expect( file, expect_acquire, sizeof(expect_acquire) );
3164 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_RESET );
3165 ok( hr == DI_OK, "SendForceFeedbackCommand returned %#lx\n", hr );
3166 wait_hid_expect( file, 100 ); /* device gain reports are written asynchronously */
3168 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_STOPALL );
3169 ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "SendForceFeedbackCommand returned %#lx\n", hr );
3170 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_PAUSE );
3171 ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "SendForceFeedbackCommand returned %#lx\n", hr );
3172 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_CONTINUE );
3173 ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "SendForceFeedbackCommand returned %#lx\n", hr );
3174 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_SETACTUATORSON );
3175 ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "SendForceFeedbackCommand returned %#lx\n", hr );
3176 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_SETACTUATORSOFF );
3177 ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "SendForceFeedbackCommand returned %#lx\n", hr );
3179 objdata.dwOfs = 0x1e;
3180 objdata.dwData = 0x80;
3181 res = 1;
3182 hr = IDirectInputDevice8_SendDeviceData( device, sizeof(DIDEVICEOBJECTDATA), &objdata, &res, 0 );
3183 if (version < 0x800) ok( hr == DI_OK, "SendDeviceData returned %#lx\n", hr );
3184 else todo_wine ok( hr == DIERR_INVALIDPARAM, "SendDeviceData returned %#lx\n", hr );
3186 test_periodic_effect( device, file, version );
3187 test_condition_effect( device, file, version );
3189 set_hid_expect( file, expect_reset, sizeof(expect_reset) );
3190 hr = IDirectInputDevice8_Unacquire( device );
3191 ok( hr == DI_OK, "Unacquire returned: %#lx\n", hr );
3192 set_hid_expect( file, NULL, 0 );
3194 ref = IDirectInputDevice8_Release( device );
3195 ok( ref == 0, "Release returned %ld\n", ref );
3197 DestroyWindow( hwnd );
3198 CloseHandle( file );
3200 done:
3201 hid_device_stop( &desc, 1 );
3202 cleanup_registry_keys();
3203 winetest_pop_context();
3205 return device != NULL;
3208 static void test_device_managed_effect(void)
3210 #include "psh_hid_macros.h"
3211 const unsigned char report_descriptor[] = {
3212 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
3213 USAGE(1, HID_USAGE_GENERIC_JOYSTICK),
3214 COLLECTION(1, Application),
3215 USAGE(1, HID_USAGE_GENERIC_JOYSTICK),
3216 COLLECTION(1, Report),
3217 REPORT_ID(1, 1),
3219 USAGE(1, HID_USAGE_GENERIC_X),
3220 USAGE(1, HID_USAGE_GENERIC_Y),
3221 USAGE(1, HID_USAGE_GENERIC_Z),
3222 LOGICAL_MINIMUM(1, 0),
3223 LOGICAL_MAXIMUM(1, 0x7f),
3224 PHYSICAL_MINIMUM(1, 0),
3225 PHYSICAL_MAXIMUM(1, 0x7f),
3226 REPORT_SIZE(1, 8),
3227 REPORT_COUNT(1, 3),
3228 INPUT(1, Data|Var|Abs),
3230 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON),
3231 USAGE_MINIMUM(1, 1),
3232 USAGE_MAXIMUM(1, 2),
3233 LOGICAL_MINIMUM(1, 0),
3234 LOGICAL_MAXIMUM(1, 1),
3235 PHYSICAL_MINIMUM(1, 0),
3236 PHYSICAL_MAXIMUM(1, 1),
3237 REPORT_SIZE(1, 1),
3238 REPORT_COUNT(1, 2),
3239 INPUT(1, Data|Var|Abs),
3240 REPORT_COUNT(1, 6),
3241 INPUT(1, Cnst|Var|Abs),
3242 END_COLLECTION,
3244 USAGE_PAGE(1, HID_USAGE_PAGE_PID),
3245 USAGE(1, PID_USAGE_STATE_REPORT),
3246 COLLECTION(1, Report),
3247 REPORT_ID(1, 2),
3249 USAGE(1, PID_USAGE_DEVICE_PAUSED),
3250 USAGE(1, PID_USAGE_ACTUATORS_ENABLED),
3251 USAGE(1, PID_USAGE_SAFETY_SWITCH),
3252 USAGE(1, PID_USAGE_ACTUATOR_OVERRIDE_SWITCH),
3253 USAGE(1, PID_USAGE_ACTUATOR_POWER),
3254 LOGICAL_MINIMUM(1, 0),
3255 LOGICAL_MAXIMUM(1, 1),
3256 PHYSICAL_MINIMUM(1, 0),
3257 PHYSICAL_MAXIMUM(1, 1),
3258 REPORT_SIZE(1, 1),
3259 REPORT_COUNT(1, 5),
3260 INPUT(1, Data|Var|Abs),
3261 REPORT_COUNT(1, 3),
3262 INPUT(1, Cnst|Var|Abs),
3264 USAGE(1, PID_USAGE_EFFECT_PLAYING),
3265 LOGICAL_MINIMUM(1, 0),
3266 LOGICAL_MAXIMUM(1, 1),
3267 PHYSICAL_MINIMUM(1, 0),
3268 PHYSICAL_MAXIMUM(1, 1),
3269 REPORT_SIZE(1, 1),
3270 REPORT_COUNT(1, 8),
3271 INPUT(1, Data|Var|Abs),
3273 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
3274 LOGICAL_MINIMUM(1, 1),
3275 LOGICAL_MAXIMUM(1, 0x7f),
3276 PHYSICAL_MINIMUM(1, 1),
3277 PHYSICAL_MAXIMUM(1, 0x7f),
3278 REPORT_SIZE(1, 8),
3279 REPORT_COUNT(1, 1),
3280 INPUT(1, Data|Var|Abs),
3281 END_COLLECTION,
3283 USAGE_PAGE(1, HID_USAGE_PAGE_PID),
3284 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT),
3285 COLLECTION(1, Report),
3286 REPORT_ID(1, 1),
3288 USAGE(1, PID_USAGE_DEVICE_CONTROL),
3289 COLLECTION(1, Logical),
3290 USAGE(1, PID_USAGE_DC_DEVICE_RESET),
3291 USAGE(1, PID_USAGE_DC_DEVICE_PAUSE),
3292 USAGE(1, PID_USAGE_DC_DEVICE_CONTINUE),
3293 USAGE(1, PID_USAGE_DC_ENABLE_ACTUATORS),
3294 USAGE(1, PID_USAGE_DC_DISABLE_ACTUATORS),
3295 USAGE(1, PID_USAGE_DC_STOP_ALL_EFFECTS),
3296 LOGICAL_MINIMUM(1, 1),
3297 LOGICAL_MAXIMUM(1, 6),
3298 PHYSICAL_MINIMUM(1, 1),
3299 PHYSICAL_MAXIMUM(1, 6),
3300 REPORT_SIZE(1, 8),
3301 REPORT_COUNT(1, 1),
3302 OUTPUT(1, Data|Ary|Abs),
3303 END_COLLECTION,
3304 END_COLLECTION,
3306 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT),
3307 COLLECTION(1, Report),
3308 REPORT_ID(1, 2),
3310 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
3311 LOGICAL_MINIMUM(1, 1),
3312 LOGICAL_MAXIMUM(1, 0x7f),
3313 PHYSICAL_MINIMUM(1, 1),
3314 PHYSICAL_MAXIMUM(1, 0x7f),
3315 REPORT_SIZE(1, 8),
3316 REPORT_COUNT(1, 1),
3317 OUTPUT(1, Data|Var|Abs),
3319 USAGE(1, PID_USAGE_EFFECT_OPERATION),
3320 COLLECTION(1, NamedArray),
3321 USAGE(1, PID_USAGE_OP_EFFECT_START),
3322 USAGE(1, PID_USAGE_OP_EFFECT_START_SOLO),
3323 USAGE(1, PID_USAGE_OP_EFFECT_STOP),
3324 LOGICAL_MINIMUM(1, 1),
3325 LOGICAL_MAXIMUM(1, 3),
3326 PHYSICAL_MINIMUM(1, 1),
3327 PHYSICAL_MAXIMUM(1, 3),
3328 REPORT_SIZE(1, 8),
3329 REPORT_COUNT(1, 1),
3330 OUTPUT(1, Data|Ary|Abs),
3331 END_COLLECTION,
3333 USAGE(1, PID_USAGE_LOOP_COUNT),
3334 LOGICAL_MINIMUM(1, 0),
3335 LOGICAL_MAXIMUM(1, 0x7f),
3336 PHYSICAL_MINIMUM(1, 0),
3337 PHYSICAL_MAXIMUM(1, 0x7f),
3338 REPORT_SIZE(1, 8),
3339 REPORT_COUNT(1, 1),
3340 OUTPUT(1, Data|Var|Abs),
3341 END_COLLECTION,
3343 USAGE(1, PID_USAGE_SET_EFFECT_REPORT),
3344 COLLECTION(1, Report),
3345 REPORT_ID(1, 3),
3347 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
3348 LOGICAL_MINIMUM(1, 1),
3349 LOGICAL_MAXIMUM(1, 0x7f),
3350 PHYSICAL_MINIMUM(1, 1),
3351 PHYSICAL_MAXIMUM(1, 0x7f),
3352 REPORT_SIZE(1, 8),
3353 REPORT_COUNT(1, 1),
3354 OUTPUT(1, Data|Var|Abs),
3356 USAGE(1, PID_USAGE_EFFECT_TYPE),
3357 COLLECTION(1, NamedArray),
3358 USAGE(1, PID_USAGE_ET_SQUARE),
3359 USAGE(1, PID_USAGE_ET_SINE),
3360 USAGE(1, PID_USAGE_ET_SPRING),
3361 LOGICAL_MINIMUM(1, 1),
3362 LOGICAL_MAXIMUM(1, 3),
3363 PHYSICAL_MINIMUM(1, 1),
3364 PHYSICAL_MAXIMUM(1, 3),
3365 REPORT_SIZE(1, 8),
3366 REPORT_COUNT(1, 1),
3367 OUTPUT(1, Data|Ary|Abs),
3368 END_COLLECTION,
3370 USAGE(1, PID_USAGE_AXES_ENABLE),
3371 COLLECTION(1, Logical),
3372 USAGE(4, (HID_USAGE_PAGE_GENERIC << 16)|HID_USAGE_GENERIC_X),
3373 USAGE(4, (HID_USAGE_PAGE_GENERIC << 16)|HID_USAGE_GENERIC_Y),
3374 USAGE(4, (HID_USAGE_PAGE_GENERIC << 16)|HID_USAGE_GENERIC_Z),
3375 LOGICAL_MINIMUM(1, 0),
3376 LOGICAL_MAXIMUM(1, 1),
3377 PHYSICAL_MINIMUM(1, 0),
3378 PHYSICAL_MAXIMUM(1, 1),
3379 REPORT_SIZE(1, 1),
3380 REPORT_COUNT(1, 3),
3381 OUTPUT(1, Data|Var|Abs),
3382 END_COLLECTION,
3383 USAGE(1, PID_USAGE_DIRECTION_ENABLE),
3384 REPORT_COUNT(1, 1),
3385 OUTPUT(1, Data|Var|Abs),
3386 REPORT_COUNT(1, 4),
3387 OUTPUT(1, Cnst|Var|Abs),
3389 USAGE(1, PID_USAGE_DURATION),
3390 USAGE(1, PID_USAGE_START_DELAY),
3391 UNIT(2, 0x1003), /* Eng Lin:Time */
3392 UNIT_EXPONENT(1, -3), /* 10^-3 */
3393 LOGICAL_MINIMUM(1, 0),
3394 LOGICAL_MAXIMUM(2, 0x7fff),
3395 PHYSICAL_MINIMUM(1, 0),
3396 PHYSICAL_MAXIMUM(2, 0x7fff),
3397 REPORT_SIZE(1, 16),
3398 REPORT_COUNT(1, 2),
3399 OUTPUT(1, Data|Var|Abs),
3400 UNIT(1, 0),
3401 UNIT_EXPONENT(1, 0),
3403 USAGE(1, PID_USAGE_TRIGGER_BUTTON),
3404 LOGICAL_MINIMUM(1, 1),
3405 LOGICAL_MAXIMUM(1, 0x08),
3406 PHYSICAL_MINIMUM(1, 1),
3407 PHYSICAL_MAXIMUM(1, 0x08),
3408 REPORT_SIZE(1, 8),
3409 REPORT_COUNT(1, 1),
3410 OUTPUT(1, Data|Var|Abs),
3412 USAGE(1, PID_USAGE_DIRECTION),
3413 COLLECTION(1, Logical),
3414 USAGE(4, (HID_USAGE_PAGE_ORDINAL << 16)|1),
3415 USAGE(4, (HID_USAGE_PAGE_ORDINAL << 16)|2),
3416 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
3417 UNIT_EXPONENT(1, -2), /* 10^-2 */
3418 LOGICAL_MINIMUM(1, 0),
3419 LOGICAL_MAXIMUM(2, 0x00ff),
3420 PHYSICAL_MINIMUM(1, 0),
3421 PHYSICAL_MAXIMUM(4, 0x00008ca0),
3422 UNIT(1, 0),
3423 REPORT_SIZE(1, 8),
3424 REPORT_COUNT(1, 2),
3425 OUTPUT(1, Data|Var|Abs),
3426 UNIT_EXPONENT(1, 0),
3427 UNIT(1, 0),
3428 END_COLLECTION,
3429 END_COLLECTION,
3431 USAGE(1, PID_USAGE_SET_CONDITION_REPORT),
3432 COLLECTION(1, Logical),
3433 REPORT_ID(1, 4),
3435 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
3436 LOGICAL_MINIMUM(1, 1),
3437 LOGICAL_MAXIMUM(1, 0x7f),
3438 PHYSICAL_MINIMUM(1, 1),
3439 PHYSICAL_MAXIMUM(1, 0x7f),
3440 REPORT_SIZE(1, 8),
3441 REPORT_COUNT(1, 1),
3442 OUTPUT(1, Data|Var|Abs),
3444 USAGE(1, PID_USAGE_PARAMETER_BLOCK_OFFSET),
3445 LOGICAL_MINIMUM(1, 0),
3446 LOGICAL_MAXIMUM(1, 1),
3447 PHYSICAL_MINIMUM(1, 0),
3448 PHYSICAL_MAXIMUM(1, 1),
3449 REPORT_SIZE(1, 4),
3450 REPORT_COUNT(1, 1),
3451 OUTPUT(1, Data|Var|Abs),
3453 USAGE(1, PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET),
3454 COLLECTION(1, Logical),
3455 USAGE(4, (HID_USAGE_PAGE_ORDINAL << 16)|1),
3456 USAGE(4, (HID_USAGE_PAGE_ORDINAL << 16)|2),
3457 LOGICAL_MINIMUM(1, 0),
3458 LOGICAL_MAXIMUM(1, 1),
3459 PHYSICAL_MINIMUM(1, 0),
3460 PHYSICAL_MAXIMUM(1, 1),
3461 REPORT_SIZE(1, 2),
3462 REPORT_COUNT(1, 2),
3463 OUTPUT(1, Data|Var|Abs),
3464 END_COLLECTION,
3466 USAGE(1, PID_USAGE_CP_OFFSET),
3467 LOGICAL_MINIMUM(1, 0x80),
3468 LOGICAL_MAXIMUM(1, 0x7f),
3469 PHYSICAL_MINIMUM(2, 0xd8f0),
3470 PHYSICAL_MAXIMUM(2, 0x2710),
3471 REPORT_SIZE(1, 8),
3472 REPORT_COUNT(1, 1),
3473 OUTPUT(1, Data|Var|Abs),
3475 USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT),
3476 USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT),
3477 LOGICAL_MINIMUM(1, 0x80),
3478 LOGICAL_MAXIMUM(1, 0x7f),
3479 PHYSICAL_MINIMUM(2, 0xd8f0),
3480 PHYSICAL_MAXIMUM(2, 0x2710),
3481 REPORT_SIZE(1, 8),
3482 REPORT_COUNT(1, 2),
3483 OUTPUT(1, Data|Var|Abs),
3485 USAGE(1, PID_USAGE_POSITIVE_SATURATION),
3486 USAGE(1, PID_USAGE_NEGATIVE_SATURATION),
3487 LOGICAL_MINIMUM(1, 0),
3488 LOGICAL_MAXIMUM(2, 0x00ff),
3489 PHYSICAL_MINIMUM(1, 0),
3490 PHYSICAL_MAXIMUM(2, 0x2710),
3491 REPORT_SIZE(1, 8),
3492 REPORT_COUNT(1, 2),
3493 OUTPUT(1, Data|Var|Abs),
3495 USAGE(1, PID_USAGE_DEAD_BAND),
3496 LOGICAL_MINIMUM(1, 0),
3497 LOGICAL_MAXIMUM(2, 0x00ff),
3498 PHYSICAL_MINIMUM(1, 0),
3499 PHYSICAL_MAXIMUM(2, 0x2710),
3500 REPORT_SIZE(1, 8),
3501 REPORT_COUNT(1, 1),
3502 OUTPUT(1, Data|Var|Abs),
3503 END_COLLECTION,
3505 USAGE(1, PID_USAGE_BLOCK_FREE_REPORT),
3506 COLLECTION(1, Logical),
3507 REPORT_ID(1, 5),
3509 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
3510 LOGICAL_MINIMUM(1, 1),
3511 LOGICAL_MAXIMUM(1, 0x7f),
3512 PHYSICAL_MINIMUM(1, 1),
3513 PHYSICAL_MAXIMUM(1, 0x7f),
3514 REPORT_SIZE(1, 8),
3515 REPORT_COUNT(1, 1),
3516 OUTPUT(1, Data|Var|Abs),
3517 END_COLLECTION,
3519 USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT),
3520 COLLECTION(1, Logical),
3521 REPORT_ID(1, 6),
3523 USAGE(1, PID_USAGE_DEVICE_GAIN),
3524 LOGICAL_MINIMUM(1, 0),
3525 LOGICAL_MAXIMUM(2, 0x00ff),
3526 PHYSICAL_MINIMUM(1, 0),
3527 PHYSICAL_MAXIMUM(2, 0x2710),
3528 REPORT_SIZE(1, 8),
3529 REPORT_COUNT(1, 1),
3530 OUTPUT(1, Data|Var|Abs),
3531 END_COLLECTION,
3533 USAGE(1, PID_USAGE_POOL_REPORT),
3534 COLLECTION(1, Logical),
3535 REPORT_ID(1, 1),
3537 USAGE(1, PID_USAGE_RAM_POOL_SIZE),
3538 LOGICAL_MINIMUM(1, 0),
3539 LOGICAL_MAXIMUM(4, 0xffff),
3540 PHYSICAL_MINIMUM(1, 0),
3541 PHYSICAL_MAXIMUM(4, 0xffff),
3542 REPORT_SIZE(1, 16),
3543 REPORT_COUNT(1, 1),
3544 FEATURE(1, Data|Var|Abs),
3546 USAGE(1, PID_USAGE_SIMULTANEOUS_EFFECTS_MAX),
3547 LOGICAL_MINIMUM(1, 0),
3548 LOGICAL_MAXIMUM(1, 0x7f),
3549 PHYSICAL_MINIMUM(1, 0),
3550 PHYSICAL_MAXIMUM(1, 0x7f),
3551 REPORT_SIZE(1, 8),
3552 REPORT_COUNT(1, 1),
3553 FEATURE(1, Data|Var|Abs),
3555 USAGE(1, PID_USAGE_DEVICE_MANAGED_POOL),
3556 USAGE(1, PID_USAGE_SHARED_PARAMETER_BLOCKS),
3557 LOGICAL_MINIMUM(1, 0),
3558 LOGICAL_MAXIMUM(1, 1),
3559 PHYSICAL_MINIMUM(1, 0),
3560 PHYSICAL_MAXIMUM(1, 1),
3561 REPORT_SIZE(1, 1),
3562 REPORT_COUNT(1, 8),
3563 FEATURE(1, Data|Var|Abs),
3564 END_COLLECTION,
3566 USAGE(1, PID_USAGE_CREATE_NEW_EFFECT_REPORT),
3567 COLLECTION(1, Logical),
3568 REPORT_ID(1, 2),
3570 USAGE(1, PID_USAGE_EFFECT_TYPE),
3571 COLLECTION(1, NamedArray),
3572 USAGE(1, PID_USAGE_ET_SQUARE),
3573 USAGE(1, PID_USAGE_ET_SINE),
3574 USAGE(1, PID_USAGE_ET_SPRING),
3575 LOGICAL_MINIMUM(1, 1),
3576 LOGICAL_MAXIMUM(1, 3),
3577 PHYSICAL_MINIMUM(1, 1),
3578 PHYSICAL_MAXIMUM(1, 3),
3579 REPORT_SIZE(1, 8),
3580 REPORT_COUNT(1, 1),
3581 FEATURE(1, Data|Ary|Abs),
3582 END_COLLECTION,
3583 END_COLLECTION,
3585 USAGE(1, PID_USAGE_BLOCK_LOAD_REPORT),
3586 COLLECTION(1, Logical),
3587 REPORT_ID(1, 3),
3589 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
3590 LOGICAL_MINIMUM(1, 1),
3591 LOGICAL_MAXIMUM(1, 0x7f),
3592 PHYSICAL_MINIMUM(1, 1),
3593 PHYSICAL_MAXIMUM(1, 0x7f),
3594 REPORT_SIZE(1, 8),
3595 REPORT_COUNT(1, 1),
3596 FEATURE(1, Data|Var|Abs),
3598 USAGE(1, PID_USAGE_BLOCK_LOAD_STATUS),
3599 COLLECTION(1, NamedArray),
3600 USAGE(1, PID_USAGE_BLOCK_LOAD_SUCCESS),
3601 USAGE(1, PID_USAGE_BLOCK_LOAD_FULL),
3602 USAGE(1, PID_USAGE_BLOCK_LOAD_ERROR),
3603 LOGICAL_MINIMUM(1, 1),
3604 LOGICAL_MAXIMUM(1, 3),
3605 PHYSICAL_MINIMUM(1, 1),
3606 PHYSICAL_MAXIMUM(1, 3),
3607 REPORT_SIZE(1, 8),
3608 REPORT_COUNT(1, 1),
3609 FEATURE(1, Data|Ary|Abs),
3610 END_COLLECTION,
3612 USAGE(1, PID_USAGE_RAM_POOL_AVAILABLE),
3613 LOGICAL_MINIMUM(1, 0),
3614 LOGICAL_MAXIMUM(4, 0xffff),
3615 PHYSICAL_MINIMUM(1, 0),
3616 PHYSICAL_MAXIMUM(4, 0xffff),
3617 REPORT_SIZE(1, 16),
3618 REPORT_COUNT(1, 1),
3619 FEATURE(1, Data|Var|Abs),
3620 END_COLLECTION,
3621 END_COLLECTION,
3623 C_ASSERT(sizeof(report_descriptor) < MAX_HID_DESCRIPTOR_LEN);
3624 #include "pop_hid_macros.h"
3626 struct hid_device_desc desc =
3628 .use_report_id = TRUE,
3629 .caps =
3631 .InputReportByteLength = 5,
3632 .OutputReportByteLength = 11,
3633 .FeatureReportByteLength = 5,
3635 .attributes = default_attributes,
3637 struct hid_expect expect_acquire[] =
3639 /* device control */
3641 .code = IOCTL_HID_WRITE_REPORT,
3642 .report_id = 1,
3643 .report_len = 2,
3644 .report_buf = {1, 0x01},
3646 /* device gain */
3648 .code = IOCTL_HID_WRITE_REPORT,
3649 .report_id = 6,
3650 .report_len = 2,
3651 .report_buf = {6, 0xff},
3654 struct hid_expect expect_reset[] =
3656 /* device control */
3658 .code = IOCTL_HID_WRITE_REPORT,
3659 .report_id = 1,
3660 .report_len = 2,
3661 .report_buf = {1, 0x01},
3664 struct hid_expect expect_enable_actuators[] =
3666 /* device control */
3668 .code = IOCTL_HID_WRITE_REPORT,
3669 .report_id = 1,
3670 .report_len = 2,
3671 .report_buf = {1, 0x04},
3674 struct hid_expect expect_disable_actuators[] =
3676 /* device control */
3678 .code = IOCTL_HID_WRITE_REPORT,
3679 .report_id = 1,
3680 .report_len = 2,
3681 .report_buf = {1, 0x05},
3684 struct hid_expect expect_stop_all[] =
3686 /* device control */
3688 .code = IOCTL_HID_WRITE_REPORT,
3689 .report_id = 1,
3690 .report_len = 2,
3691 .report_buf = {1, 0x06},
3694 struct hid_expect expect_device_pause[] =
3696 /* device control */
3698 .code = IOCTL_HID_WRITE_REPORT,
3699 .report_id = 1,
3700 .report_len = 2,
3701 .report_buf = {1, 0x02},
3704 struct hid_expect expect_device_continue[] =
3706 /* device control */
3708 .code = IOCTL_HID_WRITE_REPORT,
3709 .report_id = 1,
3710 .report_len = 2,
3711 .report_buf = {1, 0x03},
3714 struct hid_expect expect_create[] =
3716 /* create new effect */
3718 .code = IOCTL_HID_SET_FEATURE,
3719 .report_id = 2,
3720 .report_len = 2,
3721 .report_buf = {2,0x03},
3723 /* block load */
3725 .code = IOCTL_HID_GET_FEATURE,
3726 .report_id = 3,
3727 .report_len = 5,
3728 .report_buf = {3,0x01,0x01,0x00,0x00},
3730 /* set condition */
3732 .code = IOCTL_HID_WRITE_REPORT,
3733 .report_id = 4,
3734 .report_len = 9,
3735 .report_buf = {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
3737 /* set condition */
3739 .code = IOCTL_HID_WRITE_REPORT,
3740 .report_id = 4,
3741 .report_len = 9,
3742 .report_buf = {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
3744 /* update effect */
3746 .code = IOCTL_HID_WRITE_REPORT,
3747 .report_id = 3,
3748 .report_len = 11,
3749 .report_buf = {3,0x01,0x03,0x08,0x01,0x00,0x06,0x00,0x01,0x55,0x00},
3752 struct hid_expect expect_create_2[] =
3754 /* create new effect */
3756 .code = IOCTL_HID_SET_FEATURE,
3757 .report_id = 2,
3758 .report_len = 2,
3759 .report_buf = {2,0x03},
3761 /* block load */
3763 .code = IOCTL_HID_GET_FEATURE,
3764 .report_id = 3,
3765 .report_len = 5,
3766 .report_buf = {3,0x02,0x01,0x00,0x00},
3768 /* set condition */
3770 .code = IOCTL_HID_WRITE_REPORT,
3771 .report_id = 4,
3772 .report_len = 9,
3773 .report_buf = {4,0x02,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
3775 /* set condition */
3777 .code = IOCTL_HID_WRITE_REPORT,
3778 .report_id = 4,
3779 .report_len = 9,
3780 .report_buf = {4,0x02,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
3782 /* update effect */
3784 .code = IOCTL_HID_WRITE_REPORT,
3785 .report_id = 3,
3786 .report_len = 11,
3787 .report_buf = {3,0x02,0x03,0x08,0x01,0x00,0x06,0x00,0x01,0x55,0x00},
3790 struct hid_expect expect_create_delay[] =
3792 /* create new effect */
3794 .code = IOCTL_HID_SET_FEATURE,
3795 .report_id = 2,
3796 .report_len = 2,
3797 .report_buf = {2,0x03},
3799 /* block load */
3801 .code = IOCTL_HID_GET_FEATURE,
3802 .report_id = 3,
3803 .report_len = 5,
3804 .report_buf = {3,0x01,0x01,0x00,0x00},
3806 /* set condition */
3808 .code = IOCTL_HID_WRITE_REPORT,
3809 .report_id = 4,
3810 .report_len = 9,
3811 .report_buf = {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
3813 /* set condition */
3815 .code = IOCTL_HID_WRITE_REPORT,
3816 .report_id = 4,
3817 .report_len = 9,
3818 .report_buf = {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
3820 /* update effect */
3822 .code = IOCTL_HID_WRITE_REPORT,
3823 .report_id = 3,
3824 .report_len = 11,
3825 .report_buf = {3,0x01,0x03,0x08,0x01,0x00,0xff,0x7f,0x01,0x55,0x00},
3828 struct hid_expect expect_create_duration[] =
3830 /* create new effect */
3832 .code = IOCTL_HID_SET_FEATURE,
3833 .report_id = 2,
3834 .report_len = 2,
3835 .report_buf = {2,0x03},
3837 /* block load */
3839 .code = IOCTL_HID_GET_FEATURE,
3840 .report_id = 3,
3841 .report_len = 5,
3842 .report_buf = {3,0x01,0x01,0x00,0x00},
3844 /* set condition */
3846 .code = IOCTL_HID_WRITE_REPORT,
3847 .report_id = 4,
3848 .report_len = 9,
3849 .report_buf = {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
3851 /* set condition */
3853 .code = IOCTL_HID_WRITE_REPORT,
3854 .report_id = 4,
3855 .report_len = 9,
3856 .report_buf = {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
3858 /* update effect */
3860 .code = IOCTL_HID_WRITE_REPORT,
3861 .report_id = 3,
3862 .report_len = 11,
3863 .report_buf = {3,0x01,0x03,0x08,0x00,0x00,0x00,0x00,0x01,0x55,0x00},
3866 struct hid_expect expect_start =
3868 /* effect control */
3869 .code = IOCTL_HID_WRITE_REPORT,
3870 .report_id = 2,
3871 .report_len = 4,
3872 .report_buf = {2, 0x01, 0x01, 0x01},
3874 struct hid_expect expect_start_2 =
3876 /* effect control */
3877 .code = IOCTL_HID_WRITE_REPORT,
3878 .report_id = 2,
3879 .report_len = 4,
3880 .report_buf = {2, 0x02, 0x02, 0x01},
3882 struct hid_expect expect_stop =
3884 /* effect control */
3885 .code = IOCTL_HID_WRITE_REPORT,
3886 .report_id = 2,
3887 .report_len = 4,
3888 .report_buf = {2, 0x01, 0x03, 0x00},
3890 struct hid_expect expect_stop_2 =
3892 /* effect control */
3893 .code = IOCTL_HID_WRITE_REPORT,
3894 .report_id = 2,
3895 .report_len = 4,
3896 .report_buf = {2, 0x02, 0x03, 0x00},
3898 struct hid_expect expect_destroy[] =
3900 /* effect operation */
3902 .code = IOCTL_HID_WRITE_REPORT,
3903 .report_id = 2,
3904 .report_len = 4,
3905 .report_buf = {2,0x01,0x03,0x00},
3907 /* block free */
3909 .code = IOCTL_HID_WRITE_REPORT,
3910 .report_id = 5,
3911 .report_len = 2,
3912 .report_buf = {5,0x01},
3915 struct hid_expect expect_destroy_2[] =
3917 /* effect operation */
3919 .code = IOCTL_HID_WRITE_REPORT,
3920 .report_id = 2,
3921 .report_len = 4,
3922 .report_buf = {2,0x02,0x03,0x00},
3924 /* block free */
3926 .code = IOCTL_HID_WRITE_REPORT,
3927 .report_id = 5,
3928 .report_len = 2,
3929 .report_buf = {5,0x02},
3932 struct hid_expect device_state_input[] =
3934 /* effect state */
3936 .code = IOCTL_HID_READ_REPORT,
3937 .report_id = 2,
3938 .report_len = 4,
3939 .report_buf = {2,0xff,0x00,0xff},
3941 /* device state */
3943 .code = IOCTL_HID_READ_REPORT,
3944 .report_id = 1,
3945 .report_len = 5,
3946 .report_buf = {1,0x12,0x34,0x56,0xff},
3949 struct hid_expect device_state_input_0[] =
3951 /* effect state */
3953 .code = IOCTL_HID_READ_REPORT,
3954 .report_id = 2,
3955 .report_len = 4,
3956 .report_buf = {2,0xff,0x00,0xff},
3958 /* device state */
3960 .code = IOCTL_HID_READ_REPORT,
3961 .report_id = 1,
3962 .report_len = 5,
3963 .report_buf = {1,0x56,0x12,0x34,0xff},
3966 struct hid_expect device_state_input_1[] =
3968 /* effect state */
3970 .code = IOCTL_HID_READ_REPORT,
3971 .report_id = 2,
3972 .report_len = 4,
3973 .report_buf = {2,0x00,0x01,0x01},
3975 /* device state */
3977 .code = IOCTL_HID_READ_REPORT,
3978 .report_id = 1,
3979 .report_len = 5,
3980 .report_buf = {1,0x65,0x43,0x21,0x00},
3983 struct hid_expect device_state_input_2[] =
3985 /* effect state */
3987 .code = IOCTL_HID_READ_REPORT,
3988 .report_id = 2,
3989 .report_len = 4,
3990 .report_buf = {2,0x03,0x00,0x01},
3992 /* device state */
3994 .code = IOCTL_HID_READ_REPORT,
3995 .report_id = 1,
3996 .report_len = 5,
3997 .report_buf = {1,0x12,0x34,0x56,0xff},
4000 struct hid_expect expect_pool[] =
4002 /* device pool */
4004 .code = IOCTL_HID_GET_FEATURE,
4005 .report_id = 1,
4006 .report_len = 5,
4007 .report_buf = {1,0x10,0x00,0x04,0x03},
4008 .todo = TRUE,
4010 /* device pool */
4012 .code = IOCTL_HID_GET_FEATURE,
4013 .report_id = 1,
4014 .report_len = 5,
4015 .report_buf = {1,0x10,0x00,0x04,0x03},
4016 .todo = TRUE,
4019 static const DWORD expect_axes[3] =
4021 DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR,
4022 DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR,
4023 DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR,
4025 static const LONG expect_directions[3] = {
4026 +3000,
4030 static const DIENVELOPE expect_envelope =
4032 .dwSize = sizeof(DIENVELOPE),
4033 .dwAttackLevel = 1000,
4034 .dwAttackTime = 2000,
4035 .dwFadeLevel = 3000,
4036 .dwFadeTime = 4000,
4038 static const DICONDITION expect_condition[3] =
4041 .lOffset = -500,
4042 .lPositiveCoefficient = 2000,
4043 .lNegativeCoefficient = -3000,
4044 .dwPositiveSaturation = -4000,
4045 .dwNegativeSaturation = -5000,
4046 .lDeadBand = 6000,
4049 .lOffset = 6000,
4050 .lPositiveCoefficient = 5000,
4051 .lNegativeCoefficient = -4000,
4052 .dwPositiveSaturation = 3000,
4053 .dwNegativeSaturation = 2000,
4054 .lDeadBand = 1000,
4057 .lOffset = -7000,
4058 .lPositiveCoefficient = -8000,
4059 .lNegativeCoefficient = 9000,
4060 .dwPositiveSaturation = 10000,
4061 .dwNegativeSaturation = 11000,
4062 .lDeadBand = -12000,
4065 const DIEFFECT expect_desc =
4067 .dwSize = sizeof(DIEFFECT_DX6),
4068 .dwFlags = DIEFF_SPHERICAL | DIEFF_OBJECTIDS,
4069 .dwDuration = 1000,
4070 .dwSamplePeriod = 2000,
4071 .dwGain = 3000,
4072 .dwTriggerButton = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER,
4073 .dwTriggerRepeatInterval = 5000,
4074 .cAxes = 2,
4075 .rgdwAxes = (void *)expect_axes,
4076 .rglDirection = (void *)expect_directions,
4077 .lpEnvelope = (void *)&expect_envelope,
4078 .cbTypeSpecificParams = 2 * sizeof(DICONDITION),
4079 .lpvTypeSpecificParams = (void *)expect_condition,
4080 .dwStartDelay = 6000,
4082 DIPROPGUIDANDPATH prop_guid_path =
4084 .diph =
4086 .dwSize = sizeof(DIPROPGUIDANDPATH),
4087 .dwHeaderSize = sizeof(DIPROPHEADER),
4088 .dwHow = DIPH_DEVICE,
4091 DIPROPDWORD prop_dword =
4093 .diph =
4095 .dwSize = sizeof(DIPROPDWORD),
4096 .dwHeaderSize = sizeof(DIPROPHEADER),
4097 .dwHow = DIPH_DEVICE,
4100 DIDEVICEINSTANCEW devinst = {.dwSize = sizeof(DIDEVICEINSTANCEW)};
4101 IDirectInputDevice8W *device;
4102 IDirectInputEffect *effect, *effect2;
4103 DIEFFECT effect_desc;
4104 HANDLE file, event;
4105 ULONG res, ref;
4106 DWORD flags;
4107 HRESULT hr;
4108 HWND hwnd;
4110 cleanup_registry_keys();
4112 desc.report_descriptor_len = sizeof(report_descriptor);
4113 memcpy( desc.report_descriptor_buf, report_descriptor, sizeof(report_descriptor) );
4114 desc.expect_size = sizeof(expect_pool);
4115 memcpy( desc.expect, expect_pool, sizeof(expect_pool) );
4116 fill_context( desc.context, ARRAY_SIZE(desc.context) );
4118 if (!hid_device_start( &desc, 1 )) goto done;
4119 if (FAILED(hr = dinput_test_create_device( DIRECTINPUT_VERSION, &devinst, &device ))) goto done;
4121 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GUIDANDPATH, &prop_guid_path.diph );
4122 ok( hr == DI_OK, "GetProperty DIPROP_GUIDANDPATH returned %#lx\n", hr );
4123 file = CreateFileW( prop_guid_path.wszPath, FILE_READ_ACCESS | FILE_WRITE_ACCESS,
4124 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
4125 FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL );
4126 ok( file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError() );
4128 hwnd = CreateWindowW( L"static", L"dinput", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 10, 10, 200, 200,
4129 NULL, NULL, NULL, NULL );
4131 event = CreateEventW( NULL, FALSE, FALSE, NULL );
4132 ok( event != NULL, "CreateEventW failed, last error %lu\n", GetLastError() );
4133 hr = IDirectInputDevice8_SetEventNotification( device, event );
4134 ok( hr == DI_OK, "SetEventNotification returned: %#lx\n", hr );
4135 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND | DISCL_EXCLUSIVE );
4136 ok( hr == DI_OK, "SetCooperativeLevel returned: %#lx\n", hr );
4137 hr = IDirectInputDevice8_SetDataFormat( device, &c_dfDIJoystick2 );
4138 ok( hr == DI_OK, "SetDataFormat returned: %#lx\n", hr );
4140 hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFLOAD, &prop_dword.diph );
4141 ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr );
4142 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4143 ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "GetForceFeedbackState returned %#lx\n", hr );
4144 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_RESET );
4145 ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "SendForceFeedbackCommand returned %#lx\n", hr );
4147 set_hid_expect( file, expect_acquire, sizeof(expect_acquire) );
4148 hr = IDirectInputDevice8_Acquire( device );
4149 ok( hr == DI_OK, "Acquire returned: %#lx\n", hr );
4150 wait_hid_expect( file, 100 );
4152 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4153 prop_dword.dwData = 0xdeadbeef;
4154 hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFLOAD, &prop_dword.diph );
4155 ok( hr == DI_OK, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr );
4156 ok( prop_dword.dwData == 0, "got DIPROP_FFLOAD %#lx\n", prop_dword.dwData );
4157 set_hid_expect( file, NULL, 0 );
4159 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4160 res = 0xdeadbeef;
4161 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4162 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4163 flags = DIGFFS_STOPPED | DIGFFS_EMPTY;
4164 ok( res == flags, "got state %#lx\n", res );
4165 set_hid_expect( file, NULL, 0 );
4167 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4168 prop_dword.dwData = 0xdeadbeef;
4169 hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFLOAD, &prop_dword.diph );
4170 ok( hr == DI_OK, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr );
4171 ok( prop_dword.dwData == 0, "got DIPROP_FFLOAD %#lx\n", prop_dword.dwData );
4172 set_hid_expect( file, NULL, 0 );
4174 send_hid_input( file, device_state_input, sizeof(struct hid_expect) );
4175 res = WaitForSingleObject( event, 100 );
4176 ok( res == WAIT_TIMEOUT, "WaitForSingleObject returned %#lx\n", res );
4177 send_hid_input( file, device_state_input, sizeof(device_state_input) );
4178 res = WaitForSingleObject( event, 5000 );
4179 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
4181 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4182 res = 0xdeadbeef;
4183 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4184 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4185 flags = DIGFFS_PAUSED | DIGFFS_EMPTY | DIGFFS_ACTUATORSON | DIGFFS_POWERON |
4186 DIGFFS_SAFETYSWITCHON | DIGFFS_USERFFSWITCHON;
4187 ok( res == flags, "got state %#lx\n", res );
4188 set_hid_expect( file, NULL, 0 );
4190 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, NULL, &effect, NULL );
4191 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
4193 hr = IDirectInputEffect_GetEffectStatus( effect, NULL );
4194 ok( hr == E_POINTER, "GetEffectStatus returned %#lx\n", hr );
4195 res = 0xdeadbeef;
4196 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4197 ok( hr == DIERR_NOTDOWNLOADED, "GetEffectStatus returned %#lx\n", hr );
4198 ok( res == 0, "got status %#lx\n", res );
4200 flags = DIEP_ALLPARAMS;
4201 hr = IDirectInputEffect_SetParameters( effect, &expect_desc, flags | DIEP_NODOWNLOAD );
4202 ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr );
4204 set_hid_expect( file, expect_reset, sizeof(struct hid_expect) );
4205 hr = IDirectInputDevice8_Unacquire( device );
4206 ok( hr == DI_OK, "Unacquire returned: %#lx\n", hr );
4207 set_hid_expect( file, NULL, 0 );
4209 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4210 ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "GetEffectStatus returned %#lx\n", hr );
4212 set_hid_expect( file, expect_acquire, sizeof(expect_acquire) );
4213 hr = IDirectInputDevice8_Acquire( device );
4214 ok( hr == DI_OK, "Acquire returned: %#lx\n", hr );
4215 wait_hid_expect( file, 100 );
4217 res = 0xdeadbeef;
4218 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4219 ok( hr == DIERR_NOTDOWNLOADED, "GetEffectStatus returned %#lx\n", hr );
4220 ok( res == 0, "got status %#lx\n", res );
4222 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4223 res = 0xdeadbeef;
4224 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4225 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4226 flags = DIGFFS_STOPPED | DIGFFS_EMPTY;
4227 ok( res == flags, "got state %#lx\n", res );
4228 set_hid_expect( file, NULL, 0 );
4230 set_hid_expect( file, expect_create, sizeof(expect_create) );
4231 hr = IDirectInputEffect_Download( effect );
4232 ok( hr == DI_OK, "Download returned %#lx\n", hr );
4233 set_hid_expect( file, NULL, 0 );
4235 res = 0xdeadbeef;
4236 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4237 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4238 ok( res == 0, "got status %#lx\n", res );
4239 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4240 res = 0xdeadbeef;
4241 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4242 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4243 flags = DIGFFS_STOPPED;
4244 ok( res == flags, "got state %#lx\n", res );
4245 set_hid_expect( file, NULL, 0 );
4247 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4248 prop_dword.dwData = 0xdeadbeef;
4249 hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFLOAD, &prop_dword.diph );
4250 ok( hr == DI_OK, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr );
4251 ok( prop_dword.dwData == 0, "got DIPROP_FFLOAD %#lx\n", prop_dword.dwData );
4252 set_hid_expect( file, NULL, 0 );
4254 set_hid_expect( file, &expect_start, sizeof(expect_start) );
4255 hr = IDirectInputEffect_Start( effect, 1, DIES_NODOWNLOAD );
4256 ok( hr == DI_OK, "Start returned %#lx\n", hr );
4257 set_hid_expect( file, NULL, 0 );
4259 set_hid_expect( file, expect_create_2, sizeof(expect_create_2) );
4260 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, &expect_desc, &effect2, NULL );
4261 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
4262 set_hid_expect( file, NULL, 0 );
4263 set_hid_expect( file, &expect_start_2, sizeof(expect_start_2) );
4264 hr = IDirectInputEffect_Start( effect2, 1, DIES_SOLO );
4265 ok( hr == DI_OK, "Start returned %#lx\n", hr );
4266 set_hid_expect( file, NULL, 0 );
4267 res = 0xdeadbeef;
4268 hr = IDirectInputEffect_GetEffectStatus( effect2, &res );
4269 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4270 ok( res == DIEGES_PLAYING, "got status %#lx\n", res );
4271 res = 0xdeadbeef;
4272 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4273 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4274 ok( res == DIEGES_PLAYING, "got status %#lx\n", res );
4275 set_hid_expect( file, &expect_stop_2, sizeof(expect_stop_2) );
4276 hr = IDirectInputEffect_Stop( effect2 );
4277 ok( hr == DI_OK, "Stop returned %#lx\n", hr );
4278 set_hid_expect( file, NULL, 0 );
4279 res = 0xdeadbeef;
4280 hr = IDirectInputEffect_GetEffectStatus( effect2, &res );
4281 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4282 ok( res == 0, "got status %#lx\n", res );
4283 set_hid_expect( file, expect_destroy_2, sizeof(expect_destroy_2) );
4284 ref = IDirectInputEffect_Release( effect2 );
4285 ok( ref == 0, "Release returned %ld\n", ref );
4286 set_hid_expect( file, NULL, 0 );
4288 /* sending commands has no direct effect on status */
4289 set_hid_expect( file, expect_stop_all, sizeof(expect_stop_all) );
4290 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_STOPALL );
4291 ok( hr == DI_OK, "SendForceFeedbackCommand returned %#lx\n", hr );
4292 set_hid_expect( file, NULL, 0 );
4293 res = 0xdeadbeef;
4294 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4295 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4296 ok( res == DIEGES_PLAYING, "got status %#lx\n", res );
4297 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4298 res = 0xdeadbeef;
4299 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4300 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4301 flags = DIGFFS_STOPPED;
4302 ok( res == flags, "got state %#lx\n", res );
4303 set_hid_expect( file, NULL, 0 );
4305 set_hid_expect( file, expect_device_pause, sizeof(expect_device_pause) );
4306 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_PAUSE );
4307 ok( hr == DI_OK, "SendForceFeedbackCommand returned %#lx\n", hr );
4308 set_hid_expect( file, NULL, 0 );
4309 res = 0xdeadbeef;
4310 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4311 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4312 ok( res == DIEGES_PLAYING, "got status %#lx\n", res );
4313 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4314 res = 0xdeadbeef;
4315 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4316 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4317 flags = DIGFFS_STOPPED;
4318 ok( res == flags, "got state %#lx\n", res );
4319 set_hid_expect( file, NULL, 0 );
4321 set_hid_expect( file, expect_device_continue, sizeof(expect_device_continue) );
4322 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_CONTINUE );
4323 ok( hr == DI_OK, "SendForceFeedbackCommand returned %#lx\n", hr );
4324 set_hid_expect( file, NULL, 0 );
4325 res = 0xdeadbeef;
4326 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4327 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4328 ok( res == DIEGES_PLAYING, "got status %#lx\n", res );
4329 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4330 res = 0xdeadbeef;
4331 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4332 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4333 flags = DIGFFS_STOPPED;
4334 ok( res == flags, "got state %#lx\n", res );
4335 set_hid_expect( file, NULL, 0 );
4337 set_hid_expect( file, expect_disable_actuators, sizeof(expect_disable_actuators) );
4338 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_SETACTUATORSOFF );
4339 ok( hr == DI_OK, "SendForceFeedbackCommand returned %#lx\n", hr );
4340 set_hid_expect( file, NULL, 0 );
4341 res = 0xdeadbeef;
4342 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4343 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4344 ok( res == DIEGES_PLAYING, "got status %#lx\n", res );
4345 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4346 res = 0xdeadbeef;
4347 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4348 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4349 flags = DIGFFS_STOPPED;
4350 ok( res == flags, "got state %#lx\n", res );
4351 set_hid_expect( file, NULL, 0 );
4353 set_hid_expect( file, expect_enable_actuators, sizeof(expect_enable_actuators) );
4354 hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_SETACTUATORSON );
4355 ok( hr == DI_OK, "SendForceFeedbackCommand returned %#lx\n", hr );
4356 set_hid_expect( file, NULL, 0 );
4357 res = 0xdeadbeef;
4358 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4359 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4360 ok( res == DIEGES_PLAYING, "got status %#lx\n", res );
4361 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4362 res = 0xdeadbeef;
4363 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4364 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4365 flags = DIGFFS_STOPPED;
4366 ok( res == flags, "got state %#lx\n", res );
4367 set_hid_expect( file, NULL, 0 );
4369 set_hid_expect( file, &expect_stop, sizeof(expect_stop) );
4370 hr = IDirectInputEffect_Stop( effect );
4371 ok( hr == DI_OK, "Stop returned %#lx\n", hr );
4372 set_hid_expect( file, NULL, 0 );
4373 res = 0xdeadbeef;
4374 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4375 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4376 ok( res == 0, "got status %#lx\n", res );
4377 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4378 res = 0xdeadbeef;
4379 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4380 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4381 flags = DIGFFS_STOPPED;
4382 ok( res == flags, "got state %#lx\n", res );
4383 set_hid_expect( file, NULL, 0 );
4385 send_hid_input( file, device_state_input_0, sizeof(device_state_input_0) );
4386 res = WaitForSingleObject( event, 5000 );
4387 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
4388 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4389 res = 0xdeadbeef;
4390 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4391 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4392 flags = DIGFFS_PAUSED | DIGFFS_ACTUATORSON | DIGFFS_POWERON | DIGFFS_SAFETYSWITCHON | DIGFFS_USERFFSWITCHON;
4393 ok( res == flags, "got state %#lx\n", res );
4394 set_hid_expect( file, NULL, 0 );
4396 send_hid_input( file, device_state_input_1, sizeof(device_state_input_1) );
4397 res = WaitForSingleObject( event, 5000 );
4398 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
4399 res = 0xdeadbeef;
4400 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4401 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4402 ok( res == DIEGES_PLAYING, "got status %#lx\n", res );
4403 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4404 res = 0xdeadbeef;
4405 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4406 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4407 flags = DIGFFS_ACTUATORSOFF | DIGFFS_POWEROFF | DIGFFS_SAFETYSWITCHOFF | DIGFFS_USERFFSWITCHOFF;
4408 ok( res == flags, "got state %#lx\n", res );
4409 set_hid_expect( file, NULL, 0 );
4411 send_hid_input( file, device_state_input_2, sizeof(device_state_input_2) );
4412 res = WaitForSingleObject( event, 5000 );
4413 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
4414 res = 0xdeadbeef;
4415 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4416 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4417 ok( res == 0, "got status %#lx\n", res );
4418 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4419 res = 0xdeadbeef;
4420 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4421 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4422 flags = DIGFFS_PAUSED | DIGFFS_ACTUATORSON | DIGFFS_POWEROFF | DIGFFS_SAFETYSWITCHOFF | DIGFFS_USERFFSWITCHOFF;
4423 ok( res == flags, "got state %#lx\n", res );
4424 set_hid_expect( file, NULL, 0 );
4426 set_hid_expect( file, &expect_stop, sizeof(expect_stop) );
4427 hr = IDirectInputEffect_Stop( effect );
4428 ok( hr == DI_OK, "Stop returned %#lx\n", hr );
4429 set_hid_expect( file, NULL, 0 );
4431 res = 0xdeadbeef;
4432 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4433 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4434 ok( res == 0, "got status %#lx\n", res );
4435 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4436 res = 0xdeadbeef;
4437 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4438 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4439 flags = DIGFFS_PAUSED | DIGFFS_ACTUATORSON | DIGFFS_POWEROFF | DIGFFS_SAFETYSWITCHOFF | DIGFFS_USERFFSWITCHOFF;
4440 ok( res == flags, "got state %#lx\n", res );
4441 set_hid_expect( file, NULL, 0 );
4443 set_hid_expect( file, expect_destroy, sizeof(expect_destroy) );
4444 hr = IDirectInputEffect_Unload( effect );
4445 ok( hr == DI_OK, "Unload returned %#lx\n", hr );
4446 set_hid_expect( file, NULL, 0 );
4448 res = 0xdeadbeef;
4449 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4450 ok( hr == DIERR_NOTDOWNLOADED, "GetEffectStatus returned %#lx\n", hr );
4451 ok( res == 0, "got status %#lx\n", res );
4452 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
4453 res = 0xdeadbeef;
4454 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
4455 ok( hr == DI_OK, "GetForceFeedbackState returned %#lx\n", hr );
4456 flags = DIGFFS_EMPTY | DIGFFS_PAUSED | DIGFFS_ACTUATORSON | DIGFFS_POWEROFF |
4457 DIGFFS_SAFETYSWITCHOFF | DIGFFS_USERFFSWITCHOFF;
4458 ok( res == flags, "got state %#lx\n", res );
4459 set_hid_expect( file, NULL, 0 );
4461 ref = IDirectInputEffect_Release( effect );
4462 ok( ref == 0, "Release returned %ld\n", ref );
4464 /* start delay has no direct effect on effect status */
4465 effect_desc = expect_desc;
4466 effect_desc.dwStartDelay = 32767000;
4467 set_hid_expect( file, expect_create_delay, sizeof(expect_create_delay) );
4468 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, &effect_desc, &effect, NULL );
4469 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
4470 set_hid_expect( file, NULL, 0 );
4471 res = 0xdeadbeef;
4472 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4473 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4474 ok( res == 0, "got status %#lx\n", res );
4475 set_hid_expect( file, &expect_start, sizeof(expect_start) );
4476 hr = IDirectInputEffect_Start( effect, 1, 0 );
4477 ok( hr == DI_OK, "Start returned %#lx\n", hr );
4478 set_hid_expect( file, NULL, 0 );
4479 res = 0xdeadbeef;
4480 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4481 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4482 ok( res == DIEGES_PLAYING, "got status %#lx\n", res );
4483 set_hid_expect( file, expect_destroy, sizeof(expect_destroy) );
4484 ref = IDirectInputEffect_Release( effect );
4485 ok( ref == 0, "Release returned %ld\n", ref );
4486 set_hid_expect( file, NULL, 0 );
4488 /* duration has no direct effect on effect status */
4489 effect_desc = expect_desc;
4490 effect_desc.dwDuration = 100;
4491 effect_desc.dwStartDelay = 0;
4492 set_hid_expect( file, expect_create_duration, sizeof(expect_create_duration) );
4493 hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, &effect_desc, &effect, NULL );
4494 ok( hr == DI_OK, "CreateEffect returned %#lx\n", hr );
4495 set_hid_expect( file, NULL, 0 );
4496 res = 0xdeadbeef;
4497 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4498 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4499 ok( res == 0, "got status %#lx\n", res );
4500 set_hid_expect( file, &expect_start, sizeof(expect_start) );
4501 hr = IDirectInputEffect_Start( effect, 1, 0 );
4502 ok( hr == DI_OK, "Start returned %#lx\n", hr );
4503 set_hid_expect( file, NULL, 0 );
4504 Sleep( 100 );
4505 res = 0xdeadbeef;
4506 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
4507 ok( hr == DI_OK, "GetEffectStatus returned %#lx\n", hr );
4508 ok( res == DIEGES_PLAYING, "got status %#lx\n", res );
4509 set_hid_expect( file, expect_destroy, sizeof(expect_destroy) );
4510 ref = IDirectInputEffect_Release( effect );
4511 ok( ref == 0, "Release returned %ld\n", ref );
4512 set_hid_expect( file, NULL, 0 );
4514 set_hid_expect( file, expect_reset, sizeof(struct hid_expect) );
4515 hr = IDirectInputDevice8_Unacquire( device );
4516 ok( hr == DI_OK, "Unacquire returned: %#lx\n", hr );
4517 set_hid_expect( file, NULL, 0 );
4519 ref = IDirectInputDevice8_Release( device );
4520 ok( ref == 0, "Release returned %ld\n", ref );
4522 DestroyWindow( hwnd );
4523 CloseHandle( event );
4524 CloseHandle( file );
4526 done:
4527 hid_device_stop( &desc, 1 );
4528 cleanup_registry_keys();
4529 winetest_pop_context();
4532 #define check_interface( a, b, c ) check_interface_( __LINE__, a, b, c )
4533 static void check_interface_( unsigned int line, void *iface_ptr, REFIID iid, BOOL supported )
4535 IUnknown *iface = iface_ptr;
4536 HRESULT hr, expected;
4537 IUnknown *unk;
4539 expected = supported ? S_OK : E_NOINTERFACE;
4540 hr = IUnknown_QueryInterface( iface, iid, (void **)&unk );
4541 ok_(__FILE__, line)( hr == expected, "got hr %#lx, expected %#lx.\n", hr, expected );
4542 if (SUCCEEDED(hr)) IUnknown_Release( unk );
4545 #define check_runtimeclass( a, b ) check_runtimeclass_( __LINE__, (IInspectable *)a, b )
4546 static void check_runtimeclass_( int line, IInspectable *inspectable, const WCHAR *class_name )
4548 const WCHAR *buffer;
4549 UINT32 length;
4550 HSTRING str;
4551 HRESULT hr;
4553 hr = IInspectable_GetRuntimeClassName( inspectable, &str );
4554 ok_(__FILE__, line)( hr == S_OK, "GetRuntimeClassName returned %#lx\n", hr );
4555 buffer = pWindowsGetStringRawBuffer( str, &length );
4556 ok_(__FILE__, line)( !wcscmp( buffer, class_name ), "got class name %s\n", debugstr_w(buffer) );
4557 pWindowsDeleteString( str );
4560 struct controller_handler
4562 IEventHandler_RawGameController IEventHandler_RawGameController_iface;
4563 HANDLE event;
4564 BOOL invoked;
4567 static inline struct controller_handler *impl_from_IEventHandler_RawGameController( IEventHandler_RawGameController *iface )
4569 return CONTAINING_RECORD( iface, struct controller_handler, IEventHandler_RawGameController_iface );
4572 static HRESULT WINAPI controller_handler_QueryInterface( IEventHandler_RawGameController *iface, REFIID iid, void **out )
4574 if (IsEqualGUID( iid, &IID_IUnknown ) ||
4575 IsEqualGUID( iid, &IID_IAgileObject ) ||
4576 IsEqualGUID( iid, &IID_IEventHandler_RawGameController ))
4578 IUnknown_AddRef( iface );
4579 *out = iface;
4580 return S_OK;
4583 if (winetest_debug > 1) trace( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
4584 *out = NULL;
4585 return E_NOINTERFACE;
4588 static ULONG WINAPI controller_handler_AddRef( IEventHandler_RawGameController *iface )
4590 return 2;
4593 static ULONG WINAPI controller_handler_Release( IEventHandler_RawGameController *iface )
4595 return 1;
4598 static HRESULT WINAPI controller_handler_Invoke( IEventHandler_RawGameController *iface,
4599 IInspectable *sender, IRawGameController *controller )
4601 struct controller_handler *impl = impl_from_IEventHandler_RawGameController( iface );
4603 if (winetest_debug > 1) trace( "iface %p, sender %p, controller %p\n", iface, sender, controller );
4605 ok( sender == NULL, "got sender %p\n", sender );
4606 impl->invoked = TRUE;
4607 SetEvent( impl->event );
4609 return S_OK;
4612 static const IEventHandler_RawGameControllerVtbl controller_handler_vtbl =
4614 controller_handler_QueryInterface,
4615 controller_handler_AddRef,
4616 controller_handler_Release,
4617 controller_handler_Invoke,
4620 static struct controller_handler controller_added = {{&controller_handler_vtbl}};
4622 #define check_bool_async( a, b, c, d, e ) check_bool_async_( __LINE__, a, b, c, d, e )
4623 static void check_bool_async_( int line, IAsyncOperation_boolean *async, UINT32 expect_id, AsyncStatus expect_status,
4624 HRESULT expect_hr, BOOLEAN expect_result )
4626 AsyncStatus async_status;
4627 IAsyncInfo *async_info;
4628 HRESULT hr, async_hr;
4629 UINT32 async_id;
4630 BOOLEAN result;
4632 hr = IAsyncOperation_boolean_QueryInterface( async, &IID_IAsyncInfo, (void **)&async_info );
4633 ok_(__FILE__, line)( hr == S_OK, "QueryInterface returned %#lx\n", hr );
4635 async_id = 0xdeadbeef;
4636 hr = IAsyncInfo_get_Id( async_info, &async_id );
4637 if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_Id returned %#lx\n", hr );
4638 else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_Id returned %#lx\n", hr );
4639 ok_(__FILE__, line)( async_id == expect_id, "got id %u\n", async_id );
4641 async_status = 0xdeadbeef;
4642 hr = IAsyncInfo_get_Status( async_info, &async_status );
4643 if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_Status returned %#lx\n", hr );
4644 else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_Status returned %#lx\n", hr );
4645 ok_(__FILE__, line)( async_status == expect_status, "got status %u\n", async_status );
4647 async_hr = 0xdeadbeef;
4648 hr = IAsyncInfo_get_ErrorCode( async_info, &async_hr );
4649 if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_ErrorCode returned %#lx\n", hr );
4650 else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_ErrorCode returned %#lx\n", hr );
4651 if (expect_status < 4) todo_wine_if(FAILED(expect_hr)) ok_(__FILE__, line)( async_hr == expect_hr, "got error %#lx\n", async_hr );
4652 else ok_(__FILE__, line)( async_hr == E_ILLEGAL_METHOD_CALL, "got error %#lx\n", async_hr );
4654 IAsyncInfo_Release( async_info );
4656 result = !expect_result;
4657 hr = IAsyncOperation_boolean_GetResults( async, &result );
4658 switch (expect_status)
4660 case Completed:
4661 case Error:
4662 todo_wine_if(FAILED(expect_hr))
4663 ok_(__FILE__, line)( hr == expect_hr, "GetResults returned %#lx\n", hr );
4664 ok_(__FILE__, line)( result == expect_result, "got result %u\n", result );
4665 break;
4666 case Canceled:
4667 case Started:
4668 default:
4669 ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "GetResults returned %#lx\n", hr );
4670 break;
4674 #define check_result_async( a, b, c, d, e ) check_result_async_( __LINE__, a, b, c, d, e )
4675 static void check_result_async_( int line, IAsyncOperation_ForceFeedbackLoadEffectResult *async, UINT32 expect_id,
4676 AsyncStatus expect_status, HRESULT expect_hr, ForceFeedbackLoadEffectResult expect_result )
4678 ForceFeedbackLoadEffectResult result;
4679 AsyncStatus async_status;
4680 IAsyncInfo *async_info;
4681 HRESULT hr, async_hr;
4682 UINT32 async_id;
4684 hr = IAsyncOperation_ForceFeedbackLoadEffectResult_QueryInterface( async, &IID_IAsyncInfo, (void **)&async_info );
4685 ok_(__FILE__, line)( hr == S_OK, "QueryInterface returned %#lx\n", hr );
4687 async_id = 0xdeadbeef;
4688 hr = IAsyncInfo_get_Id( async_info, &async_id );
4689 if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_Id returned %#lx\n", hr );
4690 else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_Id returned %#lx\n", hr );
4691 ok_(__FILE__, line)( async_id == expect_id, "got id %u\n", async_id );
4693 async_status = 0xdeadbeef;
4694 hr = IAsyncInfo_get_Status( async_info, &async_status );
4695 if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_Status returned %#lx\n", hr );
4696 else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_Status returned %#lx\n", hr );
4697 ok_(__FILE__, line)( async_status == expect_status, "got status %u\n", async_status );
4699 async_hr = 0xdeadbeef;
4700 hr = IAsyncInfo_get_ErrorCode( async_info, &async_hr );
4701 if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_ErrorCode returned %#lx\n", hr );
4702 else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_ErrorCode returned %#lx\n", hr );
4703 if (expect_status < 4) todo_wine_if(FAILED(expect_hr)) ok_(__FILE__, line)( async_hr == expect_hr, "got error %#lx\n", async_hr );
4704 else ok_(__FILE__, line)( async_hr == E_ILLEGAL_METHOD_CALL, "got error %#lx\n", async_hr );
4706 IAsyncInfo_Release( async_info );
4708 result = !expect_result;
4709 hr = IAsyncOperation_ForceFeedbackLoadEffectResult_GetResults( async, &result );
4710 switch (expect_status)
4712 case Completed:
4713 case Error:
4714 todo_wine_if(FAILED(expect_hr))
4715 ok_(__FILE__, line)( hr == expect_hr, "GetResults returned %#lx\n", hr );
4716 ok_(__FILE__, line)( result == expect_result, "got result %u\n", result );
4717 break;
4718 case Canceled:
4719 case Started:
4720 default:
4721 ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "GetResults returned %#lx\n", hr );
4722 break;
4726 struct bool_async_handler
4728 IAsyncOperationCompletedHandler_boolean IAsyncOperationCompletedHandler_boolean_iface;
4729 LONG refcount;
4731 IAsyncOperation_boolean *async;
4732 AsyncStatus status;
4733 BOOL invoked;
4734 HANDLE event;
4737 static inline struct bool_async_handler *impl_from_IAsyncOperationCompletedHandler_boolean( IAsyncOperationCompletedHandler_boolean *iface )
4739 return CONTAINING_RECORD( iface, struct bool_async_handler, IAsyncOperationCompletedHandler_boolean_iface );
4742 static HRESULT WINAPI bool_async_handler_QueryInterface( IAsyncOperationCompletedHandler_boolean *iface, REFIID iid, void **out )
4744 if (IsEqualGUID( iid, &IID_IUnknown ) ||
4745 IsEqualGUID( iid, &IID_IAgileObject ) ||
4746 IsEqualGUID( iid, &IID_IAsyncOperationCompletedHandler_boolean ))
4748 IUnknown_AddRef( iface );
4749 *out = iface;
4750 return S_OK;
4753 if (winetest_debug > 1) trace( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
4754 *out = NULL;
4755 return E_NOINTERFACE;
4758 static ULONG WINAPI bool_async_handler_AddRef( IAsyncOperationCompletedHandler_boolean *iface )
4760 struct bool_async_handler *impl = impl_from_IAsyncOperationCompletedHandler_boolean( iface );
4761 return InterlockedIncrement( &impl->refcount );
4764 static ULONG WINAPI bool_async_handler_Release( IAsyncOperationCompletedHandler_boolean *iface )
4766 struct bool_async_handler *impl = impl_from_IAsyncOperationCompletedHandler_boolean( iface );
4767 ULONG ref = InterlockedDecrement( &impl->refcount );
4768 if (!ref) free( impl );
4769 return ref;
4772 static HRESULT WINAPI bool_async_handler_Invoke( IAsyncOperationCompletedHandler_boolean *iface,
4773 IAsyncOperation_boolean *async, AsyncStatus status )
4775 struct bool_async_handler *impl = impl_from_IAsyncOperationCompletedHandler_boolean( iface );
4777 if (winetest_debug > 1) trace( "iface %p, async %p, status %u\n", iface, async, status );
4779 ok( !impl->invoked, "invoked twice\n" );
4780 impl->invoked = TRUE;
4781 impl->async = async;
4782 impl->status = status;
4783 if (impl->event) SetEvent( impl->event );
4785 return S_OK;
4788 static IAsyncOperationCompletedHandler_booleanVtbl bool_async_handler_vtbl =
4790 /*** IUnknown methods ***/
4791 bool_async_handler_QueryInterface,
4792 bool_async_handler_AddRef,
4793 bool_async_handler_Release,
4794 /*** IAsyncOperationCompletedHandler<boolean> methods ***/
4795 bool_async_handler_Invoke,
4798 static IAsyncOperationCompletedHandler_boolean *bool_async_handler_create( HANDLE event )
4800 struct bool_async_handler *impl;
4802 if (!(impl = calloc( 1, sizeof(*impl) ))) return NULL;
4803 impl->IAsyncOperationCompletedHandler_boolean_iface.lpVtbl = &bool_async_handler_vtbl;
4804 impl->event = event;
4805 impl->refcount = 1;
4807 return &impl->IAsyncOperationCompletedHandler_boolean_iface;
4810 #define await_bool( a ) await_bool_( __LINE__, a )
4811 static void await_bool_( int line, IAsyncOperation_boolean *async )
4813 IAsyncOperationCompletedHandler_boolean *handler;
4814 HANDLE event;
4815 HRESULT hr;
4816 DWORD ret;
4818 event = CreateEventW( NULL, FALSE, FALSE, NULL );
4819 ok_(__FILE__, line)( !!event, "CreateEventW failed, error %lu\n", GetLastError() );
4821 handler = bool_async_handler_create( event );
4822 ok_(__FILE__, line)( !!handler, "bool_async_handler_create failed\n" );
4823 hr = IAsyncOperation_boolean_put_Completed( async, handler );
4824 ok_(__FILE__, line)( hr == S_OK, "put_Completed returned %#lx\n", hr );
4825 IAsyncOperationCompletedHandler_boolean_Release( handler );
4827 ret = WaitForSingleObject( event, 5000 );
4828 ok_(__FILE__, line)( !ret, "WaitForSingleObject returned %#lx\n", ret );
4829 ret = CloseHandle( event );
4830 ok_(__FILE__, line)( ret, "CloseHandle failed, error %lu\n", GetLastError() );
4833 struct result_async_handler
4835 IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface;
4836 LONG refcount;
4838 IAsyncOperation_ForceFeedbackLoadEffectResult *async;
4839 AsyncStatus status;
4840 BOOL invoked;
4841 HANDLE event;
4844 static inline struct result_async_handler *impl_from_IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult( IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult *iface )
4846 return CONTAINING_RECORD( iface, struct result_async_handler, IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface );
4849 static HRESULT WINAPI result_async_handler_QueryInterface( IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult *iface, REFIID iid, void **out )
4851 if (IsEqualGUID( iid, &IID_IUnknown ) ||
4852 IsEqualGUID( iid, &IID_IAgileObject ) ||
4853 IsEqualGUID( iid, &IID_IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult ))
4855 IUnknown_AddRef( iface );
4856 *out = iface;
4857 return S_OK;
4860 if (winetest_debug > 1) trace( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
4861 *out = NULL;
4862 return E_NOINTERFACE;
4865 static ULONG WINAPI result_async_handler_AddRef( IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult *iface )
4867 struct result_async_handler *impl = impl_from_IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult( iface );
4868 return InterlockedIncrement( &impl->refcount );
4871 static ULONG WINAPI result_async_handler_Release( IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult *iface )
4873 struct result_async_handler *impl = impl_from_IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult( iface );
4874 ULONG ref = InterlockedDecrement( &impl->refcount );
4875 if (!ref) free( impl );
4876 return ref;
4879 static HRESULT WINAPI result_async_handler_Invoke( IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult *iface,
4880 IAsyncOperation_ForceFeedbackLoadEffectResult *async, AsyncStatus status )
4882 struct result_async_handler *impl = impl_from_IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult( iface );
4884 if (winetest_debug > 1) trace( "iface %p, async %p, status %u\n", iface, async, status );
4886 ok( !impl->invoked, "invoked twice\n" );
4887 impl->invoked = TRUE;
4888 impl->async = async;
4889 impl->status = status;
4890 if (impl->event) SetEvent( impl->event );
4892 return S_OK;
4895 static IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResultVtbl result_async_handler_vtbl =
4897 /*** IUnknown methods ***/
4898 result_async_handler_QueryInterface,
4899 result_async_handler_AddRef,
4900 result_async_handler_Release,
4901 /*** IAsyncOperationCompletedHandler<ForceFeedbackLoadEffectResult> methods ***/
4902 result_async_handler_Invoke,
4905 static IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult *result_async_handler_create( HANDLE event )
4907 struct result_async_handler *impl;
4909 if (!(impl = calloc( 1, sizeof(*impl) ))) return NULL;
4910 impl->IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface.lpVtbl = &result_async_handler_vtbl;
4911 impl->event = event;
4912 impl->refcount = 1;
4914 return &impl->IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface;
4917 #define await_result( a ) await_result_( __LINE__, a )
4918 static void await_result_( int line, IAsyncOperation_ForceFeedbackLoadEffectResult *async )
4920 IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult *handler;
4921 HANDLE event;
4922 HRESULT hr;
4923 DWORD ret;
4925 event = CreateEventW( NULL, FALSE, FALSE, NULL );
4926 ok_(__FILE__, line)( !!event, "CreateEventW failed, error %lu\n", GetLastError() );
4928 handler = result_async_handler_create( event );
4929 ok_(__FILE__, line)( !!handler, "result_async_handler_create failed\n" );
4930 hr = IAsyncOperation_ForceFeedbackLoadEffectResult_put_Completed( async, handler );
4931 ok_(__FILE__, line)( hr == S_OK, "put_Completed returned %#lx\n", hr );
4932 IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_Release( handler );
4934 ret = WaitForSingleObject( event, 5000 );
4935 ok_(__FILE__, line)( !ret, "WaitForSingleObject returned %#lx\n", ret );
4936 ret = CloseHandle( event );
4937 ok_(__FILE__, line)( ret, "CloseHandle failed, error %lu\n", GetLastError() );
4940 static void test_windows_gaming_input(void)
4942 #include "psh_hid_macros.h"
4943 const unsigned char report_desc[] =
4945 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
4946 USAGE(1, HID_USAGE_GENERIC_JOYSTICK),
4947 COLLECTION(1, Application),
4948 USAGE(1, HID_USAGE_GENERIC_JOYSTICK),
4949 COLLECTION(1, Physical),
4950 REPORT_ID(1, 1),
4952 USAGE(1, HID_USAGE_GENERIC_X),
4953 USAGE(1, HID_USAGE_GENERIC_Y),
4954 USAGE(1, HID_USAGE_GENERIC_Z),
4955 LOGICAL_MINIMUM(1, 0),
4956 LOGICAL_MAXIMUM(1, 127),
4957 PHYSICAL_MINIMUM(1, 0),
4958 PHYSICAL_MAXIMUM(1, 127),
4959 REPORT_SIZE(1, 8),
4960 REPORT_COUNT(1, 3),
4961 INPUT(1, Data|Var|Abs),
4963 USAGE(1, HID_USAGE_GENERIC_HATSWITCH),
4964 LOGICAL_MINIMUM(1, 1),
4965 LOGICAL_MAXIMUM(1, 8),
4966 PHYSICAL_MINIMUM(1, 0),
4967 PHYSICAL_MAXIMUM(1, 8),
4968 REPORT_SIZE(1, 8),
4969 REPORT_COUNT(1, 1),
4970 INPUT(1, Data|Var|Abs|Null),
4972 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON),
4973 USAGE_MINIMUM(1, 1),
4974 USAGE_MAXIMUM(1, 5),
4975 LOGICAL_MINIMUM(1, 0),
4976 LOGICAL_MAXIMUM(1, 1),
4977 PHYSICAL_MINIMUM(1, 0),
4978 PHYSICAL_MAXIMUM(1, 1),
4979 REPORT_SIZE(1, 1),
4980 REPORT_COUNT(1, 8),
4981 INPUT(1, Data|Var|Abs),
4982 END_COLLECTION,
4984 USAGE_PAGE(1, HID_USAGE_PAGE_PID),
4985 USAGE(1, PID_USAGE_STATE_REPORT),
4986 COLLECTION(1, Report),
4987 REPORT_ID(1, 2),
4989 USAGE(1, PID_USAGE_DEVICE_PAUSED),
4990 USAGE(1, PID_USAGE_ACTUATORS_ENABLED),
4991 USAGE(1, PID_USAGE_SAFETY_SWITCH),
4992 USAGE(1, PID_USAGE_ACTUATOR_OVERRIDE_SWITCH),
4993 USAGE(1, PID_USAGE_ACTUATOR_POWER),
4994 LOGICAL_MINIMUM(1, 0),
4995 LOGICAL_MAXIMUM(1, 1),
4996 PHYSICAL_MINIMUM(1, 0),
4997 PHYSICAL_MAXIMUM(1, 1),
4998 REPORT_SIZE(1, 1),
4999 REPORT_COUNT(1, 5),
5000 INPUT(1, Data|Var|Abs),
5001 REPORT_COUNT(1, 3),
5002 INPUT(1, Cnst|Var|Abs),
5004 USAGE(1, PID_USAGE_EFFECT_PLAYING),
5005 LOGICAL_MINIMUM(1, 0),
5006 LOGICAL_MAXIMUM(1, 1),
5007 PHYSICAL_MINIMUM(1, 0),
5008 PHYSICAL_MAXIMUM(1, 1),
5009 REPORT_SIZE(1, 1),
5010 REPORT_COUNT(1, 8),
5011 INPUT(1, Data|Var|Abs),
5013 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
5014 LOGICAL_MINIMUM(1, 1),
5015 LOGICAL_MAXIMUM(1, 0x7f),
5016 PHYSICAL_MINIMUM(1, 1),
5017 PHYSICAL_MAXIMUM(1, 0x7f),
5018 REPORT_SIZE(1, 8),
5019 REPORT_COUNT(1, 1),
5020 INPUT(1, Data|Var|Abs),
5021 END_COLLECTION,
5023 USAGE_PAGE(1, HID_USAGE_PAGE_PID),
5024 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT),
5025 COLLECTION(1, Report),
5026 REPORT_ID(1, 1),
5028 USAGE(1, PID_USAGE_DEVICE_CONTROL),
5029 COLLECTION(1, Logical),
5030 USAGE(1, PID_USAGE_DC_DEVICE_RESET),
5031 USAGE(1, PID_USAGE_DC_DEVICE_PAUSE),
5032 USAGE(1, PID_USAGE_DC_DEVICE_CONTINUE),
5033 USAGE(1, PID_USAGE_DC_ENABLE_ACTUATORS),
5034 USAGE(1, PID_USAGE_DC_DISABLE_ACTUATORS),
5035 USAGE(1, PID_USAGE_DC_STOP_ALL_EFFECTS),
5036 LOGICAL_MINIMUM(1, 1),
5037 LOGICAL_MAXIMUM(1, 6),
5038 PHYSICAL_MINIMUM(1, 1),
5039 PHYSICAL_MAXIMUM(1, 6),
5040 REPORT_SIZE(1, 8),
5041 REPORT_COUNT(1, 1),
5042 OUTPUT(1, Data|Ary|Abs),
5043 END_COLLECTION,
5044 END_COLLECTION,
5046 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT),
5047 COLLECTION(1, Report),
5048 REPORT_ID(1, 2),
5050 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
5051 LOGICAL_MINIMUM(1, 1),
5052 LOGICAL_MAXIMUM(1, 0x7f),
5053 PHYSICAL_MINIMUM(1, 1),
5054 PHYSICAL_MAXIMUM(1, 0x7f),
5055 REPORT_SIZE(1, 8),
5056 REPORT_COUNT(1, 1),
5057 OUTPUT(1, Data|Var|Abs),
5059 USAGE(1, PID_USAGE_EFFECT_OPERATION),
5060 COLLECTION(1, NamedArray),
5061 USAGE(1, PID_USAGE_OP_EFFECT_START),
5062 USAGE(1, PID_USAGE_OP_EFFECT_START_SOLO),
5063 USAGE(1, PID_USAGE_OP_EFFECT_STOP),
5064 LOGICAL_MINIMUM(1, 1),
5065 LOGICAL_MAXIMUM(1, 3),
5066 PHYSICAL_MINIMUM(1, 1),
5067 PHYSICAL_MAXIMUM(1, 3),
5068 REPORT_SIZE(1, 8),
5069 REPORT_COUNT(1, 1),
5070 OUTPUT(1, Data|Ary|Abs),
5071 END_COLLECTION,
5073 USAGE(1, PID_USAGE_LOOP_COUNT),
5074 LOGICAL_MINIMUM(1, 0),
5075 LOGICAL_MAXIMUM(1, 0x7f),
5076 PHYSICAL_MINIMUM(1, 0),
5077 PHYSICAL_MAXIMUM(1, 0x7f),
5078 REPORT_SIZE(1, 8),
5079 REPORT_COUNT(1, 1),
5080 OUTPUT(1, Data|Var|Abs),
5081 END_COLLECTION,
5083 USAGE(1, PID_USAGE_SET_EFFECT_REPORT),
5084 COLLECTION(1, Report),
5085 REPORT_ID(1, 3),
5087 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
5088 LOGICAL_MINIMUM(1, 1),
5089 LOGICAL_MAXIMUM(1, 0x7f),
5090 PHYSICAL_MINIMUM(1, 1),
5091 PHYSICAL_MAXIMUM(1, 0x7f),
5092 REPORT_SIZE(1, 8),
5093 REPORT_COUNT(1, 1),
5094 OUTPUT(1, Data|Var|Abs),
5096 USAGE(1, PID_USAGE_EFFECT_TYPE),
5097 COLLECTION(1, NamedArray),
5098 USAGE(1, PID_USAGE_ET_SQUARE),
5099 USAGE(1, PID_USAGE_ET_SINE),
5100 USAGE(1, PID_USAGE_ET_SPRING),
5101 USAGE(1, PID_USAGE_ET_CONSTANT_FORCE),
5102 USAGE(1, PID_USAGE_ET_RAMP),
5103 LOGICAL_MINIMUM(1, 1),
5104 LOGICAL_MAXIMUM(1, 5),
5105 PHYSICAL_MINIMUM(1, 1),
5106 PHYSICAL_MAXIMUM(1, 5),
5107 REPORT_SIZE(1, 8),
5108 REPORT_COUNT(1, 1),
5109 OUTPUT(1, Data|Ary|Abs),
5110 END_COLLECTION,
5112 USAGE(1, PID_USAGE_AXES_ENABLE),
5113 COLLECTION(1, Logical),
5114 USAGE(4, (HID_USAGE_PAGE_GENERIC << 16)|HID_USAGE_GENERIC_X),
5115 USAGE(4, (HID_USAGE_PAGE_GENERIC << 16)|HID_USAGE_GENERIC_Y),
5116 LOGICAL_MINIMUM(1, 0),
5117 LOGICAL_MAXIMUM(1, 1),
5118 PHYSICAL_MINIMUM(1, 0),
5119 PHYSICAL_MAXIMUM(1, 1),
5120 REPORT_SIZE(1, 1),
5121 REPORT_COUNT(1, 2),
5122 OUTPUT(1, Data|Var|Abs),
5123 END_COLLECTION,
5124 USAGE(1, PID_USAGE_DIRECTION_ENABLE),
5125 REPORT_COUNT(1, 1),
5126 OUTPUT(1, Data|Var|Abs),
5127 REPORT_COUNT(1, 5),
5128 OUTPUT(1, Cnst|Var|Abs),
5130 USAGE(1, PID_USAGE_DURATION),
5131 USAGE(1, PID_USAGE_TRIGGER_REPEAT_INTERVAL),
5132 USAGE(1, PID_USAGE_SAMPLE_PERIOD),
5133 USAGE(1, PID_USAGE_START_DELAY),
5134 UNIT(2, 0x1003), /* Eng Lin:Time */
5135 UNIT_EXPONENT(1, -3), /* 10^-3 */
5136 LOGICAL_MINIMUM(1, 0),
5137 LOGICAL_MAXIMUM(2, 0x7fff),
5138 PHYSICAL_MINIMUM(1, 0),
5139 PHYSICAL_MAXIMUM(1, 0),
5140 REPORT_SIZE(1, 16),
5141 REPORT_COUNT(1, 4),
5142 OUTPUT(1, Data|Var|Abs),
5143 UNIT(1, 0),
5144 UNIT_EXPONENT(1, 0),
5146 USAGE(1, PID_USAGE_TRIGGER_BUTTON),
5147 LOGICAL_MINIMUM(1, 1),
5148 LOGICAL_MAXIMUM(1, 0x08),
5149 PHYSICAL_MINIMUM(1, 1),
5150 PHYSICAL_MAXIMUM(1, 0x08),
5151 REPORT_SIZE(1, 8),
5152 REPORT_COUNT(1, 1),
5153 OUTPUT(1, Data|Var|Abs),
5155 USAGE(1, PID_USAGE_GAIN),
5156 LOGICAL_MINIMUM(1, 0),
5157 LOGICAL_MAXIMUM(2, 0x00ff),
5158 PHYSICAL_MINIMUM(1, 0),
5159 PHYSICAL_MAXIMUM(2, 0x2710),
5160 REPORT_SIZE(1, 8),
5161 REPORT_COUNT(1, 1),
5162 OUTPUT(1, Data|Var|Abs),
5164 USAGE(1, PID_USAGE_DIRECTION),
5165 COLLECTION(1, Logical),
5166 USAGE(4, (HID_USAGE_PAGE_ORDINAL << 16)|1),
5167 USAGE(4, (HID_USAGE_PAGE_ORDINAL << 16)|2),
5168 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
5169 UNIT_EXPONENT(1, -2), /* 10^-2 */
5170 LOGICAL_MINIMUM(1, 0),
5171 LOGICAL_MAXIMUM(4, 360),
5172 PHYSICAL_MINIMUM(1, 0),
5173 PHYSICAL_MAXIMUM(4, 36000),
5174 UNIT(1, 0),
5175 REPORT_SIZE(1, 16),
5176 REPORT_COUNT(1, 2),
5177 OUTPUT(1, Data|Var|Abs),
5178 UNIT_EXPONENT(1, 0),
5179 UNIT(1, 0),
5180 END_COLLECTION,
5181 END_COLLECTION,
5183 USAGE(1, PID_USAGE_SET_CONDITION_REPORT),
5184 COLLECTION(1, Logical),
5185 REPORT_ID(1, 4),
5187 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
5188 LOGICAL_MINIMUM(1, 1),
5189 LOGICAL_MAXIMUM(1, 0x7f),
5190 PHYSICAL_MINIMUM(1, 1),
5191 PHYSICAL_MAXIMUM(1, 0x7f),
5192 REPORT_SIZE(1, 8),
5193 REPORT_COUNT(1, 1),
5194 OUTPUT(1, Data|Var|Abs),
5196 USAGE(1, PID_USAGE_PARAMETER_BLOCK_OFFSET),
5197 LOGICAL_MINIMUM(1, 0),
5198 LOGICAL_MAXIMUM(1, 1),
5199 PHYSICAL_MINIMUM(1, 0),
5200 PHYSICAL_MAXIMUM(1, 1),
5201 REPORT_SIZE(1, 4),
5202 REPORT_COUNT(1, 1),
5203 OUTPUT(1, Data|Var|Abs),
5205 USAGE(1, PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET),
5206 COLLECTION(1, Logical),
5207 USAGE(4, (HID_USAGE_PAGE_ORDINAL << 16)|1),
5208 USAGE(4, (HID_USAGE_PAGE_ORDINAL << 16)|2),
5209 LOGICAL_MINIMUM(1, 0),
5210 LOGICAL_MAXIMUM(1, 1),
5211 PHYSICAL_MINIMUM(1, 0),
5212 PHYSICAL_MAXIMUM(1, 1),
5213 REPORT_SIZE(1, 2),
5214 REPORT_COUNT(1, 2),
5215 OUTPUT(1, Data|Var|Abs),
5216 END_COLLECTION,
5218 USAGE(1, PID_USAGE_CP_OFFSET),
5219 LOGICAL_MINIMUM(2, -10000),
5220 LOGICAL_MAXIMUM(2, +10000),
5221 PHYSICAL_MINIMUM(2, -10000),
5222 PHYSICAL_MAXIMUM(2, +10000),
5223 REPORT_SIZE(1, 16),
5224 REPORT_COUNT(1, 1),
5225 OUTPUT(1, Data|Var|Abs),
5227 USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT),
5228 USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT),
5229 LOGICAL_MINIMUM(2, -10000),
5230 LOGICAL_MAXIMUM(2, +10000),
5231 PHYSICAL_MINIMUM(2, -10000),
5232 PHYSICAL_MAXIMUM(2, +10000),
5233 REPORT_SIZE(1, 16),
5234 REPORT_COUNT(1, 2),
5235 OUTPUT(1, Data|Var|Abs),
5237 USAGE(1, PID_USAGE_POSITIVE_SATURATION),
5238 USAGE(1, PID_USAGE_NEGATIVE_SATURATION),
5239 LOGICAL_MINIMUM(1, 0),
5240 LOGICAL_MAXIMUM(2, 0x00ff),
5241 PHYSICAL_MINIMUM(1, 0),
5242 PHYSICAL_MAXIMUM(2, 10000),
5243 REPORT_SIZE(1, 8),
5244 REPORT_COUNT(1, 2),
5245 OUTPUT(1, Data|Var|Abs),
5247 USAGE(1, PID_USAGE_DEAD_BAND),
5248 LOGICAL_MINIMUM(1, 0),
5249 LOGICAL_MAXIMUM(2, 0x00ff),
5250 PHYSICAL_MINIMUM(1, 0),
5251 PHYSICAL_MAXIMUM(2, 10000),
5252 REPORT_SIZE(1, 8),
5253 REPORT_COUNT(1, 1),
5254 OUTPUT(1, Data|Var|Abs),
5255 END_COLLECTION,
5257 USAGE(1, PID_USAGE_BLOCK_FREE_REPORT),
5258 COLLECTION(1, Logical),
5259 REPORT_ID(1, 5),
5261 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
5262 LOGICAL_MINIMUM(1, 1),
5263 LOGICAL_MAXIMUM(1, 0x7f),
5264 PHYSICAL_MINIMUM(1, 1),
5265 PHYSICAL_MAXIMUM(1, 0x7f),
5266 REPORT_SIZE(1, 8),
5267 REPORT_COUNT(1, 1),
5268 OUTPUT(1, Data|Var|Abs),
5269 END_COLLECTION,
5271 USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT),
5272 COLLECTION(1, Logical),
5273 REPORT_ID(1, 6),
5275 USAGE(1, PID_USAGE_DEVICE_GAIN),
5276 LOGICAL_MINIMUM(1, 0),
5277 LOGICAL_MAXIMUM(2, 0x00ff),
5278 PHYSICAL_MINIMUM(1, 0),
5279 PHYSICAL_MAXIMUM(2, 0x2710),
5280 REPORT_SIZE(1, 8),
5281 REPORT_COUNT(1, 1),
5282 OUTPUT(1, Data|Var|Abs),
5283 END_COLLECTION,
5285 USAGE(1, PID_USAGE_SET_PERIODIC_REPORT),
5286 COLLECTION(1, Logical),
5287 REPORT_ID(1, 7),
5289 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
5290 LOGICAL_MINIMUM(1, 1),
5291 LOGICAL_MAXIMUM(1, 0x7f),
5292 PHYSICAL_MINIMUM(1, 1),
5293 PHYSICAL_MAXIMUM(1, 0x7f),
5294 REPORT_SIZE(1, 8),
5295 REPORT_COUNT(1, 1),
5296 OUTPUT(1, Data|Var|Abs),
5298 USAGE(1, PID_USAGE_MAGNITUDE),
5299 LOGICAL_MINIMUM(1, 0),
5300 LOGICAL_MAXIMUM(2, 10000),
5301 PHYSICAL_MINIMUM(1, 0),
5302 PHYSICAL_MAXIMUM(2, 10000),
5303 REPORT_SIZE(1, 16),
5304 REPORT_COUNT(1, 1),
5305 OUTPUT(1, Data|Var|Abs),
5307 USAGE(1, PID_USAGE_OFFSET),
5308 LOGICAL_MINIMUM(2, -10000),
5309 LOGICAL_MAXIMUM(2, +10000),
5310 PHYSICAL_MINIMUM(2, -10000),
5311 PHYSICAL_MAXIMUM(2, +10000),
5312 REPORT_SIZE(1, 16),
5313 REPORT_COUNT(1, 1),
5314 OUTPUT(1, Data|Var|Abs),
5316 USAGE(1, PID_USAGE_PHASE),
5317 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
5318 UNIT_EXPONENT(1, -2),
5319 LOGICAL_MINIMUM(2, -180),
5320 LOGICAL_MAXIMUM(2, +180),
5321 PHYSICAL_MINIMUM(2, -18000),
5322 PHYSICAL_MAXIMUM(2, +18000),
5323 REPORT_SIZE(1, 16),
5324 REPORT_COUNT(1, 1),
5325 OUTPUT(1, Data|Var|Abs),
5327 USAGE(1, PID_USAGE_PERIOD),
5328 UNIT(2, 0x1003), /* Eng Lin:Time */
5329 UNIT_EXPONENT(1, -3), /* 10^-3 */
5330 LOGICAL_MINIMUM(1, 0),
5331 LOGICAL_MAXIMUM(2, 0x7fff),
5332 PHYSICAL_MINIMUM(1, 0),
5333 PHYSICAL_MAXIMUM(2, 0x7fff),
5334 REPORT_SIZE(1, 16),
5335 REPORT_COUNT(1, 1),
5336 OUTPUT(1, Data|Var|Abs),
5338 UNIT_EXPONENT(1, 0),
5339 UNIT(1, 0), /* None */
5340 END_COLLECTION,
5342 USAGE(1, PID_USAGE_SET_ENVELOPE_REPORT),
5343 COLLECTION(1, Logical),
5344 REPORT_ID(1, 8),
5346 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
5347 LOGICAL_MINIMUM(1, 1),
5348 LOGICAL_MAXIMUM(1, 0x7f),
5349 PHYSICAL_MINIMUM(1, 1),
5350 PHYSICAL_MAXIMUM(1, 0x7f),
5351 REPORT_SIZE(1, 8),
5352 REPORT_COUNT(1, 1),
5353 OUTPUT(1, Data|Var|Abs),
5355 USAGE(1, PID_USAGE_ATTACK_LEVEL),
5356 USAGE(1, PID_USAGE_FADE_LEVEL),
5357 LOGICAL_MINIMUM(1, 0),
5358 LOGICAL_MAXIMUM(2, 0x00ff),
5359 PHYSICAL_MINIMUM(1, 0),
5360 PHYSICAL_MAXIMUM(2, 0x2710),
5361 REPORT_SIZE(1, 8),
5362 REPORT_COUNT(1, 2),
5363 OUTPUT(1, Data|Var|Abs),
5365 USAGE(1, PID_USAGE_ATTACK_TIME),
5366 USAGE(1, PID_USAGE_FADE_TIME),
5367 UNIT(2, 0x1003), /* Eng Lin:Time */
5368 UNIT_EXPONENT(1, -3), /* 10^-3 */
5369 LOGICAL_MINIMUM(1, 0),
5370 LOGICAL_MAXIMUM(2, 0x7fff),
5371 PHYSICAL_MINIMUM(1, 0),
5372 PHYSICAL_MAXIMUM(2, 0x7fff),
5373 REPORT_SIZE(1, 16),
5374 REPORT_COUNT(1, 2),
5375 OUTPUT(1, Data|Var|Abs),
5376 UNIT_EXPONENT(1, 0),
5377 UNIT(1, 0),
5378 END_COLLECTION,
5380 USAGE(1, PID_USAGE_SET_CONSTANT_FORCE_REPORT),
5381 COLLECTION(1, Logical),
5382 REPORT_ID(1, 9),
5384 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
5385 LOGICAL_MINIMUM(1, 1),
5386 LOGICAL_MAXIMUM(1, 0x7f),
5387 PHYSICAL_MINIMUM(1, 1),
5388 PHYSICAL_MAXIMUM(1, 0x7f),
5389 REPORT_SIZE(1, 8),
5390 REPORT_COUNT(1, 1),
5391 OUTPUT(1, Data|Var|Abs),
5393 USAGE(1, PID_USAGE_MAGNITUDE),
5394 LOGICAL_MINIMUM(2, -10000),
5395 LOGICAL_MAXIMUM(2, +10000),
5396 PHYSICAL_MINIMUM(2, -10000),
5397 PHYSICAL_MAXIMUM(2, +10000),
5398 REPORT_SIZE(1, 16),
5399 REPORT_COUNT(1, 1),
5400 OUTPUT(1, Data|Var|Abs),
5401 END_COLLECTION,
5403 USAGE(1, PID_USAGE_SET_RAMP_FORCE_REPORT),
5404 COLLECTION(1, Logical),
5405 REPORT_ID(1, 10),
5407 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
5408 LOGICAL_MINIMUM(1, 1),
5409 LOGICAL_MAXIMUM(1, 0x7f),
5410 PHYSICAL_MINIMUM(1, 1),
5411 PHYSICAL_MAXIMUM(1, 0x7f),
5412 REPORT_SIZE(1, 8),
5413 REPORT_COUNT(1, 1),
5414 OUTPUT(1, Data|Var|Abs),
5416 USAGE(1, PID_USAGE_RAMP_START),
5417 USAGE(1, PID_USAGE_RAMP_END),
5418 LOGICAL_MINIMUM(2, -10000),
5419 LOGICAL_MAXIMUM(2, +10000),
5420 PHYSICAL_MINIMUM(2, -10000),
5421 PHYSICAL_MAXIMUM(2, +10000),
5422 REPORT_SIZE(1, 16),
5423 REPORT_COUNT(1, 2),
5424 OUTPUT(1, Data|Var|Abs),
5425 END_COLLECTION,
5427 USAGE(1, PID_USAGE_POOL_REPORT),
5428 COLLECTION(1, Logical),
5429 REPORT_ID(1, 1),
5431 USAGE(1, PID_USAGE_RAM_POOL_SIZE),
5432 LOGICAL_MINIMUM(1, 0),
5433 LOGICAL_MAXIMUM(4, 0xffff),
5434 PHYSICAL_MINIMUM(1, 0),
5435 PHYSICAL_MAXIMUM(4, 0xffff),
5436 REPORT_SIZE(1, 16),
5437 REPORT_COUNT(1, 1),
5438 FEATURE(1, Data|Var|Abs),
5440 USAGE(1, PID_USAGE_SIMULTANEOUS_EFFECTS_MAX),
5441 LOGICAL_MINIMUM(1, 0),
5442 LOGICAL_MAXIMUM(1, 0x7f),
5443 PHYSICAL_MINIMUM(1, 0),
5444 PHYSICAL_MAXIMUM(1, 0x7f),
5445 REPORT_SIZE(1, 8),
5446 REPORT_COUNT(1, 1),
5447 FEATURE(1, Data|Var|Abs),
5449 USAGE(1, PID_USAGE_DEVICE_MANAGED_POOL),
5450 USAGE(1, PID_USAGE_SHARED_PARAMETER_BLOCKS),
5451 LOGICAL_MINIMUM(1, 0),
5452 LOGICAL_MAXIMUM(1, 1),
5453 PHYSICAL_MINIMUM(1, 0),
5454 PHYSICAL_MAXIMUM(1, 1),
5455 REPORT_SIZE(1, 1),
5456 REPORT_COUNT(1, 8),
5457 FEATURE(1, Data|Var|Abs),
5458 END_COLLECTION,
5460 USAGE(1, PID_USAGE_CREATE_NEW_EFFECT_REPORT),
5461 COLLECTION(1, Logical),
5462 REPORT_ID(1, 2),
5464 USAGE(1, PID_USAGE_EFFECT_TYPE),
5465 COLLECTION(1, NamedArray),
5466 USAGE(1, PID_USAGE_ET_SQUARE),
5467 USAGE(1, PID_USAGE_ET_SINE),
5468 USAGE(1, PID_USAGE_ET_SPRING),
5469 USAGE(1, PID_USAGE_ET_CONSTANT_FORCE),
5470 USAGE(1, PID_USAGE_ET_RAMP),
5471 LOGICAL_MINIMUM(1, 1),
5472 LOGICAL_MAXIMUM(1, 5),
5473 PHYSICAL_MINIMUM(1, 1),
5474 PHYSICAL_MAXIMUM(1, 5),
5475 REPORT_SIZE(1, 8),
5476 REPORT_COUNT(1, 1),
5477 FEATURE(1, Data|Ary|Abs),
5478 END_COLLECTION,
5480 USAGE(4, (HID_USAGE_PAGE_GENERIC<<16)|HID_USAGE_GENERIC_BYTE_COUNT),
5481 LOGICAL_MINIMUM(1, 0x7f),
5482 LOGICAL_MAXIMUM(1, 0x7f),
5483 PHYSICAL_MINIMUM(1, 0x7f),
5484 PHYSICAL_MAXIMUM(1, 0x7f),
5485 REPORT_SIZE(1, 8),
5486 REPORT_COUNT(1, 1),
5487 FEATURE(1, Data|Ary|Abs),
5488 END_COLLECTION,
5490 USAGE(1, PID_USAGE_BLOCK_LOAD_REPORT),
5491 COLLECTION(1, Logical),
5492 REPORT_ID(1, 3),
5494 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
5495 LOGICAL_MINIMUM(1, 1),
5496 LOGICAL_MAXIMUM(1, 0x7f),
5497 PHYSICAL_MINIMUM(1, 1),
5498 PHYSICAL_MAXIMUM(1, 0x7f),
5499 REPORT_SIZE(1, 8),
5500 REPORT_COUNT(1, 1),
5501 FEATURE(1, Data|Var|Abs),
5503 USAGE(1, PID_USAGE_BLOCK_LOAD_STATUS),
5504 COLLECTION(1, NamedArray),
5505 USAGE(1, PID_USAGE_BLOCK_LOAD_SUCCESS),
5506 USAGE(1, PID_USAGE_BLOCK_LOAD_FULL),
5507 USAGE(1, PID_USAGE_BLOCK_LOAD_ERROR),
5508 LOGICAL_MINIMUM(1, 1),
5509 LOGICAL_MAXIMUM(1, 3),
5510 PHYSICAL_MINIMUM(1, 1),
5511 PHYSICAL_MAXIMUM(1, 3),
5512 REPORT_SIZE(1, 8),
5513 REPORT_COUNT(1, 1),
5514 FEATURE(1, Data|Ary|Abs),
5515 END_COLLECTION,
5517 USAGE(1, PID_USAGE_RAM_POOL_AVAILABLE),
5518 LOGICAL_MINIMUM(1, 0),
5519 LOGICAL_MAXIMUM(4, 0xffff),
5520 PHYSICAL_MINIMUM(1, 0),
5521 PHYSICAL_MAXIMUM(4, 0xffff),
5522 REPORT_SIZE(1, 16),
5523 REPORT_COUNT(1, 1),
5524 FEATURE(1, Data|Var|Abs),
5525 END_COLLECTION,
5526 END_COLLECTION,
5528 C_ASSERT(sizeof(report_desc) < MAX_HID_DESCRIPTOR_LEN);
5529 #include "pop_hid_macros.h"
5531 struct hid_device_desc desc =
5533 .use_report_id = TRUE,
5534 .caps =
5536 .InputReportByteLength = 6,
5537 .OutputReportByteLength = 18,
5538 .FeatureReportByteLength = 5,
5540 .attributes = default_attributes,
5542 struct hid_expect expect_init[] =
5544 /* device pool */
5546 .code = IOCTL_HID_GET_FEATURE,
5547 .report_id = 1,
5548 .report_len = 5,
5549 .report_buf = {1,0xff,0x7f,0x7f,0x03},
5550 .todo = TRUE,
5553 struct hid_expect expect_acquire[] =
5555 /* device pool */
5557 .code = IOCTL_HID_GET_FEATURE,
5558 .report_id = 1,
5559 .report_len = 5,
5560 .report_buf = {1,0xff,0x7f,0x7f,0x03},
5561 .todo = TRUE,
5563 /* device control */
5565 .code = IOCTL_HID_WRITE_REPORT,
5566 .report_id = 1,
5567 .report_len = 2,
5568 .report_buf = {1, 0x06},
5569 .todo = TRUE,
5571 /* device control */
5573 .code = IOCTL_HID_WRITE_REPORT,
5574 .report_id = 1,
5575 .report_len = 2,
5576 .report_buf = {1, 0x05},
5577 .todo = TRUE,
5579 /* device control */
5581 .code = IOCTL_HID_WRITE_REPORT,
5582 .report_id = 1,
5583 .report_len = 2,
5584 .report_buf = {1, 0x01},
5586 /* device gain */
5588 .code = IOCTL_HID_WRITE_REPORT,
5589 .report_id = 6,
5590 .report_len = 2,
5591 .report_buf = {6, 0xff},
5594 static struct hid_expect expect_set_gain =
5596 .code = IOCTL_HID_WRITE_REPORT,
5597 .report_id = 6,
5598 .report_len = 2,
5599 .report_buf = {6, 0x7f},
5601 static struct hid_expect expect_pause =
5603 .code = IOCTL_HID_WRITE_REPORT,
5604 .report_id = 1,
5605 .report_len = 2,
5606 .report_buf = {1, 0x02},
5608 static struct hid_expect expect_resume =
5610 .code = IOCTL_HID_WRITE_REPORT,
5611 .report_id = 1,
5612 .report_len = 2,
5613 .report_buf = {1, 0x03},
5615 static struct hid_expect expect_stop =
5617 .code = IOCTL_HID_WRITE_REPORT,
5618 .report_id = 1,
5619 .report_len = 2,
5620 .report_buf = {1, 0x06},
5622 static struct hid_expect expect_disable =
5624 .code = IOCTL_HID_WRITE_REPORT,
5625 .report_id = 1,
5626 .report_len = 2,
5627 .report_buf = {1, 0x05},
5629 static struct hid_expect expect_enable =
5631 .code = IOCTL_HID_WRITE_REPORT,
5632 .report_id = 1,
5633 .report_len = 2,
5634 .report_buf = {1, 0x04},
5636 static struct hid_expect expect_enable_fail =
5638 .code = IOCTL_HID_WRITE_REPORT,
5639 .ret_status = STATUS_NOT_SUPPORTED,
5640 .report_id = 1,
5641 .report_len = 2,
5642 .report_buf = {1, 0x04},
5644 struct hid_expect expect_reset[] =
5646 /* device control */
5648 .code = IOCTL_HID_WRITE_REPORT,
5649 .report_id = 1,
5650 .report_len = 2,
5651 .report_buf = {1, 0x01},
5653 /* device gain */
5655 .code = IOCTL_HID_WRITE_REPORT,
5656 .report_id = 6,
5657 .report_len = 2,
5658 .report_buf = {6, 0x7f},
5661 struct hid_expect expect_create_periodic[] =
5663 /* create new effect */
5665 .code = IOCTL_HID_SET_FEATURE,
5666 .report_id = 2,
5667 .report_len = 3,
5668 .report_buf = {2,0x02,0x00},
5670 /* block load */
5672 .code = IOCTL_HID_GET_FEATURE,
5673 .report_id = 3,
5674 .report_len = 5,
5675 .report_buf = {3,0x01,0x01,0x00,0x00},
5677 /* set periodic */
5679 .code = IOCTL_HID_WRITE_REPORT,
5680 .report_id = 7,
5681 .report_len = 10,
5682 .report_buf = {7,0x01,0xa0,0x0f,0xd0,0x07,0x70,0xff,0x0a,0x00},
5684 /* set envelope */
5686 .code = IOCTL_HID_WRITE_REPORT,
5687 .report_id = 8,
5688 .report_len = 8,
5689 .report_buf = {8,0x01,0x4c,0x7f,0x28,0x00,0x50,0x00},
5691 /* update effect */
5693 .code = IOCTL_HID_WRITE_REPORT,
5694 .report_id = 3,
5695 .report_len = 18,
5696 .report_buf = {3,0x01,0x02,0x04,0x78,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0xff,0xff,0x4e,0x01,0x00,0x00},
5699 struct hid_expect expect_create_periodic_neg[] =
5701 /* create new effect */
5703 .code = IOCTL_HID_SET_FEATURE,
5704 .report_id = 2,
5705 .report_len = 3,
5706 .report_buf = {2,0x02,0x00},
5708 /* block load */
5710 .code = IOCTL_HID_GET_FEATURE,
5711 .report_id = 3,
5712 .report_len = 5,
5713 .report_buf = {3,0x01,0x01,0x00,0x00},
5715 /* set periodic */
5717 .code = IOCTL_HID_WRITE_REPORT,
5718 .report_id = 7,
5719 .report_len = 10,
5720 .report_buf = {7,0x01,0x10,0x27,0x00,0x00,0x70,0xff,0xe8,0x03},
5722 /* update effect */
5724 .code = IOCTL_HID_WRITE_REPORT,
5725 .report_id = 3,
5726 .report_len = 18,
5727 .report_buf = {3,0x01,0x02,0x04,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1a,0x00,0x00,0x00},
5730 struct hid_expect expect_create_condition[] =
5732 /* create new effect */
5734 .code = IOCTL_HID_SET_FEATURE,
5735 .report_id = 2,
5736 .report_len = 3,
5737 .report_buf = {2,0x03,0x00},
5739 /* block load */
5741 .code = IOCTL_HID_GET_FEATURE,
5742 .report_id = 3,
5743 .report_len = 5,
5744 .report_buf = {3,0x01,0x01,0x00,0x00},
5746 /* set condition */
5748 .code = IOCTL_HID_WRITE_REPORT,
5749 .report_id = 4,
5750 .report_len = 12,
5751 .report_buf = {4,0x01,0x00,0x70,0x17,0x7b,0x02,0xe9,0x04,0x4c,0x66,0x7f},
5753 /* update effect */
5755 .code = IOCTL_HID_WRITE_REPORT,
5756 .report_id = 3,
5757 .report_len = 18,
5758 .report_buf = {3,0x01,0x03,0x04,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x00,0x00,0x00},
5761 struct hid_expect expect_create_condition_neg[] =
5763 /* create new effect */
5765 .code = IOCTL_HID_SET_FEATURE,
5766 .report_id = 2,
5767 .report_len = 3,
5768 .report_buf = {2,0x03,0x00},
5770 /* block load */
5772 .code = IOCTL_HID_GET_FEATURE,
5773 .report_id = 3,
5774 .report_len = 5,
5775 .report_buf = {3,0x01,0x01,0x00,0x00},
5777 /* set condition */
5779 .code = IOCTL_HID_WRITE_REPORT,
5780 .report_id = 4,
5781 .report_len = 12,
5782 .report_buf = {4,0x01,0x00,0x70,0x17,0x7b,0x02,0xe9,0x04,0x4c,0x66,0x7f},
5784 /* update effect */
5786 .code = IOCTL_HID_WRITE_REPORT,
5787 .report_id = 3,
5788 .report_len = 18,
5789 .report_buf = {3,0x01,0x03,0x04,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0x00,0x00,0x00},
5792 struct hid_expect expect_create_constant[] =
5794 /* create new effect */
5796 .code = IOCTL_HID_SET_FEATURE,
5797 .report_id = 2,
5798 .report_len = 3,
5799 .report_buf = {2,0x04,0x00},
5801 /* block load */
5803 .code = IOCTL_HID_GET_FEATURE,
5804 .report_id = 3,
5805 .report_len = 5,
5806 .report_buf = {3,0x01,0x01,0x00,0x00},
5808 /* set constant */
5810 .code = IOCTL_HID_WRITE_REPORT,
5811 .report_id = 9,
5812 .report_len = 4,
5813 .report_buf = {9,0x01,0xc8,0x00},
5815 /* set envelope */
5817 .code = IOCTL_HID_WRITE_REPORT,
5818 .report_id = 8,
5819 .report_len = 8,
5820 .report_buf = {8,0x01,0x19,0x4c,0x14,0x00,0x3c,0x00},
5822 /* update effect */
5824 .code = IOCTL_HID_WRITE_REPORT,
5825 .report_id = 3,
5826 .report_len = 18,
5827 .report_buf = {3,0x01,0x04,0x04,0x5a,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0xff,0x7f,0x4e,0x01,0x00,0x00},
5830 struct hid_expect expect_create_constant_neg[] =
5832 /* create new effect */
5834 .code = IOCTL_HID_SET_FEATURE,
5835 .report_id = 2,
5836 .report_len = 3,
5837 .report_buf = {2,0x04,0x00},
5839 /* block load */
5841 .code = IOCTL_HID_GET_FEATURE,
5842 .report_id = 3,
5843 .report_len = 5,
5844 .report_buf = {3,0x01,0x01,0x00,0x00},
5846 /* set constant */
5848 .code = IOCTL_HID_WRITE_REPORT,
5849 .report_id = 9,
5850 .report_len = 4,
5851 .report_buf = {9,0x01,0x18,0xfc},
5853 /* update effect */
5855 .code = IOCTL_HID_WRITE_REPORT,
5856 .report_id = 3,
5857 .report_len = 18,
5858 .report_buf = {3,0x01,0x04,0x04,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x7f,0x4e,0x01,0x00,0x00},
5861 struct hid_expect expect_create_ramp[] =
5863 /* create new effect */
5865 .code = IOCTL_HID_SET_FEATURE,
5866 .report_id = 2,
5867 .report_len = 3,
5868 .report_buf = {2,0x05,0x00},
5870 /* block load */
5872 .code = IOCTL_HID_GET_FEATURE,
5873 .report_id = 3,
5874 .report_len = 5,
5875 .report_buf = {3,0x01,0x01,0x00,0x00},
5877 /* set ramp */
5879 .code = IOCTL_HID_WRITE_REPORT,
5880 .report_id = 10,
5881 .report_len = 6,
5882 .report_buf = {10,0x01,0xc8,0x00,0x20,0x03},
5884 /* set envelope */
5886 .code = IOCTL_HID_WRITE_REPORT,
5887 .report_id = 8,
5888 .report_len = 8,
5889 .report_buf = {8,0x01,0x19,0x4c,0x14,0x00,0x3c,0x00},
5891 /* update effect */
5893 .code = IOCTL_HID_WRITE_REPORT,
5894 .report_id = 3,
5895 .report_len = 18,
5896 .report_buf = {3,0x01,0x05,0x04,0x5a,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0xff,0xff,0x4e,0x01,0x00,0x00},
5899 struct hid_expect expect_create_ramp_inf[] =
5901 /* create new effect */
5903 .code = IOCTL_HID_SET_FEATURE,
5904 .report_id = 2,
5905 .report_len = 3,
5906 .report_buf = {2,0x05,0x00},
5908 /* block load */
5910 .code = IOCTL_HID_GET_FEATURE,
5911 .report_id = 3,
5912 .report_len = 5,
5913 .report_buf = {3,0x01,0x01,0x00,0x00},
5915 /* set ramp */
5917 .code = IOCTL_HID_WRITE_REPORT,
5918 .report_id = 10,
5919 .report_len = 6,
5920 .report_buf = {10,0x01,0xe8,0x03,0xa0,0x0f},
5922 /* update effect */
5924 .code = IOCTL_HID_WRITE_REPORT,
5925 .report_id = 3,
5926 .report_len = 18,
5927 .report_buf = {3,0x01,0x05,0x04,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x01,0x00,0x00},
5930 struct hid_expect expect_create_ramp_neg[] =
5932 /* create new effect */
5934 .code = IOCTL_HID_SET_FEATURE,
5935 .report_id = 2,
5936 .report_len = 3,
5937 .report_buf = {2,0x05,0x00},
5939 /* block load */
5941 .code = IOCTL_HID_GET_FEATURE,
5942 .report_id = 3,
5943 .report_len = 5,
5944 .report_buf = {3,0x01,0x01,0x00,0x00},
5946 /* set ramp */
5948 .code = IOCTL_HID_WRITE_REPORT,
5949 .report_id = 10,
5950 .report_len = 6,
5951 .report_buf = {10,0x01,0x18,0xfc,0x60,0xf0},
5953 /* update effect */
5955 .code = IOCTL_HID_WRITE_REPORT,
5956 .report_id = 3,
5957 .report_len = 18,
5958 .report_buf = {3,0x01,0x05,0x04,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x01,0x00,0x00},
5961 struct hid_expect expect_effect_start =
5963 .code = IOCTL_HID_WRITE_REPORT,
5964 .report_id = 2,
5965 .report_len = 4,
5966 .report_buf = {2,0x01,0x01,0x01},
5968 struct hid_expect expect_effect_stop =
5970 .code = IOCTL_HID_WRITE_REPORT,
5971 .report_id = 2,
5972 .report_len = 4,
5973 .report_buf = {2,0x01,0x03,0x00},
5975 struct hid_expect expect_unload[] =
5977 /* effect stop */
5979 .code = IOCTL_HID_WRITE_REPORT,
5980 .report_id = 2,
5981 .report_len = 4,
5982 .report_buf = {2,0x01,0x03,0x00},
5984 /* effect free */
5986 .code = IOCTL_HID_WRITE_REPORT,
5987 .report_id = 5,
5988 .report_len = 2,
5989 .report_buf = {5,0x01},
5992 static const WCHAR *condition_effect_class_name = RuntimeClass_Windows_Gaming_Input_ForceFeedback_ConditionForceEffect;
5993 static const WCHAR *periodic_effect_class_name = RuntimeClass_Windows_Gaming_Input_ForceFeedback_PeriodicForceEffect;
5994 static const WCHAR *constant_effect_class_name = RuntimeClass_Windows_Gaming_Input_ForceFeedback_ConstantForceEffect;
5995 static const WCHAR *force_feedback_motor = RuntimeClass_Windows_Gaming_Input_ForceFeedback_ForceFeedbackMotor;
5996 static const WCHAR *ramp_effect_class_name = RuntimeClass_Windows_Gaming_Input_ForceFeedback_RampForceEffect;
5997 static const WCHAR *controller_class_name = RuntimeClass_Windows_Gaming_Input_RawGameController;
5999 DIPROPGUIDANDPATH guid_path =
6001 .diph =
6003 .dwSize = sizeof(DIPROPGUIDANDPATH),
6004 .dwHeaderSize = sizeof(DIPROPHEADER),
6005 .dwHow = DIPH_DEVICE,
6008 TimeSpan delay = {100000}, attack_duration = {200000}, release_duration = {300000}, duration = {400000}, infinite_duration = {INT64_MAX};
6009 Vector3 direction = {0.1, 0.2, 0.3}, end_direction = {0.4, 0.5, 0.6};
6010 DIDEVICEINSTANCEW devinst = {.dwSize = sizeof(DIDEVICEINSTANCEW)};
6011 IAsyncOperation_ForceFeedbackLoadEffectResult *result_async;
6012 IAsyncOperationCompletedHandler_boolean *tmp_handler;
6013 IVectorView_RawGameController *controllers_view;
6014 IConditionForceEffectFactory *condition_factory;
6015 IRawGameControllerStatics *controller_statics;
6016 EventRegistrationToken controller_added_token;
6017 IPeriodicForceEffectFactory *periodic_factory;
6018 struct bool_async_handler *bool_async_handler;
6019 ForceFeedbackEffectAxes supported_axes, axes;
6020 IVectorView_ForceFeedbackMotor *motors_view;
6021 IConditionForceEffect *condition_effect;
6022 ConditionForceEffectKind condition_kind;
6023 IActivationFactory *activation_factory;
6024 IPeriodicForceEffect *periodic_effect;
6025 IConstantForceEffect *constant_effect;
6026 PeriodicForceEffectKind periodic_kind;
6027 IAsyncOperation_boolean *bool_async;
6028 IRawGameController *raw_controller;
6029 ForceFeedbackEffectState state;
6030 IRampForceEffect *ramp_effect;
6031 IInspectable *tmp_inspectable;
6032 IForceFeedbackEffect *effect;
6033 IDirectInputDevice8W *device;
6034 IForceFeedbackMotor *motor;
6035 BOOLEAN paused, enabled;
6036 IAsyncInfo *async_info;
6037 DOUBLE gain;
6038 HSTRING str;
6039 HANDLE file;
6040 UINT32 size;
6041 HRESULT hr;
6042 DWORD ret;
6044 if (!load_combase_functions()) return;
6046 cleanup_registry_keys();
6048 hr = pRoInitialize( RO_INIT_MULTITHREADED );
6049 ok( hr == RPC_E_CHANGED_MODE, "RoInitialize returned %#lx\n", hr );
6051 hr = pWindowsCreateString( controller_class_name, wcslen( controller_class_name ), &str );
6052 ok( hr == S_OK, "WindowsCreateString returned %#lx\n", hr );
6053 hr = pRoGetActivationFactory( str, &IID_IRawGameControllerStatics, (void **)&controller_statics );
6054 ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "RoGetActivationFactory returned %#lx\n", hr );
6055 pWindowsDeleteString( str );
6057 if (hr == REGDB_E_CLASSNOTREG)
6059 win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( controller_class_name ) );
6060 goto done;
6063 controller_added.event = CreateEventW( NULL, FALSE, FALSE, NULL );
6064 ok( !!controller_added.event, "CreateEventW failed, error %lu\n", GetLastError() );
6066 hr = IRawGameControllerStatics_add_RawGameControllerAdded( controller_statics, &controller_added.IEventHandler_RawGameController_iface,
6067 &controller_added_token );
6068 ok( hr == S_OK, "add_RawGameControllerAdded returned %#lx\n", hr );
6069 ok( controller_added_token.value, "got token %I64u\n", controller_added_token.value );
6071 desc.report_descriptor_len = sizeof(report_desc);
6072 memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) );
6073 desc.expect_size = sizeof(expect_init);
6074 memcpy( desc.expect, expect_init, sizeof(expect_init) );
6075 fill_context( desc.context, ARRAY_SIZE(desc.context) );
6077 if (!hid_device_start( &desc, 1 )) goto done;
6078 ret = WaitForSingleObject( controller_added.event, 5000 );
6079 ok( !ret, "WaitForSingleObject returned %#lx\n", ret );
6080 CloseHandle( controller_added.event );
6082 if (FAILED(hr = dinput_test_create_device( 0x800, &devinst, &device ))) goto done;
6083 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GUIDANDPATH, &guid_path.diph );
6084 ok( hr == DI_OK, "GetProperty DIPROP_GUIDANDPATH returned %#lx\n", hr );
6085 IDirectInputDevice8_Release( device );
6087 file = CreateFileW( guid_path.wszPath, FILE_READ_ACCESS | FILE_WRITE_ACCESS,
6088 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
6089 FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL );
6090 ok( file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError() );
6092 hr = IRawGameControllerStatics_remove_RawGameControllerAdded( controller_statics, controller_added_token );
6093 ok( hr == S_OK, "remove_RawGameControllerAdded returned %#lx\n", hr );
6095 hr = IRawGameControllerStatics_get_RawGameControllers( controller_statics, &controllers_view );
6096 ok( hr == S_OK, "get_RawGameControllers returned %#lx\n", hr );
6097 hr = IVectorView_RawGameController_get_Size( controllers_view, &size );
6098 ok( hr == S_OK, "get_Size returned %#lx\n", hr );
6099 ok( size == 1, "got size %u\n", size );
6100 hr = IVectorView_RawGameController_GetAt( controllers_view, 0, &raw_controller );
6101 ok( hr == S_OK, "GetAt returned %#lx\n", hr );
6102 IVectorView_RawGameController_Release( controllers_view );
6104 set_hid_expect( file, expect_acquire, sizeof(expect_acquire) );
6105 hr = IRawGameController_get_ForceFeedbackMotors( raw_controller, &motors_view );
6106 ok( hr == S_OK, "get_ForceFeedbackMotors returned %#lx\n", hr );
6107 wait_hid_expect( file, 100 ); /* device gain reports are written asynchronously */
6109 hr = IVectorView_ForceFeedbackMotor_get_Size( motors_view, &size );
6110 ok( hr == S_OK, "get_Size returned %#lx\n", hr );
6111 ok( size == 1, "got size %u\n", size );
6112 hr = IVectorView_ForceFeedbackMotor_GetAt( motors_view, 0, &motor );
6113 ok( hr == S_OK, "GetAt returned %#lx\n", hr );
6114 IVectorView_ForceFeedbackMotor_Release( motors_view );
6116 check_interface( motor, &IID_IUnknown, TRUE );
6117 check_interface( motor, &IID_IInspectable, TRUE );
6118 check_interface( motor, &IID_IAgileObject, TRUE );
6119 check_interface( motor, &IID_IForceFeedbackMotor, TRUE );
6120 check_runtimeclass( motor, force_feedback_motor );
6122 paused = TRUE;
6123 hr = IForceFeedbackMotor_get_AreEffectsPaused( motor, &paused );
6124 ok( hr == S_OK, "get_AreEffectsPaused returned %#lx\n", hr );
6125 ok( paused == FALSE, "got paused %u\n", paused );
6127 gain = 12345.6;
6128 hr = IForceFeedbackMotor_get_MasterGain( motor, &gain );
6129 ok( hr == S_OK, "get_MasterGain returned %#lx\n", hr );
6130 ok( gain == 1.0, "got gain %f\n", gain );
6131 set_hid_expect( file, &expect_set_gain, sizeof(expect_set_gain) );
6132 hr = IForceFeedbackMotor_put_MasterGain( motor, 0.5 );
6133 ok( hr == S_OK, "put_MasterGain returned %#lx\n", hr );
6134 wait_hid_expect( file, 100 ); /* device gain reports are written asynchronously */
6136 enabled = FALSE;
6137 hr = IForceFeedbackMotor_get_IsEnabled( motor, &enabled );
6138 ok( hr == S_OK, "get_IsEnabled returned %#lx\n", hr );
6139 ok( enabled == TRUE, "got enabled %u\n", enabled );
6141 /* SupportedAxes always returns ForceFeedbackEffectAxes_X on Windows,
6142 * no matter which axis is available for FFB in the Set Effects report,
6143 * or whether a X axis is declared at all.
6146 supported_axes = 0xdeadbeef;
6147 hr = IForceFeedbackMotor_get_SupportedAxes( motor, &supported_axes );
6148 ok( hr == S_OK, "get_SupportedAxes returned %#lx\n", hr );
6149 axes = ForceFeedbackEffectAxes_X | ForceFeedbackEffectAxes_Y;
6150 ok( supported_axes == axes || broken( supported_axes == ForceFeedbackEffectAxes_X ),
6151 "got axes %#x\n", supported_axes );
6153 set_hid_expect( file, &expect_pause, sizeof(expect_pause) );
6154 hr = IForceFeedbackMotor_PauseAllEffects( motor );
6155 ok( hr == S_OK, "PauseAllEffects returned %#lx\n", hr );
6156 set_hid_expect( file, &expect_resume, sizeof(expect_resume) );
6157 hr = IForceFeedbackMotor_ResumeAllEffects( motor );
6158 ok( hr == S_OK, "ResumeAllEffects returned %#lx\n", hr );
6159 set_hid_expect( file, &expect_stop, sizeof(expect_stop) );
6160 hr = IForceFeedbackMotor_StopAllEffects( motor );
6161 ok( hr == S_OK, "StopAllEffects returned %#lx\n", hr );
6162 set_hid_expect( file, NULL, 0 );
6165 set_hid_expect( file, &expect_disable, sizeof(expect_disable) );
6166 hr = IForceFeedbackMotor_TryDisableAsync( motor, &bool_async );
6167 ok( hr == S_OK, "TryDisableAsync returned %#lx\n", hr );
6168 wait_hid_expect( file, 100 );
6169 check_bool_async( bool_async, 1, Completed, S_OK, TRUE );
6171 check_interface( bool_async, &IID_IUnknown, TRUE );
6172 check_interface( bool_async, &IID_IInspectable, TRUE );
6173 check_interface( bool_async, &IID_IAgileObject, TRUE );
6174 check_interface( bool_async, &IID_IAsyncInfo, TRUE );
6175 check_interface( bool_async, &IID_IAsyncOperation_boolean, TRUE );
6176 check_runtimeclass( bool_async, L"Windows.Foundation.IAsyncOperation`1<Boolean>" );
6178 hr = IAsyncOperation_boolean_get_Completed( bool_async, &tmp_handler );
6179 ok( hr == S_OK, "get_Completed returned %#lx\n", hr );
6180 ok( tmp_handler == NULL, "got handler %p\n", tmp_handler );
6182 bool_async_handler = impl_from_IAsyncOperationCompletedHandler_boolean( bool_async_handler_create( NULL ) );
6183 ok( !!bool_async_handler, "bool_async_handler_create failed\n" );
6184 hr = IAsyncOperation_boolean_put_Completed( bool_async, &bool_async_handler->IAsyncOperationCompletedHandler_boolean_iface );
6185 ok( hr == S_OK, "put_Completed returned %#lx\n", hr );
6186 ok( bool_async_handler->invoked, "handler not invoked\n" );
6187 ok( bool_async_handler->async == bool_async, "got async %p\n", bool_async_handler->async );
6188 ok( bool_async_handler->status == Completed, "got status %u\n", bool_async_handler->status );
6189 hr = IAsyncOperation_boolean_get_Completed( bool_async, &tmp_handler );
6190 ok( hr == S_OK, "get_Completed returned %#lx\n", hr );
6191 ok( tmp_handler == NULL, "got handler %p\n", tmp_handler );
6192 IAsyncOperationCompletedHandler_boolean_Release( &bool_async_handler->IAsyncOperationCompletedHandler_boolean_iface );
6194 bool_async_handler = impl_from_IAsyncOperationCompletedHandler_boolean( bool_async_handler_create( NULL ) );
6195 ok( !!bool_async_handler, "bool_async_handler_create failed\n" );
6196 hr = IAsyncOperation_boolean_put_Completed( bool_async, &bool_async_handler->IAsyncOperationCompletedHandler_boolean_iface );
6197 ok( hr == E_ILLEGAL_DELEGATE_ASSIGNMENT, "put_Completed returned %#lx\n", hr );
6198 ok( !bool_async_handler->invoked, "handler invoked\n" );
6199 ok( bool_async_handler->async == NULL, "got async %p\n", bool_async_handler->async );
6200 ok( bool_async_handler->status == Started, "got status %u\n", bool_async_handler->status );
6201 IAsyncOperationCompletedHandler_boolean_Release( &bool_async_handler->IAsyncOperationCompletedHandler_boolean_iface );
6203 hr = IAsyncOperation_boolean_QueryInterface( bool_async, &IID_IAsyncInfo, (void **)&async_info );
6204 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6205 hr = IAsyncInfo_Cancel( async_info );
6206 ok( hr == S_OK, "Cancel returned %#lx\n", hr );
6207 check_bool_async( bool_async, 1, Completed, S_OK, TRUE );
6208 hr = IAsyncInfo_Close( async_info );
6209 ok( hr == S_OK, "Close returned %#lx\n", hr );
6210 check_bool_async( bool_async, 1, 4, S_OK, FALSE );
6211 IAsyncInfo_Release( async_info );
6213 IAsyncOperation_boolean_Release( bool_async );
6216 set_hid_expect( file, &expect_enable_fail, sizeof(expect_enable_fail) );
6217 hr = IForceFeedbackMotor_TryEnableAsync( motor, &bool_async );
6218 ok( hr == S_OK, "TryEnableAsync returned %#lx\n", hr );
6219 wait_hid_expect( file, 100 );
6220 check_bool_async( bool_async, 1, Error, 0x8685400d, FALSE );
6222 bool_async_handler = impl_from_IAsyncOperationCompletedHandler_boolean( bool_async_handler_create( NULL ) );
6223 ok( !!bool_async_handler, "bool_async_handler_create failed\n" );
6224 hr = IAsyncOperation_boolean_put_Completed( bool_async, &bool_async_handler->IAsyncOperationCompletedHandler_boolean_iface );
6225 ok( hr == S_OK, "put_Completed returned %#lx\n", hr );
6226 ok( bool_async_handler->invoked, "handler not invoked\n" );
6227 ok( bool_async_handler->async == bool_async, "got async %p\n", bool_async_handler->async );
6228 ok( bool_async_handler->status == Error, "got status %u\n", bool_async_handler->status );
6229 IAsyncOperationCompletedHandler_boolean_Release( &bool_async_handler->IAsyncOperationCompletedHandler_boolean_iface );
6231 hr = IAsyncOperation_boolean_QueryInterface( bool_async, &IID_IAsyncInfo, (void **)&async_info );
6232 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6233 hr = IAsyncInfo_Cancel( async_info );
6234 ok( hr == S_OK, "Cancel returned %#lx\n", hr );
6235 check_bool_async( bool_async, 1, Error, 0x8685400d, FALSE );
6236 hr = IAsyncInfo_Close( async_info );
6237 ok( hr == S_OK, "Close returned %#lx\n", hr );
6238 check_bool_async( bool_async, 1, 4, 0x8685400d, FALSE );
6239 IAsyncInfo_Release( async_info );
6241 IAsyncOperation_boolean_Release( bool_async );
6244 set_hid_expect( file, &expect_enable, sizeof(expect_enable) );
6245 hr = IForceFeedbackMotor_TryEnableAsync( motor, &bool_async );
6246 ok( hr == S_OK, "TryEnableAsync returned %#lx\n", hr );
6247 wait_hid_expect( file, 100 );
6248 IAsyncOperation_boolean_Release( bool_async );
6251 set_hid_expect( file, expect_reset, sizeof(expect_reset) );
6252 hr = IForceFeedbackMotor_TryResetAsync( motor, &bool_async );
6253 ok( hr == S_OK, "TryResetAsync returned %#lx\n", hr );
6254 wait_hid_expect( file, 100 );
6255 IAsyncOperation_boolean_Release( bool_async );
6258 hr = pWindowsCreateString( force_feedback_motor, wcslen( force_feedback_motor ), &str );
6259 ok( hr == S_OK, "WindowsCreateString returned %#lx\n", hr );
6260 hr = pRoGetActivationFactory( str, &IID_IInspectable, (void **)&tmp_inspectable );
6261 ok( hr == REGDB_E_CLASSNOTREG, "RoGetActivationFactory returned %#lx\n", hr );
6262 pWindowsDeleteString( str );
6265 hr = pWindowsCreateString( periodic_effect_class_name, wcslen( periodic_effect_class_name ), &str );
6266 ok( hr == S_OK, "WindowsCreateString returned %#lx\n", hr );
6267 hr = pRoGetActivationFactory( str, &IID_IPeriodicForceEffectFactory, (void **)&periodic_factory );
6268 ok( hr == S_OK, "RoGetActivationFactory returned %#lx\n", hr );
6269 pWindowsDeleteString( str );
6271 check_interface( periodic_factory, &IID_IUnknown, TRUE );
6272 check_interface( periodic_factory, &IID_IInspectable, TRUE );
6273 check_interface( periodic_factory, &IID_IAgileObject, TRUE );
6274 check_interface( periodic_factory, &IID_IActivationFactory, TRUE );
6275 check_interface( periodic_factory, &IID_IPeriodicForceEffectFactory, TRUE );
6276 check_interface( periodic_factory, &IID_IConditionForceEffectFactory, FALSE );
6278 hr = IPeriodicForceEffectFactory_QueryInterface( periodic_factory, &IID_IActivationFactory, (void **)&activation_factory );
6279 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6280 hr = IActivationFactory_ActivateInstance( activation_factory, &tmp_inspectable );
6281 ok( hr == E_NOTIMPL, "ActivateInstance returned %#lx\n", hr );
6282 IActivationFactory_Release( activation_factory );
6284 hr = IPeriodicForceEffectFactory_CreateInstance( periodic_factory, PeriodicForceEffectKind_SawtoothWaveUp, &effect );
6285 ok( hr == S_OK, "CreateInstance returned %#lx\n", hr );
6287 check_interface( effect, &IID_IUnknown, TRUE );
6288 check_interface( effect, &IID_IInspectable, TRUE );
6289 check_interface( effect, &IID_IAgileObject, TRUE );
6290 check_interface( effect, &IID_IForceFeedbackEffect, TRUE );
6291 check_interface( effect, &IID_IPeriodicForceEffect, TRUE );
6292 check_interface( effect, &IID_IConditionForceEffect, FALSE );
6293 check_runtimeclass( effect, periodic_effect_class_name );
6295 hr = IForceFeedbackEffect_QueryInterface( effect, &IID_IPeriodicForceEffect, (void **)&periodic_effect );
6296 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6298 hr = IPeriodicForceEffect_get_Kind( periodic_effect, &periodic_kind );
6299 ok( hr == S_OK, "get_Kind returned %#lx\n", hr );
6300 ok( periodic_kind == PeriodicForceEffectKind_SawtoothWaveUp, "got kind %u\n", periodic_kind );
6301 hr = IPeriodicForceEffect_SetParameters( periodic_effect, direction, 1.0, 0.1, 0.0, duration );
6302 ok( hr == S_OK, "SetParameters returned %#lx\n", hr );
6303 hr = IPeriodicForceEffect_SetParametersWithEnvelope( periodic_effect, direction, 100.0, 0.1, 0.2, 0.3, 0.4, 0.5,
6304 delay, attack_duration, duration, release_duration, 1 );
6305 ok( hr == S_OK, "SetParametersWithEnvelope returned %#lx\n", hr );
6306 IPeriodicForceEffect_Release( periodic_effect );
6308 gain = 12345.6;
6309 hr = IForceFeedbackEffect_get_Gain( effect, &gain );
6310 ok( hr == S_OK, "get_Gain returned %#lx\n", hr );
6311 ok( gain == 1.0, "got gain %f\n", gain );
6312 hr = IForceFeedbackEffect_put_Gain( effect, 0.5 );
6313 ok( hr == S_FALSE, "put_Gain returned %#lx\n", hr );
6314 state = 0xdeadbeef;
6315 hr = IForceFeedbackEffect_get_State( effect, &state );
6316 ok( hr == S_OK, "get_State returned %#lx\n", hr );
6317 ok( state == ForceFeedbackEffectState_Stopped, "got state %#x\n", state );
6318 hr = IForceFeedbackEffect_Start( effect );
6319 todo_wine
6320 ok( hr == 0x86854003, "Start returned %#lx\n", hr );
6321 hr = IForceFeedbackEffect_Stop( effect );
6322 todo_wine
6323 ok( hr == 0x86854003, "Stop returned %#lx\n", hr );
6325 hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async );
6326 ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr );
6327 await_result( result_async );
6328 check_result_async( result_async, 1, Error, 0x86854008, ForceFeedbackLoadEffectResult_EffectNotSupported );
6329 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async );
6331 hr = IForceFeedbackEffect_Start( effect );
6332 todo_wine
6333 ok( hr == 0x86854003, "Start returned %#lx\n", hr );
6334 hr = IForceFeedbackEffect_Stop( effect );
6335 todo_wine
6336 ok( hr == 0x86854003, "Stop returned %#lx\n", hr );
6337 hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async );
6338 todo_wine
6339 ok( hr == 0x86854003, "TryUnloadEffectAsync returned %#lx\n", hr );
6341 IForceFeedbackEffect_Release( effect );
6344 hr = IPeriodicForceEffectFactory_CreateInstance( periodic_factory, PeriodicForceEffectKind_SineWave, &effect );
6345 ok( hr == S_OK, "CreateInstance returned %#lx\n", hr );
6347 check_interface( effect, &IID_IUnknown, TRUE );
6348 check_interface( effect, &IID_IInspectable, TRUE );
6349 check_interface( effect, &IID_IAgileObject, TRUE );
6350 check_interface( effect, &IID_IForceFeedbackEffect, TRUE );
6351 check_interface( effect, &IID_IPeriodicForceEffect, TRUE );
6352 check_interface( effect, &IID_IConditionForceEffect, FALSE );
6353 check_runtimeclass( effect, periodic_effect_class_name );
6355 hr = IForceFeedbackEffect_QueryInterface( effect, &IID_IPeriodicForceEffect, (void **)&periodic_effect );
6356 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6358 hr = IPeriodicForceEffect_get_Kind( periodic_effect, &periodic_kind );
6359 ok( hr == S_OK, "get_Kind returned %#lx\n", hr );
6360 ok( periodic_kind == PeriodicForceEffectKind_SineWave, "got kind %u\n", periodic_kind );
6361 hr = IPeriodicForceEffect_SetParameters( periodic_effect, direction, 1.0, 0.1, 0.0, duration );
6362 ok( hr == S_OK, "SetParameters returned %#lx\n", hr );
6363 hr = IPeriodicForceEffect_SetParametersWithEnvelope( periodic_effect, direction, 100.0, 0.1, 0.2, 0.3, 0.4, 0.5,
6364 delay, duration, duration, duration, 1 );
6365 ok( hr == S_OK, "SetParametersWithEnvelope returned %#lx\n", hr );
6366 IPeriodicForceEffect_Release( periodic_effect );
6368 /* Windows.Gaming.Input always uses the X and Y directions on Windows,
6369 * ignoring what is declared in the Axes Enable collection at the
6370 * Set Effects report, or even the existence of the axes in the HID
6371 * report. It ignores the Z direction, at least on HID PID devices.
6372 * DirectInput works properly in such cases on Windows.
6375 set_hid_expect( file, expect_create_periodic, sizeof(expect_create_periodic) );
6376 hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async );
6377 ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr );
6378 await_result( result_async );
6379 check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded );
6380 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async );
6381 set_hid_expect( file, NULL, 0 );
6383 set_hid_expect( file, &expect_effect_start, sizeof(expect_effect_start) );
6384 hr = IForceFeedbackEffect_Start( effect );
6385 ok( hr == S_OK, "Start returned %#lx\n", hr );
6386 set_hid_expect( file, &expect_effect_start, sizeof(expect_effect_start) );
6387 hr = IForceFeedbackEffect_Start( effect );
6388 ok( hr == S_OK, "Start returned %#lx\n", hr );
6390 set_hid_expect( file, &expect_effect_stop, sizeof(expect_effect_stop) );
6391 hr = IForceFeedbackEffect_Stop( effect );
6392 ok( hr == S_OK, "Stop returned %#lx\n", hr );
6393 set_hid_expect( file, &expect_effect_stop, sizeof(expect_effect_stop) );
6394 hr = IForceFeedbackEffect_Stop( effect );
6395 ok( hr == S_OK, "Stop returned %#lx\n", hr );
6397 set_hid_expect( file, expect_unload, sizeof(expect_unload) );
6398 hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async );
6399 ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr );
6400 await_bool( bool_async );
6401 check_bool_async( bool_async, 1, Completed, S_OK, TRUE );
6402 IAsyncOperation_boolean_Release( bool_async );
6403 set_hid_expect( file, NULL, 0 );
6406 hr = IForceFeedbackEffect_QueryInterface( effect, &IID_IPeriodicForceEffect, (void **)&periodic_effect );
6407 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6408 direction.X = -direction.X;
6409 hr = IPeriodicForceEffect_SetParameters( periodic_effect, direction, 1.0, 0.1, 0.0, duration );
6410 ok( hr == S_OK, "SetParameters returned %#lx\n", hr );
6411 direction.X = -direction.X;
6412 IPeriodicForceEffect_Release( periodic_effect );
6414 set_hid_expect( file, expect_create_periodic_neg, sizeof(expect_create_periodic_neg) );
6415 hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async );
6416 ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr );
6417 await_result( result_async );
6418 check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded );
6419 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async );
6420 set_hid_expect( file, NULL, 0 );
6422 set_hid_expect( file, expect_unload, sizeof(expect_unload) );
6423 hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async );
6424 ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr );
6425 await_bool( bool_async );
6426 check_bool_async( bool_async, 1, Completed, S_OK, TRUE );
6427 IAsyncOperation_boolean_Release( bool_async );
6428 set_hid_expect( file, NULL, 0 );
6431 IForceFeedbackEffect_Release( effect );
6433 IPeriodicForceEffectFactory_Release( periodic_factory );
6436 hr = pWindowsCreateString( condition_effect_class_name, wcslen( condition_effect_class_name ), &str );
6437 ok( hr == S_OK, "WindowsCreateString returned %#lx\n", hr );
6438 hr = pRoGetActivationFactory( str, &IID_IConditionForceEffectFactory, (void **)&condition_factory );
6439 ok( hr == S_OK, "RoGetActivationFactory returned %#lx\n", hr );
6440 pWindowsDeleteString( str );
6442 check_interface( condition_factory, &IID_IUnknown, TRUE );
6443 check_interface( condition_factory, &IID_IInspectable, TRUE );
6444 check_interface( condition_factory, &IID_IAgileObject, TRUE );
6445 check_interface( condition_factory, &IID_IActivationFactory, TRUE );
6446 check_interface( condition_factory, &IID_IConditionForceEffectFactory, TRUE );
6447 check_interface( condition_factory, &IID_IPeriodicForceEffectFactory, FALSE );
6449 hr = IConditionForceEffectFactory_QueryInterface( condition_factory, &IID_IActivationFactory, (void **)&activation_factory );
6450 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6451 hr = IActivationFactory_ActivateInstance( activation_factory, &tmp_inspectable );
6452 ok( hr == E_NOTIMPL, "ActivateInstance returned %#lx\n", hr );
6453 IActivationFactory_Release( activation_factory );
6456 hr = IConditionForceEffectFactory_CreateInstance( condition_factory, ConditionForceEffectKind_Spring, &effect );
6457 ok( hr == S_OK, "CreateInstance returned %#lx\n", hr );
6459 check_interface( effect, &IID_IUnknown, TRUE );
6460 check_interface( effect, &IID_IInspectable, TRUE );
6461 check_interface( effect, &IID_IAgileObject, TRUE );
6462 check_interface( effect, &IID_IForceFeedbackEffect, TRUE );
6463 check_interface( effect, &IID_IConditionForceEffect, TRUE );
6464 check_interface( effect, &IID_IPeriodicForceEffect, FALSE );
6465 check_runtimeclass( effect, condition_effect_class_name );
6467 hr = IForceFeedbackEffect_QueryInterface( effect, &IID_IConditionForceEffect, (void **)&condition_effect );
6468 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6470 hr = IConditionForceEffect_get_Kind( condition_effect, &condition_kind );
6471 ok( hr == S_OK, "get_Kind returned %#lx\n", hr );
6472 ok( condition_kind == ConditionForceEffectKind_Spring, "got kind %u\n", condition_kind );
6473 hr = IConditionForceEffect_SetParameters( condition_effect, direction, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6 );
6474 ok( hr == S_OK, "SetParameters returned %#lx\n", hr );
6475 IConditionForceEffect_Release( condition_effect );
6477 set_hid_expect( file, expect_create_condition, sizeof(expect_create_condition) );
6478 hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async );
6479 ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr );
6480 await_result( result_async );
6481 check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded );
6482 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async );
6483 set_hid_expect( file, NULL, 0 );
6485 set_hid_expect( file, &expect_effect_start, sizeof(expect_effect_start) );
6486 hr = IForceFeedbackEffect_Start( effect );
6487 ok( hr == S_OK, "Start returned %#lx\n", hr );
6488 set_hid_expect( file, &expect_effect_start, sizeof(expect_effect_start) );
6489 hr = IForceFeedbackEffect_Start( effect );
6490 ok( hr == S_OK, "Start returned %#lx\n", hr );
6492 set_hid_expect( file, &expect_effect_stop, sizeof(expect_effect_stop) );
6493 hr = IForceFeedbackEffect_Stop( effect );
6494 ok( hr == S_OK, "Stop returned %#lx\n", hr );
6495 set_hid_expect( file, &expect_effect_stop, sizeof(expect_effect_stop) );
6496 hr = IForceFeedbackEffect_Stop( effect );
6497 ok( hr == S_OK, "Stop returned %#lx\n", hr );
6499 set_hid_expect( file, expect_unload, sizeof(expect_unload) );
6500 hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async );
6501 ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr );
6502 await_bool( bool_async );
6503 check_bool_async( bool_async, 1, Completed, S_OK, TRUE );
6504 IAsyncOperation_boolean_Release( bool_async );
6505 set_hid_expect( file, NULL, 0 );
6508 hr = IForceFeedbackEffect_QueryInterface( effect, &IID_IConditionForceEffect, (void **)&condition_effect );
6509 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6510 direction.X = -direction.X;
6511 hr = IConditionForceEffect_SetParameters( condition_effect, direction, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6 );
6512 ok( hr == S_OK, "SetParameters returned %#lx\n", hr );
6513 direction.X = -direction.X;
6514 IConditionForceEffect_Release( condition_effect );
6516 set_hid_expect( file, expect_create_condition_neg, sizeof(expect_create_condition_neg) );
6517 hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async );
6518 ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr );
6519 await_result( result_async );
6520 check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded );
6521 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async );
6522 set_hid_expect( file, NULL, 0 );
6524 set_hid_expect( file, expect_unload, sizeof(expect_unload) );
6525 hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async );
6526 ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr );
6527 await_bool( bool_async );
6528 check_bool_async( bool_async, 1, Completed, S_OK, TRUE );
6529 IAsyncOperation_boolean_Release( bool_async );
6530 set_hid_expect( file, NULL, 0 );
6533 IForceFeedbackEffect_Release( effect );
6535 IConditionForceEffectFactory_Release( condition_factory );
6538 hr = pWindowsCreateString( constant_effect_class_name, wcslen( constant_effect_class_name ), &str );
6539 ok( hr == S_OK, "WindowsCreateString returned %#lx\n", hr );
6540 hr = pRoGetActivationFactory( str, &IID_IActivationFactory, (void **)&activation_factory );
6541 ok( hr == S_OK, "RoGetActivationFactory returned %#lx\n", hr );
6542 pWindowsDeleteString( str );
6544 hr = IActivationFactory_ActivateInstance( activation_factory, &tmp_inspectable );
6545 ok( hr == S_OK, "ActivateInstance returned %#lx\n", hr );
6546 IActivationFactory_Release( activation_factory );
6548 hr = IInspectable_QueryInterface( tmp_inspectable, &IID_IForceFeedbackEffect, (void **)&effect );
6549 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6550 IInspectable_Release( tmp_inspectable );
6552 hr = IForceFeedbackEffect_QueryInterface( effect, &IID_IConstantForceEffect, (void **)&constant_effect );
6553 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6555 hr = IConstantForceEffect_SetParameters( constant_effect, direction, duration );
6556 ok( hr == S_OK, "SetParameters returned %#lx\n", hr );
6557 hr = IConstantForceEffect_SetParametersWithEnvelope( constant_effect, direction, 0.1, 0.2, 0.3,
6558 delay, attack_duration, duration, release_duration, 1 );
6559 ok( hr == S_OK, "SetParametersWithEnvelope returned %#lx\n", hr );
6560 IConstantForceEffect_Release( constant_effect );
6562 gain = 12345.6;
6563 hr = IForceFeedbackEffect_get_Gain( effect, &gain );
6564 ok( hr == S_OK, "get_Gain returned %#lx\n", hr );
6565 ok( gain == 1.0, "get_MasterGain returned %f\n", gain );
6566 hr = IForceFeedbackEffect_put_Gain( effect, 0.5 );
6567 ok( hr == S_FALSE, "put_Gain returned %#lx\n", hr );
6568 state = 0xdeadbeef;
6569 hr = IForceFeedbackEffect_get_State( effect, &state );
6570 ok( hr == S_OK, "get_State returned %#lx\n", hr );
6571 ok( state == ForceFeedbackEffectState_Stopped, "get_State returned %#lx\n", hr );
6572 hr = IForceFeedbackEffect_Start( effect );
6573 todo_wine
6574 ok( hr == 0x86854003, "Start returned %#lx\n", hr );
6575 hr = IForceFeedbackEffect_Stop( effect );
6576 todo_wine
6577 ok( hr == 0x86854003, "Stop returned %#lx\n", hr );
6579 set_hid_expect( file, expect_create_constant, sizeof(expect_create_constant) );
6580 hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async );
6581 ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr );
6582 await_result( result_async );
6583 check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded );
6584 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async );
6585 set_hid_expect( file, NULL, 0 );
6587 set_hid_expect( file, &expect_effect_start, sizeof(expect_effect_start) );
6588 hr = IForceFeedbackEffect_Start( effect );
6589 ok( hr == S_OK, "Start returned %#lx\n", hr );
6590 set_hid_expect( file, &expect_effect_start, sizeof(expect_effect_start) );
6591 hr = IForceFeedbackEffect_Start( effect );
6592 ok( hr == S_OK, "Start returned %#lx\n", hr );
6594 set_hid_expect( file, &expect_effect_stop, sizeof(expect_effect_stop) );
6595 hr = IForceFeedbackEffect_Stop( effect );
6596 ok( hr == S_OK, "Stop returned %#lx\n", hr );
6597 set_hid_expect( file, &expect_effect_stop, sizeof(expect_effect_stop) );
6598 hr = IForceFeedbackEffect_Stop( effect );
6599 ok( hr == S_OK, "Stop returned %#lx\n", hr );
6601 set_hid_expect( file, expect_unload, sizeof(expect_unload) );
6602 hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async );
6603 ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr );
6604 await_bool( bool_async );
6605 check_bool_async( bool_async, 1, Completed, S_OK, TRUE );
6606 IAsyncOperation_boolean_Release( bool_async );
6607 set_hid_expect( file, NULL, 0 );
6610 hr = IForceFeedbackEffect_QueryInterface( effect, &IID_IConstantForceEffect, (void **)&constant_effect );
6611 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6612 direction.X = -direction.X;
6613 direction.Y = -direction.Y;
6614 direction.Z = -direction.Z;
6615 hr = IConstantForceEffect_SetParameters( constant_effect, direction, duration );
6616 ok( hr == S_OK, "SetParameters returned %#lx\n", hr );
6617 direction.X = -direction.X;
6618 direction.Y = -direction.Y;
6619 direction.Z = -direction.Z;
6620 IConstantForceEffect_Release( constant_effect );
6622 set_hid_expect( file, expect_create_constant_neg, sizeof(expect_create_constant_neg) );
6623 hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async );
6624 ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr );
6625 await_result( result_async );
6626 check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded );
6627 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async );
6628 set_hid_expect( file, NULL, 0 );
6630 set_hid_expect( file, expect_unload, sizeof(expect_unload) );
6631 hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async );
6632 ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr );
6633 await_bool( bool_async );
6634 check_bool_async( bool_async, 1, Completed, S_OK, TRUE );
6635 IAsyncOperation_boolean_Release( bool_async );
6636 set_hid_expect( file, NULL, 0 );
6638 IForceFeedbackEffect_Release( effect );
6641 hr = pWindowsCreateString( ramp_effect_class_name, wcslen( ramp_effect_class_name ), &str );
6642 ok( hr == S_OK, "WindowsCreateString returned %#lx\n", hr );
6643 hr = pRoGetActivationFactory( str, &IID_IActivationFactory, (void **)&activation_factory );
6644 ok( hr == S_OK, "RoGetActivationFactory returned %#lx\n", hr );
6645 pWindowsDeleteString( str );
6647 hr = IActivationFactory_ActivateInstance( activation_factory, &tmp_inspectable );
6648 ok( hr == S_OK, "ActivateInstance returned %#lx\n", hr );
6649 IActivationFactory_Release( activation_factory );
6651 hr = IInspectable_QueryInterface( tmp_inspectable, &IID_IForceFeedbackEffect, (void **)&effect );
6652 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6653 IInspectable_Release( tmp_inspectable );
6655 hr = IForceFeedbackEffect_QueryInterface( effect, &IID_IRampForceEffect, (void **)&ramp_effect );
6656 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6658 hr = IRampForceEffect_SetParameters( ramp_effect, direction, end_direction, duration );
6659 ok( hr == S_OK, "SetParameters returned %#lx\n", hr );
6660 hr = IRampForceEffect_SetParametersWithEnvelope( ramp_effect, direction, end_direction, 0.1, 0.2, 0.3,
6661 delay, attack_duration, duration, release_duration, 1 );
6662 ok( hr == S_OK, "SetParametersWithEnvelope returned %#lx\n", hr );
6663 IRampForceEffect_Release( ramp_effect );
6665 set_hid_expect( file, expect_create_ramp, sizeof(expect_create_ramp) );
6666 hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async );
6667 ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr );
6668 await_result( result_async );
6669 check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded );
6670 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async );
6671 set_hid_expect( file, NULL, 0 );
6673 set_hid_expect( file, &expect_effect_start, sizeof(expect_effect_start) );
6674 hr = IForceFeedbackEffect_Start( effect );
6675 ok( hr == S_OK, "Start returned %#lx\n", hr );
6676 set_hid_expect( file, &expect_effect_start, sizeof(expect_effect_start) );
6677 hr = IForceFeedbackEffect_Start( effect );
6678 ok( hr == S_OK, "Start returned %#lx\n", hr );
6680 set_hid_expect( file, &expect_effect_stop, sizeof(expect_effect_stop) );
6681 hr = IForceFeedbackEffect_Stop( effect );
6682 ok( hr == S_OK, "Stop returned %#lx\n", hr );
6683 set_hid_expect( file, &expect_effect_stop, sizeof(expect_effect_stop) );
6684 hr = IForceFeedbackEffect_Stop( effect );
6685 ok( hr == S_OK, "Stop returned %#lx\n", hr );
6687 set_hid_expect( file, expect_unload, sizeof(expect_unload) );
6688 hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async );
6689 ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr );
6690 await_bool( bool_async );
6691 check_bool_async( bool_async, 1, Completed, S_OK, TRUE );
6692 IAsyncOperation_boolean_Release( bool_async );
6693 set_hid_expect( file, NULL, 0 );
6696 hr = IForceFeedbackEffect_QueryInterface( effect, &IID_IRampForceEffect, (void **)&ramp_effect );
6697 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6698 hr = IRampForceEffect_SetParameters( ramp_effect, direction, end_direction, infinite_duration );
6699 ok( hr == S_OK, "SetParameters returned %#lx\n", hr );
6700 IRampForceEffect_Release( ramp_effect );
6702 set_hid_expect( file, expect_create_ramp_inf, sizeof(expect_create_ramp_inf) );
6703 hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async );
6704 ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr );
6705 await_result( result_async );
6706 check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded );
6707 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async );
6708 set_hid_expect( file, NULL, 0 );
6710 set_hid_expect( file, expect_unload, sizeof(expect_unload) );
6711 hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async );
6712 ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr );
6713 await_bool( bool_async );
6714 check_bool_async( bool_async, 1, Completed, S_OK, TRUE );
6715 IAsyncOperation_boolean_Release( bool_async );
6716 set_hid_expect( file, NULL, 0 );
6719 hr = IForceFeedbackEffect_QueryInterface( effect, &IID_IRampForceEffect, (void **)&ramp_effect );
6720 ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
6721 direction.X = -direction.X;
6722 direction.Y = -direction.Y;
6723 end_direction.X = -end_direction.X;
6724 end_direction.Z = -end_direction.Z;
6725 hr = IRampForceEffect_SetParameters( ramp_effect, direction, end_direction, infinite_duration );
6726 ok( hr == S_OK, "SetParameters returned %#lx\n", hr );
6727 direction.X = -direction.X;
6728 direction.Y = -direction.Y;
6729 end_direction.X = -end_direction.X;
6730 end_direction.Z = -end_direction.Z;
6731 IRampForceEffect_Release( ramp_effect );
6733 set_hid_expect( file, expect_create_ramp_neg, sizeof(expect_create_ramp_neg) );
6734 hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async );
6735 ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr );
6736 await_result( result_async );
6737 check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded );
6738 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async );
6739 set_hid_expect( file, NULL, 0 );
6741 set_hid_expect( file, expect_unload, sizeof(expect_unload) );
6742 hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async );
6743 ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr );
6744 await_bool( bool_async );
6745 check_bool_async( bool_async, 1, Completed, S_OK, TRUE );
6746 IAsyncOperation_boolean_Release( bool_async );
6747 set_hid_expect( file, NULL, 0 );
6750 IForceFeedbackEffect_Release( effect );
6753 IForceFeedbackMotor_Release( motor );
6755 IRawGameController_Release( raw_controller );
6757 CloseHandle( file );
6758 IRawGameControllerStatics_Release( controller_statics );
6760 done:
6761 hid_device_stop( &desc, 1 );
6762 cleanup_registry_keys();
6765 START_TEST( force_feedback )
6767 dinput_test_init();
6768 if (!bus_device_start()) goto done;
6770 if (test_force_feedback_joystick( 0x800 ))
6772 test_force_feedback_joystick( 0x500 );
6773 test_force_feedback_joystick( 0x700 );
6774 test_device_managed_effect();
6775 test_windows_gaming_input();
6778 done:
6779 bus_device_stop();
6780 dinput_test_exit();