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
25 #define WIN32_NO_STATUS
34 #include "winstring.h"
38 #include "dinput_test.h"
40 #define WIDL_using_Windows_Foundation
41 #define WIDL_using_Windows_Foundation_Collections
42 #define WIDL_using_Windows_Foundation_Numerics
43 #include "windows.foundation.h"
44 #define WIDL_using_Windows_Devices_Haptics
45 #define WIDL_using_Windows_Gaming_Input
46 #define WIDL_using_Windows_Gaming_Input_ForceFeedback
47 #include "windows.gaming.input.h"
48 #include "windows.gaming.input.forcefeedback.h"
51 #define MAKE_FUNC(f) static typeof(f) *p ## f
52 MAKE_FUNC( RoGetActivationFactory
);
53 MAKE_FUNC( RoInitialize
);
54 MAKE_FUNC( WindowsCreateString
);
55 MAKE_FUNC( WindowsDeleteString
);
56 MAKE_FUNC( WindowsGetStringRawBuffer
);
59 static BOOL
load_combase_functions(void)
61 HMODULE combase
= GetModuleHandleW( L
"combase.dll" );
63 #define LOAD_FUNC(m, f) if (!(p ## f = (void *)GetProcAddress( m, #f ))) goto failed;
64 LOAD_FUNC( combase
, RoGetActivationFactory
);
65 LOAD_FUNC( combase
, RoInitialize
);
66 LOAD_FUNC( combase
, WindowsCreateString
);
67 LOAD_FUNC( combase
, WindowsDeleteString
);
68 LOAD_FUNC( combase
, WindowsGetStringRawBuffer
);
74 win_skip("Failed to load combase.dll functions, skipping tests\n");
78 struct check_objects_todos
86 struct check_objects_params
91 const DIDEVICEOBJECTINSTANCEW
*expect_objs
;
92 const struct check_objects_todos
*todo_objs
;
96 static BOOL CALLBACK
check_objects( const DIDEVICEOBJECTINSTANCEW
*obj
, void *args
)
98 static const DIDEVICEOBJECTINSTANCEW unexpected_obj
= {0};
99 static const struct check_objects_todos todo_none
= {0};
100 struct check_objects_params
*params
= args
;
101 const DIDEVICEOBJECTINSTANCEW
*exp
= params
->expect_objs
+ params
->index
;
102 const struct check_objects_todos
*todo
;
104 if (!params
->todo_objs
) todo
= &todo_none
;
105 else todo
= params
->todo_objs
+ params
->index
;
107 todo_wine_if( params
->todo_extra
&& params
->index
>= params
->expect_count
)
108 ok( params
->index
< params
->expect_count
, "unexpected extra object\n" );
109 if (params
->index
>= params
->expect_count
) return DIENUM_STOP
;
111 winetest_push_context( "obj[%d]", params
->index
);
113 ok( params
->index
< params
->expect_count
, "unexpected extra object\n" );
114 if (params
->index
>= params
->expect_count
) exp
= &unexpected_obj
;
116 check_member( *obj
, *exp
, "%lu", dwSize
);
117 todo_wine_if( todo
->guid
)
118 check_member_guid( *obj
, *exp
, guidType
);
119 todo_wine_if( params
->version
< 0x700 && (obj
->dwType
& DIDFT_BUTTON
) )
120 check_member( *obj
, *exp
, "%#lx", dwOfs
);
121 todo_wine_if( todo
->type
)
122 check_member( *obj
, *exp
, "%#lx", dwType
);
123 check_member( *obj
, *exp
, "%#lx", dwFlags
);
124 if (!localized
) todo_wine_if( todo
->name
) check_member_wstr( *obj
, *exp
, tszName
);
125 check_member( *obj
, *exp
, "%lu", dwFFMaxForce
);
126 check_member( *obj
, *exp
, "%lu", dwFFForceResolution
);
127 check_member( *obj
, *exp
, "%u", wCollectionNumber
);
128 check_member( *obj
, *exp
, "%u", wDesignatorIndex
);
129 check_member( *obj
, *exp
, "%#04x", wUsagePage
);
130 todo_wine_if( todo
->usage
)
131 check_member( *obj
, *exp
, "%#04x", wUsage
);
132 check_member( *obj
, *exp
, "%#lx", dwDimension
);
133 check_member( *obj
, *exp
, "%#04x", wExponent
);
134 check_member( *obj
, *exp
, "%u", wReportId
);
136 winetest_pop_context();
139 return DIENUM_CONTINUE
;
142 struct check_effects_params
146 const DIEFFECTINFOW
*expect_effects
;
149 static BOOL CALLBACK
check_effects( const DIEFFECTINFOW
*effect
, void *args
)
151 static const DIEFFECTINFOW unexpected_effect
= {0};
152 struct check_effects_params
*params
= args
;
153 const DIEFFECTINFOW
*exp
= params
->expect_effects
+ params
->index
;
155 winetest_push_context( "effect[%d]", params
->index
);
157 ok( params
->index
< params
->expect_count
, "unexpected extra object\n" );
158 if (params
->index
>= params
->expect_count
) exp
= &unexpected_effect
;
160 check_member( *effect
, *exp
, "%lu", dwSize
);
161 check_member_guid( *effect
, *exp
, guid
);
162 check_member( *effect
, *exp
, "%#lx", dwEffType
);
163 check_member( *effect
, *exp
, "%#lx", dwStaticParams
);
164 check_member( *effect
, *exp
, "%#lx", dwDynamicParams
);
165 check_member_wstr( *effect
, *exp
, tszName
);
167 winetest_pop_context();
170 return DIENUM_CONTINUE
;
173 static BOOL CALLBACK
check_effect_count( const DIEFFECTINFOW
*effect
, void *args
)
177 return DIENUM_CONTINUE
;
180 static BOOL CALLBACK
check_no_created_effect_objects( IDirectInputEffect
*effect
, void *context
)
182 ok( 0, "unexpected effect %p\n", effect
);
183 return DIENUM_CONTINUE
;
186 struct check_created_effect_params
188 IDirectInputEffect
*expect_effect
;
192 static BOOL CALLBACK
check_created_effect_objects( IDirectInputEffect
*effect
, void *context
)
194 struct check_created_effect_params
*params
= context
;
197 ok( effect
== params
->expect_effect
, "got effect %p, expected %p\n", effect
, params
->expect_effect
);
200 IDirectInputEffect_AddRef( effect
);
201 ref
= IDirectInputEffect_Release( effect
);
202 ok( ref
== 1, "got ref %lu, expected 1\n", ref
);
203 return DIENUM_CONTINUE
;
206 static BOOL CALLBACK
enum_device_count( const DIDEVICEINSTANCEW
*devinst
, void *context
)
208 DWORD
*count
= context
;
210 return DIENUM_CONTINUE
;
213 static void check_dinput_devices( DWORD version
, DIDEVICEINSTANCEW
*devinst
)
220 if (version
>= 0x800)
222 hr
= DirectInput8Create( instance
, version
, &IID_IDirectInput8W
, (void **)&di8
, NULL
);
223 ok( hr
== DI_OK
, "DirectInput8Create returned %#lx\n", hr
);
225 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, NULL
, NULL
, DIEDFL_ALLDEVICES
);
226 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
227 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, enum_device_count
, &count
, 0xdeadbeef );
228 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
229 hr
= IDirectInput8_EnumDevices( di8
, 0xdeadbeef, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
230 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
233 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
234 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
235 ok( count
== 3, "got count %lu, expected 0\n", count
);
237 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_DEVICE
, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
238 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
239 ok( count
== 0, "got count %lu, expected 0\n", count
);
241 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_POINTER
, enum_device_count
, &count
,
242 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
| DIEDFL_INCLUDEHIDDEN
);
243 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
245 ok( count
== 3, "got count %lu, expected 3\n", count
);
247 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_KEYBOARD
, enum_device_count
, &count
,
248 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
| DIEDFL_INCLUDEHIDDEN
);
249 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
251 ok( count
== 3, "got count %lu, expected 3\n", count
);
253 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_GAMECTRL
, enum_device_count
, &count
,
254 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
| DIEDFL_INCLUDEHIDDEN
);
255 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
256 ok( count
== 1, "got count %lu, expected 1\n", count
);
259 hr
= IDirectInput8_EnumDevices( di8
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
260 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
261 ok( count
== 1, "got count %lu, expected 1\n", count
);
264 hr
= IDirectInput8_EnumDevices( di8
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_FORCEFEEDBACK
);
265 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
266 if (IsEqualGUID( &devinst
->guidFFDriver
, &GUID_NULL
)) ok( count
== 0, "got count %lu, expected 0\n", count
);
267 else ok( count
== 1, "got count %lu, expected 1\n", count
);
270 hr
= IDirectInput8_EnumDevices( di8
, (devinst
->dwDevType
& 0xff) + 1, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
271 if ((devinst
->dwDevType
& 0xff) != DI8DEVTYPE_SUPPLEMENTAL
) ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
272 else ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
273 ok( count
== 0, "got count %lu, expected 0\n", count
);
277 hr
= DirectInputCreateEx( instance
, version
, &IID_IDirectInput2W
, (void **)&di
, NULL
);
278 ok( hr
== DI_OK
, "DirectInputCreateEx returned %#lx\n", hr
);
280 hr
= IDirectInput_EnumDevices( di
, 0, NULL
, NULL
, DIEDFL_ALLDEVICES
);
281 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
282 hr
= IDirectInput_EnumDevices( di
, 0, enum_device_count
, &count
, 0xdeadbeef );
283 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
284 hr
= IDirectInput_EnumDevices( di
, 0xdeadbeef, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
285 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
286 hr
= IDirectInput_EnumDevices( di
, 0, enum_device_count
, &count
, DIEDFL_INCLUDEHIDDEN
);
287 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
290 hr
= IDirectInput_EnumDevices( di
, 0, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
291 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
292 ok( count
== 3, "got count %lu, expected 0\n", count
);
294 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_DEVICE
, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
295 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
296 ok( count
== 0, "got count %lu, expected 0\n", count
);
298 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_MOUSE
, enum_device_count
, &count
,
299 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
);
300 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
302 ok( count
== 3, "got count %lu, expected 3\n", count
);
304 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_KEYBOARD
, enum_device_count
, &count
,
305 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
);
306 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
308 ok( count
== 3, "got count %lu, expected 3\n", count
);
310 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_JOYSTICK
, enum_device_count
, &count
,
311 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
);
312 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
313 ok( count
== 1, "got count %lu, expected 1\n", count
);
316 hr
= IDirectInput_EnumDevices( di
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
317 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
318 ok( count
== 1, "got count %lu, expected 1\n", count
);
321 hr
= IDirectInput_EnumDevices( di
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_FORCEFEEDBACK
);
322 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
323 if (IsEqualGUID( &devinst
->guidFFDriver
, &GUID_NULL
)) ok( count
== 0, "got count %lu, expected 0\n", count
);
324 else ok( count
== 1, "got count %lu, expected 1\n", count
);
326 hr
= IDirectInput_EnumDevices( di
, 0x14, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
327 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
331 static void test_periodic_effect( IDirectInputDevice8W
*device
, HANDLE file
, DWORD version
)
333 struct hid_expect expect_download
[] =
337 .code
= IOCTL_HID_WRITE_REPORT
,
340 .report_buf
= {0x05,0x19},
344 .code
= IOCTL_HID_WRITE_REPORT
,
347 .report_buf
= {0x06,0x19,0x4c,0x02,0x00,0x04,0x00},
351 .code
= IOCTL_HID_WRITE_REPORT
,
354 .report_buf
= {0x03,0x01,0x01,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
356 /* start command when DIEP_START is set */
358 .code
= IOCTL_HID_WRITE_REPORT
,
361 .report_buf
= {0x02,0x01,0x01,0x01},
364 struct hid_expect expect_download_2
[] =
368 .code
= IOCTL_HID_WRITE_REPORT
,
371 .report_buf
= {0x05,0x19},
375 .code
= IOCTL_HID_WRITE_REPORT
,
378 .report_buf
= {0x06,0x19,0x4c,0x02,0x00,0x04,0x00},
382 .code
= IOCTL_HID_WRITE_REPORT
,
385 .report_buf
= {0x03,0x01,0x02,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
388 struct hid_expect expect_update
[] =
392 .code
= IOCTL_HID_WRITE_REPORT
,
395 .report_buf
= {0x03, 0x01, 0x02, 0x08, 0xff, 0xff, version
>= 0x700 ? 0x06 : 0x00, 0x00, 0x01, 0x55, 0xd5},
398 struct hid_expect expect_set_envelope
[] =
402 .code
= IOCTL_HID_WRITE_REPORT
,
405 .report_buf
= {0x06, 0x19, 0x4c, 0x01, 0x00, 0x04, 0x00},
408 struct hid_expect expect_start
=
410 .code
= IOCTL_HID_WRITE_REPORT
,
413 .report_buf
= {0x02, 0x01, 0x01, 0x01},
415 struct hid_expect expect_start_solo
=
417 .code
= IOCTL_HID_WRITE_REPORT
,
420 .report_buf
= {0x02, 0x01, 0x02, 0x01},
422 struct hid_expect expect_start_0
=
424 .code
= IOCTL_HID_WRITE_REPORT
,
427 .report_buf
= {0x02, 0x01, 0x01, 0x00},
429 struct hid_expect expect_start_4
=
431 .code
= IOCTL_HID_WRITE_REPORT
,
434 .report_buf
= {0x02, 0x01, 0x01, 0x04},
436 struct hid_expect expect_stop
=
438 .code
= IOCTL_HID_WRITE_REPORT
,
441 .report_buf
= {0x02, 0x01, 0x03, 0x00},
443 struct hid_expect expect_unload
[] =
446 .code
= IOCTL_HID_WRITE_REPORT
,
449 .report_buf
= {0x02,0x01,0x03,0x00},
451 /* device reset, when unloaded from Unacquire */
453 .code
= IOCTL_HID_WRITE_REPORT
,
456 .report_buf
= {1,0x01},
459 struct hid_expect expect_acquire
[] =
462 .code
= IOCTL_HID_WRITE_REPORT
,
465 .report_buf
= {1, 0x01},
468 .code
= IOCTL_HID_WRITE_REPORT
,
471 .report_buf
= {8, 0x19},
474 struct hid_expect expect_reset
[] =
477 .code
= IOCTL_HID_WRITE_REPORT
,
480 .report_buf
= {1, 0x01},
483 static const DWORD expect_axes_init
[2] = {0};
484 const DIEFFECT expect_desc_init
=
486 .dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
),
487 .dwTriggerButton
= -1,
488 .rgdwAxes
= (void *)expect_axes_init
,
490 static const DWORD expect_axes
[3] =
492 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
,
493 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
,
494 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
,
496 static const LONG expect_directions
[3] =
502 static const DIENVELOPE expect_envelope
=
504 .dwSize
= sizeof(DIENVELOPE
),
505 .dwAttackLevel
= 1000,
506 .dwAttackTime
= 2000,
510 static const DIPERIODIC expect_periodic
=
517 const DIEFFECT expect_desc
=
519 .dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
),
520 .dwFlags
= DIEFF_SPHERICAL
| DIEFF_OBJECTIDS
,
522 .dwSamplePeriod
= 2000,
524 .dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
525 .dwTriggerRepeatInterval
= 5000,
527 .rgdwAxes
= (void *)expect_axes
,
528 .rglDirection
= (void *)expect_directions
,
529 .lpEnvelope
= (void *)&expect_envelope
,
530 .cbTypeSpecificParams
= sizeof(DIPERIODIC
),
531 .lpvTypeSpecificParams
= (void *)&expect_periodic
,
532 .dwStartDelay
= 6000,
534 struct check_created_effect_params check_params
= {0};
535 IDirectInputEffect
*effect
;
536 DIPERIODIC periodic
= {0};
537 DIENVELOPE envelope
= {0};
538 LONG directions
[4] = {0};
545 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, NULL
, NULL
);
546 ok( hr
== E_POINTER
, "CreateEffect returned %#lx\n", hr
);
547 hr
= IDirectInputDevice8_CreateEffect( device
, NULL
, NULL
, &effect
, NULL
);
548 ok( hr
== E_POINTER
, "CreateEffect returned %#lx\n", hr
);
549 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_NULL
, NULL
, &effect
, NULL
);
550 ok( hr
== DIERR_DEVICENOTREG
, "CreateEffect returned %#lx\n", hr
);
552 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
553 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
554 if (hr
!= DI_OK
) return;
556 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_no_created_effect_objects
, effect
, 0xdeadbeef );
557 ok( hr
== DIERR_INVALIDPARAM
, "EnumCreatedEffectObjects returned %#lx\n", hr
);
558 check_params
.expect_effect
= effect
;
559 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_created_effect_objects
, &check_params
, 0 );
560 ok( hr
== DI_OK
, "EnumCreatedEffectObjects returned %#lx\n", hr
);
561 ok( check_params
.count
== 1, "got count %lu, expected 1\n", check_params
.count
);
563 hr
= IDirectInputEffect_Initialize( effect
, NULL
, version
, &GUID_Sine
);
564 ok( hr
== DIERR_INVALIDPARAM
, "Initialize returned %#lx\n", hr
);
565 hr
= IDirectInputEffect_Initialize( effect
, instance
, 0x800 - (version
- 0x700), &GUID_Sine
);
566 if (version
== 0x800)
569 ok( hr
== DIERR_BETADIRECTINPUTVERSION
, "Initialize returned %#lx\n", hr
);
574 ok( hr
== DIERR_OLDDIRECTINPUTVERSION
, "Initialize returned %#lx\n", hr
);
576 hr
= IDirectInputEffect_Initialize( effect
, instance
, 0, &GUID_Sine
);
578 ok( hr
== DIERR_NOTINITIALIZED
, "Initialize returned %#lx\n", hr
);
579 hr
= IDirectInputEffect_Initialize( effect
, instance
, version
, NULL
);
580 ok( hr
== E_POINTER
, "Initialize returned %#lx\n", hr
);
582 hr
= IDirectInputEffect_Initialize( effect
, instance
, version
, &GUID_NULL
);
583 ok( hr
== DIERR_DEVICENOTREG
, "Initialize returned %#lx\n", hr
);
584 hr
= IDirectInputEffect_Initialize( effect
, instance
, version
, &GUID_Sine
);
585 ok( hr
== DI_OK
, "Initialize returned %#lx\n", hr
);
586 hr
= IDirectInputEffect_Initialize( effect
, instance
, version
, &GUID_Square
);
587 ok( hr
== DI_OK
, "Initialize returned %#lx\n", hr
);
589 hr
= IDirectInputEffect_GetEffectGuid( effect
, NULL
);
590 ok( hr
== E_POINTER
, "GetEffectGuid returned %#lx\n", hr
);
591 hr
= IDirectInputEffect_GetEffectGuid( effect
, &guid
);
592 ok( hr
== DI_OK
, "GetEffectGuid returned %#lx\n", hr
);
593 ok( IsEqualGUID( &guid
, &GUID_Square
), "got guid %s, expected %s\n", debugstr_guid( &guid
),
594 debugstr_guid( &GUID_Square
) );
596 hr
= IDirectInputEffect_GetParameters( effect
, NULL
, 0 );
597 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
598 hr
= IDirectInputEffect_GetParameters( effect
, NULL
, DIEP_DURATION
);
599 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
600 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, 0 );
601 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#lx\n", hr
);
602 desc
.dwSize
= sizeof(DIEFFECT_DX5
) + 2;
603 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, 0 );
604 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#lx\n", hr
);
605 desc
.dwSize
= sizeof(DIEFFECT_DX5
);
606 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, 0 );
607 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
608 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_STARTDELAY
);
609 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#lx\n", hr
);
610 desc
.dwSize
= sizeof(DIEFFECT_DX6
);
611 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, 0 );
612 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
614 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
615 hr
= IDirectInputDevice8_Unacquire( device
);
616 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
617 set_hid_expect( file
, NULL
, 0 );
618 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DURATION
);
619 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
620 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
621 hr
= IDirectInputDevice8_Acquire( device
);
622 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
623 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
625 desc
.dwDuration
= 0xdeadbeef;
626 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DURATION
);
627 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
628 check_member( desc
, expect_desc_init
, "%lu", dwDuration
);
629 memset( &desc
, 0xcd, sizeof(desc
) );
630 desc
.dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
);
632 desc
.dwStartDelay
= 0xdeadbeef;
633 flags
= DIEP_GAIN
| DIEP_SAMPLEPERIOD
| DIEP_TRIGGERREPEATINTERVAL
|
634 (version
>= 0x700 ? DIEP_STARTDELAY
: 0);
635 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, flags
);
636 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
637 check_member( desc
, expect_desc_init
, "%lu", dwSamplePeriod
);
638 check_member( desc
, expect_desc_init
, "%lu", dwGain
);
639 if (version
>= 0x700) check_member( desc
, expect_desc_init
, "%lu", dwStartDelay
);
640 else ok( desc
.dwStartDelay
== 0xdeadbeef, "got dwStartDelay %#lx\n", desc
.dwStartDelay
);
641 check_member( desc
, expect_desc_init
, "%lu", dwTriggerRepeatInterval
);
643 memset( &desc
, 0xcd, sizeof(desc
) );
644 desc
.dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
);
646 desc
.lpEnvelope
= NULL
;
647 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_ENVELOPE
);
648 ok( hr
== E_POINTER
, "GetParameters returned %#lx\n", hr
);
649 desc
.lpEnvelope
= &envelope
;
650 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_ENVELOPE
);
651 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#lx\n", hr
);
652 envelope
.dwSize
= sizeof(DIENVELOPE
);
653 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_ENVELOPE
);
654 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
658 desc
.rgdwAxes
= NULL
;
659 desc
.rglDirection
= NULL
;
660 desc
.lpEnvelope
= NULL
;
661 desc
.cbTypeSpecificParams
= 0;
662 desc
.lpvTypeSpecificParams
= NULL
;
663 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
);
664 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#lx\n", hr
);
665 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TRIGGERBUTTON
);
666 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#lx\n", hr
);
667 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
);
668 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#lx\n", hr
);
669 desc
.dwFlags
= DIEFF_OBJECTOFFSETS
;
670 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
671 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#lx\n", hr
);
672 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TRIGGERBUTTON
);
673 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
674 check_member( desc
, expect_desc_init
, "%#lx", dwTriggerButton
);
675 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
);
676 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
677 check_member( desc
, expect_desc_init
, "%lu", cAxes
);
678 desc
.dwFlags
= DIEFF_OBJECTIDS
;
679 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
680 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#lx\n", hr
);
681 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TRIGGERBUTTON
);
682 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
683 check_member( desc
, expect_desc_init
, "%#lx", dwTriggerButton
);
684 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
);
685 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
686 check_member( desc
, expect_desc_init
, "%lu", cAxes
);
687 desc
.dwFlags
|= DIEFF_CARTESIAN
;
688 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
689 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
690 ok( desc
.dwFlags
== DIEFF_OBJECTIDS
, "got flags %#lx, expected %#x\n", desc
.dwFlags
, DIEFF_OBJECTIDS
);
691 desc
.dwFlags
|= DIEFF_POLAR
;
692 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
693 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#lx\n", hr
);
694 ok( desc
.dwFlags
== DIEFF_OBJECTIDS
, "got flags %#lx, expected %#x\n", desc
.dwFlags
, DIEFF_OBJECTIDS
);
695 desc
.dwFlags
|= DIEFF_SPHERICAL
;
696 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
697 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
698 check_member( desc
, expect_desc_init
, "%lu", cAxes
);
699 ok( desc
.dwFlags
== DIEFF_OBJECTIDS
, "got flags %#lx, expected %#x\n", desc
.dwFlags
, DIEFF_OBJECTIDS
);
701 desc
.dwFlags
|= DIEFF_SPHERICAL
;
703 desc
.rgdwAxes
= axes
;
704 desc
.rglDirection
= directions
;
705 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
| DIEP_DIRECTION
);
706 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
707 check_member( desc
, expect_desc_init
, "%lu", cAxes
);
708 check_member( desc
, expect_desc_init
, "%lu", rgdwAxes
[0] );
709 check_member( desc
, expect_desc_init
, "%lu", rgdwAxes
[1] );
710 check_member( desc
, expect_desc_init
, "%p", rglDirection
);
711 ok( desc
.dwFlags
== DIEFF_OBJECTIDS
, "got flags %#lx, expected %#x\n", desc
.dwFlags
, DIEFF_OBJECTIDS
);
713 desc
.dwFlags
|= DIEFF_SPHERICAL
;
714 desc
.lpEnvelope
= &envelope
;
715 desc
.cbTypeSpecificParams
= sizeof(periodic
);
716 desc
.lpvTypeSpecificParams
= &periodic
;
717 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
);
718 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
719 check_member( desc
, expect_desc_init
, "%lu", dwDuration
);
720 check_member( desc
, expect_desc_init
, "%lu", dwSamplePeriod
);
721 check_member( desc
, expect_desc_init
, "%lu", dwGain
);
722 check_member( desc
, expect_desc_init
, "%#lx", dwTriggerButton
);
723 check_member( desc
, expect_desc_init
, "%lu", dwTriggerRepeatInterval
);
724 check_member( desc
, expect_desc_init
, "%lu", cAxes
);
725 check_member( desc
, expect_desc_init
, "%lu", rgdwAxes
[0] );
726 check_member( desc
, expect_desc_init
, "%lu", rgdwAxes
[1] );
727 check_member( desc
, expect_desc_init
, "%p", rglDirection
);
728 check_member( desc
, expect_desc_init
, "%p", lpEnvelope
);
729 check_member( desc
, expect_desc_init
, "%lu", cbTypeSpecificParams
);
730 if (version
>= 0x700) check_member( desc
, expect_desc_init
, "%lu", dwStartDelay
);
731 else ok( desc
.dwStartDelay
== 0xcdcdcdcd, "got dwStartDelay %#lx\n", desc
.dwStartDelay
);
733 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
734 hr
= IDirectInputDevice8_Unacquire( device
);
735 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
736 set_hid_expect( file
, NULL
, 0 );
737 hr
= IDirectInputEffect_Download( effect
);
738 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "Download returned %#lx\n", hr
);
739 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
740 hr
= IDirectInputDevice8_Acquire( device
);
741 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
742 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
744 hr
= IDirectInputEffect_Download( effect
);
745 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#lx\n", hr
);
746 hr
= IDirectInputEffect_Unload( effect
);
747 ok( hr
== DI_NOEFFECT
, "Unload returned %#lx\n", hr
);
749 hr
= IDirectInputEffect_SetParameters( effect
, NULL
, DIEP_NODOWNLOAD
);
750 ok( hr
== E_POINTER
, "SetParameters returned %#lx\n", hr
);
751 memset( &desc
, 0, sizeof(desc
) );
752 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
);
753 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#lx\n", hr
);
754 desc
.dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
);
755 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
);
756 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
758 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
759 hr
= IDirectInputDevice8_Unacquire( device
);
760 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
761 set_hid_expect( file
, NULL
, 0 );
762 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_DURATION
);
763 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
764 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
765 hr
= IDirectInputDevice8_Acquire( device
);
766 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
767 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
769 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_DURATION
| DIEP_NODOWNLOAD
);
770 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
772 desc
.dwTriggerButton
= -1;
773 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DURATION
);
774 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
775 check_member( desc
, expect_desc
, "%lu", dwDuration
);
776 check_member( desc
, expect_desc_init
, "%lu", dwSamplePeriod
);
777 check_member( desc
, expect_desc_init
, "%lu", dwGain
);
778 check_member( desc
, expect_desc_init
, "%#lx", dwTriggerButton
);
779 check_member( desc
, expect_desc_init
, "%lu", dwTriggerRepeatInterval
);
780 check_member( desc
, expect_desc_init
, "%lu", cAxes
);
781 check_member( desc
, expect_desc_init
, "%p", rglDirection
);
782 check_member( desc
, expect_desc_init
, "%p", lpEnvelope
);
783 check_member( desc
, expect_desc_init
, "%lu", cbTypeSpecificParams
);
784 check_member( desc
, expect_desc_init
, "%lu", dwStartDelay
);
786 hr
= IDirectInputEffect_Download( effect
);
787 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#lx\n", hr
);
788 hr
= IDirectInputEffect_Unload( effect
);
789 ok( hr
== DI_NOEFFECT
, "Unload returned %#lx\n", hr
);
791 flags
= DIEP_GAIN
| DIEP_SAMPLEPERIOD
| DIEP_TRIGGERREPEATINTERVAL
| DIEP_NODOWNLOAD
;
792 if (version
>= 0x700) flags
|= DIEP_STARTDELAY
;
793 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, flags
);
794 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
796 flags
= DIEP_DURATION
| DIEP_GAIN
| DIEP_SAMPLEPERIOD
| DIEP_TRIGGERREPEATINTERVAL
;
797 if (version
>= 0x700) flags
|= DIEP_STARTDELAY
;
798 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, flags
);
799 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
800 check_member( desc
, expect_desc
, "%lu", dwDuration
);
801 check_member( desc
, expect_desc
, "%lu", dwSamplePeriod
);
802 check_member( desc
, expect_desc
, "%lu", dwGain
);
803 check_member( desc
, expect_desc_init
, "%#lx", dwTriggerButton
);
804 check_member( desc
, expect_desc
, "%lu", dwTriggerRepeatInterval
);
805 check_member( desc
, expect_desc_init
, "%lu", cAxes
);
806 check_member( desc
, expect_desc_init
, "%p", rglDirection
);
807 check_member( desc
, expect_desc_init
, "%p", lpEnvelope
);
808 check_member( desc
, expect_desc_init
, "%lu", cbTypeSpecificParams
);
809 if (version
>= 0x700) check_member( desc
, expect_desc
, "%lu", dwStartDelay
);
810 else ok( desc
.dwStartDelay
== 0, "got dwStartDelay %#lx\n", desc
.dwStartDelay
);
812 hr
= IDirectInputEffect_Download( effect
);
813 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#lx\n", hr
);
814 hr
= IDirectInputEffect_Unload( effect
);
815 ok( hr
== DI_NOEFFECT
, "Unload returned %#lx\n", hr
);
817 desc
.lpEnvelope
= NULL
;
818 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_ENVELOPE
| DIEP_NODOWNLOAD
);
819 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
820 desc
.lpEnvelope
= &envelope
;
822 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_ENVELOPE
| DIEP_NODOWNLOAD
);
823 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#lx\n", hr
);
825 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_ENVELOPE
| DIEP_NODOWNLOAD
);
826 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
828 desc
.lpEnvelope
= &envelope
;
829 envelope
.dwSize
= sizeof(DIENVELOPE
);
830 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_ENVELOPE
);
831 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
832 check_member( envelope
, expect_envelope
, "%lu", dwAttackLevel
);
833 check_member( envelope
, expect_envelope
, "%lu", dwAttackTime
);
834 check_member( envelope
, expect_envelope
, "%lu", dwFadeLevel
);
835 check_member( envelope
, expect_envelope
, "%lu", dwFadeTime
);
837 hr
= IDirectInputEffect_Download( effect
);
838 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#lx\n", hr
);
839 hr
= IDirectInputEffect_Unload( effect
);
840 ok( hr
== DI_NOEFFECT
, "Unload returned %#lx\n", hr
);
844 desc
.rgdwAxes
= NULL
;
845 desc
.rglDirection
= NULL
;
846 desc
.lpEnvelope
= NULL
;
847 desc
.cbTypeSpecificParams
= 0;
848 desc
.lpvTypeSpecificParams
= NULL
;
849 flags
= version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
;
850 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, flags
| DIEP_NODOWNLOAD
);
851 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#lx\n", hr
);
852 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_TRIGGERBUTTON
| DIEP_NODOWNLOAD
);
853 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#lx\n", hr
);
854 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_AXES
| DIEP_NODOWNLOAD
);
855 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#lx\n", hr
);
857 desc
.dwFlags
= DIEFF_OBJECTOFFSETS
;
859 desc
.rgdwAxes
= axes
;
860 desc
.rgdwAxes
[0] = DIJOFS_X
;
861 desc
.dwTriggerButton
= DIJOFS_BUTTON( 1 );
862 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
863 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#lx\n", hr
);
864 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
| DIEP_NODOWNLOAD
);
865 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
866 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
| DIEP_NODOWNLOAD
);
867 ok( hr
== DIERR_ALREADYINITIALIZED
, "SetParameters returned %#lx\n", hr
);
870 desc
.dwFlags
= DIEFF_OBJECTIDS
;
871 desc
.rgdwAxes
= axes
;
872 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
);
873 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#lx\n", hr
);
874 check_member( desc
, expect_desc
, "%lu", cAxes
);
875 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
);
876 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
877 check_member( desc
, expect_desc
, "%#lx", dwTriggerButton
);
878 check_member( desc
, expect_desc
, "%lu", cAxes
);
879 check_member( desc
, expect_desc
, "%lu", rgdwAxes
[0] );
880 check_member( desc
, expect_desc
, "%lu", rgdwAxes
[1] );
881 check_member( desc
, expect_desc
, "%lu", rgdwAxes
[2] );
883 desc
.dwFlags
= DIEFF_OBJECTOFFSETS
;
884 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
);
885 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
886 ok( desc
.dwTriggerButton
== 0x30, "got %#lx expected %#x\n", desc
.dwTriggerButton
, 0x30 );
887 ok( desc
.rgdwAxes
[0] == 8, "got %#lx expected %#x\n", desc
.rgdwAxes
[0], 8 );
888 ok( desc
.rgdwAxes
[1] == 0, "got %#lx expected %#x\n", desc
.rgdwAxes
[1], 0 );
889 ok( desc
.rgdwAxes
[2] == 4, "got %#lx expected %#x\n", desc
.rgdwAxes
[2], 4 );
891 hr
= IDirectInputEffect_Download( effect
);
892 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#lx\n", hr
);
893 hr
= IDirectInputEffect_Unload( effect
);
894 ok( hr
== DI_NOEFFECT
, "Unload returned %#lx\n", hr
);
896 desc
.dwFlags
= DIEFF_CARTESIAN
;
898 desc
.rglDirection
= directions
;
899 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
900 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#lx\n", hr
);
902 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
903 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
904 desc
.dwFlags
= DIEFF_POLAR
;
906 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
907 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#lx\n", hr
);
909 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
910 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
912 desc
.dwFlags
= DIEFF_SPHERICAL
;
914 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
915 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#lx\n", hr
);
916 ok( desc
.dwFlags
== DIEFF_SPHERICAL
, "got flags %#lx, expected %#x\n", desc
.dwFlags
, DIEFF_SPHERICAL
);
917 check_member( desc
, expect_desc
, "%lu", cAxes
);
918 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
919 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
920 check_member( desc
, expect_desc
, "%lu", cAxes
);
921 ok( desc
.rglDirection
[0] == 3000, "got rglDirection[0] %ld expected %d\n", desc
.rglDirection
[0], 3000 );
922 ok( desc
.rglDirection
[1] == 30000, "got rglDirection[1] %ld expected %d\n", desc
.rglDirection
[1], 30000 );
923 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %ld expected %d\n", desc
.rglDirection
[2], 0 );
924 desc
.dwFlags
= DIEFF_CARTESIAN
;
926 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
927 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#lx\n", hr
);
928 ok( desc
.dwFlags
== DIEFF_CARTESIAN
, "got flags %#lx, expected %#x\n", desc
.dwFlags
, DIEFF_CARTESIAN
);
929 check_member( desc
, expect_desc
, "%lu", cAxes
);
930 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
931 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
932 check_member( desc
, expect_desc
, "%lu", cAxes
);
933 ok( desc
.rglDirection
[0] == 4330, "got rglDirection[0] %ld expected %d\n", desc
.rglDirection
[0], 4330 );
934 ok( desc
.rglDirection
[1] == 2500, "got rglDirection[1] %ld expected %d\n", desc
.rglDirection
[1], 2500 );
935 ok( desc
.rglDirection
[2] == -8660, "got rglDirection[2] %ld expected %d\n", desc
.rglDirection
[2], -8660 );
936 desc
.dwFlags
= DIEFF_POLAR
;
938 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
939 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#lx\n", hr
);
941 hr
= IDirectInputEffect_Download( effect
);
942 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#lx\n", hr
);
943 hr
= IDirectInputEffect_Unload( effect
);
944 ok( hr
== DI_NOEFFECT
, "Unload returned %#lx\n", hr
);
946 desc
.cbTypeSpecificParams
= 0;
947 desc
.lpvTypeSpecificParams
= &periodic
;
948 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_TYPESPECIFICPARAMS
| DIEP_NODOWNLOAD
);
949 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#lx\n", hr
);
950 desc
.cbTypeSpecificParams
= sizeof(DIPERIODIC
);
951 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_TYPESPECIFICPARAMS
| DIEP_NODOWNLOAD
);
952 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
953 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_TYPESPECIFICPARAMS
| DIEP_NODOWNLOAD
);
954 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
956 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TYPESPECIFICPARAMS
);
957 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
958 check_member( periodic
, expect_periodic
, "%lu", dwMagnitude
);
959 check_member( periodic
, expect_periodic
, "%ld", lOffset
);
960 check_member( periodic
, expect_periodic
, "%lu", dwPhase
);
961 check_member( periodic
, expect_periodic
, "%lu", dwPeriod
);
963 hr
= IDirectInputEffect_Start( effect
, 1, DIES_NODOWNLOAD
);
964 ok( hr
== DIERR_NOTDOWNLOADED
, "Start returned %#lx\n", hr
);
965 hr
= IDirectInputEffect_Stop( effect
);
966 ok( hr
== DIERR_NOTDOWNLOADED
, "Stop returned %#lx\n", hr
);
968 set_hid_expect( file
, expect_download
, 3 * sizeof(struct hid_expect
) );
969 hr
= IDirectInputEffect_Download( effect
);
970 ok( hr
== DI_OK
, "Download returned %#lx\n", hr
);
971 set_hid_expect( file
, NULL
, 0 );
973 hr
= IDirectInputEffect_Download( effect
);
974 ok( hr
== DI_NOEFFECT
, "Download returned %#lx\n", hr
);
976 hr
= IDirectInputEffect_Start( effect
, 1, 0xdeadbeef );
977 ok( hr
== DIERR_INVALIDPARAM
, "Start returned %#lx\n", hr
);
979 set_hid_expect( file
, &expect_start_solo
, sizeof(expect_start_solo
) );
980 hr
= IDirectInputEffect_Start( effect
, 1, DIES_SOLO
);
981 ok( hr
== DI_OK
, "Start returned %#lx\n", hr
);
982 set_hid_expect( file
, NULL
, 0 );
984 set_hid_expect( file
, &expect_stop
, sizeof(expect_stop
) );
985 hr
= IDirectInputEffect_Stop( effect
);
986 ok( hr
== DI_OK
, "Stop returned %#lx\n", hr
);
987 set_hid_expect( file
, NULL
, 0 );
989 set_hid_expect( file
, &expect_start
, sizeof(expect_start
) );
990 hr
= IDirectInputEffect_Start( effect
, 1, 0 );
991 ok( hr
== DI_OK
, "Start returned %#lx\n", hr
);
992 set_hid_expect( file
, NULL
, 0 );
994 set_hid_expect( file
, &expect_start_4
, sizeof(expect_start_4
) );
995 hr
= IDirectInputEffect_Start( effect
, 4, 0 );
996 ok( hr
== DI_OK
, "Start returned %#lx\n", hr
);
997 set_hid_expect( file
, NULL
, 0 );
999 set_hid_expect( file
, &expect_start_0
, sizeof(expect_start_4
) );
1000 hr
= IDirectInputEffect_Start( effect
, 0, 0 );
1001 ok( hr
== DI_OK
, "Start returned %#lx\n", hr
);
1002 set_hid_expect( file
, NULL
, 0 );
1004 set_hid_expect( file
, expect_unload
, sizeof(struct hid_expect
) );
1005 hr
= IDirectInputEffect_Unload( effect
);
1006 ok( hr
== DI_OK
, "Unload returned %#lx\n", hr
);
1007 set_hid_expect( file
, NULL
, 0 );
1009 set_hid_expect( file
, expect_download
, 4 * sizeof(struct hid_expect
) );
1010 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_START
);
1011 ok( hr
== DI_OK
, "SetParameters returned %#lx\n", hr
);
1012 set_hid_expect( file
, NULL
, 0 );
1014 set_hid_expect( file
, expect_unload
, sizeof(struct hid_expect
) );
1015 hr
= IDirectInputEffect_Unload( effect
);
1016 ok( hr
== DI_OK
, "Unload returned %#lx\n", hr
);
1017 set_hid_expect( file
, NULL
, 0 );
1019 set_hid_expect( file
, expect_download
, 3 * sizeof(struct hid_expect
) );
1020 hr
= IDirectInputEffect_Download( effect
);
1021 ok( hr
== DI_OK
, "Download returned %#lx\n", hr
);
1022 set_hid_expect( file
, NULL
, 0 );
1024 set_hid_expect( file
, expect_unload
, 2 * sizeof(struct hid_expect
) );
1025 hr
= IDirectInputDevice8_Unacquire( device
);
1026 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
1027 set_hid_expect( file
, NULL
, 0 );
1029 hr
= IDirectInputEffect_Start( effect
, 1, DIES_NODOWNLOAD
);
1030 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "Start returned %#lx\n", hr
);
1031 hr
= IDirectInputEffect_Stop( effect
);
1032 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "Stop returned %#lx\n", hr
);
1034 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
1035 hr
= IDirectInputDevice8_Acquire( device
);
1036 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
1037 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
1039 hr
= IDirectInputEffect_Unload( effect
);
1040 ok( hr
== DI_NOEFFECT
, "Unload returned %#lx\n", hr
);
1042 ref
= IDirectInputEffect_Release( effect
);
1043 ok( ref
== 0, "Release returned %ld\n", ref
);
1045 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
1046 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
1048 desc
.dwFlags
= DIEFF_POLAR
| DIEFF_OBJECTIDS
;
1050 desc
.rgdwAxes
[0] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
;
1051 desc
.rgdwAxes
[1] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
;
1052 desc
.rglDirection
[0] = 3000;
1053 desc
.rglDirection
[1] = 0;
1054 desc
.rglDirection
[2] = 0;
1055 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_AXES
| DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
1056 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
1057 desc
.rglDirection
[0] = 0;
1059 desc
.dwFlags
= DIEFF_SPHERICAL
;
1061 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
1062 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#lx\n", hr
);
1063 ok( desc
.dwFlags
== DIEFF_SPHERICAL
, "got flags %#lx, expected %#x\n", desc
.dwFlags
, DIEFF_SPHERICAL
);
1064 ok( desc
.cAxes
== 2, "got cAxes %lu expected 2\n", desc
.cAxes
);
1065 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
1066 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
1067 ok( desc
.cAxes
== 2, "got cAxes %lu expected 2\n", desc
.cAxes
);
1068 ok( desc
.rglDirection
[0] == 30000, "got rglDirection[0] %ld expected %d\n", desc
.rglDirection
[0], 30000 );
1069 ok( desc
.rglDirection
[1] == 0, "got rglDirection[1] %ld expected %d\n", desc
.rglDirection
[1], 0 );
1070 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %ld expected %d\n", desc
.rglDirection
[2], 0 );
1072 desc
.dwFlags
= DIEFF_CARTESIAN
;
1074 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
1075 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#lx\n", hr
);
1076 ok( desc
.dwFlags
== DIEFF_CARTESIAN
, "got flags %#lx, expected %#x\n", desc
.dwFlags
, DIEFF_CARTESIAN
);
1077 ok( desc
.cAxes
== 2, "got cAxes %lu expected 2\n", desc
.cAxes
);
1078 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
1079 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
1080 ok( desc
.cAxes
== 2, "got cAxes %lu expected 2\n", desc
.cAxes
);
1081 ok( desc
.rglDirection
[0] == 5000, "got rglDirection[0] %ld expected %d\n", desc
.rglDirection
[0], 5000 );
1082 ok( desc
.rglDirection
[1] == -8660, "got rglDirection[1] %ld expected %d\n", desc
.rglDirection
[1], -8660 );
1083 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %ld expected %d\n", desc
.rglDirection
[2], 0 );
1085 desc
.dwFlags
= DIEFF_POLAR
;
1087 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
1088 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#lx\n", hr
);
1089 ok( desc
.dwFlags
== DIEFF_POLAR
, "got flags %#lx, expected %#x\n", desc
.dwFlags
, DIEFF_POLAR
);
1090 ok( desc
.cAxes
== 2, "got cAxes %lu expected 2\n", desc
.cAxes
);
1091 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
1092 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
1093 ok( desc
.cAxes
== 2, "got cAxes %lu expected 2\n", desc
.cAxes
);
1094 ok( desc
.rglDirection
[0] == 3000, "got rglDirection[0] %ld expected %d\n", desc
.rglDirection
[0], 3000 );
1095 ok( desc
.rglDirection
[1] == 0, "got rglDirection[1] %ld expected %d\n", desc
.rglDirection
[1], 0 );
1096 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %ld expected %d\n", desc
.rglDirection
[2], 0 );
1098 ref
= IDirectInputEffect_Release( effect
);
1099 ok( ref
== 0, "Release returned %ld\n", ref
);
1101 for (i
= 1; i
< 4; i
++)
1103 struct hid_expect expect_directions
[] =
1107 .code
= IOCTL_HID_WRITE_REPORT
,
1110 .report_buf
= {0x05,0x19},
1114 .code
= IOCTL_HID_WRITE_REPORT
,
1117 .report_buf
= {0x06,0x19,0x4c,0x02,0x00,0x04,0x00},
1121 /* effect control */
1123 .code
= IOCTL_HID_WRITE_REPORT
,
1126 .report_buf
= {0x02,0x01,0x03,0x00},
1129 struct hid_expect expect_spherical
=
1131 .code
= IOCTL_HID_WRITE_REPORT
,
1134 .report_buf
= { 0x03, 0x01, 0x02, 0x08, 0x01, 0x00, version
>= 0x700 ? 0x06 : 0x00, 0x00, 0x01,
1135 i
>= 2 ? 0x55 : 0, i
>= 3 ? 0x1c : 0 },
1137 struct hid_expect expect_cartesian
=
1139 .code
= IOCTL_HID_WRITE_REPORT
,
1142 .report_buf
= {0x03, 0x01, 0x02, 0x08, 0x01, 0x00, version
>= 0x700 ? 0x06 : 0x00, 0x00,
1143 0x01, i
>= 2 ? 0x63 : 0, i
>= 3 ? 0x1d : 0},
1145 struct hid_expect expect_polar
=
1147 .code
= IOCTL_HID_WRITE_REPORT
,
1150 .report_buf
= {0x03, 0x01, 0x02, 0x08, 0x01, 0x00, version
>= 0x700 ? 0x06 : 0x00, 0x00,
1151 0x01, i
>= 2 ? 0x3f : 0, i
>= 3 ? 0x00 : 0},
1154 winetest_push_context( "%lu axes", i
);
1155 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
1156 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
1158 desc
.dwFlags
= DIEFF_OBJECTIDS
;
1160 desc
.rgdwAxes
[0] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
;
1161 desc
.rgdwAxes
[1] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
;
1162 desc
.rgdwAxes
[2] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
;
1163 desc
.rglDirection
[0] = 0;
1164 desc
.rglDirection
[1] = 0;
1165 desc
.rglDirection
[2] = 0;
1166 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_AXES
| DIEP_NODOWNLOAD
);
1167 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
1169 desc
.dwFlags
= DIEFF_CARTESIAN
;
1170 desc
.cAxes
= i
== 3 ? 2 : 3;
1171 desc
.rglDirection
[0] = 1000;
1172 desc
.rglDirection
[1] = 2000;
1173 desc
.rglDirection
[2] = 3000;
1174 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
1175 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#lx\n", hr
);
1177 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
1178 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
1180 desc
.dwFlags
= DIEFF_SPHERICAL
;
1182 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
1183 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
1185 memset( desc
.rglDirection
, 0xcd, 3 * sizeof(LONG
) );
1186 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
1187 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
1188 ok( desc
.cAxes
== i
, "got cAxes %lu expected 2\n", desc
.cAxes
);
1191 ok( desc
.rglDirection
[0] == 0, "got rglDirection[0] %ld expected %d\n", desc
.rglDirection
[0], 0 );
1192 ok( desc
.rglDirection
[1] == 0xcdcdcdcd, "got rglDirection[1] %ld expected %d\n",
1193 desc
.rglDirection
[1], 0xcdcdcdcd );
1194 ok( desc
.rglDirection
[2] == 0xcdcdcdcd, "got rglDirection[2] %ld expected %d\n",
1195 desc
.rglDirection
[2], 0xcdcdcdcd );
1199 ok( desc
.rglDirection
[0] == 6343, "got rglDirection[0] %ld expected %d\n",
1200 desc
.rglDirection
[0], 6343 );
1203 ok( desc
.rglDirection
[1] == 0, "got rglDirection[1] %ld expected %d\n",
1204 desc
.rglDirection
[1], 0 );
1205 ok( desc
.rglDirection
[2] == 0xcdcdcdcd, "got rglDirection[2] %ld expected %d\n",
1206 desc
.rglDirection
[2], 0xcdcdcdcd );
1210 ok( desc
.rglDirection
[1] == 5330, "got rglDirection[1] %ld expected %d\n",
1211 desc
.rglDirection
[1], 5330 );
1212 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %ld expected %d\n",
1213 desc
.rglDirection
[2], 0 );
1217 desc
.dwFlags
= DIEFF_CARTESIAN
;
1219 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
1220 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
1222 memset( desc
.rglDirection
, 0xcd, 3 * sizeof(LONG
) );
1223 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
1224 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
1225 ok( desc
.cAxes
== i
, "got cAxes %lu expected 2\n", desc
.cAxes
);
1226 ok( desc
.rglDirection
[0] == 1000, "got rglDirection[0] %ld expected %d\n", desc
.rglDirection
[0], 1000 );
1228 ok( desc
.rglDirection
[1] == 0xcdcdcdcd, "got rglDirection[1] %ld expected %d\n",
1229 desc
.rglDirection
[1], 0xcdcdcdcd );
1231 ok( desc
.rglDirection
[1] == 2000, "got rglDirection[1] %ld expected %d\n",
1232 desc
.rglDirection
[1], 2000 );
1234 ok( desc
.rglDirection
[2] == 0xcdcdcdcd, "got rglDirection[2] %ld expected %d\n",
1235 desc
.rglDirection
[2], 0xcdcdcdcd );
1237 ok( desc
.rglDirection
[2] == 3000, "got rglDirection[2] %ld expected %d\n",
1238 desc
.rglDirection
[2], 3000 );
1240 desc
.dwFlags
= DIEFF_POLAR
;
1242 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
1243 if (i
!= 2) ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#lx\n", hr
);
1244 else ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#lx\n", hr
);
1246 memset( desc
.rglDirection
, 0xcd, 3 * sizeof(LONG
) );
1247 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
1248 if (i
!= 2) ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#lx\n", hr
);
1251 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
1252 ok( desc
.cAxes
== i
, "got cAxes %lu expected 2\n", desc
.cAxes
);
1253 ok( desc
.rglDirection
[0] == 15343, "got rglDirection[0] %ld expected %d\n",
1254 desc
.rglDirection
[0], 15343 );
1255 ok( desc
.rglDirection
[1] == 0, "got rglDirection[1] %ld expected %d\n", desc
.rglDirection
[1], 0 );
1256 ok( desc
.rglDirection
[2] == 0xcdcdcdcd, "got rglDirection[2] %ld expected %d\n",
1257 desc
.rglDirection
[2], 0xcdcdcdcd );
1260 ref
= IDirectInputEffect_Release( effect
);
1261 ok( ref
== 0, "Release returned %ld\n", ref
);
1264 desc
.dwFlags
= DIEFF_SPHERICAL
| DIEFF_OBJECTIDS
;
1266 desc
.rgdwAxes
= axes
;
1267 desc
.rglDirection
= directions
;
1268 desc
.rglDirection
[0] = 3000;
1269 desc
.rglDirection
[1] = 4000;
1270 desc
.rglDirection
[2] = 5000;
1271 flags
= version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
;
1272 expect_directions
[2] = expect_spherical
;
1273 set_hid_expect( file
, expect_directions
, sizeof(expect_directions
) );
1274 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, &desc
, &effect
, NULL
);
1275 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
1276 ref
= IDirectInputEffect_Release( effect
);
1277 ok( ref
== 0, "Release returned %ld\n", ref
);
1278 set_hid_expect( file
, NULL
, 0 );
1281 desc
.dwFlags
= DIEFF_CARTESIAN
| DIEFF_OBJECTIDS
;
1283 desc
.rgdwAxes
= axes
;
1284 desc
.rglDirection
= directions
;
1285 desc
.rglDirection
[0] = 6000;
1286 desc
.rglDirection
[1] = 7000;
1287 desc
.rglDirection
[2] = 8000;
1288 flags
= version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
;
1289 expect_directions
[2] = expect_cartesian
;
1290 set_hid_expect( file
, expect_directions
, sizeof(expect_directions
) );
1291 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, &desc
, &effect
, NULL
);
1292 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
1293 ref
= IDirectInputEffect_Release( effect
);
1294 ok( ref
== 0, "Release returned %ld\n", ref
);
1295 set_hid_expect( file
, NULL
, 0 );
1300 desc
.dwFlags
= DIEFF_POLAR
| DIEFF_OBJECTIDS
;
1302 desc
.rgdwAxes
= axes
;
1303 desc
.rglDirection
= directions
;
1304 desc
.rglDirection
[0] = 9000;
1305 desc
.rglDirection
[1] = 10000;
1306 desc
.rglDirection
[2] = 11000;
1307 flags
= version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
;
1308 expect_directions
[2] = expect_polar
;
1309 set_hid_expect( file
, expect_directions
, sizeof(expect_directions
) );
1310 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, &desc
, &effect
, NULL
);
1311 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
1312 ref
= IDirectInputEffect_Release( effect
);
1313 ok( ref
== 0, "Release returned %ld\n", ref
);
1314 set_hid_expect( file
, NULL
, 0 );
1317 winetest_pop_context();
1320 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
1321 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
1323 set_hid_expect( file
, expect_download_2
, sizeof(expect_download_2
) );
1324 flags
= version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
;
1325 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, flags
);
1326 ok( hr
== DI_OK
, "SetParameters returned %#lx\n", hr
);
1327 set_hid_expect( file
, NULL
, 0 );
1329 desc
.dwDuration
= INFINITE
;
1330 desc
.dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
1331 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
| DIEP_DURATION
| DIEP_TRIGGERBUTTON
);
1332 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
1333 set_hid_expect( file
, expect_update
, sizeof(expect_update
) );
1334 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, 0 );
1335 ok( hr
== DI_OK
, "SetParameters returned %#lx\n", hr
);
1336 wait_hid_expect( file
, 100 ); /* these updates are sent asynchronously */
1338 desc
.dwDuration
= INFINITE
;
1339 desc
.dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
1340 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
| DIEP_DURATION
| DIEP_TRIGGERBUTTON
);
1341 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
1342 set_hid_expect( file
, expect_update
, sizeof(expect_update
) );
1343 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, 0 );
1344 ok( hr
== DI_OK
, "SetParameters returned %#lx\n", hr
);
1345 wait_hid_expect( file
, 100 ); /* these updates are sent asynchronously */
1348 desc
.lpEnvelope
= &envelope
;
1349 desc
.lpEnvelope
->dwAttackTime
= 1000;
1350 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
| DIEP_ENVELOPE
);
1351 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
1352 set_hid_expect( file
, expect_set_envelope
, sizeof(expect_set_envelope
) );
1353 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, 0 );
1354 ok( hr
== DI_OK
, "SetParameters returned %#lx\n", hr
);
1355 wait_hid_expect( file
, 100 ); /* these updates are sent asynchronously */
1357 set_hid_expect( file
, &expect_stop
, sizeof(expect_stop
) );
1358 ref
= IDirectInputEffect_Release( effect
);
1359 ok( ref
== 0, "Release returned %ld\n", ref
);
1360 set_hid_expect( file
, NULL
, 0 );
1362 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
1363 hr
= IDirectInputDevice8_Unacquire( device
);
1364 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
1365 set_hid_expect( file
, NULL
, 0 );
1366 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, &expect_desc
, &effect
, NULL
);
1367 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
1368 ref
= IDirectInputEffect_Release( effect
);
1369 ok( ref
== 0, "Release returned %ld\n", ref
);
1370 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
1371 hr
= IDirectInputDevice8_Acquire( device
);
1372 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
1373 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
1376 static void test_condition_effect( IDirectInputDevice8W
*device
, HANDLE file
, DWORD version
)
1378 struct hid_expect expect_create
[] =
1382 .code
= IOCTL_HID_WRITE_REPORT
,
1385 .report_buf
= {0x07,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
1389 .code
= IOCTL_HID_WRITE_REPORT
,
1392 .report_buf
= {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
1396 .code
= IOCTL_HID_WRITE_REPORT
,
1399 .report_buf
= {0x03,0x01,0x03,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0x00},
1402 struct hid_expect expect_create_1
[] =
1406 .code
= IOCTL_HID_WRITE_REPORT
,
1409 .report_buf
= {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
1413 .code
= IOCTL_HID_WRITE_REPORT
,
1416 .report_buf
= {0x03,0x01,0x03,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x3f,0x00},
1419 struct hid_expect expect_create_2
[] =
1423 .code
= IOCTL_HID_WRITE_REPORT
,
1426 .report_buf
= {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
1430 .code
= IOCTL_HID_WRITE_REPORT
,
1433 .report_buf
= {0x03,0x01,0x03,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xf1},
1436 struct hid_expect expect_create_3
[] =
1440 .code
= IOCTL_HID_WRITE_REPORT
,
1443 .report_buf
= {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
1447 .code
= IOCTL_HID_WRITE_REPORT
,
1450 .report_buf
= {0x03,0x01,0x03,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0x00},
1453 struct hid_expect expect_destroy
=
1455 .code
= IOCTL_HID_WRITE_REPORT
,
1458 .report_buf
= {0x02, 0x01, 0x03, 0x00},
1460 static const DWORD expect_axes
[3] =
1462 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
,
1463 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
,
1464 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
,
1466 static const LONG expect_directions
[3] = {
1471 static const DIENVELOPE expect_envelope
=
1473 .dwSize
= sizeof(DIENVELOPE
),
1474 .dwAttackLevel
= 1000,
1475 .dwAttackTime
= 2000,
1476 .dwFadeLevel
= 3000,
1479 static const DICONDITION expect_condition
[3] =
1483 .lPositiveCoefficient
= 2000,
1484 .lNegativeCoefficient
= -3000,
1485 .dwPositiveSaturation
= -4000,
1486 .dwNegativeSaturation
= -5000,
1491 .lPositiveCoefficient
= 5000,
1492 .lNegativeCoefficient
= -4000,
1493 .dwPositiveSaturation
= 3000,
1494 .dwNegativeSaturation
= 2000,
1499 .lPositiveCoefficient
= -8000,
1500 .lNegativeCoefficient
= 9000,
1501 .dwPositiveSaturation
= 10000,
1502 .dwNegativeSaturation
= 11000,
1503 .lDeadBand
= -12000,
1506 const DIEFFECT expect_desc
=
1508 .dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
),
1509 .dwFlags
= DIEFF_SPHERICAL
| DIEFF_OBJECTIDS
,
1511 .dwSamplePeriod
= 2000,
1513 .dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
1514 .dwTriggerRepeatInterval
= 5000,
1516 .rgdwAxes
= (void *)expect_axes
,
1517 .rglDirection
= (void *)expect_directions
,
1518 .lpEnvelope
= (void *)&expect_envelope
,
1519 .cbTypeSpecificParams
= 2 * sizeof(DICONDITION
),
1520 .lpvTypeSpecificParams
= (void *)expect_condition
,
1521 .dwStartDelay
= 6000,
1523 struct check_created_effect_params check_params
= {0};
1524 DIENVELOPE envelope
= {.dwSize
= sizeof(DIENVELOPE
)};
1525 DICONDITION condition
[2] = {{0}};
1526 IDirectInputEffect
*effect
;
1527 LONG directions
[4] = {0};
1528 DWORD axes
[4] = {0};
1531 .dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
),
1532 .dwFlags
= DIEFF_SPHERICAL
| DIEFF_OBJECTIDS
,
1535 .rglDirection
= directions
,
1536 .lpEnvelope
= &envelope
,
1537 .cbTypeSpecificParams
= 2 * sizeof(DICONDITION
),
1538 .lpvTypeSpecificParams
= condition
,
1544 set_hid_expect( file
, expect_create
, sizeof(expect_create
) );
1545 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &expect_desc
, &effect
, NULL
);
1546 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
1547 set_hid_expect( file
, NULL
, 0 );
1549 check_params
.expect_effect
= effect
;
1550 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_created_effect_objects
, &check_params
, 0 );
1551 ok( hr
== DI_OK
, "EnumCreatedEffectObjects returned %#lx\n", hr
);
1552 ok( check_params
.count
== 1, "got count %lu, expected 1\n", check_params
.count
);
1554 hr
= IDirectInputEffect_GetEffectGuid( effect
, &guid
);
1555 ok( hr
== DI_OK
, "GetEffectGuid returned %#lx\n", hr
);
1556 ok( IsEqualGUID( &guid
, &GUID_Spring
), "got guid %s, expected %s\n", debugstr_guid( &guid
),
1557 debugstr_guid( &GUID_Spring
) );
1559 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
);
1560 ok( hr
== DI_OK
, "GetParameters returned %#lx\n", hr
);
1561 check_member( desc
, expect_desc
, "%lu", dwDuration
);
1562 check_member( desc
, expect_desc
, "%lu", dwSamplePeriod
);
1563 check_member( desc
, expect_desc
, "%lu", dwGain
);
1564 check_member( desc
, expect_desc
, "%#lx", dwTriggerButton
);
1565 check_member( desc
, expect_desc
, "%lu", dwTriggerRepeatInterval
);
1566 check_member( desc
, expect_desc
, "%lu", cAxes
);
1567 check_member( desc
, expect_desc
, "%#lx", rgdwAxes
[0] );
1568 check_member( desc
, expect_desc
, "%#lx", rgdwAxes
[1] );
1569 check_member( desc
, expect_desc
, "%ld", rglDirection
[0] );
1570 check_member( desc
, expect_desc
, "%ld", rglDirection
[1] );
1571 check_member( desc
, expect_desc
, "%lu", cbTypeSpecificParams
);
1572 if (version
>= 0x700) check_member( desc
, expect_desc
, "%lu", dwStartDelay
);
1573 else ok( desc
.dwStartDelay
== 0, "got dwStartDelay %#lx\n", desc
.dwStartDelay
);
1574 check_member( envelope
, expect_envelope
, "%lu", dwAttackLevel
);
1575 check_member( envelope
, expect_envelope
, "%lu", dwAttackTime
);
1576 check_member( envelope
, expect_envelope
, "%lu", dwFadeLevel
);
1577 check_member( envelope
, expect_envelope
, "%lu", dwFadeTime
);
1578 check_member( condition
[0], expect_condition
[0], "%ld", lOffset
);
1579 check_member( condition
[0], expect_condition
[0], "%ld", lPositiveCoefficient
);
1580 check_member( condition
[0], expect_condition
[0], "%ld", lNegativeCoefficient
);
1581 check_member( condition
[0], expect_condition
[0], "%lu", dwPositiveSaturation
);
1582 check_member( condition
[0], expect_condition
[0], "%lu", dwNegativeSaturation
);
1583 check_member( condition
[0], expect_condition
[0], "%ld", lDeadBand
);
1584 check_member( condition
[1], expect_condition
[1], "%ld", lOffset
);
1585 check_member( condition
[1], expect_condition
[1], "%ld", lPositiveCoefficient
);
1586 check_member( condition
[1], expect_condition
[1], "%ld", lNegativeCoefficient
);
1587 check_member( condition
[1], expect_condition
[1], "%lu", dwPositiveSaturation
);
1588 check_member( condition
[1], expect_condition
[1], "%lu", dwNegativeSaturation
);
1589 check_member( condition
[1], expect_condition
[1], "%ld", lDeadBand
);
1591 set_hid_expect( file
, &expect_destroy
, sizeof(expect_destroy
) );
1592 ref
= IDirectInputEffect_Release( effect
);
1593 ok( ref
== 0, "Release returned %ld\n", ref
);
1594 set_hid_expect( file
, NULL
, 0 );
1598 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
1599 ok( hr
== DIERR_INVALIDPARAM
, "CreateEffect returned %#lx\n", hr
);
1600 desc
.cbTypeSpecificParams
= 1 * sizeof(DICONDITION
);
1601 desc
.lpvTypeSpecificParams
= (void *)&expect_condition
[1];
1602 set_hid_expect( file
, expect_create_1
, sizeof(expect_create_1
) );
1603 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
1604 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
1605 set_hid_expect( file
, NULL
, 0 );
1607 set_hid_expect( file
, &expect_destroy
, sizeof(expect_destroy
) );
1608 ref
= IDirectInputEffect_Release( effect
);
1609 ok( ref
== 0, "Release returned %ld\n", ref
);
1610 set_hid_expect( file
, NULL
, 0 );
1614 desc
.rglDirection
= directions
;
1615 desc
.rglDirection
[0] = +3000;
1616 desc
.rglDirection
[1] = -2000;
1617 desc
.rglDirection
[2] = +1000;
1618 desc
.cbTypeSpecificParams
= 1 * sizeof(DICONDITION
);
1619 desc
.lpvTypeSpecificParams
= (void *)&expect_condition
[1];
1620 set_hid_expect( file
, expect_create_2
, sizeof(expect_create_2
) );
1621 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
1622 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
1623 set_hid_expect( file
, NULL
, 0 );
1625 set_hid_expect( file
, &expect_destroy
, sizeof(expect_destroy
) );
1626 ref
= IDirectInputEffect_Release( effect
);
1627 ok( ref
== 0, "Release returned %ld\n", ref
);
1628 set_hid_expect( file
, NULL
, 0 );
1632 desc
.rgdwAxes
= axes
;
1633 desc
.rgdwAxes
[0] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
;
1634 desc
.rgdwAxes
[1] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
;
1635 desc
.rglDirection
= directions
;
1636 desc
.rglDirection
[0] = +3000;
1637 desc
.rglDirection
[1] = -2000;
1638 desc
.cbTypeSpecificParams
= 1 * sizeof(DICONDITION
);
1639 desc
.lpvTypeSpecificParams
= (void *)&expect_condition
[1];
1640 set_hid_expect( file
, expect_create_3
, sizeof(expect_create_3
) );
1641 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
1642 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
1643 set_hid_expect( file
, NULL
, 0 );
1645 set_hid_expect( file
, &expect_destroy
, sizeof(expect_destroy
) );
1646 ref
= IDirectInputEffect_Release( effect
);
1647 ok( ref
== 0, "Release returned %ld\n", ref
);
1648 set_hid_expect( file
, NULL
, 0 );
1650 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, NULL
, &effect
, NULL
);
1651 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
1654 desc
.cbTypeSpecificParams
= 1 * sizeof(DICONDITION
);
1655 desc
.lpvTypeSpecificParams
= (void *)&expect_condition
[0];
1656 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_TYPESPECIFICPARAMS
| DIEP_NODOWNLOAD
);
1657 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
1658 desc
.cbTypeSpecificParams
= 0 * sizeof(DICONDITION
);
1659 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TYPESPECIFICPARAMS
);
1660 ok( hr
== DIERR_MOREDATA
, "SetParameters returned %#lx\n", hr
);
1661 ok( desc
.cbTypeSpecificParams
== 1 * sizeof(DICONDITION
), "got %lu\n", desc
.cbTypeSpecificParams
);
1662 desc
.cbTypeSpecificParams
= 0 * sizeof(DICONDITION
);
1663 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_TYPESPECIFICPARAMS
| DIEP_NODOWNLOAD
);
1664 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
1665 desc
.cbTypeSpecificParams
= 0 * sizeof(DICONDITION
);
1666 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TYPESPECIFICPARAMS
);
1667 ok( hr
== DI_OK
, "SetParameters returned %#lx\n", hr
);
1668 ok( desc
.cbTypeSpecificParams
== 0 * sizeof(DICONDITION
), "got %lu\n", desc
.cbTypeSpecificParams
);
1669 ref
= IDirectInputEffect_Release( effect
);
1670 ok( ref
== 0, "Release returned %ld\n", ref
);
1673 static BOOL
test_force_feedback_joystick( DWORD version
)
1675 #include "psh_hid_macros.h"
1676 const unsigned char report_descriptor
[] =
1678 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
1679 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
1680 COLLECTION(1, Application
),
1681 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
1682 COLLECTION(1, Report
),
1685 USAGE(1, HID_USAGE_GENERIC_X
),
1686 USAGE(1, HID_USAGE_GENERIC_Y
),
1687 USAGE(1, HID_USAGE_GENERIC_Z
),
1688 LOGICAL_MINIMUM(1, 0),
1689 LOGICAL_MAXIMUM(1, 0x7f),
1690 PHYSICAL_MINIMUM(1, 0),
1691 PHYSICAL_MAXIMUM(1, 0x7f),
1694 INPUT(1, Data
|Var
|Abs
),
1696 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
1697 USAGE_MINIMUM(1, 1),
1698 USAGE_MAXIMUM(1, 2),
1699 LOGICAL_MINIMUM(1, 0),
1700 LOGICAL_MAXIMUM(1, 1),
1701 PHYSICAL_MINIMUM(1, 0),
1702 PHYSICAL_MAXIMUM(1, 1),
1705 INPUT(1, Data
|Var
|Abs
),
1707 INPUT(1, Cnst
|Var
|Abs
),
1710 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
1711 USAGE(1, PID_USAGE_STATE_REPORT
),
1712 COLLECTION(1, Report
),
1715 USAGE(1, PID_USAGE_DEVICE_PAUSED
),
1716 USAGE(1, PID_USAGE_ACTUATORS_ENABLED
),
1717 USAGE(1, PID_USAGE_SAFETY_SWITCH
),
1718 USAGE(1, PID_USAGE_ACTUATOR_OVERRIDE_SWITCH
),
1719 USAGE(1, PID_USAGE_ACTUATOR_POWER
),
1720 LOGICAL_MINIMUM(1, 0),
1721 LOGICAL_MAXIMUM(1, 1),
1722 PHYSICAL_MINIMUM(1, 0),
1723 PHYSICAL_MAXIMUM(1, 1),
1726 INPUT(1, Data
|Var
|Abs
),
1728 INPUT(1, Cnst
|Var
|Abs
),
1730 USAGE(1, PID_USAGE_EFFECT_PLAYING
),
1731 LOGICAL_MINIMUM(1, 0),
1732 LOGICAL_MAXIMUM(1, 1),
1733 PHYSICAL_MINIMUM(1, 0),
1734 PHYSICAL_MAXIMUM(1, 1),
1737 INPUT(1, Data
|Var
|Abs
),
1739 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
1740 LOGICAL_MAXIMUM(1, 0x7f),
1741 LOGICAL_MINIMUM(1, 0x00),
1744 INPUT(1, Data
|Var
|Abs
),
1747 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
1748 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT
),
1749 COLLECTION(1, Report
),
1752 USAGE(1, PID_USAGE_DEVICE_CONTROL
),
1753 COLLECTION(1, Logical
),
1754 USAGE(1, PID_USAGE_DC_DEVICE_RESET
),
1755 LOGICAL_MINIMUM(1, 1),
1756 LOGICAL_MAXIMUM(1, 2),
1757 PHYSICAL_MINIMUM(1, 1),
1758 PHYSICAL_MAXIMUM(1, 2),
1761 OUTPUT(1, Data
|Ary
|Abs
),
1765 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT
),
1766 COLLECTION(1, Report
),
1769 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
1770 LOGICAL_MINIMUM(1, 0),
1771 LOGICAL_MAXIMUM(1, 0x7f),
1772 PHYSICAL_MINIMUM(1, 0),
1773 PHYSICAL_MAXIMUM(1, 0x7f),
1776 OUTPUT(1, Data
|Var
|Abs
),
1778 USAGE(1, PID_USAGE_EFFECT_OPERATION
),
1779 COLLECTION(1, NamedArray
),
1780 USAGE(1, PID_USAGE_OP_EFFECT_START
),
1781 USAGE(1, PID_USAGE_OP_EFFECT_START_SOLO
),
1782 USAGE(1, PID_USAGE_OP_EFFECT_STOP
),
1783 LOGICAL_MINIMUM(1, 1),
1784 LOGICAL_MAXIMUM(1, 3),
1785 PHYSICAL_MINIMUM(1, 1),
1786 PHYSICAL_MAXIMUM(1, 3),
1789 OUTPUT(1, Data
|Ary
|Abs
),
1792 USAGE(1, PID_USAGE_LOOP_COUNT
),
1793 LOGICAL_MINIMUM(1, 0),
1794 LOGICAL_MAXIMUM(1, 0x7f),
1795 PHYSICAL_MINIMUM(1, 0),
1796 PHYSICAL_MAXIMUM(1, 0x7f),
1799 OUTPUT(1, Data
|Var
|Abs
),
1802 USAGE(1, PID_USAGE_SET_EFFECT_REPORT
),
1803 COLLECTION(1, Report
),
1806 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
1807 LOGICAL_MINIMUM(1, 0),
1808 LOGICAL_MAXIMUM(1, 0x7f),
1809 PHYSICAL_MINIMUM(1, 0),
1810 PHYSICAL_MAXIMUM(1, 0x7f),
1813 OUTPUT(1, Data
|Var
|Abs
),
1815 USAGE(1, PID_USAGE_EFFECT_TYPE
),
1816 COLLECTION(1, NamedArray
),
1817 USAGE(1, PID_USAGE_ET_SQUARE
),
1818 USAGE(1, PID_USAGE_ET_SINE
),
1819 USAGE(1, PID_USAGE_ET_SPRING
),
1820 LOGICAL_MINIMUM(1, 1),
1821 LOGICAL_MAXIMUM(1, 3),
1822 PHYSICAL_MINIMUM(1, 1),
1823 PHYSICAL_MAXIMUM(1, 3),
1826 OUTPUT(1, Data
|Ary
|Abs
),
1829 USAGE(1, PID_USAGE_AXES_ENABLE
),
1830 COLLECTION(1, Logical
),
1831 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_X
),
1832 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Y
),
1833 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Z
),
1834 LOGICAL_MINIMUM(1, 0),
1835 LOGICAL_MAXIMUM(1, 1),
1836 PHYSICAL_MINIMUM(1, 0),
1837 PHYSICAL_MAXIMUM(1, 1),
1840 OUTPUT(1, Data
|Var
|Abs
),
1842 USAGE(1, PID_USAGE_DIRECTION_ENABLE
),
1844 OUTPUT(1, Data
|Var
|Abs
),
1846 OUTPUT(1, Cnst
|Var
|Abs
),
1848 USAGE(1, PID_USAGE_DURATION
),
1849 USAGE(1, PID_USAGE_START_DELAY
),
1850 UNIT(2, 0x1003), /* Eng Lin:Time */
1851 UNIT_EXPONENT(1, -3), /* 10^-3 */
1852 LOGICAL_MINIMUM(1, 0),
1853 LOGICAL_MAXIMUM(2, 0x7fff),
1854 PHYSICAL_MINIMUM(1, 0),
1855 PHYSICAL_MAXIMUM(2, 0x7fff),
1858 OUTPUT(1, Data
|Var
|Abs
),
1860 UNIT_EXPONENT(1, 0),
1862 USAGE(1, PID_USAGE_TRIGGER_BUTTON
),
1863 LOGICAL_MINIMUM(1, 1),
1864 LOGICAL_MAXIMUM(1, 0x08),
1865 PHYSICAL_MINIMUM(1, 1),
1866 PHYSICAL_MAXIMUM(1, 0x08),
1869 OUTPUT(1, Data
|Var
|Abs
),
1871 USAGE(1, PID_USAGE_DIRECTION
),
1872 COLLECTION(1, Logical
),
1873 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
1874 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
1875 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
1876 UNIT_EXPONENT(1, -2), /* 10^-2 */
1877 LOGICAL_MINIMUM(1, 0),
1878 LOGICAL_MAXIMUM(2, 0x00ff),
1879 PHYSICAL_MINIMUM(1, 0),
1880 PHYSICAL_MAXIMUM(4, 0x00008ca0),
1884 OUTPUT(1, Data
|Var
|Abs
),
1885 UNIT_EXPONENT(1, 0),
1890 USAGE(1, PID_USAGE_SET_PERIODIC_REPORT
),
1891 COLLECTION(1, Logical
),
1894 USAGE(1, PID_USAGE_MAGNITUDE
),
1895 LOGICAL_MINIMUM(1, 0),
1896 LOGICAL_MAXIMUM(2, 0x00ff),
1897 PHYSICAL_MINIMUM(1, 0),
1898 PHYSICAL_MAXIMUM(2, 0x2710),
1901 OUTPUT(1, Data
|Var
|Abs
),
1904 USAGE(1, PID_USAGE_SET_ENVELOPE_REPORT
),
1905 COLLECTION(1, Logical
),
1908 USAGE(1, PID_USAGE_ATTACK_LEVEL
),
1909 USAGE(1, PID_USAGE_FADE_LEVEL
),
1910 LOGICAL_MINIMUM(1, 0),
1911 LOGICAL_MAXIMUM(2, 0x00ff),
1912 PHYSICAL_MINIMUM(1, 0),
1913 PHYSICAL_MAXIMUM(2, 0x2710),
1916 OUTPUT(1, Data
|Var
|Abs
),
1918 USAGE(1, PID_USAGE_ATTACK_TIME
),
1919 USAGE(1, PID_USAGE_FADE_TIME
),
1920 UNIT(2, 0x1003), /* Eng Lin:Time */
1921 UNIT_EXPONENT(1, -3), /* 10^-3 */
1922 LOGICAL_MINIMUM(1, 0),
1923 LOGICAL_MAXIMUM(2, 0x7fff),
1924 PHYSICAL_MINIMUM(1, 0),
1925 PHYSICAL_MAXIMUM(2, 0x7fff),
1928 OUTPUT(1, Data
|Var
|Abs
),
1929 PHYSICAL_MAXIMUM(1, 0),
1930 UNIT_EXPONENT(1, 0),
1935 USAGE(1, PID_USAGE_SET_CONDITION_REPORT
),
1936 COLLECTION(1, Logical
),
1939 USAGE(1, PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET
),
1940 COLLECTION(1, Logical
),
1941 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
1942 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
1943 LOGICAL_MINIMUM(1, 0),
1944 LOGICAL_MAXIMUM(1, 1),
1945 PHYSICAL_MINIMUM(1, 0),
1946 PHYSICAL_MAXIMUM(1, 1),
1949 OUTPUT(1, Data
|Var
|Abs
),
1953 OUTPUT(1, Cnst
|Var
|Abs
),
1955 USAGE(1, PID_USAGE_CP_OFFSET
),
1956 LOGICAL_MINIMUM(1, 0x80),
1957 LOGICAL_MAXIMUM(1, 0x7f),
1958 PHYSICAL_MINIMUM(2, 0xd8f0),
1959 PHYSICAL_MAXIMUM(2, 0x2710),
1962 OUTPUT(1, Data
|Var
|Abs
),
1964 USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT
),
1965 USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT
),
1966 LOGICAL_MINIMUM(1, 0x80),
1967 LOGICAL_MAXIMUM(1, 0x7f),
1968 PHYSICAL_MINIMUM(2, 0xd8f0),
1969 PHYSICAL_MAXIMUM(2, 0x2710),
1972 OUTPUT(1, Data
|Var
|Abs
),
1974 USAGE(1, PID_USAGE_POSITIVE_SATURATION
),
1975 USAGE(1, PID_USAGE_NEGATIVE_SATURATION
),
1976 LOGICAL_MINIMUM(1, 0),
1977 LOGICAL_MAXIMUM(2, 0x00ff),
1978 PHYSICAL_MINIMUM(1, 0),
1979 PHYSICAL_MAXIMUM(2, 0x2710),
1982 OUTPUT(1, Data
|Var
|Abs
),
1984 USAGE(1, PID_USAGE_DEAD_BAND
),
1985 LOGICAL_MINIMUM(1, 0),
1986 LOGICAL_MAXIMUM(2, 0x00ff),
1987 PHYSICAL_MINIMUM(1, 0),
1988 PHYSICAL_MAXIMUM(2, 0x2710),
1991 OUTPUT(1, Data
|Var
|Abs
),
1995 USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT
),
1996 COLLECTION(1, Logical
),
1999 USAGE(1, PID_USAGE_DEVICE_GAIN
),
2000 LOGICAL_MINIMUM(1, 0),
2001 LOGICAL_MAXIMUM(2, 0x00ff),
2002 PHYSICAL_MINIMUM(1, 0),
2003 PHYSICAL_MAXIMUM(2, 0x2710),
2006 OUTPUT(1, Data
|Var
|Abs
),
2010 C_ASSERT(sizeof(report_descriptor
) < MAX_HID_DESCRIPTOR_LEN
);
2011 #include "pop_hid_macros.h"
2013 struct hid_device_desc desc
=
2015 .use_report_id
= TRUE
,
2018 .InputReportByteLength
= 5,
2019 .OutputReportByteLength
= 11,
2021 .attributes
= default_attributes
,
2023 const DIDEVCAPS expect_caps
=
2025 .dwSize
= sizeof(DIDEVCAPS
),
2026 .dwFlags
= DIDC_FORCEFEEDBACK
| DIDC_ATTACHED
| DIDC_EMULATED
| DIDC_STARTDELAY
|
2027 DIDC_FFFADE
| DIDC_FFATTACK
| DIDC_DEADBAND
| DIDC_SATURATION
,
2028 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
2029 : DIDEVTYPE_HID
| (DIDEVTYPEJOYSTICK_UNKNOWN
<< 8) | DIDEVTYPE_JOYSTICK
,
2032 .dwFFSamplePeriod
= 1000000,
2033 .dwFFMinTimeResolution
= 1000000,
2034 .dwHardwareRevision
= 1,
2035 .dwFFDriverVersion
= 1,
2037 struct hid_expect expect_acquire
[] =
2040 .code
= IOCTL_HID_WRITE_REPORT
,
2043 .report_buf
= {1, 0x01},
2046 .code
= IOCTL_HID_WRITE_REPORT
,
2049 .report_buf
= {8, 0x19},
2052 struct hid_expect expect_reset
[] =
2055 .code
= IOCTL_HID_WRITE_REPORT
,
2058 .report_buf
= {1, 0x01},
2061 struct hid_expect expect_set_device_gain_1
=
2063 .code
= IOCTL_HID_WRITE_REPORT
,
2066 .report_buf
= {8, 0x19},
2068 struct hid_expect expect_set_device_gain_2
=
2070 .code
= IOCTL_HID_WRITE_REPORT
,
2073 .report_buf
= {8, 0x33},
2076 const DIDEVICEINSTANCEW expect_devinst
=
2078 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
2079 .guidInstance
= expect_guid_product
,
2080 .guidProduct
= expect_guid_product
,
2081 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
2082 : DIDEVTYPE_HID
| (DIDEVTYPEJOYSTICK_UNKNOWN
<< 8) | DIDEVTYPE_JOYSTICK
,
2083 .tszInstanceName
= L
"Wine Test",
2084 .tszProductName
= L
"Wine Test",
2085 .guidFFDriver
= IID_IDirectInputPIDDriver
,
2086 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
2087 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
2089 const DIDEVICEOBJECTINSTANCEW expect_objects_5
[] =
2092 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2093 .guidType
= GUID_XAxis
,
2094 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(0)|DIDFT_FFACTUATOR
,
2095 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
2096 .tszName
= L
"X Axis",
2097 .wCollectionNumber
= 1,
2098 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
2099 .wUsage
= HID_USAGE_GENERIC_X
,
2103 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2104 .guidType
= GUID_YAxis
,
2106 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(1)|DIDFT_FFACTUATOR
,
2107 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
2108 .tszName
= L
"Y Axis",
2109 .wCollectionNumber
= 1,
2110 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
2111 .wUsage
= HID_USAGE_GENERIC_Y
,
2115 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2116 .guidType
= GUID_ZAxis
,
2118 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(2)|DIDFT_FFACTUATOR
,
2119 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
2120 .tszName
= L
"Z Axis",
2121 .wCollectionNumber
= 1,
2122 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
2123 .wUsage
= HID_USAGE_GENERIC_Z
,
2127 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2128 .guidType
= GUID_Button
,
2130 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(0)|DIDFT_FFEFFECTTRIGGER
,
2131 .dwFlags
= DIDOI_FFEFFECTTRIGGER
,
2132 .tszName
= L
"Button 0",
2133 .wCollectionNumber
= 1,
2134 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
2139 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2140 .guidType
= GUID_Button
,
2142 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(1)|DIDFT_FFEFFECTTRIGGER
,
2143 .dwFlags
= DIDOI_FFEFFECTTRIGGER
,
2144 .tszName
= L
"Button 1",
2145 .wCollectionNumber
= 1,
2146 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
2151 const DIDEVICEOBJECTINSTANCEW expect_objects
[] =
2154 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2155 .guidType
= GUID_ZAxis
,
2156 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(2)|DIDFT_FFACTUATOR
,
2157 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
2158 .tszName
= L
"Z Axis",
2159 .wCollectionNumber
= 1,
2160 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
2161 .wUsage
= HID_USAGE_GENERIC_Z
,
2165 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2166 .guidType
= GUID_YAxis
,
2168 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(1)|DIDFT_FFACTUATOR
,
2169 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
2170 .tszName
= L
"Y Axis",
2171 .wCollectionNumber
= 1,
2172 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
2173 .wUsage
= HID_USAGE_GENERIC_Y
,
2177 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2178 .guidType
= GUID_XAxis
,
2180 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(0)|DIDFT_FFACTUATOR
,
2181 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
2182 .tszName
= L
"X Axis",
2183 .wCollectionNumber
= 1,
2184 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
2185 .wUsage
= HID_USAGE_GENERIC_X
,
2189 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2190 .guidType
= GUID_Button
,
2191 .dwOfs
= version
>= 0x800 ? 0x68 : 0x10,
2192 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(0)|DIDFT_FFEFFECTTRIGGER
,
2193 .dwFlags
= DIDOI_FFEFFECTTRIGGER
,
2194 .tszName
= L
"Button 0",
2195 .wCollectionNumber
= 1,
2196 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
2201 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2202 .guidType
= GUID_Button
,
2203 .dwOfs
= version
>= 0x800 ? 0x69 : 0x11,
2204 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(1)|DIDFT_FFEFFECTTRIGGER
,
2205 .dwFlags
= DIDOI_FFEFFECTTRIGGER
,
2206 .tszName
= L
"Button 1",
2207 .wCollectionNumber
= 1,
2208 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
2213 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2214 .guidType
= GUID_Unknown
,
2215 .dwOfs
= version
>= 0x800 ? 0x70 : 0,
2216 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(12)|DIDFT_OUTPUT
,
2217 .dwFlags
= 0x80008000,
2218 .tszName
= L
"DC Device Reset",
2219 .wCollectionNumber
= 4,
2220 .wUsagePage
= HID_USAGE_PAGE_PID
,
2221 .wUsage
= PID_USAGE_DC_DEVICE_RESET
,
2225 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2226 .guidType
= GUID_Unknown
,
2227 .dwOfs
= version
>= 0x800 ? 0x10 : 0,
2228 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(13)|DIDFT_OUTPUT
,
2229 .dwFlags
= 0x80008000,
2230 .tszName
= L
"Effect Block Index",
2231 .wCollectionNumber
= 5,
2232 .wUsagePage
= HID_USAGE_PAGE_PID
,
2233 .wUsage
= PID_USAGE_EFFECT_BLOCK_INDEX
,
2237 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2238 .guidType
= GUID_Unknown
,
2239 .dwOfs
= version
>= 0x800 ? 0x71 : 0,
2240 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(14)|DIDFT_OUTPUT
,
2241 .dwFlags
= 0x80008000,
2242 .tszName
= L
"Op Effect Start",
2243 .wCollectionNumber
= 6,
2244 .wUsagePage
= HID_USAGE_PAGE_PID
,
2245 .wUsage
= PID_USAGE_OP_EFFECT_START
,
2249 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2250 .guidType
= GUID_Unknown
,
2251 .dwOfs
= version
>= 0x800 ? 0x72 : 0,
2252 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(15)|DIDFT_OUTPUT
,
2253 .dwFlags
= 0x80008000,
2254 .tszName
= L
"Op Effect Start Solo",
2255 .wCollectionNumber
= 6,
2256 .wUsagePage
= HID_USAGE_PAGE_PID
,
2257 .wUsage
= PID_USAGE_OP_EFFECT_START_SOLO
,
2261 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2262 .guidType
= GUID_Unknown
,
2263 .dwOfs
= version
>= 0x800 ? 0x73 : 0,
2264 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(16)|DIDFT_OUTPUT
,
2265 .dwFlags
= 0x80008000,
2266 .tszName
= L
"Op Effect Stop",
2267 .wCollectionNumber
= 6,
2268 .wUsagePage
= HID_USAGE_PAGE_PID
,
2269 .wUsage
= PID_USAGE_OP_EFFECT_STOP
,
2273 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2274 .guidType
= GUID_Unknown
,
2275 .dwOfs
= version
>= 0x800 ? 0x14 : 0,
2276 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(17)|DIDFT_OUTPUT
,
2277 .dwFlags
= 0x80008000,
2278 .tszName
= L
"Loop Count",
2279 .wCollectionNumber
= 5,
2280 .wUsagePage
= HID_USAGE_PAGE_PID
,
2281 .wUsage
= PID_USAGE_LOOP_COUNT
,
2285 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2286 .guidType
= GUID_Unknown
,
2287 .dwOfs
= version
>= 0x800 ? 0x18 : 0,
2288 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(18)|DIDFT_OUTPUT
,
2289 .dwFlags
= 0x80008000,
2290 .tszName
= L
"Effect Block Index",
2291 .wCollectionNumber
= 7,
2292 .wUsagePage
= HID_USAGE_PAGE_PID
,
2293 .wUsage
= PID_USAGE_EFFECT_BLOCK_INDEX
,
2297 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2298 .guidType
= GUID_Unknown
,
2299 .dwOfs
= version
>= 0x800 ? 0x74 : 0,
2300 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(19)|DIDFT_OUTPUT
,
2301 .dwFlags
= 0x80008000,
2302 .tszName
= L
"ET Square",
2303 .wCollectionNumber
= 8,
2304 .wUsagePage
= HID_USAGE_PAGE_PID
,
2305 .wUsage
= PID_USAGE_ET_SQUARE
,
2309 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2310 .guidType
= GUID_Unknown
,
2311 .dwOfs
= version
>= 0x800 ? 0x75 : 0,
2312 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(20)|DIDFT_OUTPUT
,
2313 .dwFlags
= 0x80008000,
2314 .tszName
= L
"ET Sine",
2315 .wCollectionNumber
= 8,
2316 .wUsagePage
= HID_USAGE_PAGE_PID
,
2317 .wUsage
= PID_USAGE_ET_SINE
,
2321 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2322 .guidType
= GUID_Unknown
,
2323 .dwOfs
= version
>= 0x800 ? 0x76 : 0,
2324 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(21)|DIDFT_OUTPUT
,
2325 .dwFlags
= 0x80008000,
2326 .tszName
= L
"ET Spring",
2327 .wCollectionNumber
= 8,
2328 .wUsagePage
= HID_USAGE_PAGE_PID
,
2329 .wUsage
= PID_USAGE_ET_SPRING
,
2333 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2334 .guidType
= GUID_Unknown
,
2335 .dwOfs
= version
>= 0x800 ? 0x77 : 0,
2336 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(22)|DIDFT_OUTPUT
,
2337 .dwFlags
= 0x80008000,
2338 .tszName
= L
"Z Axis",
2339 .wCollectionNumber
= 9,
2340 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
2341 .wUsage
= HID_USAGE_GENERIC_Z
,
2345 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2346 .guidType
= GUID_Unknown
,
2347 .dwOfs
= version
>= 0x800 ? 0x78 : 0,
2348 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(23)|DIDFT_OUTPUT
,
2349 .dwFlags
= 0x80008000,
2350 .tszName
= L
"Y Axis",
2351 .wCollectionNumber
= 9,
2352 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
2353 .wUsage
= HID_USAGE_GENERIC_Y
,
2357 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2358 .guidType
= GUID_Unknown
,
2359 .dwOfs
= version
>= 0x800 ? 0x79 : 0,
2360 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(24)|DIDFT_OUTPUT
,
2361 .dwFlags
= 0x80008000,
2362 .tszName
= L
"X Axis",
2363 .wCollectionNumber
= 9,
2364 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
2365 .wUsage
= HID_USAGE_GENERIC_X
,
2369 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2370 .guidType
= GUID_Unknown
,
2371 .dwOfs
= version
>= 0x800 ? 0x7a : 0,
2372 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(25)|DIDFT_OUTPUT
,
2373 .dwFlags
= 0x80008000,
2374 .tszName
= L
"Direction Enable",
2375 .wCollectionNumber
= 7,
2376 .wUsagePage
= HID_USAGE_PAGE_PID
,
2377 .wUsage
= PID_USAGE_DIRECTION_ENABLE
,
2381 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2382 .guidType
= GUID_Unknown
,
2383 .dwOfs
= version
>= 0x800 ? 0x1c : 0,
2384 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(26)|DIDFT_OUTPUT
,
2385 .dwFlags
= 0x80008000,
2386 .tszName
= L
"Start Delay",
2387 .wCollectionNumber
= 7,
2388 .wUsagePage
= HID_USAGE_PAGE_PID
,
2389 .wUsage
= PID_USAGE_START_DELAY
,
2391 .dwDimension
= 0x1003,
2395 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2396 .guidType
= GUID_Unknown
,
2397 .dwOfs
= version
>= 0x800 ? 0x20 : 0,
2398 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(27)|DIDFT_OUTPUT
,
2399 .dwFlags
= 0x80008000,
2400 .tszName
= L
"Duration",
2401 .wCollectionNumber
= 7,
2402 .wUsagePage
= HID_USAGE_PAGE_PID
,
2403 .wUsage
= PID_USAGE_DURATION
,
2405 .dwDimension
= 0x1003,
2409 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2410 .guidType
= GUID_Unknown
,
2411 .dwOfs
= version
>= 0x800 ? 0x24 : 0,
2412 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(28)|DIDFT_OUTPUT
,
2413 .dwFlags
= 0x80008000,
2414 .tszName
= L
"Trigger Button",
2415 .wCollectionNumber
= 7,
2416 .wUsagePage
= HID_USAGE_PAGE_PID
,
2417 .wUsage
= PID_USAGE_TRIGGER_BUTTON
,
2421 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2422 .guidType
= GUID_Unknown
,
2423 .dwOfs
= version
>= 0x800 ? 0x28 : 0,
2424 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(29)|DIDFT_OUTPUT
,
2425 .dwFlags
= 0x80008000,
2426 .tszName
= L
"Unknown 29",
2427 .wCollectionNumber
= 10,
2428 .wUsagePage
= HID_USAGE_PAGE_ORDINAL
,
2434 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2435 .guidType
= GUID_Unknown
,
2436 .dwOfs
= version
>= 0x800 ? 0x2c : 0,
2437 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(30)|DIDFT_OUTPUT
,
2438 .dwFlags
= 0x80008000,
2439 .tszName
= L
"Unknown 30",
2440 .wCollectionNumber
= 10,
2441 .wUsagePage
= HID_USAGE_PAGE_ORDINAL
,
2447 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2448 .guidType
= GUID_Unknown
,
2449 .dwOfs
= version
>= 0x800 ? 0x30 : 0,
2450 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(31)|DIDFT_OUTPUT
,
2451 .dwFlags
= 0x80008000,
2452 .tszName
= L
"Magnitude",
2453 .wCollectionNumber
= 11,
2454 .wUsagePage
= HID_USAGE_PAGE_PID
,
2455 .wUsage
= PID_USAGE_MAGNITUDE
,
2459 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2460 .guidType
= GUID_Unknown
,
2461 .dwOfs
= version
>= 0x800 ? 0x34 : 0,
2462 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(32)|DIDFT_OUTPUT
,
2463 .dwFlags
= 0x80008000,
2464 .tszName
= L
"Fade Level",
2465 .wCollectionNumber
= 12,
2466 .wUsagePage
= HID_USAGE_PAGE_PID
,
2467 .wUsage
= PID_USAGE_FADE_LEVEL
,
2471 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2472 .guidType
= GUID_Unknown
,
2473 .dwOfs
= version
>= 0x800 ? 0x38 : 0,
2474 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(33)|DIDFT_OUTPUT
,
2475 .dwFlags
= 0x80008000,
2476 .tszName
= L
"Attack Level",
2477 .wCollectionNumber
= 12,
2478 .wUsagePage
= HID_USAGE_PAGE_PID
,
2479 .wUsage
= PID_USAGE_ATTACK_LEVEL
,
2483 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2484 .guidType
= GUID_Unknown
,
2485 .dwOfs
= version
>= 0x800 ? 0x3c : 0,
2486 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(34)|DIDFT_OUTPUT
,
2487 .dwFlags
= 0x80008000,
2488 .tszName
= L
"Fade Time",
2489 .wCollectionNumber
= 12,
2490 .wUsagePage
= HID_USAGE_PAGE_PID
,
2491 .wUsage
= PID_USAGE_FADE_TIME
,
2493 .dwDimension
= 0x1003,
2497 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2498 .guidType
= GUID_Unknown
,
2499 .dwOfs
= version
>= 0x800 ? 0x40 : 0,
2500 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(35)|DIDFT_OUTPUT
,
2501 .dwFlags
= 0x80008000,
2502 .tszName
= L
"Attack Time",
2503 .wCollectionNumber
= 12,
2504 .wUsagePage
= HID_USAGE_PAGE_PID
,
2505 .wUsage
= PID_USAGE_ATTACK_TIME
,
2507 .dwDimension
= 0x1003,
2511 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2512 .guidType
= GUID_Unknown
,
2513 .dwOfs
= version
>= 0x800 ? 0x44 : 0,
2514 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(36)|DIDFT_OUTPUT
,
2515 .dwFlags
= 0x80008000,
2516 .tszName
= L
"Unknown 36",
2517 .wCollectionNumber
= 14,
2518 .wUsagePage
= HID_USAGE_PAGE_ORDINAL
,
2523 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2524 .guidType
= GUID_Unknown
,
2525 .dwOfs
= version
>= 0x800 ? 0x48 : 0,
2526 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(37)|DIDFT_OUTPUT
,
2527 .dwFlags
= 0x80008000,
2528 .tszName
= L
"Unknown 37",
2529 .wCollectionNumber
= 14,
2530 .wUsagePage
= HID_USAGE_PAGE_ORDINAL
,
2535 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2536 .guidType
= GUID_Unknown
,
2537 .dwOfs
= version
>= 0x800 ? 0x4c : 0,
2538 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(38)|DIDFT_OUTPUT
,
2539 .dwFlags
= 0x80008000,
2540 .tszName
= L
"CP Offset",
2541 .wCollectionNumber
= 13,
2542 .wUsagePage
= HID_USAGE_PAGE_PID
,
2543 .wUsage
= PID_USAGE_CP_OFFSET
,
2547 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2548 .guidType
= GUID_Unknown
,
2549 .dwOfs
= version
>= 0x800 ? 0x50 : 0,
2550 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(39)|DIDFT_OUTPUT
,
2551 .dwFlags
= 0x80008000,
2552 .tszName
= L
"Negative Coefficient",
2553 .wCollectionNumber
= 13,
2554 .wUsagePage
= HID_USAGE_PAGE_PID
,
2555 .wUsage
= PID_USAGE_NEGATIVE_COEFFICIENT
,
2559 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2560 .guidType
= GUID_Unknown
,
2561 .dwOfs
= version
>= 0x800 ? 0x54 : 0,
2562 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(40)|DIDFT_OUTPUT
,
2563 .dwFlags
= 0x80008000,
2564 .tszName
= L
"Positive Coefficient",
2565 .wCollectionNumber
= 13,
2566 .wUsagePage
= HID_USAGE_PAGE_PID
,
2567 .wUsage
= PID_USAGE_POSITIVE_COEFFICIENT
,
2571 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2572 .guidType
= GUID_Unknown
,
2573 .dwOfs
= version
>= 0x800 ? 0x58 : 0,
2574 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(41)|DIDFT_OUTPUT
,
2575 .dwFlags
= 0x80008000,
2576 .tszName
= L
"Negative Saturation",
2577 .wCollectionNumber
= 13,
2578 .wUsagePage
= HID_USAGE_PAGE_PID
,
2579 .wUsage
= PID_USAGE_NEGATIVE_SATURATION
,
2583 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2584 .guidType
= GUID_Unknown
,
2585 .dwOfs
= version
>= 0x800 ? 0x5c : 0,
2586 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(42)|DIDFT_OUTPUT
,
2587 .dwFlags
= 0x80008000,
2588 .tszName
= L
"Positive Saturation",
2589 .wCollectionNumber
= 13,
2590 .wUsagePage
= HID_USAGE_PAGE_PID
,
2591 .wUsage
= PID_USAGE_POSITIVE_SATURATION
,
2595 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2596 .guidType
= GUID_Unknown
,
2597 .dwOfs
= version
>= 0x800 ? 0x60 : 0,
2598 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(43)|DIDFT_OUTPUT
,
2599 .dwFlags
= 0x80008000,
2600 .tszName
= L
"Dead Band",
2601 .wCollectionNumber
= 13,
2602 .wUsagePage
= HID_USAGE_PAGE_PID
,
2603 .wUsage
= PID_USAGE_DEAD_BAND
,
2607 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2608 .guidType
= GUID_Unknown
,
2609 .dwOfs
= version
>= 0x800 ? 0x64 : 0,
2610 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(44)|DIDFT_OUTPUT
,
2611 .dwFlags
= 0x80008000,
2612 .tszName
= L
"Device Gain",
2613 .wCollectionNumber
= 15,
2614 .wUsagePage
= HID_USAGE_PAGE_PID
,
2615 .wUsage
= PID_USAGE_DEVICE_GAIN
,
2619 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2620 .guidType
= GUID_Unknown
,
2621 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(0),
2622 .tszName
= L
"Collection 0 - Joystick",
2623 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
2624 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
2627 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2628 .guidType
= GUID_Unknown
,
2629 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(1),
2630 .tszName
= L
"Collection 1 - Joystick",
2631 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
2632 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
2635 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2636 .guidType
= GUID_Unknown
,
2637 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(2),
2638 .tszName
= L
"Collection 2 - PID State Report",
2639 .wUsagePage
= HID_USAGE_PAGE_PID
,
2640 .wUsage
= PID_USAGE_STATE_REPORT
,
2643 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2644 .guidType
= GUID_Unknown
,
2645 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(3),
2646 .tszName
= L
"Collection 3 - PID Device Control Report",
2647 .wUsagePage
= HID_USAGE_PAGE_PID
,
2648 .wUsage
= PID_USAGE_DEVICE_CONTROL_REPORT
,
2651 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2652 .guidType
= GUID_Unknown
,
2653 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(4),
2654 .tszName
= L
"Collection 4 - PID Device Control",
2655 .wCollectionNumber
= 3,
2656 .wUsagePage
= HID_USAGE_PAGE_PID
,
2657 .wUsage
= PID_USAGE_DEVICE_CONTROL
,
2660 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2661 .guidType
= GUID_Unknown
,
2662 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(5),
2663 .tszName
= L
"Collection 5 - Effect Operation Report",
2664 .wUsagePage
= HID_USAGE_PAGE_PID
,
2665 .wUsage
= PID_USAGE_EFFECT_OPERATION_REPORT
,
2668 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2669 .guidType
= GUID_Unknown
,
2670 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(6),
2671 .tszName
= L
"Collection 6 - Effect Operation",
2672 .wCollectionNumber
= 5,
2673 .wUsagePage
= HID_USAGE_PAGE_PID
,
2674 .wUsage
= PID_USAGE_EFFECT_OPERATION
,
2677 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2678 .guidType
= GUID_Unknown
,
2679 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(7),
2680 .tszName
= L
"Collection 7 - Set Effect Report",
2681 .wUsagePage
= HID_USAGE_PAGE_PID
,
2682 .wUsage
= PID_USAGE_SET_EFFECT_REPORT
,
2685 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2686 .guidType
= GUID_Unknown
,
2687 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(8),
2688 .tszName
= L
"Collection 8 - Effect Type",
2689 .wCollectionNumber
= 7,
2690 .wUsagePage
= HID_USAGE_PAGE_PID
,
2691 .wUsage
= PID_USAGE_EFFECT_TYPE
,
2694 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2695 .guidType
= GUID_Unknown
,
2696 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(9),
2697 .tszName
= L
"Collection 9 - Axes Enable",
2698 .wCollectionNumber
= 7,
2699 .wUsagePage
= HID_USAGE_PAGE_PID
,
2700 .wUsage
= PID_USAGE_AXES_ENABLE
,
2703 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2704 .guidType
= GUID_Unknown
,
2705 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(10),
2706 .tszName
= L
"Collection 10 - Direction",
2707 .wCollectionNumber
= 7,
2708 .wUsagePage
= HID_USAGE_PAGE_PID
,
2709 .wUsage
= PID_USAGE_DIRECTION
,
2712 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2713 .guidType
= GUID_Unknown
,
2714 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(11),
2715 .tszName
= L
"Collection 11 - Set Periodic Report",
2716 .wUsagePage
= HID_USAGE_PAGE_PID
,
2717 .wUsage
= PID_USAGE_SET_PERIODIC_REPORT
,
2720 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2721 .guidType
= GUID_Unknown
,
2722 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(12),
2723 .tszName
= L
"Collection 12 - Set Envelope Report",
2724 .wUsagePage
= HID_USAGE_PAGE_PID
,
2725 .wUsage
= PID_USAGE_SET_ENVELOPE_REPORT
,
2728 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2729 .guidType
= GUID_Unknown
,
2730 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(13),
2731 .tszName
= L
"Collection 13 - Set Condition Report",
2732 .wUsagePage
= HID_USAGE_PAGE_PID
,
2733 .wUsage
= PID_USAGE_SET_CONDITION_REPORT
,
2736 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2737 .guidType
= GUID_Unknown
,
2738 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(14),
2739 .tszName
= L
"Collection 14 - Type Specific Block Offset",
2740 .wCollectionNumber
= 13,
2741 .wUsagePage
= HID_USAGE_PAGE_PID
,
2742 .wUsage
= PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET
,
2745 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
2746 .guidType
= GUID_Unknown
,
2747 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(15),
2748 .tszName
= L
"Collection 15 - Device Gain Report",
2749 .wUsagePage
= HID_USAGE_PAGE_PID
,
2750 .wUsage
= PID_USAGE_DEVICE_GAIN_REPORT
,
2753 const DIEFFECTINFOW expect_effects
[] =
2756 .dwSize
= sizeof(DIEFFECTINFOW
),
2757 .guid
= GUID_Square
,
2758 .dwEffType
= DIEFT_PERIODIC
| DIEFT_STARTDELAY
| DIEFT_FFFADE
| DIEFT_FFATTACK
,
2759 .dwStaticParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
2760 DIEP_DURATION
| DIEP_TRIGGERBUTTON
| DIEP_ENVELOPE
,
2761 .dwDynamicParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
2762 DIEP_DURATION
| DIEP_TRIGGERBUTTON
| DIEP_ENVELOPE
,
2763 .tszName
= L
"GUID_Square",
2766 .dwSize
= sizeof(DIEFFECTINFOW
),
2768 .dwEffType
= DIEFT_PERIODIC
| DIEFT_STARTDELAY
| DIEFT_FFFADE
| DIEFT_FFATTACK
,
2769 .dwStaticParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
2770 DIEP_DURATION
| DIEP_TRIGGERBUTTON
| DIEP_ENVELOPE
,
2771 .dwDynamicParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
2772 DIEP_DURATION
| DIEP_TRIGGERBUTTON
| DIEP_ENVELOPE
,
2773 .tszName
= L
"GUID_Sine",
2776 .dwSize
= sizeof(DIEFFECTINFOW
),
2777 .guid
= GUID_Spring
,
2778 .dwEffType
= DIEFT_CONDITION
| DIEFT_STARTDELAY
| DIEFT_DEADBAND
| DIEFT_SATURATION
,
2779 .dwStaticParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
2781 .dwDynamicParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
2783 .tszName
= L
"GUID_Spring",
2787 struct check_objects_todos todo_objects_5
[ARRAY_SIZE(expect_objects_5
)] =
2789 {.guid
= TRUE
, .type
= TRUE
, .usage
= TRUE
, .name
= TRUE
},
2791 {.guid
= TRUE
, .type
= TRUE
, .usage
= TRUE
, .name
= TRUE
},
2793 struct check_objects_params check_objects_params
=
2796 .expect_count
= version
< 0x700 ? ARRAY_SIZE(expect_objects_5
) : ARRAY_SIZE(expect_objects
),
2797 .expect_objs
= version
< 0x700 ? expect_objects_5
: expect_objects
,
2798 .todo_objs
= version
< 0x700 ? todo_objects_5
: NULL
,
2799 .todo_extra
= version
< 0x700 ? TRUE
: FALSE
,
2801 struct check_effects_params check_effects_params
=
2803 .expect_count
= ARRAY_SIZE(expect_effects
),
2804 .expect_effects
= expect_effects
,
2806 DIPROPDWORD prop_dword
=
2810 .dwSize
= sizeof(DIPROPDWORD
),
2811 .dwHeaderSize
= sizeof(DIPROPHEADER
),
2812 .dwHow
= DIPH_DEVICE
,
2815 DIPROPGUIDANDPATH prop_guid_path
=
2819 .dwSize
= sizeof(DIPROPGUIDANDPATH
),
2820 .dwHeaderSize
= sizeof(DIPROPHEADER
),
2821 .dwHow
= DIPH_DEVICE
,
2824 DIDEVICEINSTANCEW devinst
= {.dwSize
= sizeof(DIDEVICEINSTANCEW
)};
2825 IDirectInputDevice8W
*device
= NULL
;
2826 DIDEVICEOBJECTDATA objdata
= {0};
2827 DIEFFECTINFOW effectinfo
= {0};
2828 DIEFFESCAPE escape
= {0};
2829 DIDEVCAPS caps
= {0};
2836 winetest_push_context( "%#lx", version
);
2837 cleanup_registry_keys();
2839 desc
.report_descriptor_len
= sizeof(report_descriptor
);
2840 memcpy( desc
.report_descriptor_buf
, report_descriptor
, sizeof(report_descriptor
) );
2841 fill_context( __LINE__
, desc
.context
, ARRAY_SIZE(desc
.context
) );
2843 if (!hid_device_start( &desc
)) goto done
;
2844 if (FAILED(hr
= dinput_test_create_device( version
, &devinst
, &device
))) goto done
;
2846 check_dinput_devices( version
, &devinst
);
2848 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
2849 ok( hr
== DI_OK
, "GetDeviceInfo returned %#lx\n", hr
);
2850 check_member( devinst
, expect_devinst
, "%lu", dwSize
);
2852 check_member_guid( devinst
, expect_devinst
, guidInstance
);
2853 check_member_guid( devinst
, expect_devinst
, guidProduct
);
2854 check_member( devinst
, expect_devinst
, "%#lx", dwDevType
);
2855 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
2856 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
2857 check_member_guid( devinst
, expect_devinst
, guidFFDriver
);
2858 check_member( devinst
, expect_devinst
, "%04x", wUsagePage
);
2859 check_member( devinst
, expect_devinst
, "%04x", wUsage
);
2861 caps
.dwSize
= sizeof(DIDEVCAPS
);
2862 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
2863 ok( hr
== DI_OK
, "GetCapabilities returned %#lx\n", hr
);
2864 check_member( caps
, expect_caps
, "%lu", dwSize
);
2865 check_member( caps
, expect_caps
, "%#lx", dwFlags
);
2866 check_member( caps
, expect_caps
, "%#lx", dwDevType
);
2867 check_member( caps
, expect_caps
, "%lu", dwAxes
);
2868 check_member( caps
, expect_caps
, "%lu", dwButtons
);
2869 check_member( caps
, expect_caps
, "%lu", dwPOVs
);
2870 check_member( caps
, expect_caps
, "%lu", dwFFSamplePeriod
);
2871 check_member( caps
, expect_caps
, "%lu", dwFFMinTimeResolution
);
2872 check_member( caps
, expect_caps
, "%lu", dwFirmwareRevision
);
2873 check_member( caps
, expect_caps
, "%lu", dwHardwareRevision
);
2874 check_member( caps
, expect_caps
, "%lu", dwFFDriverVersion
);
2876 prop_dword
.dwData
= 0xdeadbeef;
2877 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
2878 ok( hr
== DI_OK
, "GetProperty DIPROP_FFGAIN returned %#lx\n", hr
);
2879 ok( prop_dword
.dwData
== 10000, "got %lu expected %u\n", prop_dword
.dwData
, 10000 );
2881 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
2882 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr
);
2884 hr
= IDirectInputDevice8_EnumObjects( device
, check_objects
, &check_objects_params
, DIDFT_ALL
);
2885 ok( hr
== DI_OK
, "EnumObjects returned %#lx\n", hr
);
2886 ok( check_objects_params
.index
>= check_objects_params
.expect_count
, "missing %u objects\n",
2887 check_objects_params
.expect_count
- check_objects_params
.index
);
2890 hr
= IDirectInputDevice8_EnumEffects( device
, check_effect_count
, &res
, 0xfe );
2891 ok( hr
== DI_OK
, "EnumEffects returned %#lx\n", hr
);
2892 ok( res
== 0, "got %lu expected %u\n", res
, 0 );
2894 hr
= IDirectInputDevice8_EnumEffects( device
, check_effect_count
, &res
, DIEFT_PERIODIC
);
2895 ok( hr
== DI_OK
, "EnumEffects returned %#lx\n", hr
);
2896 ok( res
== 2, "got %lu expected %u\n", res
, 2 );
2897 hr
= IDirectInputDevice8_EnumEffects( device
, check_effects
, &check_effects_params
, DIEFT_ALL
);
2898 ok( hr
== DI_OK
, "EnumEffects returned %#lx\n", hr
);
2899 ok( check_effects_params
.index
>= check_effects_params
.expect_count
, "missing %u effects\n",
2900 check_effects_params
.expect_count
- check_effects_params
.index
);
2902 effectinfo
.dwSize
= sizeof(DIEFFECTINFOW
);
2903 hr
= IDirectInputDevice8_GetEffectInfo( device
, &effectinfo
, &GUID_Sine
);
2904 ok( hr
== DI_OK
, "GetEffectInfo returned %#lx\n", hr
);
2905 check_member_guid( effectinfo
, expect_effects
[1], guid
);
2906 check_member( effectinfo
, expect_effects
[1], "%#lx", dwEffType
);
2907 check_member( effectinfo
, expect_effects
[1], "%#lx", dwStaticParams
);
2908 check_member( effectinfo
, expect_effects
[1], "%#lx", dwDynamicParams
);
2909 check_member_wstr( effectinfo
, expect_effects
[1], tszName
);
2911 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
2912 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
2914 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
2915 ok( hr
== DI_OK
, "GetProperty DIPROP_GUIDANDPATH returned %#lx\n", hr
);
2917 file
= CreateFileW( prop_guid_path
.wszPath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
2918 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
2919 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
2920 ok( file
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError() );
2922 hwnd
= CreateWindowW( L
"static", L
"dinput", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 10, 10, 200, 200,
2923 NULL
, NULL
, NULL
, NULL
);
2925 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_BACKGROUND
| DISCL_NONEXCLUSIVE
);
2926 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#lx\n", hr
);
2928 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
2929 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2930 prop_dword
.dwData
= DIPROPAUTOCENTER_ON
;
2931 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
2932 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_AUTOCENTER returned %#lx\n", hr
);
2933 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
2934 prop_dword
.diph
.dwObj
= 0;
2935 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
2936 ok( hr
== DI_OK
, "SetProperty DIPROP_AUTOCENTER returned %#lx\n", hr
);
2938 hr
= IDirectInputDevice8_Acquire( device
);
2939 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
2941 prop_dword
.dwData
= 0xdeadbeef;
2942 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
2943 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr
);
2944 prop_dword
.dwData
= 1000;
2945 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
2946 ok( hr
== DI_OK
, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr
);
2948 prop_dword
.dwData
= 0xdeadbeef;
2949 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
2950 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_FFLOAD returned %#lx\n", hr
);
2951 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
2952 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr
);
2953 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
2954 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetForceFeedbackState returned %#lx\n", hr
);
2955 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_RESET
);
2956 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "SendForceFeedbackCommand returned %#lx\n", hr
);
2958 escape
.dwSize
= sizeof(DIEFFESCAPE
);
2959 escape
.dwCommand
= 0;
2960 escape
.lpvInBuffer
= buffer
;
2961 escape
.cbInBuffer
= 10;
2962 escape
.lpvOutBuffer
= buffer
+ 10;
2963 escape
.cbOutBuffer
= 10;
2964 hr
= IDirectInputDevice8_Escape( device
, &escape
);
2966 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "Escape returned: %#lx\n", hr
);
2968 hr
= IDirectInputDevice8_Unacquire( device
);
2969 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2970 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
2971 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#lx\n", hr
);
2972 prop_dword
.dwData
= DIPROPAUTOCENTER_ON
;
2973 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
2974 ok( hr
== DI_OK
, "SetProperty DIPROP_AUTOCENTER returned %#lx\n", hr
);
2976 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
2977 hr
= IDirectInputDevice8_Acquire( device
);
2978 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
2979 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
2981 set_hid_expect( file
, &expect_set_device_gain_2
, sizeof(expect_set_device_gain_2
) );
2982 prop_dword
.dwData
= 2000;
2983 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
2984 ok( hr
== DI_OK
, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr
);
2985 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
2987 set_hid_expect( file
, &expect_set_device_gain_1
, sizeof(expect_set_device_gain_1
) );
2988 prop_dword
.dwData
= 1000;
2989 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
2990 ok( hr
== DI_OK
, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr
);
2991 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
2993 hr
= IDirectInputDevice8_Escape( device
, &escape
);
2995 ok( hr
== DIERR_UNSUPPORTED
, "Escape returned: %#lx\n", hr
);
2997 prop_dword
.dwData
= 0xdeadbeef;
2998 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
3000 ok( hr
== 0x80040301, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr
);
3002 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
3004 ok( hr
== 0x80040301, "GetForceFeedbackState returned %#lx\n", hr
);
3006 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, 0xdeadbeef );
3007 ok( hr
== DIERR_INVALIDPARAM
, "SendForceFeedbackCommand returned %#lx\n", hr
);
3009 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
3010 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_RESET
);
3011 ok( hr
== DI_OK
, "SendForceFeedbackCommand returned %#lx\n", hr
);
3012 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
3014 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_STOPALL
);
3015 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#lx\n", hr
);
3016 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_PAUSE
);
3017 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#lx\n", hr
);
3018 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_CONTINUE
);
3019 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#lx\n", hr
);
3020 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_SETACTUATORSON
);
3021 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#lx\n", hr
);
3022 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_SETACTUATORSOFF
);
3023 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#lx\n", hr
);
3025 objdata
.dwOfs
= 0x1e;
3026 objdata
.dwData
= 0x80;
3028 hr
= IDirectInputDevice8_SendDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), &objdata
, &res
, 0 );
3029 if (version
< 0x800) ok( hr
== DI_OK
, "SendDeviceData returned %#lx\n", hr
);
3030 else todo_wine
ok( hr
== DIERR_INVALIDPARAM
, "SendDeviceData returned %#lx\n", hr
);
3032 test_periodic_effect( device
, file
, version
);
3033 test_condition_effect( device
, file
, version
);
3035 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
3036 hr
= IDirectInputDevice8_Unacquire( device
);
3037 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
3038 set_hid_expect( file
, NULL
, 0 );
3040 ref
= IDirectInputDevice8_Release( device
);
3041 ok( ref
== 0, "Release returned %ld\n", ref
);
3043 DestroyWindow( hwnd
);
3044 CloseHandle( file
);
3047 hid_device_stop( &desc
);
3048 cleanup_registry_keys();
3049 winetest_pop_context();
3051 return device
!= NULL
;
3054 static void test_device_managed_effect(void)
3056 #include "psh_hid_macros.h"
3057 const unsigned char report_descriptor
[] = {
3058 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3059 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3060 COLLECTION(1, Application
),
3061 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3062 COLLECTION(1, Report
),
3065 USAGE(1, HID_USAGE_GENERIC_X
),
3066 USAGE(1, HID_USAGE_GENERIC_Y
),
3067 USAGE(1, HID_USAGE_GENERIC_Z
),
3068 LOGICAL_MINIMUM(1, 0),
3069 LOGICAL_MAXIMUM(1, 0x7f),
3070 PHYSICAL_MINIMUM(1, 0),
3071 PHYSICAL_MAXIMUM(1, 0x7f),
3074 INPUT(1, Data
|Var
|Abs
),
3076 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3077 USAGE_MINIMUM(1, 1),
3078 USAGE_MAXIMUM(1, 2),
3079 LOGICAL_MINIMUM(1, 0),
3080 LOGICAL_MAXIMUM(1, 1),
3081 PHYSICAL_MINIMUM(1, 0),
3082 PHYSICAL_MAXIMUM(1, 1),
3085 INPUT(1, Data
|Var
|Abs
),
3087 INPUT(1, Cnst
|Var
|Abs
),
3090 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
3091 USAGE(1, PID_USAGE_STATE_REPORT
),
3092 COLLECTION(1, Report
),
3095 USAGE(1, PID_USAGE_DEVICE_PAUSED
),
3096 USAGE(1, PID_USAGE_ACTUATORS_ENABLED
),
3097 USAGE(1, PID_USAGE_SAFETY_SWITCH
),
3098 USAGE(1, PID_USAGE_ACTUATOR_OVERRIDE_SWITCH
),
3099 USAGE(1, PID_USAGE_ACTUATOR_POWER
),
3100 LOGICAL_MINIMUM(1, 0),
3101 LOGICAL_MAXIMUM(1, 1),
3102 PHYSICAL_MINIMUM(1, 0),
3103 PHYSICAL_MAXIMUM(1, 1),
3106 INPUT(1, Data
|Var
|Abs
),
3108 INPUT(1, Cnst
|Var
|Abs
),
3110 USAGE(1, PID_USAGE_EFFECT_PLAYING
),
3111 LOGICAL_MINIMUM(1, 0),
3112 LOGICAL_MAXIMUM(1, 1),
3113 PHYSICAL_MINIMUM(1, 0),
3114 PHYSICAL_MAXIMUM(1, 1),
3117 INPUT(1, Data
|Var
|Abs
),
3119 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
3120 LOGICAL_MINIMUM(1, 1),
3121 LOGICAL_MAXIMUM(1, 0x7f),
3122 PHYSICAL_MINIMUM(1, 1),
3123 PHYSICAL_MAXIMUM(1, 0x7f),
3126 INPUT(1, Data
|Var
|Abs
),
3129 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
3130 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT
),
3131 COLLECTION(1, Report
),
3134 USAGE(1, PID_USAGE_DEVICE_CONTROL
),
3135 COLLECTION(1, Logical
),
3136 USAGE(1, PID_USAGE_DC_DEVICE_RESET
),
3137 USAGE(1, PID_USAGE_DC_DEVICE_PAUSE
),
3138 USAGE(1, PID_USAGE_DC_DEVICE_CONTINUE
),
3139 USAGE(1, PID_USAGE_DC_ENABLE_ACTUATORS
),
3140 USAGE(1, PID_USAGE_DC_DISABLE_ACTUATORS
),
3141 USAGE(1, PID_USAGE_DC_STOP_ALL_EFFECTS
),
3142 LOGICAL_MINIMUM(1, 1),
3143 LOGICAL_MAXIMUM(1, 6),
3144 PHYSICAL_MINIMUM(1, 1),
3145 PHYSICAL_MAXIMUM(1, 6),
3148 OUTPUT(1, Data
|Ary
|Abs
),
3152 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT
),
3153 COLLECTION(1, Report
),
3156 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
3157 LOGICAL_MINIMUM(1, 1),
3158 LOGICAL_MAXIMUM(1, 0x7f),
3159 PHYSICAL_MINIMUM(1, 1),
3160 PHYSICAL_MAXIMUM(1, 0x7f),
3163 OUTPUT(1, Data
|Var
|Abs
),
3165 USAGE(1, PID_USAGE_EFFECT_OPERATION
),
3166 COLLECTION(1, NamedArray
),
3167 USAGE(1, PID_USAGE_OP_EFFECT_START
),
3168 USAGE(1, PID_USAGE_OP_EFFECT_START_SOLO
),
3169 USAGE(1, PID_USAGE_OP_EFFECT_STOP
),
3170 LOGICAL_MINIMUM(1, 1),
3171 LOGICAL_MAXIMUM(1, 3),
3172 PHYSICAL_MINIMUM(1, 1),
3173 PHYSICAL_MAXIMUM(1, 3),
3176 OUTPUT(1, Data
|Ary
|Abs
),
3179 USAGE(1, PID_USAGE_LOOP_COUNT
),
3180 LOGICAL_MINIMUM(1, 0),
3181 LOGICAL_MAXIMUM(1, 0x7f),
3182 PHYSICAL_MINIMUM(1, 0),
3183 PHYSICAL_MAXIMUM(1, 0x7f),
3186 OUTPUT(1, Data
|Var
|Abs
),
3189 USAGE(1, PID_USAGE_SET_EFFECT_REPORT
),
3190 COLLECTION(1, Report
),
3193 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
3194 LOGICAL_MINIMUM(1, 1),
3195 LOGICAL_MAXIMUM(1, 0x7f),
3196 PHYSICAL_MINIMUM(1, 1),
3197 PHYSICAL_MAXIMUM(1, 0x7f),
3200 OUTPUT(1, Data
|Var
|Abs
),
3202 USAGE(1, PID_USAGE_EFFECT_TYPE
),
3203 COLLECTION(1, NamedArray
),
3204 USAGE(1, PID_USAGE_ET_SQUARE
),
3205 USAGE(1, PID_USAGE_ET_SINE
),
3206 USAGE(1, PID_USAGE_ET_SPRING
),
3207 LOGICAL_MINIMUM(1, 1),
3208 LOGICAL_MAXIMUM(1, 3),
3209 PHYSICAL_MINIMUM(1, 1),
3210 PHYSICAL_MAXIMUM(1, 3),
3213 OUTPUT(1, Data
|Ary
|Abs
),
3216 USAGE(1, PID_USAGE_AXES_ENABLE
),
3217 COLLECTION(1, Logical
),
3218 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_X
),
3219 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Y
),
3220 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Z
),
3221 LOGICAL_MINIMUM(1, 0),
3222 LOGICAL_MAXIMUM(1, 1),
3223 PHYSICAL_MINIMUM(1, 0),
3224 PHYSICAL_MAXIMUM(1, 1),
3227 OUTPUT(1, Data
|Var
|Abs
),
3229 USAGE(1, PID_USAGE_DIRECTION_ENABLE
),
3231 OUTPUT(1, Data
|Var
|Abs
),
3233 OUTPUT(1, Cnst
|Var
|Abs
),
3235 USAGE(1, PID_USAGE_DURATION
),
3236 USAGE(1, PID_USAGE_START_DELAY
),
3237 UNIT(2, 0x1003), /* Eng Lin:Time */
3238 UNIT_EXPONENT(1, -3), /* 10^-3 */
3239 LOGICAL_MINIMUM(1, 0),
3240 LOGICAL_MAXIMUM(2, 0x7fff),
3241 PHYSICAL_MINIMUM(1, 0),
3242 PHYSICAL_MAXIMUM(2, 0x7fff),
3245 OUTPUT(1, Data
|Var
|Abs
),
3247 UNIT_EXPONENT(1, 0),
3249 USAGE(1, PID_USAGE_TRIGGER_BUTTON
),
3250 LOGICAL_MINIMUM(1, 1),
3251 LOGICAL_MAXIMUM(1, 0x08),
3252 PHYSICAL_MINIMUM(1, 1),
3253 PHYSICAL_MAXIMUM(1, 0x08),
3256 OUTPUT(1, Data
|Var
|Abs
),
3258 USAGE(1, PID_USAGE_DIRECTION
),
3259 COLLECTION(1, Logical
),
3260 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
3261 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
3262 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
3263 UNIT_EXPONENT(1, -2), /* 10^-2 */
3264 LOGICAL_MINIMUM(1, 0),
3265 LOGICAL_MAXIMUM(2, 0x00ff),
3266 PHYSICAL_MINIMUM(1, 0),
3267 PHYSICAL_MAXIMUM(4, 0x00008ca0),
3271 OUTPUT(1, Data
|Var
|Abs
),
3272 UNIT_EXPONENT(1, 0),
3277 USAGE(1, PID_USAGE_SET_CONDITION_REPORT
),
3278 COLLECTION(1, Logical
),
3281 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
3282 LOGICAL_MINIMUM(1, 1),
3283 LOGICAL_MAXIMUM(1, 0x7f),
3284 PHYSICAL_MINIMUM(1, 1),
3285 PHYSICAL_MAXIMUM(1, 0x7f),
3288 OUTPUT(1, Data
|Var
|Abs
),
3290 USAGE(1, PID_USAGE_PARAMETER_BLOCK_OFFSET
),
3291 LOGICAL_MINIMUM(1, 0),
3292 LOGICAL_MAXIMUM(1, 1),
3293 PHYSICAL_MINIMUM(1, 0),
3294 PHYSICAL_MAXIMUM(1, 1),
3297 OUTPUT(1, Data
|Var
|Abs
),
3299 USAGE(1, PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET
),
3300 COLLECTION(1, Logical
),
3301 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
3302 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
3303 LOGICAL_MINIMUM(1, 0),
3304 LOGICAL_MAXIMUM(1, 1),
3305 PHYSICAL_MINIMUM(1, 0),
3306 PHYSICAL_MAXIMUM(1, 1),
3309 OUTPUT(1, Data
|Var
|Abs
),
3312 USAGE(1, PID_USAGE_CP_OFFSET
),
3313 LOGICAL_MINIMUM(1, 0x80),
3314 LOGICAL_MAXIMUM(1, 0x7f),
3315 PHYSICAL_MINIMUM(2, 0xd8f0),
3316 PHYSICAL_MAXIMUM(2, 0x2710),
3319 OUTPUT(1, Data
|Var
|Abs
),
3321 USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT
),
3322 USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT
),
3323 LOGICAL_MINIMUM(1, 0x80),
3324 LOGICAL_MAXIMUM(1, 0x7f),
3325 PHYSICAL_MINIMUM(2, 0xd8f0),
3326 PHYSICAL_MAXIMUM(2, 0x2710),
3329 OUTPUT(1, Data
|Var
|Abs
),
3331 USAGE(1, PID_USAGE_POSITIVE_SATURATION
),
3332 USAGE(1, PID_USAGE_NEGATIVE_SATURATION
),
3333 LOGICAL_MINIMUM(1, 0),
3334 LOGICAL_MAXIMUM(2, 0x00ff),
3335 PHYSICAL_MINIMUM(1, 0),
3336 PHYSICAL_MAXIMUM(2, 0x2710),
3339 OUTPUT(1, Data
|Var
|Abs
),
3341 USAGE(1, PID_USAGE_DEAD_BAND
),
3342 LOGICAL_MINIMUM(1, 0),
3343 LOGICAL_MAXIMUM(2, 0x00ff),
3344 PHYSICAL_MINIMUM(1, 0),
3345 PHYSICAL_MAXIMUM(2, 0x2710),
3348 OUTPUT(1, Data
|Var
|Abs
),
3351 USAGE(1, PID_USAGE_BLOCK_FREE_REPORT
),
3352 COLLECTION(1, Logical
),
3355 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
3356 LOGICAL_MINIMUM(1, 1),
3357 LOGICAL_MAXIMUM(1, 0x7f),
3358 PHYSICAL_MINIMUM(1, 1),
3359 PHYSICAL_MAXIMUM(1, 0x7f),
3362 OUTPUT(1, Data
|Var
|Abs
),
3365 USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT
),
3366 COLLECTION(1, Logical
),
3369 USAGE(1, PID_USAGE_DEVICE_GAIN
),
3370 LOGICAL_MINIMUM(1, 0),
3371 LOGICAL_MAXIMUM(2, 0x00ff),
3372 PHYSICAL_MINIMUM(1, 0),
3373 PHYSICAL_MAXIMUM(2, 0x2710),
3376 OUTPUT(1, Data
|Var
|Abs
),
3379 USAGE(1, PID_USAGE_POOL_REPORT
),
3380 COLLECTION(1, Logical
),
3383 USAGE(1, PID_USAGE_RAM_POOL_SIZE
),
3384 LOGICAL_MINIMUM(1, 0),
3385 LOGICAL_MAXIMUM(4, 0xffff),
3386 PHYSICAL_MINIMUM(1, 0),
3387 PHYSICAL_MAXIMUM(4, 0xffff),
3390 FEATURE(1, Data
|Var
|Abs
),
3392 USAGE(1, PID_USAGE_SIMULTANEOUS_EFFECTS_MAX
),
3393 LOGICAL_MINIMUM(1, 0),
3394 LOGICAL_MAXIMUM(1, 0x7f),
3395 PHYSICAL_MINIMUM(1, 0),
3396 PHYSICAL_MAXIMUM(1, 0x7f),
3399 FEATURE(1, Data
|Var
|Abs
),
3401 USAGE(1, PID_USAGE_DEVICE_MANAGED_POOL
),
3402 USAGE(1, PID_USAGE_SHARED_PARAMETER_BLOCKS
),
3403 LOGICAL_MINIMUM(1, 0),
3404 LOGICAL_MAXIMUM(1, 1),
3405 PHYSICAL_MINIMUM(1, 0),
3406 PHYSICAL_MAXIMUM(1, 1),
3409 FEATURE(1, Data
|Var
|Abs
),
3412 USAGE(1, PID_USAGE_CREATE_NEW_EFFECT_REPORT
),
3413 COLLECTION(1, Logical
),
3416 USAGE(1, PID_USAGE_EFFECT_TYPE
),
3417 COLLECTION(1, NamedArray
),
3418 USAGE(1, PID_USAGE_ET_SQUARE
),
3419 USAGE(1, PID_USAGE_ET_SINE
),
3420 USAGE(1, PID_USAGE_ET_SPRING
),
3421 LOGICAL_MINIMUM(1, 1),
3422 LOGICAL_MAXIMUM(1, 3),
3423 PHYSICAL_MINIMUM(1, 1),
3424 PHYSICAL_MAXIMUM(1, 3),
3427 FEATURE(1, Data
|Ary
|Abs
),
3431 USAGE(1, PID_USAGE_BLOCK_LOAD_REPORT
),
3432 COLLECTION(1, Logical
),
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),
3442 FEATURE(1, Data
|Var
|Abs
),
3444 USAGE(1, PID_USAGE_BLOCK_LOAD_STATUS
),
3445 COLLECTION(1, NamedArray
),
3446 USAGE(1, PID_USAGE_BLOCK_LOAD_SUCCESS
),
3447 USAGE(1, PID_USAGE_BLOCK_LOAD_FULL
),
3448 USAGE(1, PID_USAGE_BLOCK_LOAD_ERROR
),
3449 LOGICAL_MINIMUM(1, 1),
3450 LOGICAL_MAXIMUM(1, 3),
3451 PHYSICAL_MINIMUM(1, 1),
3452 PHYSICAL_MAXIMUM(1, 3),
3455 FEATURE(1, Data
|Ary
|Abs
),
3458 USAGE(1, PID_USAGE_RAM_POOL_AVAILABLE
),
3459 LOGICAL_MINIMUM(1, 0),
3460 LOGICAL_MAXIMUM(4, 0xffff),
3461 PHYSICAL_MINIMUM(1, 0),
3462 PHYSICAL_MAXIMUM(4, 0xffff),
3465 FEATURE(1, Data
|Var
|Abs
),
3469 C_ASSERT(sizeof(report_descriptor
) < MAX_HID_DESCRIPTOR_LEN
);
3470 #include "pop_hid_macros.h"
3472 struct hid_device_desc desc
=
3474 .use_report_id
= TRUE
,
3477 .InputReportByteLength
= 5,
3478 .OutputReportByteLength
= 11,
3479 .FeatureReportByteLength
= 5,
3481 .attributes
= default_attributes
,
3483 struct hid_expect expect_acquire
[] =
3485 /* device control */
3487 .code
= IOCTL_HID_WRITE_REPORT
,
3490 .report_buf
= {1, 0x01},
3494 .code
= IOCTL_HID_WRITE_REPORT
,
3497 .report_buf
= {6, 0xff},
3500 struct hid_expect expect_reset
[] =
3502 /* device control */
3504 .code
= IOCTL_HID_WRITE_REPORT
,
3507 .report_buf
= {1, 0x01},
3510 struct hid_expect expect_enable_actuators
[] =
3512 /* device control */
3514 .code
= IOCTL_HID_WRITE_REPORT
,
3517 .report_buf
= {1, 0x04},
3520 struct hid_expect expect_disable_actuators
[] =
3522 /* device control */
3524 .code
= IOCTL_HID_WRITE_REPORT
,
3527 .report_buf
= {1, 0x05},
3530 struct hid_expect expect_stop_all
[] =
3532 /* device control */
3534 .code
= IOCTL_HID_WRITE_REPORT
,
3537 .report_buf
= {1, 0x06},
3540 struct hid_expect expect_device_pause
[] =
3542 /* device control */
3544 .code
= IOCTL_HID_WRITE_REPORT
,
3547 .report_buf
= {1, 0x02},
3550 struct hid_expect expect_device_continue
[] =
3552 /* device control */
3554 .code
= IOCTL_HID_WRITE_REPORT
,
3557 .report_buf
= {1, 0x03},
3560 struct hid_expect expect_create
[] =
3562 /* create new effect */
3564 .code
= IOCTL_HID_SET_FEATURE
,
3567 .report_buf
= {2,0x03},
3571 .code
= IOCTL_HID_GET_FEATURE
,
3574 .report_buf
= {3,0x01,0x01,0x00,0x00},
3578 .code
= IOCTL_HID_WRITE_REPORT
,
3581 .report_buf
= {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
3585 .code
= IOCTL_HID_WRITE_REPORT
,
3588 .report_buf
= {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
3592 .code
= IOCTL_HID_WRITE_REPORT
,
3595 .report_buf
= {3,0x01,0x03,0x08,0x01,0x00,0x06,0x00,0x01,0x55,0x00},
3598 struct hid_expect expect_create_2
[] =
3600 /* create new effect */
3602 .code
= IOCTL_HID_SET_FEATURE
,
3605 .report_buf
= {2,0x03},
3609 .code
= IOCTL_HID_GET_FEATURE
,
3612 .report_buf
= {3,0x02,0x01,0x00,0x00},
3616 .code
= IOCTL_HID_WRITE_REPORT
,
3619 .report_buf
= {4,0x02,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
3623 .code
= IOCTL_HID_WRITE_REPORT
,
3626 .report_buf
= {4,0x02,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
3630 .code
= IOCTL_HID_WRITE_REPORT
,
3633 .report_buf
= {3,0x02,0x03,0x08,0x01,0x00,0x06,0x00,0x01,0x55,0x00},
3636 struct hid_expect expect_create_delay
[] =
3638 /* create new effect */
3640 .code
= IOCTL_HID_SET_FEATURE
,
3643 .report_buf
= {2,0x03},
3647 .code
= IOCTL_HID_GET_FEATURE
,
3650 .report_buf
= {3,0x01,0x01,0x00,0x00},
3654 .code
= IOCTL_HID_WRITE_REPORT
,
3657 .report_buf
= {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
3661 .code
= IOCTL_HID_WRITE_REPORT
,
3664 .report_buf
= {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
3668 .code
= IOCTL_HID_WRITE_REPORT
,
3671 .report_buf
= {3,0x01,0x03,0x08,0x01,0x00,0xff,0x7f,0x01,0x55,0x00},
3674 struct hid_expect expect_create_duration
[] =
3676 /* create new effect */
3678 .code
= IOCTL_HID_SET_FEATURE
,
3681 .report_buf
= {2,0x03},
3685 .code
= IOCTL_HID_GET_FEATURE
,
3688 .report_buf
= {3,0x01,0x01,0x00,0x00},
3692 .code
= IOCTL_HID_WRITE_REPORT
,
3695 .report_buf
= {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
3699 .code
= IOCTL_HID_WRITE_REPORT
,
3702 .report_buf
= {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
3706 .code
= IOCTL_HID_WRITE_REPORT
,
3709 .report_buf
= {3,0x01,0x03,0x08,0x00,0x00,0x00,0x00,0x01,0x55,0x00},
3712 struct hid_expect expect_start
=
3714 /* effect control */
3715 .code
= IOCTL_HID_WRITE_REPORT
,
3718 .report_buf
= {2, 0x01, 0x01, 0x01},
3720 struct hid_expect expect_start_2
=
3722 /* effect control */
3723 .code
= IOCTL_HID_WRITE_REPORT
,
3726 .report_buf
= {2, 0x02, 0x02, 0x01},
3728 struct hid_expect expect_stop
=
3730 /* effect control */
3731 .code
= IOCTL_HID_WRITE_REPORT
,
3734 .report_buf
= {2, 0x01, 0x03, 0x00},
3736 struct hid_expect expect_stop_2
=
3738 /* effect control */
3739 .code
= IOCTL_HID_WRITE_REPORT
,
3742 .report_buf
= {2, 0x02, 0x03, 0x00},
3744 struct hid_expect expect_destroy
[] =
3746 /* effect operation */
3748 .code
= IOCTL_HID_WRITE_REPORT
,
3751 .report_buf
= {2,0x01,0x03,0x00},
3755 .code
= IOCTL_HID_WRITE_REPORT
,
3758 .report_buf
= {5,0x01},
3761 struct hid_expect expect_destroy_2
[] =
3763 /* effect operation */
3765 .code
= IOCTL_HID_WRITE_REPORT
,
3768 .report_buf
= {2,0x02,0x03,0x00},
3772 .code
= IOCTL_HID_WRITE_REPORT
,
3775 .report_buf
= {5,0x02},
3778 struct hid_expect device_state_input
[] =
3782 .code
= IOCTL_HID_READ_REPORT
,
3785 .report_buf
= {2,0xff,0x00,0xff},
3789 .code
= IOCTL_HID_READ_REPORT
,
3792 .report_buf
= {1,0x12,0x34,0x56,0xff},
3795 struct hid_expect device_state_input_0
[] =
3799 .code
= IOCTL_HID_READ_REPORT
,
3802 .report_buf
= {2,0xff,0x00,0xff},
3806 .code
= IOCTL_HID_READ_REPORT
,
3809 .report_buf
= {1,0x56,0x12,0x34,0xff},
3812 struct hid_expect device_state_input_1
[] =
3816 .code
= IOCTL_HID_READ_REPORT
,
3819 .report_buf
= {2,0x00,0x01,0x01},
3823 .code
= IOCTL_HID_READ_REPORT
,
3826 .report_buf
= {1,0x65,0x43,0x21,0x00},
3829 struct hid_expect device_state_input_2
[] =
3833 .code
= IOCTL_HID_READ_REPORT
,
3836 .report_buf
= {2,0x03,0x00,0x01},
3840 .code
= IOCTL_HID_READ_REPORT
,
3843 .report_buf
= {1,0x12,0x34,0x56,0xff},
3846 struct hid_expect expect_pool
[] =
3850 .code
= IOCTL_HID_GET_FEATURE
,
3853 .report_buf
= {1,0x10,0x00,0x04,0x03},
3858 .code
= IOCTL_HID_GET_FEATURE
,
3861 .report_buf
= {1,0x10,0x00,0x04,0x03},
3865 static const DWORD expect_axes
[3] =
3867 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
,
3868 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
,
3869 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
,
3871 static const LONG expect_directions
[3] = {
3876 static const DIENVELOPE expect_envelope
=
3878 .dwSize
= sizeof(DIENVELOPE
),
3879 .dwAttackLevel
= 1000,
3880 .dwAttackTime
= 2000,
3881 .dwFadeLevel
= 3000,
3884 static const DICONDITION expect_condition
[3] =
3888 .lPositiveCoefficient
= 2000,
3889 .lNegativeCoefficient
= -3000,
3890 .dwPositiveSaturation
= -4000,
3891 .dwNegativeSaturation
= -5000,
3896 .lPositiveCoefficient
= 5000,
3897 .lNegativeCoefficient
= -4000,
3898 .dwPositiveSaturation
= 3000,
3899 .dwNegativeSaturation
= 2000,
3904 .lPositiveCoefficient
= -8000,
3905 .lNegativeCoefficient
= 9000,
3906 .dwPositiveSaturation
= 10000,
3907 .dwNegativeSaturation
= 11000,
3908 .lDeadBand
= -12000,
3911 const DIEFFECT expect_desc
=
3913 .dwSize
= sizeof(DIEFFECT_DX6
),
3914 .dwFlags
= DIEFF_SPHERICAL
| DIEFF_OBJECTIDS
,
3916 .dwSamplePeriod
= 2000,
3918 .dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
3919 .dwTriggerRepeatInterval
= 5000,
3921 .rgdwAxes
= (void *)expect_axes
,
3922 .rglDirection
= (void *)expect_directions
,
3923 .lpEnvelope
= (void *)&expect_envelope
,
3924 .cbTypeSpecificParams
= 2 * sizeof(DICONDITION
),
3925 .lpvTypeSpecificParams
= (void *)expect_condition
,
3926 .dwStartDelay
= 6000,
3928 DIPROPGUIDANDPATH prop_guid_path
=
3932 .dwSize
= sizeof(DIPROPGUIDANDPATH
),
3933 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3934 .dwHow
= DIPH_DEVICE
,
3937 DIPROPDWORD prop_dword
=
3941 .dwSize
= sizeof(DIPROPDWORD
),
3942 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3943 .dwHow
= DIPH_DEVICE
,
3946 DIDEVICEINSTANCEW devinst
= {.dwSize
= sizeof(DIDEVICEINSTANCEW
)};
3947 IDirectInputDevice8W
*device
;
3948 IDirectInputEffect
*effect
, *effect2
;
3949 DIEFFECT effect_desc
;
3956 cleanup_registry_keys();
3958 desc
.report_descriptor_len
= sizeof(report_descriptor
);
3959 memcpy( desc
.report_descriptor_buf
, report_descriptor
, sizeof(report_descriptor
) );
3960 desc
.expect_size
= sizeof(expect_pool
);
3961 memcpy( desc
.expect
, expect_pool
, sizeof(expect_pool
) );
3962 fill_context( __LINE__
, desc
.context
, ARRAY_SIZE(desc
.context
) );
3964 if (!hid_device_start( &desc
)) goto done
;
3965 if (FAILED(hr
= dinput_test_create_device( DIRECTINPUT_VERSION
, &devinst
, &device
))) goto done
;
3967 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
3968 ok( hr
== DI_OK
, "GetProperty DIPROP_GUIDANDPATH returned %#lx\n", hr
);
3969 file
= CreateFileW( prop_guid_path
.wszPath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
3970 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
3971 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
3972 ok( file
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError() );
3974 hwnd
= CreateWindowW( L
"static", L
"dinput", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 10, 10, 200, 200,
3975 NULL
, NULL
, NULL
, NULL
);
3977 event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
3978 ok( event
!= NULL
, "CreateEventW failed, last error %lu\n", GetLastError() );
3979 hr
= IDirectInputDevice8_SetEventNotification( device
, event
);
3980 ok( hr
== DI_OK
, "SetEventNotification returned: %#lx\n", hr
);
3981 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
3982 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#lx\n", hr
);
3983 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
3984 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
3986 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
3987 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr
);
3988 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
3989 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetForceFeedbackState returned %#lx\n", hr
);
3990 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_RESET
);
3991 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "SendForceFeedbackCommand returned %#lx\n", hr
);
3993 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
3994 hr
= IDirectInputDevice8_Acquire( device
);
3995 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
3996 wait_hid_expect( file
, 100 );
3998 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
3999 prop_dword
.dwData
= 0xdeadbeef;
4000 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
4001 ok( hr
== DI_OK
, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr
);
4002 ok( prop_dword
.dwData
== 0, "got DIPROP_FFLOAD %#lx\n", prop_dword
.dwData
);
4003 set_hid_expect( file
, NULL
, 0 );
4005 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4007 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4008 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4009 flags
= DIGFFS_STOPPED
| DIGFFS_EMPTY
;
4010 ok( res
== flags
, "got state %#lx\n", res
);
4011 set_hid_expect( file
, NULL
, 0 );
4013 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4014 prop_dword
.dwData
= 0xdeadbeef;
4015 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
4016 ok( hr
== DI_OK
, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr
);
4017 ok( prop_dword
.dwData
== 0, "got DIPROP_FFLOAD %#lx\n", prop_dword
.dwData
);
4018 set_hid_expect( file
, NULL
, 0 );
4020 send_hid_input( file
, device_state_input
, sizeof(struct hid_expect
) );
4021 res
= WaitForSingleObject( event
, 100 );
4022 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
4023 send_hid_input( file
, device_state_input
, sizeof(device_state_input
) );
4024 res
= WaitForSingleObject( event
, 100 );
4025 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#lx\n", res
);
4027 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4029 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4030 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4031 flags
= DIGFFS_PAUSED
| DIGFFS_EMPTY
| DIGFFS_ACTUATORSON
| DIGFFS_POWERON
|
4032 DIGFFS_SAFETYSWITCHON
| DIGFFS_USERFFSWITCHON
;
4033 ok( res
== flags
, "got state %#lx\n", res
);
4034 set_hid_expect( file
, NULL
, 0 );
4036 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, NULL
, &effect
, NULL
);
4037 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
4039 hr
= IDirectInputEffect_GetEffectStatus( effect
, NULL
);
4040 ok( hr
== E_POINTER
, "GetEffectStatus returned %#lx\n", hr
);
4042 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4043 ok( hr
== DIERR_NOTDOWNLOADED
, "GetEffectStatus returned %#lx\n", hr
);
4044 ok( res
== 0, "got status %#lx\n", res
);
4046 flags
= DIEP_ALLPARAMS
;
4047 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, flags
| DIEP_NODOWNLOAD
);
4048 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#lx\n", hr
);
4050 set_hid_expect( file
, expect_reset
, sizeof(struct hid_expect
) );
4051 hr
= IDirectInputDevice8_Unacquire( device
);
4052 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
4053 set_hid_expect( file
, NULL
, 0 );
4055 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4056 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetEffectStatus returned %#lx\n", hr
);
4058 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
4059 hr
= IDirectInputDevice8_Acquire( device
);
4060 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
4061 wait_hid_expect( file
, 100 );
4064 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4065 ok( hr
== DIERR_NOTDOWNLOADED
, "GetEffectStatus returned %#lx\n", hr
);
4066 ok( res
== 0, "got status %#lx\n", res
);
4068 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4070 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4071 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4072 flags
= DIGFFS_STOPPED
| DIGFFS_EMPTY
;
4073 ok( res
== flags
, "got state %#lx\n", res
);
4074 set_hid_expect( file
, NULL
, 0 );
4076 set_hid_expect( file
, expect_create
, sizeof(expect_create
) );
4077 hr
= IDirectInputEffect_Download( effect
);
4078 ok( hr
== DI_OK
, "Download returned %#lx\n", hr
);
4079 set_hid_expect( file
, NULL
, 0 );
4082 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4083 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4084 ok( res
== 0, "got status %#lx\n", res
);
4085 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4087 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4088 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4089 flags
= DIGFFS_STOPPED
;
4090 ok( res
== flags
, "got state %#lx\n", res
);
4091 set_hid_expect( file
, NULL
, 0 );
4093 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4094 prop_dword
.dwData
= 0xdeadbeef;
4095 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
4096 ok( hr
== DI_OK
, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr
);
4097 ok( prop_dword
.dwData
== 0, "got DIPROP_FFLOAD %#lx\n", prop_dword
.dwData
);
4098 set_hid_expect( file
, NULL
, 0 );
4100 set_hid_expect( file
, &expect_start
, sizeof(expect_start
) );
4101 hr
= IDirectInputEffect_Start( effect
, 1, DIES_NODOWNLOAD
);
4102 ok( hr
== DI_OK
, "Start returned %#lx\n", hr
);
4103 set_hid_expect( file
, NULL
, 0 );
4105 set_hid_expect( file
, expect_create_2
, sizeof(expect_create_2
) );
4106 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &expect_desc
, &effect2
, NULL
);
4107 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
4108 set_hid_expect( file
, NULL
, 0 );
4109 set_hid_expect( file
, &expect_start_2
, sizeof(expect_start_2
) );
4110 hr
= IDirectInputEffect_Start( effect2
, 1, DIES_SOLO
);
4111 ok( hr
== DI_OK
, "Start returned %#lx\n", hr
);
4112 set_hid_expect( file
, NULL
, 0 );
4114 hr
= IDirectInputEffect_GetEffectStatus( effect2
, &res
);
4115 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4116 ok( res
== DIEGES_PLAYING
, "got status %#lx\n", res
);
4118 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4119 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4120 ok( res
== DIEGES_PLAYING
, "got status %#lx\n", res
);
4121 set_hid_expect( file
, &expect_stop_2
, sizeof(expect_stop_2
) );
4122 hr
= IDirectInputEffect_Stop( effect2
);
4123 ok( hr
== DI_OK
, "Stop returned %#lx\n", hr
);
4124 set_hid_expect( file
, NULL
, 0 );
4126 hr
= IDirectInputEffect_GetEffectStatus( effect2
, &res
);
4127 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4128 ok( res
== 0, "got status %#lx\n", res
);
4129 set_hid_expect( file
, expect_destroy_2
, sizeof(expect_destroy_2
) );
4130 ref
= IDirectInputEffect_Release( effect2
);
4131 ok( ref
== 0, "Release returned %ld\n", ref
);
4132 set_hid_expect( file
, NULL
, 0 );
4134 /* sending commands has no direct effect on status */
4135 set_hid_expect( file
, expect_stop_all
, sizeof(expect_stop_all
) );
4136 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_STOPALL
);
4137 ok( hr
== DI_OK
, "SendForceFeedbackCommand returned %#lx\n", hr
);
4138 set_hid_expect( file
, NULL
, 0 );
4140 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4141 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4142 ok( res
== DIEGES_PLAYING
, "got status %#lx\n", res
);
4143 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4145 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4146 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4147 flags
= DIGFFS_STOPPED
;
4148 ok( res
== flags
, "got state %#lx\n", res
);
4149 set_hid_expect( file
, NULL
, 0 );
4151 set_hid_expect( file
, expect_device_pause
, sizeof(expect_device_pause
) );
4152 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_PAUSE
);
4153 ok( hr
== DI_OK
, "SendForceFeedbackCommand returned %#lx\n", hr
);
4154 set_hid_expect( file
, NULL
, 0 );
4156 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4157 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4158 ok( res
== DIEGES_PLAYING
, "got status %#lx\n", res
);
4159 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4161 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4162 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4163 flags
= DIGFFS_STOPPED
;
4164 ok( res
== flags
, "got state %#lx\n", res
);
4165 set_hid_expect( file
, NULL
, 0 );
4167 set_hid_expect( file
, expect_device_continue
, sizeof(expect_device_continue
) );
4168 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_CONTINUE
);
4169 ok( hr
== DI_OK
, "SendForceFeedbackCommand returned %#lx\n", hr
);
4170 set_hid_expect( file
, NULL
, 0 );
4172 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4173 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4174 ok( res
== DIEGES_PLAYING
, "got status %#lx\n", res
);
4175 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4177 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4178 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4179 flags
= DIGFFS_STOPPED
;
4180 ok( res
== flags
, "got state %#lx\n", res
);
4181 set_hid_expect( file
, NULL
, 0 );
4183 set_hid_expect( file
, expect_disable_actuators
, sizeof(expect_disable_actuators
) );
4184 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_SETACTUATORSOFF
);
4185 ok( hr
== DI_OK
, "SendForceFeedbackCommand returned %#lx\n", hr
);
4186 set_hid_expect( file
, NULL
, 0 );
4188 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4189 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4190 ok( res
== DIEGES_PLAYING
, "got status %#lx\n", res
);
4191 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4193 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4194 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4195 flags
= DIGFFS_STOPPED
;
4196 ok( res
== flags
, "got state %#lx\n", res
);
4197 set_hid_expect( file
, NULL
, 0 );
4199 set_hid_expect( file
, expect_enable_actuators
, sizeof(expect_enable_actuators
) );
4200 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_SETACTUATORSON
);
4201 ok( hr
== DI_OK
, "SendForceFeedbackCommand returned %#lx\n", hr
);
4202 set_hid_expect( file
, NULL
, 0 );
4204 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4205 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4206 ok( res
== DIEGES_PLAYING
, "got status %#lx\n", res
);
4207 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4209 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4210 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4211 flags
= DIGFFS_STOPPED
;
4212 ok( res
== flags
, "got state %#lx\n", res
);
4213 set_hid_expect( file
, NULL
, 0 );
4215 set_hid_expect( file
, &expect_stop
, sizeof(expect_stop
) );
4216 hr
= IDirectInputEffect_Stop( effect
);
4217 ok( hr
== DI_OK
, "Stop returned %#lx\n", hr
);
4218 set_hid_expect( file
, NULL
, 0 );
4220 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4221 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4222 ok( res
== 0, "got status %#lx\n", res
);
4223 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4225 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4226 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4227 flags
= DIGFFS_STOPPED
;
4228 ok( res
== flags
, "got state %#lx\n", res
);
4229 set_hid_expect( file
, NULL
, 0 );
4231 send_hid_input( file
, device_state_input_0
, sizeof(device_state_input_0
) );
4232 res
= WaitForSingleObject( event
, 100 );
4233 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#lx\n", res
);
4234 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4236 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4237 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4238 flags
= DIGFFS_PAUSED
| DIGFFS_ACTUATORSON
| DIGFFS_POWERON
| DIGFFS_SAFETYSWITCHON
| DIGFFS_USERFFSWITCHON
;
4239 ok( res
== flags
, "got state %#lx\n", res
);
4240 set_hid_expect( file
, NULL
, 0 );
4242 send_hid_input( file
, device_state_input_1
, sizeof(device_state_input_1
) );
4243 res
= WaitForSingleObject( event
, 100 );
4244 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#lx\n", res
);
4246 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4247 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4248 ok( res
== DIEGES_PLAYING
, "got status %#lx\n", res
);
4249 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4251 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4252 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4253 flags
= DIGFFS_ACTUATORSOFF
| DIGFFS_POWEROFF
| DIGFFS_SAFETYSWITCHOFF
| DIGFFS_USERFFSWITCHOFF
;
4254 ok( res
== flags
, "got state %#lx\n", res
);
4255 set_hid_expect( file
, NULL
, 0 );
4257 send_hid_input( file
, device_state_input_2
, sizeof(device_state_input_2
) );
4258 res
= WaitForSingleObject( event
, 100 );
4259 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#lx\n", res
);
4261 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4262 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4263 ok( res
== 0, "got status %#lx\n", res
);
4264 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4266 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4267 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4268 flags
= DIGFFS_PAUSED
| DIGFFS_ACTUATORSON
| DIGFFS_POWEROFF
| DIGFFS_SAFETYSWITCHOFF
| DIGFFS_USERFFSWITCHOFF
;
4269 ok( res
== flags
, "got state %#lx\n", res
);
4270 set_hid_expect( file
, NULL
, 0 );
4272 set_hid_expect( file
, &expect_stop
, sizeof(expect_stop
) );
4273 hr
= IDirectInputEffect_Stop( effect
);
4274 ok( hr
== DI_OK
, "Stop returned %#lx\n", hr
);
4275 set_hid_expect( file
, NULL
, 0 );
4278 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4279 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4280 ok( res
== 0, "got status %#lx\n", res
);
4281 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4283 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4284 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4285 flags
= DIGFFS_PAUSED
| DIGFFS_ACTUATORSON
| DIGFFS_POWEROFF
| DIGFFS_SAFETYSWITCHOFF
| DIGFFS_USERFFSWITCHOFF
;
4286 ok( res
== flags
, "got state %#lx\n", res
);
4287 set_hid_expect( file
, NULL
, 0 );
4289 set_hid_expect( file
, expect_destroy
, sizeof(expect_destroy
) );
4290 hr
= IDirectInputEffect_Unload( effect
);
4291 ok( hr
== DI_OK
, "Unload returned %#lx\n", hr
);
4292 set_hid_expect( file
, NULL
, 0 );
4295 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4296 ok( hr
== DIERR_NOTDOWNLOADED
, "GetEffectStatus returned %#lx\n", hr
);
4297 ok( res
== 0, "got status %#lx\n", res
);
4298 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
4300 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
4301 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#lx\n", hr
);
4302 flags
= DIGFFS_EMPTY
| DIGFFS_PAUSED
| DIGFFS_ACTUATORSON
| DIGFFS_POWEROFF
|
4303 DIGFFS_SAFETYSWITCHOFF
| DIGFFS_USERFFSWITCHOFF
;
4304 ok( res
== flags
, "got state %#lx\n", res
);
4305 set_hid_expect( file
, NULL
, 0 );
4307 ref
= IDirectInputEffect_Release( effect
);
4308 ok( ref
== 0, "Release returned %ld\n", ref
);
4310 /* start delay has no direct effect on effect status */
4311 effect_desc
= expect_desc
;
4312 effect_desc
.dwStartDelay
= 32767000;
4313 set_hid_expect( file
, expect_create_delay
, sizeof(expect_create_delay
) );
4314 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &effect_desc
, &effect
, NULL
);
4315 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
4316 set_hid_expect( file
, NULL
, 0 );
4318 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4319 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4320 ok( res
== 0, "got status %#lx\n", res
);
4321 set_hid_expect( file
, &expect_start
, sizeof(expect_start
) );
4322 hr
= IDirectInputEffect_Start( effect
, 1, 0 );
4323 ok( hr
== DI_OK
, "Start returned %#lx\n", hr
);
4324 set_hid_expect( file
, NULL
, 0 );
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_destroy
, sizeof(expect_destroy
) );
4330 ref
= IDirectInputEffect_Release( effect
);
4331 ok( ref
== 0, "Release returned %ld\n", ref
);
4332 set_hid_expect( file
, NULL
, 0 );
4334 /* duration has no direct effect on effect status */
4335 effect_desc
= expect_desc
;
4336 effect_desc
.dwDuration
= 100;
4337 effect_desc
.dwStartDelay
= 0;
4338 set_hid_expect( file
, expect_create_duration
, sizeof(expect_create_duration
) );
4339 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &effect_desc
, &effect
, NULL
);
4340 ok( hr
== DI_OK
, "CreateEffect returned %#lx\n", hr
);
4341 set_hid_expect( file
, NULL
, 0 );
4343 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4344 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4345 ok( res
== 0, "got status %#lx\n", res
);
4346 set_hid_expect( file
, &expect_start
, sizeof(expect_start
) );
4347 hr
= IDirectInputEffect_Start( effect
, 1, 0 );
4348 ok( hr
== DI_OK
, "Start returned %#lx\n", hr
);
4349 set_hid_expect( file
, NULL
, 0 );
4352 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
4353 ok( hr
== DI_OK
, "GetEffectStatus returned %#lx\n", hr
);
4354 ok( res
== DIEGES_PLAYING
, "got status %#lx\n", res
);
4355 set_hid_expect( file
, expect_destroy
, sizeof(expect_destroy
) );
4356 ref
= IDirectInputEffect_Release( effect
);
4357 ok( ref
== 0, "Release returned %ld\n", ref
);
4358 set_hid_expect( file
, NULL
, 0 );
4360 set_hid_expect( file
, expect_reset
, sizeof(struct hid_expect
) );
4361 hr
= IDirectInputDevice8_Unacquire( device
);
4362 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
4363 set_hid_expect( file
, NULL
, 0 );
4365 ref
= IDirectInputDevice8_Release( device
);
4366 ok( ref
== 0, "Release returned %ld\n", ref
);
4368 DestroyWindow( hwnd
);
4369 CloseHandle( event
);
4370 CloseHandle( file
);
4373 hid_device_stop( &desc
);
4374 cleanup_registry_keys();
4375 winetest_pop_context();
4378 #define check_interface( a, b, c ) check_interface_( __LINE__, a, b, c )
4379 static void check_interface_( unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
4381 IUnknown
*iface
= iface_ptr
;
4382 HRESULT hr
, expected
;
4385 expected
= supported
? S_OK
: E_NOINTERFACE
;
4386 hr
= IUnknown_QueryInterface( iface
, iid
, (void **)&unk
);
4387 ok_(__FILE__
, line
)( hr
== expected
, "got hr %#lx, expected %#lx.\n", hr
, expected
);
4388 if (SUCCEEDED(hr
)) IUnknown_Release( unk
);
4391 #define check_runtimeclass( a, b ) check_runtimeclass_( __LINE__, (IInspectable *)a, b )
4392 static void check_runtimeclass_( int line
, IInspectable
*inspectable
, const WCHAR
*class_name
)
4394 const WCHAR
*buffer
;
4399 hr
= IInspectable_GetRuntimeClassName( inspectable
, &str
);
4400 ok_(__FILE__
, line
)( hr
== S_OK
, "GetRuntimeClassName returned %#lx\n", hr
);
4401 buffer
= pWindowsGetStringRawBuffer( str
, &length
);
4402 ok_(__FILE__
, line
)( !wcscmp( buffer
, class_name
), "got class name %s\n", debugstr_w(buffer
) );
4403 pWindowsDeleteString( str
);
4406 struct controller_handler
4408 IEventHandler_RawGameController IEventHandler_RawGameController_iface
;
4413 static inline struct controller_handler
*impl_from_IEventHandler_RawGameController( IEventHandler_RawGameController
*iface
)
4415 return CONTAINING_RECORD( iface
, struct controller_handler
, IEventHandler_RawGameController_iface
);
4418 static HRESULT WINAPI
controller_handler_QueryInterface( IEventHandler_RawGameController
*iface
, REFIID iid
, void **out
)
4420 if (IsEqualGUID( iid
, &IID_IUnknown
) ||
4421 IsEqualGUID( iid
, &IID_IAgileObject
) ||
4422 IsEqualGUID( iid
, &IID_IEventHandler_RawGameController
))
4424 IUnknown_AddRef( iface
);
4429 trace( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid
) );
4431 return E_NOINTERFACE
;
4434 static ULONG WINAPI
controller_handler_AddRef( IEventHandler_RawGameController
*iface
)
4439 static ULONG WINAPI
controller_handler_Release( IEventHandler_RawGameController
*iface
)
4444 static HRESULT WINAPI
controller_handler_Invoke( IEventHandler_RawGameController
*iface
,
4445 IInspectable
*sender
, IRawGameController
*controller
)
4447 struct controller_handler
*impl
= impl_from_IEventHandler_RawGameController( iface
);
4449 trace( "iface %p, sender %p, controller %p\n", iface
, sender
, controller
);
4451 ok( sender
== NULL
, "got sender %p\n", sender
);
4452 impl
->invoked
= TRUE
;
4453 SetEvent( impl
->event
);
4458 static const IEventHandler_RawGameControllerVtbl controller_handler_vtbl
=
4460 controller_handler_QueryInterface
,
4461 controller_handler_AddRef
,
4462 controller_handler_Release
,
4463 controller_handler_Invoke
,
4466 static struct controller_handler controller_added
= {{&controller_handler_vtbl
}};
4468 #define check_bool_async( a, b, c, d, e ) check_bool_async_( __LINE__, a, b, c, d, e )
4469 static void check_bool_async_( int line
, IAsyncOperation_boolean
*async
, UINT32 expect_id
, AsyncStatus expect_status
,
4470 HRESULT expect_hr
, BOOLEAN expect_result
)
4472 AsyncStatus async_status
;
4473 IAsyncInfo
*async_info
;
4474 HRESULT hr
, async_hr
;
4478 hr
= IAsyncOperation_boolean_QueryInterface( async
, &IID_IAsyncInfo
, (void **)&async_info
);
4479 ok_(__FILE__
, line
)( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
4481 async_id
= 0xdeadbeef;
4482 hr
= IAsyncInfo_get_Id( async_info
, &async_id
);
4483 if (expect_status
< 4) ok_(__FILE__
, line
)( hr
== S_OK
, "get_Id returned %#lx\n", hr
);
4484 else ok_(__FILE__
, line
)( hr
== E_ILLEGAL_METHOD_CALL
, "get_Id returned %#lx\n", hr
);
4485 ok_(__FILE__
, line
)( async_id
== expect_id
, "got id %u\n", async_id
);
4487 async_status
= 0xdeadbeef;
4488 hr
= IAsyncInfo_get_Status( async_info
, &async_status
);
4489 if (expect_status
< 4) ok_(__FILE__
, line
)( hr
== S_OK
, "get_Status returned %#lx\n", hr
);
4490 else ok_(__FILE__
, line
)( hr
== E_ILLEGAL_METHOD_CALL
, "get_Status returned %#lx\n", hr
);
4491 ok_(__FILE__
, line
)( async_status
== expect_status
, "got status %u\n", async_status
);
4493 async_hr
= 0xdeadbeef;
4494 hr
= IAsyncInfo_get_ErrorCode( async_info
, &async_hr
);
4495 if (expect_status
< 4) ok_(__FILE__
, line
)( hr
== S_OK
, "get_ErrorCode returned %#lx\n", hr
);
4496 else ok_(__FILE__
, line
)( hr
== E_ILLEGAL_METHOD_CALL
, "get_ErrorCode returned %#lx\n", hr
);
4497 if (expect_status
< 4) todo_wine_if(FAILED(expect_hr
)) ok_(__FILE__
, line
)( async_hr
== expect_hr
, "got error %#lx\n", async_hr
);
4498 else ok_(__FILE__
, line
)( async_hr
== E_ILLEGAL_METHOD_CALL
, "got error %#lx\n", async_hr
);
4500 IAsyncInfo_Release( async_info
);
4502 result
= !expect_result
;
4503 hr
= IAsyncOperation_boolean_GetResults( async
, &result
);
4504 switch (expect_status
)
4508 todo_wine_if(FAILED(expect_hr
))
4509 ok_(__FILE__
, line
)( hr
== expect_hr
, "GetResults returned %#lx\n", hr
);
4510 ok_(__FILE__
, line
)( result
== expect_result
, "got result %u\n", result
);
4515 ok_(__FILE__
, line
)( hr
== E_ILLEGAL_METHOD_CALL
, "GetResults returned %#lx\n", hr
);
4520 #define check_result_async( a, b, c, d, e ) check_result_async_( __LINE__, a, b, c, d, e )
4521 static void check_result_async_( int line
, IAsyncOperation_ForceFeedbackLoadEffectResult
*async
, UINT32 expect_id
,
4522 AsyncStatus expect_status
, HRESULT expect_hr
, ForceFeedbackLoadEffectResult expect_result
)
4524 ForceFeedbackLoadEffectResult result
;
4525 AsyncStatus async_status
;
4526 IAsyncInfo
*async_info
;
4527 HRESULT hr
, async_hr
;
4530 hr
= IAsyncOperation_ForceFeedbackLoadEffectResult_QueryInterface( async
, &IID_IAsyncInfo
, (void **)&async_info
);
4531 ok_(__FILE__
, line
)( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
4533 async_id
= 0xdeadbeef;
4534 hr
= IAsyncInfo_get_Id( async_info
, &async_id
);
4535 if (expect_status
< 4) ok_(__FILE__
, line
)( hr
== S_OK
, "get_Id returned %#lx\n", hr
);
4536 else ok_(__FILE__
, line
)( hr
== E_ILLEGAL_METHOD_CALL
, "get_Id returned %#lx\n", hr
);
4537 ok_(__FILE__
, line
)( async_id
== expect_id
, "got id %u\n", async_id
);
4539 async_status
= 0xdeadbeef;
4540 hr
= IAsyncInfo_get_Status( async_info
, &async_status
);
4541 if (expect_status
< 4) ok_(__FILE__
, line
)( hr
== S_OK
, "get_Status returned %#lx\n", hr
);
4542 else ok_(__FILE__
, line
)( hr
== E_ILLEGAL_METHOD_CALL
, "get_Status returned %#lx\n", hr
);
4543 ok_(__FILE__
, line
)( async_status
== expect_status
, "got status %u\n", async_status
);
4545 async_hr
= 0xdeadbeef;
4546 hr
= IAsyncInfo_get_ErrorCode( async_info
, &async_hr
);
4547 if (expect_status
< 4) ok_(__FILE__
, line
)( hr
== S_OK
, "get_ErrorCode returned %#lx\n", hr
);
4548 else ok_(__FILE__
, line
)( hr
== E_ILLEGAL_METHOD_CALL
, "get_ErrorCode returned %#lx\n", hr
);
4549 if (expect_status
< 4) todo_wine_if(FAILED(expect_hr
)) ok_(__FILE__
, line
)( async_hr
== expect_hr
, "got error %#lx\n", async_hr
);
4550 else ok_(__FILE__
, line
)( async_hr
== E_ILLEGAL_METHOD_CALL
, "got error %#lx\n", async_hr
);
4552 IAsyncInfo_Release( async_info
);
4554 result
= !expect_result
;
4555 hr
= IAsyncOperation_ForceFeedbackLoadEffectResult_GetResults( async
, &result
);
4556 switch (expect_status
)
4560 todo_wine_if(FAILED(expect_hr
))
4561 ok_(__FILE__
, line
)( hr
== expect_hr
, "GetResults returned %#lx\n", hr
);
4562 ok_(__FILE__
, line
)( result
== expect_result
, "got result %u\n", result
);
4567 ok_(__FILE__
, line
)( hr
== E_ILLEGAL_METHOD_CALL
, "GetResults returned %#lx\n", hr
);
4572 struct bool_async_handler
4574 IAsyncOperationCompletedHandler_boolean IAsyncOperationCompletedHandler_boolean_iface
;
4575 IAsyncOperation_boolean
*async
;
4581 static inline struct bool_async_handler
*impl_from_IAsyncOperationCompletedHandler_boolean( IAsyncOperationCompletedHandler_boolean
*iface
)
4583 return CONTAINING_RECORD( iface
, struct bool_async_handler
, IAsyncOperationCompletedHandler_boolean_iface
);
4586 static HRESULT WINAPI
bool_async_handler_QueryInterface( IAsyncOperationCompletedHandler_boolean
*iface
, REFIID iid
, void **out
)
4588 if (IsEqualGUID( iid
, &IID_IUnknown
) ||
4589 IsEqualGUID( iid
, &IID_IAgileObject
) ||
4590 IsEqualGUID( iid
, &IID_IAsyncOperationCompletedHandler_boolean
))
4592 IUnknown_AddRef( iface
);
4597 trace( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid
) );
4599 return E_NOINTERFACE
;
4602 static ULONG WINAPI
bool_async_handler_AddRef( IAsyncOperationCompletedHandler_boolean
*iface
)
4607 static ULONG WINAPI
bool_async_handler_Release( IAsyncOperationCompletedHandler_boolean
*iface
)
4612 static HRESULT WINAPI
bool_async_handler_Invoke( IAsyncOperationCompletedHandler_boolean
*iface
,
4613 IAsyncOperation_boolean
*async
, AsyncStatus status
)
4615 struct bool_async_handler
*impl
= impl_from_IAsyncOperationCompletedHandler_boolean( iface
);
4617 trace( "iface %p, async %p, status %u\n", iface
, async
, status
);
4619 ok( !impl
->invoked
, "invoked twice\n" );
4620 impl
->invoked
= TRUE
;
4621 impl
->async
= async
;
4622 impl
->status
= status
;
4623 if (impl
->event
) SetEvent( impl
->event
);
4628 static IAsyncOperationCompletedHandler_booleanVtbl bool_async_handler_vtbl
=
4630 /*** IUnknown methods ***/
4631 bool_async_handler_QueryInterface
,
4632 bool_async_handler_AddRef
,
4633 bool_async_handler_Release
,
4634 /*** IAsyncOperationCompletedHandler<boolean> methods ***/
4635 bool_async_handler_Invoke
,
4638 static struct bool_async_handler default_bool_async_handler
= {{&bool_async_handler_vtbl
}};
4640 struct result_async_handler
4642 IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface
;
4643 IAsyncOperation_ForceFeedbackLoadEffectResult
*async
;
4649 static inline struct result_async_handler
*impl_from_IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult( IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult
*iface
)
4651 return CONTAINING_RECORD( iface
, struct result_async_handler
, IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface
);
4654 static HRESULT WINAPI
result_async_handler_QueryInterface( IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult
*iface
, REFIID iid
, void **out
)
4656 if (IsEqualGUID( iid
, &IID_IUnknown
) ||
4657 IsEqualGUID( iid
, &IID_IAgileObject
) ||
4658 IsEqualGUID( iid
, &IID_IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult
))
4660 IUnknown_AddRef( iface
);
4665 trace( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid
) );
4667 return E_NOINTERFACE
;
4670 static ULONG WINAPI
result_async_handler_AddRef( IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult
*iface
)
4675 static ULONG WINAPI
result_async_handler_Release( IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult
*iface
)
4680 static HRESULT WINAPI
result_async_handler_Invoke( IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult
*iface
,
4681 IAsyncOperation_ForceFeedbackLoadEffectResult
*async
, AsyncStatus status
)
4683 struct result_async_handler
*impl
= impl_from_IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult( iface
);
4685 trace( "iface %p, async %p, status %u\n", iface
, async
, status
);
4687 ok( !impl
->invoked
, "invoked twice\n" );
4688 impl
->invoked
= TRUE
;
4689 impl
->async
= async
;
4690 impl
->status
= status
;
4691 if (impl
->event
) SetEvent( impl
->event
);
4696 static IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResultVtbl result_async_handler_vtbl
=
4698 /*** IUnknown methods ***/
4699 result_async_handler_QueryInterface
,
4700 result_async_handler_AddRef
,
4701 result_async_handler_Release
,
4702 /*** IAsyncOperationCompletedHandler<ForceFeedbackLoadEffectResult> methods ***/
4703 result_async_handler_Invoke
,
4706 static struct result_async_handler default_result_async_handler
= {{&result_async_handler_vtbl
}};
4708 static void test_windows_gaming_input(void)
4710 #include "psh_hid_macros.h"
4711 const unsigned char report_desc
[] =
4713 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
4714 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
4715 COLLECTION(1, Application
),
4716 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
4717 COLLECTION(1, Physical
),
4720 USAGE(1, HID_USAGE_GENERIC_X
),
4721 USAGE(1, HID_USAGE_GENERIC_Y
),
4722 USAGE(1, HID_USAGE_GENERIC_Z
),
4723 LOGICAL_MINIMUM(1, 0),
4724 LOGICAL_MAXIMUM(1, 127),
4725 PHYSICAL_MINIMUM(1, 0),
4726 PHYSICAL_MAXIMUM(1, 127),
4729 INPUT(1, Data
|Var
|Abs
),
4731 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
4732 LOGICAL_MINIMUM(1, 1),
4733 LOGICAL_MAXIMUM(1, 8),
4734 PHYSICAL_MINIMUM(1, 0),
4735 PHYSICAL_MAXIMUM(1, 8),
4738 INPUT(1, Data
|Var
|Abs
|Null
),
4740 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
4741 USAGE_MINIMUM(1, 1),
4742 USAGE_MAXIMUM(1, 5),
4743 LOGICAL_MINIMUM(1, 0),
4744 LOGICAL_MAXIMUM(1, 1),
4745 PHYSICAL_MINIMUM(1, 0),
4746 PHYSICAL_MAXIMUM(1, 1),
4749 INPUT(1, Data
|Var
|Abs
),
4752 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
4753 USAGE(1, PID_USAGE_STATE_REPORT
),
4754 COLLECTION(1, Report
),
4757 USAGE(1, PID_USAGE_DEVICE_PAUSED
),
4758 USAGE(1, PID_USAGE_ACTUATORS_ENABLED
),
4759 USAGE(1, PID_USAGE_SAFETY_SWITCH
),
4760 USAGE(1, PID_USAGE_ACTUATOR_OVERRIDE_SWITCH
),
4761 USAGE(1, PID_USAGE_ACTUATOR_POWER
),
4762 LOGICAL_MINIMUM(1, 0),
4763 LOGICAL_MAXIMUM(1, 1),
4764 PHYSICAL_MINIMUM(1, 0),
4765 PHYSICAL_MAXIMUM(1, 1),
4768 INPUT(1, Data
|Var
|Abs
),
4770 INPUT(1, Cnst
|Var
|Abs
),
4772 USAGE(1, PID_USAGE_EFFECT_PLAYING
),
4773 LOGICAL_MINIMUM(1, 0),
4774 LOGICAL_MAXIMUM(1, 1),
4775 PHYSICAL_MINIMUM(1, 0),
4776 PHYSICAL_MAXIMUM(1, 1),
4779 INPUT(1, Data
|Var
|Abs
),
4781 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
4782 LOGICAL_MINIMUM(1, 1),
4783 LOGICAL_MAXIMUM(1, 0x7f),
4784 PHYSICAL_MINIMUM(1, 1),
4785 PHYSICAL_MAXIMUM(1, 0x7f),
4788 INPUT(1, Data
|Var
|Abs
),
4791 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
4792 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT
),
4793 COLLECTION(1, Report
),
4796 USAGE(1, PID_USAGE_DEVICE_CONTROL
),
4797 COLLECTION(1, Logical
),
4798 USAGE(1, PID_USAGE_DC_DEVICE_RESET
),
4799 USAGE(1, PID_USAGE_DC_DEVICE_PAUSE
),
4800 USAGE(1, PID_USAGE_DC_DEVICE_CONTINUE
),
4801 USAGE(1, PID_USAGE_DC_ENABLE_ACTUATORS
),
4802 USAGE(1, PID_USAGE_DC_DISABLE_ACTUATORS
),
4803 USAGE(1, PID_USAGE_DC_STOP_ALL_EFFECTS
),
4804 LOGICAL_MINIMUM(1, 1),
4805 LOGICAL_MAXIMUM(1, 6),
4806 PHYSICAL_MINIMUM(1, 1),
4807 PHYSICAL_MAXIMUM(1, 6),
4810 OUTPUT(1, Data
|Ary
|Abs
),
4814 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT
),
4815 COLLECTION(1, Report
),
4818 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
4819 LOGICAL_MINIMUM(1, 1),
4820 LOGICAL_MAXIMUM(1, 0x7f),
4821 PHYSICAL_MINIMUM(1, 1),
4822 PHYSICAL_MAXIMUM(1, 0x7f),
4825 OUTPUT(1, Data
|Var
|Abs
),
4827 USAGE(1, PID_USAGE_EFFECT_OPERATION
),
4828 COLLECTION(1, NamedArray
),
4829 USAGE(1, PID_USAGE_OP_EFFECT_START
),
4830 USAGE(1, PID_USAGE_OP_EFFECT_START_SOLO
),
4831 USAGE(1, PID_USAGE_OP_EFFECT_STOP
),
4832 LOGICAL_MINIMUM(1, 1),
4833 LOGICAL_MAXIMUM(1, 3),
4834 PHYSICAL_MINIMUM(1, 1),
4835 PHYSICAL_MAXIMUM(1, 3),
4838 OUTPUT(1, Data
|Ary
|Abs
),
4841 USAGE(1, PID_USAGE_LOOP_COUNT
),
4842 LOGICAL_MINIMUM(1, 0),
4843 LOGICAL_MAXIMUM(1, 0x7f),
4844 PHYSICAL_MINIMUM(1, 0),
4845 PHYSICAL_MAXIMUM(1, 0x7f),
4848 OUTPUT(1, Data
|Var
|Abs
),
4851 USAGE(1, PID_USAGE_SET_EFFECT_REPORT
),
4852 COLLECTION(1, Report
),
4855 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
4856 LOGICAL_MINIMUM(1, 1),
4857 LOGICAL_MAXIMUM(1, 0x7f),
4858 PHYSICAL_MINIMUM(1, 1),
4859 PHYSICAL_MAXIMUM(1, 0x7f),
4862 OUTPUT(1, Data
|Var
|Abs
),
4864 USAGE(1, PID_USAGE_EFFECT_TYPE
),
4865 COLLECTION(1, NamedArray
),
4866 USAGE(1, PID_USAGE_ET_SQUARE
),
4867 USAGE(1, PID_USAGE_ET_SINE
),
4868 USAGE(1, PID_USAGE_ET_SPRING
),
4869 USAGE(1, PID_USAGE_ET_CONSTANT_FORCE
),
4870 USAGE(1, PID_USAGE_ET_RAMP
),
4871 LOGICAL_MINIMUM(1, 1),
4872 LOGICAL_MAXIMUM(1, 5),
4873 PHYSICAL_MINIMUM(1, 1),
4874 PHYSICAL_MAXIMUM(1, 5),
4877 OUTPUT(1, Data
|Ary
|Abs
),
4880 USAGE(1, PID_USAGE_AXES_ENABLE
),
4881 COLLECTION(1, Logical
),
4882 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_X
),
4883 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Y
),
4884 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Z
),
4885 LOGICAL_MINIMUM(1, 0),
4886 LOGICAL_MAXIMUM(1, 1),
4887 PHYSICAL_MINIMUM(1, 0),
4888 PHYSICAL_MAXIMUM(1, 1),
4891 OUTPUT(1, Data
|Var
|Abs
),
4893 USAGE(1, PID_USAGE_DIRECTION_ENABLE
),
4895 OUTPUT(1, Data
|Var
|Abs
),
4897 OUTPUT(1, Cnst
|Var
|Abs
),
4899 USAGE(1, PID_USAGE_DURATION
),
4900 USAGE(1, PID_USAGE_TRIGGER_REPEAT_INTERVAL
),
4901 USAGE(1, PID_USAGE_SAMPLE_PERIOD
),
4902 USAGE(1, PID_USAGE_START_DELAY
),
4903 UNIT(2, 0x1003), /* Eng Lin:Time */
4904 UNIT_EXPONENT(1, -3), /* 10^-3 */
4905 LOGICAL_MINIMUM(1, 0),
4906 LOGICAL_MAXIMUM(2, 0x7fff),
4907 PHYSICAL_MINIMUM(1, 0),
4908 PHYSICAL_MAXIMUM(2, 0x7fff),
4911 OUTPUT(1, Data
|Var
|Abs
),
4913 UNIT_EXPONENT(1, 0),
4915 USAGE(1, PID_USAGE_TRIGGER_BUTTON
),
4916 LOGICAL_MINIMUM(1, 1),
4917 LOGICAL_MAXIMUM(1, 0x08),
4918 PHYSICAL_MINIMUM(1, 1),
4919 PHYSICAL_MAXIMUM(1, 0x08),
4922 OUTPUT(1, Data
|Var
|Abs
),
4924 USAGE(1, PID_USAGE_GAIN
),
4925 LOGICAL_MINIMUM(1, 0),
4926 LOGICAL_MAXIMUM(2, 0x00ff),
4927 PHYSICAL_MINIMUM(1, 0),
4928 PHYSICAL_MAXIMUM(2, 0x2710),
4931 OUTPUT(1, Data
|Var
|Abs
),
4933 USAGE(1, PID_USAGE_DIRECTION
),
4934 COLLECTION(1, Logical
),
4935 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
4936 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
4937 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
4938 UNIT_EXPONENT(1, -2), /* 10^-2 */
4939 LOGICAL_MINIMUM(1, 0),
4940 LOGICAL_MAXIMUM(4, 360),
4941 PHYSICAL_MINIMUM(1, 0),
4942 PHYSICAL_MAXIMUM(4, 36000),
4946 OUTPUT(1, Data
|Var
|Abs
),
4947 UNIT_EXPONENT(1, 0),
4952 USAGE(1, PID_USAGE_SET_CONDITION_REPORT
),
4953 COLLECTION(1, Logical
),
4956 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
4957 LOGICAL_MINIMUM(1, 1),
4958 LOGICAL_MAXIMUM(1, 0x7f),
4959 PHYSICAL_MINIMUM(1, 1),
4960 PHYSICAL_MAXIMUM(1, 0x7f),
4963 OUTPUT(1, Data
|Var
|Abs
),
4965 USAGE(1, PID_USAGE_PARAMETER_BLOCK_OFFSET
),
4966 LOGICAL_MINIMUM(1, 0),
4967 LOGICAL_MAXIMUM(1, 1),
4968 PHYSICAL_MINIMUM(1, 0),
4969 PHYSICAL_MAXIMUM(1, 1),
4972 OUTPUT(1, Data
|Var
|Abs
),
4974 USAGE(1, PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET
),
4975 COLLECTION(1, Logical
),
4976 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
4977 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
4978 LOGICAL_MINIMUM(1, 0),
4979 LOGICAL_MAXIMUM(1, 1),
4980 PHYSICAL_MINIMUM(1, 0),
4981 PHYSICAL_MAXIMUM(1, 1),
4984 OUTPUT(1, Data
|Var
|Abs
),
4987 USAGE(1, PID_USAGE_CP_OFFSET
),
4988 LOGICAL_MINIMUM(2, -10000),
4989 LOGICAL_MAXIMUM(2, +10000),
4990 PHYSICAL_MINIMUM(2, -10000),
4991 PHYSICAL_MAXIMUM(2, +10000),
4994 OUTPUT(1, Data
|Var
|Abs
),
4996 USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT
),
4997 USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT
),
4998 LOGICAL_MINIMUM(2, -10000),
4999 LOGICAL_MAXIMUM(2, +10000),
5000 PHYSICAL_MINIMUM(2, -10000),
5001 PHYSICAL_MAXIMUM(2, +10000),
5004 OUTPUT(1, Data
|Var
|Abs
),
5006 USAGE(1, PID_USAGE_POSITIVE_SATURATION
),
5007 USAGE(1, PID_USAGE_NEGATIVE_SATURATION
),
5008 LOGICAL_MINIMUM(1, 0),
5009 LOGICAL_MAXIMUM(2, 0x00ff),
5010 PHYSICAL_MINIMUM(1, 0),
5011 PHYSICAL_MAXIMUM(2, 10000),
5014 OUTPUT(1, Data
|Var
|Abs
),
5016 USAGE(1, PID_USAGE_DEAD_BAND
),
5017 LOGICAL_MINIMUM(1, 0),
5018 LOGICAL_MAXIMUM(2, 0x00ff),
5019 PHYSICAL_MINIMUM(1, 0),
5020 PHYSICAL_MAXIMUM(2, 10000),
5023 OUTPUT(1, Data
|Var
|Abs
),
5026 USAGE(1, PID_USAGE_BLOCK_FREE_REPORT
),
5027 COLLECTION(1, Logical
),
5030 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
5031 LOGICAL_MINIMUM(1, 1),
5032 LOGICAL_MAXIMUM(1, 0x7f),
5033 PHYSICAL_MINIMUM(1, 1),
5034 PHYSICAL_MAXIMUM(1, 0x7f),
5037 OUTPUT(1, Data
|Var
|Abs
),
5040 USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT
),
5041 COLLECTION(1, Logical
),
5044 USAGE(1, PID_USAGE_DEVICE_GAIN
),
5045 LOGICAL_MINIMUM(1, 0),
5046 LOGICAL_MAXIMUM(2, 0x00ff),
5047 PHYSICAL_MINIMUM(1, 0),
5048 PHYSICAL_MAXIMUM(2, 0x2710),
5051 OUTPUT(1, Data
|Var
|Abs
),
5054 USAGE(1, PID_USAGE_SET_PERIODIC_REPORT
),
5055 COLLECTION(1, Logical
),
5058 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
5059 LOGICAL_MINIMUM(1, 1),
5060 LOGICAL_MAXIMUM(1, 0x7f),
5061 PHYSICAL_MINIMUM(1, 1),
5062 PHYSICAL_MAXIMUM(1, 0x7f),
5065 OUTPUT(1, Data
|Var
|Abs
),
5067 USAGE(1, PID_USAGE_MAGNITUDE
),
5068 LOGICAL_MINIMUM(1, 0),
5069 LOGICAL_MAXIMUM(2, 10000),
5070 PHYSICAL_MINIMUM(1, 0),
5071 PHYSICAL_MAXIMUM(2, 10000),
5074 OUTPUT(1, Data
|Var
|Abs
),
5076 USAGE(1, PID_USAGE_OFFSET
),
5077 LOGICAL_MINIMUM(2, -10000),
5078 LOGICAL_MAXIMUM(2, +10000),
5079 PHYSICAL_MINIMUM(2, -10000),
5080 PHYSICAL_MAXIMUM(2, +10000),
5083 OUTPUT(1, Data
|Var
|Abs
),
5085 USAGE(1, PID_USAGE_PHASE
),
5086 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
5087 UNIT_EXPONENT(1, -2),
5088 LOGICAL_MINIMUM(2, -180),
5089 LOGICAL_MAXIMUM(2, +180),
5090 PHYSICAL_MINIMUM(2, -18000),
5091 PHYSICAL_MAXIMUM(2, +18000),
5094 OUTPUT(1, Data
|Var
|Abs
),
5096 USAGE(1, PID_USAGE_PERIOD
),
5097 UNIT(2, 0x1003), /* Eng Lin:Time */
5098 UNIT_EXPONENT(1, -3), /* 10^-3 */
5099 LOGICAL_MINIMUM(1, 0),
5100 LOGICAL_MAXIMUM(2, 0x7fff),
5101 PHYSICAL_MINIMUM(1, 0),
5102 PHYSICAL_MAXIMUM(2, 0x7fff),
5105 OUTPUT(1, Data
|Var
|Abs
),
5107 UNIT_EXPONENT(1, 0),
5108 UNIT(1, 0), /* None */
5111 USAGE(1, PID_USAGE_SET_ENVELOPE_REPORT
),
5112 COLLECTION(1, Logical
),
5115 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
5116 LOGICAL_MINIMUM(1, 1),
5117 LOGICAL_MAXIMUM(1, 0x7f),
5118 PHYSICAL_MINIMUM(1, 1),
5119 PHYSICAL_MAXIMUM(1, 0x7f),
5122 OUTPUT(1, Data
|Var
|Abs
),
5124 USAGE(1, PID_USAGE_ATTACK_LEVEL
),
5125 USAGE(1, PID_USAGE_FADE_LEVEL
),
5126 LOGICAL_MINIMUM(1, 0),
5127 LOGICAL_MAXIMUM(2, 0x00ff),
5128 PHYSICAL_MINIMUM(1, 0),
5129 PHYSICAL_MAXIMUM(2, 0x2710),
5132 OUTPUT(1, Data
|Var
|Abs
),
5134 USAGE(1, PID_USAGE_ATTACK_TIME
),
5135 USAGE(1, PID_USAGE_FADE_TIME
),
5136 UNIT(2, 0x1003), /* Eng Lin:Time */
5137 UNIT_EXPONENT(1, -3), /* 10^-3 */
5138 LOGICAL_MINIMUM(1, 0),
5139 LOGICAL_MAXIMUM(2, 0x7fff),
5140 PHYSICAL_MINIMUM(1, 0),
5141 PHYSICAL_MAXIMUM(2, 0x7fff),
5144 OUTPUT(1, Data
|Var
|Abs
),
5145 UNIT_EXPONENT(1, 0),
5149 USAGE(1, PID_USAGE_SET_CONSTANT_FORCE_REPORT
),
5150 COLLECTION(1, Logical
),
5153 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
5154 LOGICAL_MINIMUM(1, 1),
5155 LOGICAL_MAXIMUM(1, 0x7f),
5156 PHYSICAL_MINIMUM(1, 1),
5157 PHYSICAL_MAXIMUM(1, 0x7f),
5160 OUTPUT(1, Data
|Var
|Abs
),
5162 USAGE(1, PID_USAGE_MAGNITUDE
),
5163 LOGICAL_MINIMUM(2, -10000),
5164 LOGICAL_MAXIMUM(2, +10000),
5165 PHYSICAL_MINIMUM(2, -10000),
5166 PHYSICAL_MAXIMUM(2, +10000),
5169 OUTPUT(1, Data
|Var
|Abs
),
5172 USAGE(1, PID_USAGE_SET_RAMP_FORCE_REPORT
),
5173 COLLECTION(1, Logical
),
5176 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
5177 LOGICAL_MINIMUM(1, 1),
5178 LOGICAL_MAXIMUM(1, 0x7f),
5179 PHYSICAL_MINIMUM(1, 1),
5180 PHYSICAL_MAXIMUM(1, 0x7f),
5183 OUTPUT(1, Data
|Var
|Abs
),
5185 USAGE(1, PID_USAGE_RAMP_START
),
5186 USAGE(1, PID_USAGE_RAMP_END
),
5187 LOGICAL_MINIMUM(2, -10000),
5188 LOGICAL_MAXIMUM(2, +10000),
5189 PHYSICAL_MINIMUM(2, -10000),
5190 PHYSICAL_MAXIMUM(2, +10000),
5193 OUTPUT(1, Data
|Var
|Abs
),
5196 USAGE(1, PID_USAGE_POOL_REPORT
),
5197 COLLECTION(1, Logical
),
5200 USAGE(1, PID_USAGE_RAM_POOL_SIZE
),
5201 LOGICAL_MINIMUM(1, 0),
5202 LOGICAL_MAXIMUM(4, 0xffff),
5203 PHYSICAL_MINIMUM(1, 0),
5204 PHYSICAL_MAXIMUM(4, 0xffff),
5207 FEATURE(1, Data
|Var
|Abs
),
5209 USAGE(1, PID_USAGE_SIMULTANEOUS_EFFECTS_MAX
),
5210 LOGICAL_MINIMUM(1, 0),
5211 LOGICAL_MAXIMUM(1, 0x7f),
5212 PHYSICAL_MINIMUM(1, 0),
5213 PHYSICAL_MAXIMUM(1, 0x7f),
5216 FEATURE(1, Data
|Var
|Abs
),
5218 USAGE(1, PID_USAGE_DEVICE_MANAGED_POOL
),
5219 USAGE(1, PID_USAGE_SHARED_PARAMETER_BLOCKS
),
5220 LOGICAL_MINIMUM(1, 0),
5221 LOGICAL_MAXIMUM(1, 1),
5222 PHYSICAL_MINIMUM(1, 0),
5223 PHYSICAL_MAXIMUM(1, 1),
5226 FEATURE(1, Data
|Var
|Abs
),
5229 USAGE(1, PID_USAGE_CREATE_NEW_EFFECT_REPORT
),
5230 COLLECTION(1, Logical
),
5233 USAGE(1, PID_USAGE_EFFECT_TYPE
),
5234 COLLECTION(1, NamedArray
),
5235 USAGE(1, PID_USAGE_ET_SQUARE
),
5236 USAGE(1, PID_USAGE_ET_SINE
),
5237 USAGE(1, PID_USAGE_ET_SPRING
),
5238 USAGE(1, PID_USAGE_ET_CONSTANT_FORCE
),
5239 USAGE(1, PID_USAGE_ET_RAMP
),
5240 LOGICAL_MINIMUM(1, 1),
5241 LOGICAL_MAXIMUM(1, 5),
5242 PHYSICAL_MINIMUM(1, 1),
5243 PHYSICAL_MAXIMUM(1, 5),
5246 FEATURE(1, Data
|Ary
|Abs
),
5249 USAGE(4, (HID_USAGE_PAGE_GENERIC
<<16)|HID_USAGE_GENERIC_BYTE_COUNT
),
5250 LOGICAL_MINIMUM(1, 0x7f),
5251 LOGICAL_MAXIMUM(1, 0x7f),
5252 PHYSICAL_MINIMUM(1, 0x7f),
5253 PHYSICAL_MAXIMUM(1, 0x7f),
5256 FEATURE(1, Data
|Ary
|Abs
),
5259 USAGE(1, PID_USAGE_BLOCK_LOAD_REPORT
),
5260 COLLECTION(1, Logical
),
5263 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
5264 LOGICAL_MINIMUM(1, 1),
5265 LOGICAL_MAXIMUM(1, 0x7f),
5266 PHYSICAL_MINIMUM(1, 1),
5267 PHYSICAL_MAXIMUM(1, 0x7f),
5270 FEATURE(1, Data
|Var
|Abs
),
5272 USAGE(1, PID_USAGE_BLOCK_LOAD_STATUS
),
5273 COLLECTION(1, NamedArray
),
5274 USAGE(1, PID_USAGE_BLOCK_LOAD_SUCCESS
),
5275 USAGE(1, PID_USAGE_BLOCK_LOAD_FULL
),
5276 USAGE(1, PID_USAGE_BLOCK_LOAD_ERROR
),
5277 LOGICAL_MINIMUM(1, 1),
5278 LOGICAL_MAXIMUM(1, 3),
5279 PHYSICAL_MINIMUM(1, 1),
5280 PHYSICAL_MAXIMUM(1, 3),
5283 FEATURE(1, Data
|Ary
|Abs
),
5286 USAGE(1, PID_USAGE_RAM_POOL_AVAILABLE
),
5287 LOGICAL_MINIMUM(1, 0),
5288 LOGICAL_MAXIMUM(4, 0xffff),
5289 PHYSICAL_MINIMUM(1, 0),
5290 PHYSICAL_MAXIMUM(4, 0xffff),
5293 FEATURE(1, Data
|Var
|Abs
),
5297 C_ASSERT(sizeof(report_desc
) < MAX_HID_DESCRIPTOR_LEN
);
5298 #include "pop_hid_macros.h"
5300 struct hid_device_desc desc
=
5302 .use_report_id
= TRUE
,
5305 .InputReportByteLength
= 6,
5306 .OutputReportByteLength
= 18,
5307 .FeatureReportByteLength
= 5,
5309 .attributes
= default_attributes
,
5311 struct hid_expect expect_init
[] =
5315 .code
= IOCTL_HID_GET_FEATURE
,
5318 .report_buf
= {1,0xff,0x7f,0x7f,0x03},
5322 struct hid_expect expect_acquire
[] =
5326 .code
= IOCTL_HID_GET_FEATURE
,
5329 .report_buf
= {1,0xff,0x7f,0x7f,0x03},
5332 /* device control */
5334 .code
= IOCTL_HID_WRITE_REPORT
,
5337 .report_buf
= {1, 0x06},
5340 /* device control */
5342 .code
= IOCTL_HID_WRITE_REPORT
,
5345 .report_buf
= {1, 0x05},
5348 /* device control */
5350 .code
= IOCTL_HID_WRITE_REPORT
,
5353 .report_buf
= {1, 0x01},
5357 .code
= IOCTL_HID_WRITE_REPORT
,
5360 .report_buf
= {6, 0xff},
5363 static struct hid_expect expect_set_gain
=
5365 .code
= IOCTL_HID_WRITE_REPORT
,
5368 .report_buf
= {6, 0x7f},
5370 static struct hid_expect expect_pause
=
5372 .code
= IOCTL_HID_WRITE_REPORT
,
5375 .report_buf
= {1, 0x02},
5377 static struct hid_expect expect_resume
=
5379 .code
= IOCTL_HID_WRITE_REPORT
,
5382 .report_buf
= {1, 0x03},
5384 static struct hid_expect expect_stop
=
5386 .code
= IOCTL_HID_WRITE_REPORT
,
5389 .report_buf
= {1, 0x06},
5391 static struct hid_expect expect_disable
=
5393 .code
= IOCTL_HID_WRITE_REPORT
,
5396 .report_buf
= {1, 0x05},
5398 static struct hid_expect expect_enable
=
5400 .code
= IOCTL_HID_WRITE_REPORT
,
5403 .report_buf
= {1, 0x04},
5405 static struct hid_expect expect_enable_fail
=
5407 .code
= IOCTL_HID_WRITE_REPORT
,
5408 .ret_status
= STATUS_NOT_SUPPORTED
,
5411 .report_buf
= {1, 0x04},
5413 static struct hid_expect expect_reset_delay
[] =
5415 /* device control */
5417 .code
= IOCTL_HID_WRITE_REPORT
,
5418 .ret_status
= STATUS_PENDING
,
5421 .report_buf
= {1, 0x01},
5425 .code
= IOCTL_HID_WRITE_REPORT
,
5428 .report_buf
= {6, 0x7f},
5431 struct hid_expect expect_reset
[] =
5433 /* device control */
5435 .code
= IOCTL_HID_WRITE_REPORT
,
5438 .report_buf
= {1, 0x01},
5442 .code
= IOCTL_HID_WRITE_REPORT
,
5445 .report_buf
= {6, 0x7f},
5448 struct hid_expect expect_create_periodic
[] =
5450 /* create new effect */
5452 .code
= IOCTL_HID_SET_FEATURE
,
5455 .report_buf
= {2,0x02,0x00},
5459 .code
= IOCTL_HID_GET_FEATURE
,
5462 .report_buf
= {3,0x01,0x01,0x00,0x00},
5466 .code
= IOCTL_HID_WRITE_REPORT
,
5469 .report_buf
= {7,0x01,0xa0,0x0f,0xd0,0x07,0x70,0xff,0x0a,0x00},
5473 .code
= IOCTL_HID_WRITE_REPORT
,
5476 .report_buf
= {8,0x01,0x4c,0x7f,0x28,0x00,0x50,0x00},
5480 .code
= IOCTL_HID_WRITE_REPORT
,
5483 .report_buf
= {3,0x01,0x02,0x08,0x78,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0xff,0xff,0x4e,0x01,0x00,0x00},
5486 struct hid_expect expect_create_condition
[] =
5488 /* create new effect */
5490 .code
= IOCTL_HID_SET_FEATURE
,
5493 .report_buf
= {2,0x03,0x00},
5497 .code
= IOCTL_HID_GET_FEATURE
,
5500 .report_buf
= {3,0x01,0x01,0x00,0x00},
5504 .code
= IOCTL_HID_WRITE_REPORT
,
5507 .report_buf
= {4,0x01,0x00,0x70,0x17,0x7b,0x02,0xe9,0x04,0x4c,0x66,0x7f},
5511 .code
= IOCTL_HID_WRITE_REPORT
,
5514 .report_buf
= {3,0x01,0x03,0x08,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x00,0x00,0x00},
5517 struct hid_expect expect_create_constant
[] =
5519 /* create new effect */
5521 .code
= IOCTL_HID_SET_FEATURE
,
5524 .report_buf
= {2,0x04,0x00},
5528 .code
= IOCTL_HID_GET_FEATURE
,
5531 .report_buf
= {3,0x01,0x01,0x00,0x00},
5535 .code
= IOCTL_HID_WRITE_REPORT
,
5538 .report_buf
= {9,0x01,0xc8,0x00},
5542 .code
= IOCTL_HID_WRITE_REPORT
,
5545 .report_buf
= {8,0x01,0x19,0x4c,0x14,0x00,0x3c,0x00},
5549 .code
= IOCTL_HID_WRITE_REPORT
,
5552 .report_buf
= {3,0x01,0x04,0x08,0x5a,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0xff,0x7f,0x4e,0x01,0x00,0x00},
5555 struct hid_expect expect_create_ramp
[] =
5557 /* create new effect */
5559 .code
= IOCTL_HID_SET_FEATURE
,
5562 .report_buf
= {2,0x05,0x00},
5566 .code
= IOCTL_HID_GET_FEATURE
,
5569 .report_buf
= {3,0x01,0x01,0x00,0x00},
5573 .code
= IOCTL_HID_WRITE_REPORT
,
5576 .report_buf
= {10,0x01,0xc8,0x00,0x20,0x03},
5580 .code
= IOCTL_HID_WRITE_REPORT
,
5583 .report_buf
= {8,0x01,0x19,0x4c,0x14,0x00,0x3c,0x00},
5587 .code
= IOCTL_HID_WRITE_REPORT
,
5590 .report_buf
= {3,0x01,0x05,0x08,0x5a,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0xff,0xff,0x4e,0x01,0x00,0x00},
5593 struct hid_expect expect_effect_start
=
5595 .code
= IOCTL_HID_WRITE_REPORT
,
5598 .report_buf
= {2,0x01,0x01,0x01},
5601 struct hid_expect expect_effect_stop
=
5603 .code
= IOCTL_HID_WRITE_REPORT
,
5606 .report_buf
= {2,0x01,0x03,0x00},
5609 struct hid_expect expect_unload
[] =
5613 .code
= IOCTL_HID_WRITE_REPORT
,
5616 .report_buf
= {2,0x01,0x03,0x00},
5620 .code
= IOCTL_HID_WRITE_REPORT
,
5623 .report_buf
= {5,0x01},
5626 static const WCHAR
*condition_effect_class_name
= RuntimeClass_Windows_Gaming_Input_ForceFeedback_ConditionForceEffect
;
5627 static const WCHAR
*periodic_effect_class_name
= RuntimeClass_Windows_Gaming_Input_ForceFeedback_PeriodicForceEffect
;
5628 static const WCHAR
*constant_effect_class_name
= RuntimeClass_Windows_Gaming_Input_ForceFeedback_ConstantForceEffect
;
5629 static const WCHAR
*force_feedback_motor
= RuntimeClass_Windows_Gaming_Input_ForceFeedback_ForceFeedbackMotor
;
5630 static const WCHAR
*ramp_effect_class_name
= RuntimeClass_Windows_Gaming_Input_ForceFeedback_RampForceEffect
;
5631 static const WCHAR
*controller_class_name
= RuntimeClass_Windows_Gaming_Input_RawGameController
;
5633 DIPROPGUIDANDPATH guid_path
=
5637 .dwSize
= sizeof(DIPROPGUIDANDPATH
),
5638 .dwHeaderSize
= sizeof(DIPROPHEADER
),
5639 .dwHow
= DIPH_DEVICE
,
5642 TimeSpan delay
= {100000}, attack_duration
= {200000}, release_duration
= {300000}, duration
= {400000};
5643 Vector3 direction
= {0.1, 0.2, 0.3}, end_direction
= {0.4, 0.5, 0.6};
5644 DIDEVICEINSTANCEW devinst
= {.dwSize
= sizeof(DIDEVICEINSTANCEW
)};
5645 IAsyncOperation_ForceFeedbackLoadEffectResult
*result_async
;
5646 IAsyncOperationCompletedHandler_boolean
*tmp_handler
;
5647 struct result_async_handler result_async_handler
;
5648 IVectorView_RawGameController
*controllers_view
;
5649 IConditionForceEffectFactory
*condition_factory
;
5650 IRawGameControllerStatics
*controller_statics
;
5651 EventRegistrationToken controller_added_token
;
5652 IPeriodicForceEffectFactory
*periodic_factory
;
5653 struct bool_async_handler bool_async_handler
;
5654 IVectorView_ForceFeedbackMotor
*motors_view
;
5655 IConditionForceEffect
*condition_effect
;
5656 ConditionForceEffectKind condition_kind
;
5657 ForceFeedbackEffectAxes supported_axes
;
5658 IActivationFactory
*activation_factory
;
5659 IPeriodicForceEffect
*periodic_effect
;
5660 IConstantForceEffect
*constant_effect
;
5661 PeriodicForceEffectKind periodic_kind
;
5662 IAsyncOperation_boolean
*bool_async
;
5663 IRawGameController
*raw_controller
;
5664 ForceFeedbackEffectState state
;
5665 IRampForceEffect
*ramp_effect
;
5666 IInspectable
*tmp_inspectable
;
5667 IForceFeedbackEffect
*effect
;
5668 IDirectInputDevice8W
*device
;
5669 IForceFeedbackMotor
*motor
;
5670 BOOLEAN paused
, enabled
;
5671 IAsyncInfo
*async_info
;
5680 if (!load_combase_functions()) return;
5682 cleanup_registry_keys();
5684 hr
= pRoInitialize( RO_INIT_MULTITHREADED
);
5685 ok( hr
== RPC_E_CHANGED_MODE
, "RoInitialize returned %#lx\n", hr
);
5687 hr
= pWindowsCreateString( controller_class_name
, wcslen( controller_class_name
), &str
);
5688 ok( hr
== S_OK
, "WindowsCreateString returned %#lx\n", hr
);
5689 hr
= pRoGetActivationFactory( str
, &IID_IRawGameControllerStatics
, (void **)&controller_statics
);
5690 ok( hr
== S_OK
|| broken( hr
== REGDB_E_CLASSNOTREG
), "RoGetActivationFactory returned %#lx\n", hr
);
5691 pWindowsDeleteString( str
);
5693 if (hr
== REGDB_E_CLASSNOTREG
)
5695 win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( controller_class_name
) );
5699 controller_added
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
5700 ok( !!controller_added
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
5702 hr
= IRawGameControllerStatics_add_RawGameControllerAdded( controller_statics
, &controller_added
.IEventHandler_RawGameController_iface
,
5703 &controller_added_token
);
5704 ok( hr
== S_OK
, "add_RawGameControllerAdded returned %#lx\n", hr
);
5705 ok( controller_added_token
.value
, "got token %I64u\n", controller_added_token
.value
);
5707 desc
.report_descriptor_len
= sizeof(report_desc
);
5708 memcpy( desc
.report_descriptor_buf
, report_desc
, sizeof(report_desc
) );
5709 desc
.expect_size
= sizeof(expect_init
);
5710 memcpy( desc
.expect
, expect_init
, sizeof(expect_init
) );
5711 fill_context( __LINE__
, desc
.context
, ARRAY_SIZE(desc
.context
) );
5713 if (!hid_device_start( &desc
)) goto done
;
5714 WaitForSingleObject( controller_added
.event
, INFINITE
);
5715 CloseHandle( controller_added
.event
);
5717 if (FAILED(hr
= dinput_test_create_device( 0x800, &devinst
, &device
))) goto done
;
5718 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GUIDANDPATH
, &guid_path
.diph
);
5719 ok( hr
== DI_OK
, "GetProperty DIPROP_GUIDANDPATH returned %#lx\n", hr
);
5720 IDirectInputDevice8_Release( device
);
5722 file
= CreateFileW( guid_path
.wszPath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
5723 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
5724 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
5725 ok( file
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError() );
5727 hr
= IRawGameControllerStatics_remove_RawGameControllerAdded( controller_statics
, controller_added_token
);
5728 ok( hr
== S_OK
, "remove_RawGameControllerAdded returned %#lx\n", hr
);
5730 hr
= IRawGameControllerStatics_get_RawGameControllers( controller_statics
, &controllers_view
);
5731 ok( hr
== S_OK
, "get_RawGameControllers returned %#lx\n", hr
);
5732 hr
= IVectorView_RawGameController_get_Size( controllers_view
, &size
);
5733 ok( hr
== S_OK
, "get_Size returned %#lx\n", hr
);
5734 ok( size
== 1, "got size %u\n", size
);
5735 hr
= IVectorView_RawGameController_GetAt( controllers_view
, 0, &raw_controller
);
5736 ok( hr
== S_OK
, "GetAt returned %#lx\n", hr
);
5737 IVectorView_RawGameController_Release( controllers_view
);
5739 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
5740 hr
= IRawGameController_get_ForceFeedbackMotors( raw_controller
, &motors_view
);
5741 ok( hr
== S_OK
, "get_ForceFeedbackMotors returned %#lx\n", hr
);
5742 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
5744 hr
= IVectorView_ForceFeedbackMotor_get_Size( motors_view
, &size
);
5745 ok( hr
== S_OK
, "get_Size returned %#lx\n", hr
);
5746 ok( size
== 1, "got size %u\n", size
);
5747 hr
= IVectorView_ForceFeedbackMotor_GetAt( motors_view
, 0, &motor
);
5748 ok( hr
== S_OK
, "GetAt returned %#lx\n", hr
);
5749 IVectorView_ForceFeedbackMotor_Release( motors_view
);
5751 check_interface( motor
, &IID_IUnknown
, TRUE
);
5752 check_interface( motor
, &IID_IInspectable
, TRUE
);
5753 check_interface( motor
, &IID_IAgileObject
, TRUE
);
5754 check_interface( motor
, &IID_IForceFeedbackMotor
, TRUE
);
5755 check_runtimeclass( motor
, force_feedback_motor
);
5758 hr
= IForceFeedbackMotor_get_AreEffectsPaused( motor
, &paused
);
5759 ok( hr
== S_OK
, "get_AreEffectsPaused returned %#lx\n", hr
);
5760 ok( paused
== FALSE
, "got paused %u\n", paused
);
5763 hr
= IForceFeedbackMotor_get_MasterGain( motor
, &gain
);
5764 ok( hr
== S_OK
, "get_MasterGain returned %#lx\n", hr
);
5765 ok( gain
== 1.0, "got gain %f\n", gain
);
5766 set_hid_expect( file
, &expect_set_gain
, sizeof(expect_set_gain
) );
5767 hr
= IForceFeedbackMotor_put_MasterGain( motor
, 0.5 );
5768 ok( hr
== S_OK
, "put_MasterGain returned %#lx\n", hr
);
5769 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
5772 hr
= IForceFeedbackMotor_get_IsEnabled( motor
, &enabled
);
5773 ok( hr
== S_OK
, "get_IsEnabled returned %#lx\n", hr
);
5774 ok( enabled
== TRUE
, "got enabled %u\n", enabled
);
5776 supported_axes
= 0xdeadbeef;
5777 hr
= IForceFeedbackMotor_get_SupportedAxes( motor
, &supported_axes
);
5779 ok( hr
== S_OK
, "get_SupportedAxes returned %#lx\n", hr
);
5781 ok( supported_axes
== ForceFeedbackEffectAxes_X
, "got axes %#x\n", supported_axes
);
5783 set_hid_expect( file
, &expect_pause
, sizeof(expect_pause
) );
5784 hr
= IForceFeedbackMotor_PauseAllEffects( motor
);
5785 ok( hr
== S_OK
, "PauseAllEffects returned %#lx\n", hr
);
5786 set_hid_expect( file
, &expect_resume
, sizeof(expect_resume
) );
5787 hr
= IForceFeedbackMotor_ResumeAllEffects( motor
);
5788 ok( hr
== S_OK
, "ResumeAllEffects returned %#lx\n", hr
);
5789 set_hid_expect( file
, &expect_stop
, sizeof(expect_stop
) );
5790 hr
= IForceFeedbackMotor_StopAllEffects( motor
);
5791 ok( hr
== S_OK
, "StopAllEffects returned %#lx\n", hr
);
5792 set_hid_expect( file
, NULL
, 0 );
5795 set_hid_expect( file
, &expect_disable
, sizeof(expect_disable
) );
5796 hr
= IForceFeedbackMotor_TryDisableAsync( motor
, &bool_async
);
5797 ok( hr
== S_OK
, "TryDisableAsync returned %#lx\n", hr
);
5798 wait_hid_expect( file
, 100 );
5799 check_bool_async( bool_async
, 1, Completed
, S_OK
, TRUE
);
5801 check_interface( bool_async
, &IID_IUnknown
, TRUE
);
5802 check_interface( bool_async
, &IID_IInspectable
, TRUE
);
5803 check_interface( bool_async
, &IID_IAgileObject
, TRUE
);
5804 check_interface( bool_async
, &IID_IAsyncInfo
, TRUE
);
5805 check_interface( bool_async
, &IID_IAsyncOperation_boolean
, TRUE
);
5806 check_runtimeclass( bool_async
, L
"Windows.Foundation.IAsyncOperation`1<Boolean>" );
5808 hr
= IAsyncOperation_boolean_get_Completed( bool_async
, &tmp_handler
);
5809 ok( hr
== S_OK
, "get_Completed returned %#lx\n", hr
);
5810 ok( tmp_handler
== NULL
, "got handler %p\n", tmp_handler
);
5811 bool_async_handler
= default_bool_async_handler
;
5812 hr
= IAsyncOperation_boolean_put_Completed( bool_async
, &bool_async_handler
.IAsyncOperationCompletedHandler_boolean_iface
);
5813 ok( hr
== S_OK
, "put_Completed returned %#lx\n", hr
);
5814 ok( bool_async_handler
.invoked
, "handler not invoked\n" );
5815 ok( bool_async_handler
.async
== bool_async
, "got async %p\n", bool_async_handler
.async
);
5816 ok( bool_async_handler
.status
== Completed
, "got status %u\n", bool_async_handler
.status
);
5817 hr
= IAsyncOperation_boolean_get_Completed( bool_async
, &tmp_handler
);
5818 ok( hr
== S_OK
, "get_Completed returned %#lx\n", hr
);
5819 ok( tmp_handler
== NULL
, "got handler %p\n", tmp_handler
);
5820 bool_async_handler
= default_bool_async_handler
;
5821 hr
= IAsyncOperation_boolean_put_Completed( bool_async
, &bool_async_handler
.IAsyncOperationCompletedHandler_boolean_iface
);
5822 ok( hr
== E_ILLEGAL_DELEGATE_ASSIGNMENT
, "put_Completed returned %#lx\n", hr
);
5823 ok( !bool_async_handler
.invoked
, "handler invoked\n" );
5824 ok( bool_async_handler
.async
== NULL
, "got async %p\n", bool_async_handler
.async
);
5825 ok( bool_async_handler
.status
== Started
, "got status %u\n", bool_async_handler
.status
);
5827 hr
= IAsyncOperation_boolean_QueryInterface( bool_async
, &IID_IAsyncInfo
, (void **)&async_info
);
5828 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
5829 hr
= IAsyncInfo_Cancel( async_info
);
5830 ok( hr
== S_OK
, "Cancel returned %#lx\n", hr
);
5831 check_bool_async( bool_async
, 1, Completed
, S_OK
, TRUE
);
5832 hr
= IAsyncInfo_Close( async_info
);
5833 ok( hr
== S_OK
, "Close returned %#lx\n", hr
);
5834 check_bool_async( bool_async
, 1, 4, S_OK
, FALSE
);
5835 IAsyncInfo_Release( async_info
);
5837 IAsyncOperation_boolean_Release( bool_async
);
5840 set_hid_expect( file
, &expect_enable_fail
, sizeof(expect_enable_fail
) );
5841 hr
= IForceFeedbackMotor_TryEnableAsync( motor
, &bool_async
);
5842 ok( hr
== S_OK
, "TryEnableAsync returned %#lx\n", hr
);
5843 wait_hid_expect( file
, 100 );
5844 check_bool_async( bool_async
, 1, Error
, 0x8685400d, FALSE
);
5846 bool_async_handler
= default_bool_async_handler
;
5847 hr
= IAsyncOperation_boolean_put_Completed( bool_async
, &bool_async_handler
.IAsyncOperationCompletedHandler_boolean_iface
);
5848 ok( hr
== S_OK
, "put_Completed returned %#lx\n", hr
);
5849 ok( bool_async_handler
.invoked
, "handler not invoked\n" );
5850 ok( bool_async_handler
.async
== bool_async
, "got async %p\n", bool_async_handler
.async
);
5851 ok( bool_async_handler
.status
== Error
, "got status %u\n", bool_async_handler
.status
);
5853 hr
= IAsyncOperation_boolean_QueryInterface( bool_async
, &IID_IAsyncInfo
, (void **)&async_info
);
5854 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
5855 hr
= IAsyncInfo_Cancel( async_info
);
5856 ok( hr
== S_OK
, "Cancel returned %#lx\n", hr
);
5857 check_bool_async( bool_async
, 1, Error
, 0x8685400d, FALSE
);
5858 hr
= IAsyncInfo_Close( async_info
);
5859 ok( hr
== S_OK
, "Close returned %#lx\n", hr
);
5860 check_bool_async( bool_async
, 1, 4, 0x8685400d, FALSE
);
5861 IAsyncInfo_Release( async_info
);
5863 IAsyncOperation_boolean_Release( bool_async
);
5866 /* canceling the async op is just ignored */
5868 set_hid_expect( file
, expect_reset_delay
, sizeof(expect_reset_delay
) );
5869 hr
= IForceFeedbackMotor_TryResetAsync( motor
, &bool_async
);
5870 ok( hr
== S_OK
, "TryResetAsync returned %#lx\n", hr
);
5871 check_bool_async( bool_async
, 1, Started
, S_OK
, FALSE
);
5873 bool_async_handler
= default_bool_async_handler
;
5874 bool_async_handler
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
5875 ok( !!bool_async_handler
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
5877 hr
= IAsyncOperation_boolean_put_Completed( bool_async
, &bool_async_handler
.IAsyncOperationCompletedHandler_boolean_iface
);
5878 ok( hr
== S_OK
, "put_Completed returned %#lx\n", hr
);
5879 ok( !bool_async_handler
.invoked
, "handler invoked\n" );
5880 hr
= IAsyncOperation_boolean_get_Completed( bool_async
, &tmp_handler
);
5881 ok( hr
== S_OK
, "get_Completed returned %#lx\n", hr
);
5882 ok( tmp_handler
== &bool_async_handler
.IAsyncOperationCompletedHandler_boolean_iface
,
5883 "got handler %p\n", tmp_handler
);
5885 hr
= IAsyncOperation_boolean_QueryInterface( bool_async
, &IID_IAsyncInfo
, (void **)&async_info
);
5886 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
5887 hr
= IAsyncInfo_Cancel( async_info
);
5888 ok( hr
== S_OK
, "Cancel returned %#lx\n", hr
);
5889 check_bool_async( bool_async
, 1, Canceled
, S_OK
, FALSE
);
5890 ok( !bool_async_handler
.invoked
, "handler invoked\n" );
5891 IAsyncInfo_Release( async_info
);
5893 wait_hid_pending( file
, 100 );
5894 ret
= WaitForSingleObject( bool_async_handler
.event
, 500 );
5895 ok( ret
== 0, "WaitForSingleObject returned %#lx\n", ret
);
5896 CloseHandle( bool_async_handler
.event
);
5897 check_bool_async( bool_async
, 1, Completed
, S_OK
, TRUE
);
5899 ok( bool_async_handler
.invoked
, "handler not invoked\n" );
5900 ok( bool_async_handler
.async
== bool_async
, "got async %p\n", bool_async_handler
.async
);
5901 ok( bool_async_handler
.status
== Completed
, "got status %u\n", bool_async_handler
.status
);
5902 hr
= IAsyncOperation_boolean_get_Completed( bool_async
, &tmp_handler
);
5903 ok( hr
== S_OK
, "get_Completed returned %#lx\n", hr
);
5904 ok( tmp_handler
== NULL
, "got handler %p\n", tmp_handler
);
5906 IAsyncOperation_boolean_Release( bool_async
);
5909 /* canceling then closing it calls the handler with closed state */
5911 set_hid_expect( file
, expect_reset_delay
, sizeof(expect_reset_delay
) );
5912 hr
= IForceFeedbackMotor_TryResetAsync( motor
, &bool_async
);
5913 ok( hr
== S_OK
, "TryResetAsync returned %#lx\n", hr
);
5914 check_bool_async( bool_async
, 1, Started
, S_OK
, FALSE
);
5916 bool_async_handler
= default_bool_async_handler
;
5917 bool_async_handler
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
5918 ok( !!bool_async_handler
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
5920 hr
= IAsyncOperation_boolean_put_Completed( bool_async
, &bool_async_handler
.IAsyncOperationCompletedHandler_boolean_iface
);
5921 ok( hr
== S_OK
, "put_Completed returned %#lx\n", hr
);
5922 ok( !bool_async_handler
.invoked
, "handler invoked\n" );
5924 hr
= IAsyncOperation_boolean_QueryInterface( bool_async
, &IID_IAsyncInfo
, (void **)&async_info
);
5925 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
5926 hr
= IAsyncInfo_Close( async_info
);
5927 ok( hr
== E_ILLEGAL_STATE_CHANGE
, "Close returned %#lx\n", hr
);
5928 hr
= IAsyncInfo_Cancel( async_info
);
5929 ok( hr
== S_OK
, "Cancel returned %#lx\n", hr
);
5930 check_bool_async( bool_async
, 1, Canceled
, S_OK
, FALSE
);
5931 ok( !bool_async_handler
.invoked
, "handler invoked\n" );
5932 hr
= IAsyncInfo_Close( async_info
);
5933 ok( hr
== S_OK
, "Close returned %#lx\n", hr
);
5934 check_bool_async( bool_async
, 1, 4, S_OK
, FALSE
);
5935 ok( !bool_async_handler
.invoked
, "handler invoked\n" );
5936 IAsyncInfo_Release( async_info
);
5938 wait_hid_pending( file
, 100 );
5939 ret
= WaitForSingleObject( bool_async_handler
.event
, 500 );
5940 ok( ret
== 0, "WaitForSingleObject returned %#lx\n", ret
);
5941 CloseHandle( bool_async_handler
.event
);
5942 check_bool_async( bool_async
, 1, 4, S_OK
, FALSE
);
5944 ok( bool_async_handler
.invoked
, "handler not invoked\n" );
5945 ok( bool_async_handler
.async
== bool_async
, "got async %p\n", bool_async_handler
.async
);
5946 ok( bool_async_handler
.status
== 4, "got status %u\n", bool_async_handler
.status
);
5947 hr
= IAsyncOperation_boolean_get_Completed( bool_async
, &tmp_handler
);
5948 ok( hr
== E_ILLEGAL_METHOD_CALL
, "get_Completed returned %#lx\n", hr
);
5950 IAsyncOperation_boolean_Release( bool_async
);
5953 set_hid_expect( file
, &expect_enable
, sizeof(expect_enable
) );
5954 hr
= IForceFeedbackMotor_TryEnableAsync( motor
, &bool_async
);
5955 ok( hr
== S_OK
, "TryEnableAsync returned %#lx\n", hr
);
5956 wait_hid_expect( file
, 100 );
5957 IAsyncOperation_boolean_Release( bool_async
);
5960 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
5961 hr
= IForceFeedbackMotor_TryResetAsync( motor
, &bool_async
);
5962 ok( hr
== S_OK
, "TryResetAsync returned %#lx\n", hr
);
5963 wait_hid_expect( file
, 100 );
5964 IAsyncOperation_boolean_Release( bool_async
);
5967 hr
= pWindowsCreateString( force_feedback_motor
, wcslen( force_feedback_motor
), &str
);
5968 ok( hr
== S_OK
, "WindowsCreateString returned %#lx\n", hr
);
5969 hr
= pRoGetActivationFactory( str
, &IID_IInspectable
, (void **)&tmp_inspectable
);
5970 ok( hr
== REGDB_E_CLASSNOTREG
, "RoGetActivationFactory returned %#lx\n", hr
);
5971 pWindowsDeleteString( str
);
5974 hr
= pWindowsCreateString( periodic_effect_class_name
, wcslen( periodic_effect_class_name
), &str
);
5975 ok( hr
== S_OK
, "WindowsCreateString returned %#lx\n", hr
);
5976 hr
= pRoGetActivationFactory( str
, &IID_IPeriodicForceEffectFactory
, (void **)&periodic_factory
);
5977 ok( hr
== S_OK
, "RoGetActivationFactory returned %#lx\n", hr
);
5978 pWindowsDeleteString( str
);
5980 check_interface( periodic_factory
, &IID_IUnknown
, TRUE
);
5981 check_interface( periodic_factory
, &IID_IInspectable
, TRUE
);
5982 check_interface( periodic_factory
, &IID_IAgileObject
, TRUE
);
5983 check_interface( periodic_factory
, &IID_IActivationFactory
, TRUE
);
5984 check_interface( periodic_factory
, &IID_IPeriodicForceEffectFactory
, TRUE
);
5985 check_interface( periodic_factory
, &IID_IConditionForceEffectFactory
, FALSE
);
5987 hr
= IPeriodicForceEffectFactory_QueryInterface( periodic_factory
, &IID_IActivationFactory
, (void **)&activation_factory
);
5988 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
5989 hr
= IActivationFactory_ActivateInstance( activation_factory
, &tmp_inspectable
);
5990 ok( hr
== E_NOTIMPL
, "ActivateInstance returned %#lx\n", hr
);
5991 IActivationFactory_Release( activation_factory
);
5993 hr
= IPeriodicForceEffectFactory_CreateInstance( periodic_factory
, PeriodicForceEffectKind_SawtoothWaveUp
, &effect
);
5994 ok( hr
== S_OK
, "CreateInstance returned %#lx\n", hr
);
5996 check_interface( effect
, &IID_IUnknown
, TRUE
);
5997 check_interface( effect
, &IID_IInspectable
, TRUE
);
5998 check_interface( effect
, &IID_IAgileObject
, TRUE
);
5999 check_interface( effect
, &IID_IForceFeedbackEffect
, TRUE
);
6000 check_interface( effect
, &IID_IPeriodicForceEffect
, TRUE
);
6001 check_interface( effect
, &IID_IConditionForceEffect
, FALSE
);
6002 check_runtimeclass( effect
, periodic_effect_class_name
);
6004 hr
= IForceFeedbackEffect_QueryInterface( effect
, &IID_IPeriodicForceEffect
, (void **)&periodic_effect
);
6005 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
6007 hr
= IPeriodicForceEffect_get_Kind( periodic_effect
, &periodic_kind
);
6008 ok( hr
== S_OK
, "get_Kind returned %#lx\n", hr
);
6009 ok( periodic_kind
== PeriodicForceEffectKind_SawtoothWaveUp
, "got kind %u\n", periodic_kind
);
6010 hr
= IPeriodicForceEffect_SetParameters( periodic_effect
, direction
, 1.0, 0.1, 0.0, duration
);
6011 ok( hr
== S_OK
, "SetParameters returned %#lx\n", hr
);
6012 hr
= IPeriodicForceEffect_SetParametersWithEnvelope( periodic_effect
, direction
, 100.0, 0.1, 0.2, 0.3, 0.4, 0.5,
6013 delay
, attack_duration
, duration
, release_duration
, 1 );
6014 ok( hr
== S_OK
, "SetParametersWithEnvelope returned %#lx\n", hr
);
6015 IPeriodicForceEffect_Release( periodic_effect
);
6018 hr
= IForceFeedbackEffect_get_Gain( effect
, &gain
);
6019 ok( hr
== S_OK
, "get_Gain returned %#lx\n", hr
);
6020 ok( gain
== 1.0, "got gain %f\n", gain
);
6021 hr
= IForceFeedbackEffect_put_Gain( effect
, 0.5 );
6022 ok( hr
== S_FALSE
, "put_Gain returned %#lx\n", hr
);
6024 hr
= IForceFeedbackEffect_get_State( effect
, &state
);
6026 ok( hr
== S_OK
, "get_State returned %#lx\n", hr
);
6028 ok( state
== ForceFeedbackEffectState_Stopped
, "got state %#x\n", state
);
6029 hr
= IForceFeedbackEffect_Start( effect
);
6031 ok( hr
== 0x86854003, "Start returned %#lx\n", hr
);
6032 hr
= IForceFeedbackEffect_Stop( effect
);
6034 ok( hr
== 0x86854003, "Stop returned %#lx\n", hr
);
6036 hr
= IForceFeedbackMotor_LoadEffectAsync( motor
, effect
, &result_async
);
6037 ok( hr
== S_OK
, "LoadEffectAsync returned %#lx\n", hr
);
6038 result_async_handler
= default_result_async_handler
;
6039 result_async_handler
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
6040 ok( !!result_async_handler
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
6041 hr
= IAsyncOperation_ForceFeedbackLoadEffectResult_put_Completed( result_async
, &result_async_handler
.IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface
);
6042 ok( hr
== S_OK
, "put_Completed returned %#lx\n", hr
);
6043 ret
= WaitForSingleObject( result_async_handler
.event
, 5000 );
6044 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
6045 ret
= CloseHandle( result_async_handler
.event
);
6046 ok( ret
, "CloseHandle failed, error %lu\n", GetLastError() );
6047 check_result_async( result_async
, 1, Error
, 0x86854008, ForceFeedbackLoadEffectResult_EffectNotSupported
);
6048 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async
);
6050 hr
= IForceFeedbackEffect_Start( effect
);
6052 ok( hr
== 0x86854003, "Start returned %#lx\n", hr
);
6053 hr
= IForceFeedbackEffect_Stop( effect
);
6055 ok( hr
== 0x86854003, "Stop returned %#lx\n", hr
);
6056 hr
= IForceFeedbackMotor_TryUnloadEffectAsync( motor
, effect
, &bool_async
);
6058 ok( hr
== 0x86854003, "TryUnloadEffectAsync returned %#lx\n", hr
);
6060 ref
= IForceFeedbackEffect_Release( effect
);
6061 ok( ref
== 0, "Release returned %lu\n", ref
);
6064 hr
= IPeriodicForceEffectFactory_CreateInstance( periodic_factory
, PeriodicForceEffectKind_SineWave
, &effect
);
6065 ok( hr
== S_OK
, "CreateInstance returned %#lx\n", hr
);
6067 check_interface( effect
, &IID_IUnknown
, TRUE
);
6068 check_interface( effect
, &IID_IInspectable
, TRUE
);
6069 check_interface( effect
, &IID_IAgileObject
, TRUE
);
6070 check_interface( effect
, &IID_IForceFeedbackEffect
, TRUE
);
6071 check_interface( effect
, &IID_IPeriodicForceEffect
, TRUE
);
6072 check_interface( effect
, &IID_IConditionForceEffect
, FALSE
);
6073 check_runtimeclass( effect
, periodic_effect_class_name
);
6075 hr
= IForceFeedbackEffect_QueryInterface( effect
, &IID_IPeriodicForceEffect
, (void **)&periodic_effect
);
6076 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
6078 hr
= IPeriodicForceEffect_get_Kind( periodic_effect
, &periodic_kind
);
6079 ok( hr
== S_OK
, "get_Kind returned %#lx\n", hr
);
6080 ok( periodic_kind
== PeriodicForceEffectKind_SineWave
, "got kind %u\n", periodic_kind
);
6081 hr
= IPeriodicForceEffect_SetParameters( periodic_effect
, direction
, 1.0, 0.1, 0.0, duration
);
6082 ok( hr
== S_OK
, "SetParameters returned %#lx\n", hr
);
6083 hr
= IPeriodicForceEffect_SetParametersWithEnvelope( periodic_effect
, direction
, 100.0, 0.1, 0.2, 0.3, 0.4, 0.5,
6084 delay
, duration
, duration
, duration
, 1 );
6085 ok( hr
== S_OK
, "SetParametersWithEnvelope returned %#lx\n", hr
);
6086 IPeriodicForceEffect_Release( periodic_effect
);
6088 set_hid_expect( file
, expect_create_periodic
, sizeof(expect_create_periodic
) );
6089 hr
= IForceFeedbackMotor_LoadEffectAsync( motor
, effect
, &result_async
);
6090 ok( hr
== S_OK
, "LoadEffectAsync returned %#lx\n", hr
);
6091 result_async_handler
= default_result_async_handler
;
6092 result_async_handler
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
6093 ok( !!result_async_handler
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
6094 hr
= IAsyncOperation_ForceFeedbackLoadEffectResult_put_Completed( result_async
, &result_async_handler
.IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface
);
6095 ok( hr
== S_OK
, "put_Completed returned %#lx\n", hr
);
6096 ret
= WaitForSingleObject( result_async_handler
.event
, 5000 );
6097 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
6098 ret
= CloseHandle( result_async_handler
.event
);
6099 ok( ret
, "CloseHandle failed, error %lu\n", GetLastError() );
6100 check_result_async( result_async
, 1, Completed
, S_OK
, ForceFeedbackLoadEffectResult_Succeeded
);
6101 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async
);
6102 set_hid_expect( file
, NULL
, 0 );
6104 set_hid_expect( file
, &expect_effect_start
, sizeof(expect_effect_start
) );
6105 hr
= IForceFeedbackEffect_Start( effect
);
6107 ok( hr
== S_OK
, "Start returned %#lx\n", hr
);
6108 set_hid_expect( file
, &expect_effect_start
, sizeof(expect_effect_start
) );
6109 hr
= IForceFeedbackEffect_Start( effect
);
6111 ok( hr
== S_OK
, "Start returned %#lx\n", hr
);
6113 set_hid_expect( file
, &expect_effect_stop
, sizeof(expect_effect_stop
) );
6114 hr
= IForceFeedbackEffect_Stop( effect
);
6116 ok( hr
== S_OK
, "Stop returned %#lx\n", hr
);
6117 set_hid_expect( file
, &expect_effect_stop
, sizeof(expect_effect_stop
) );
6118 hr
= IForceFeedbackEffect_Stop( effect
);
6120 ok( hr
== S_OK
, "Stop returned %#lx\n", hr
);
6122 set_hid_expect( file
, expect_unload
, sizeof(expect_unload
) );
6123 hr
= IForceFeedbackMotor_TryUnloadEffectAsync( motor
, effect
, &bool_async
);
6124 ok( hr
== S_OK
, "TryUnloadEffectAsync returned %#lx\n", hr
);
6125 bool_async_handler
= default_bool_async_handler
;
6126 bool_async_handler
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
6127 ok( !!bool_async_handler
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
6128 hr
= IAsyncOperation_boolean_put_Completed( bool_async
, &bool_async_handler
.IAsyncOperationCompletedHandler_boolean_iface
);
6129 ok( hr
== S_OK
, "put_Completed returned %#lx\n", hr
);
6130 ret
= WaitForSingleObject( bool_async_handler
.event
, 5000 );
6131 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
6132 ret
= CloseHandle( bool_async_handler
.event
);
6133 ok( ret
, "CloseHandle failed, error %lu\n", GetLastError() );
6134 check_bool_async( bool_async
, 1, Completed
, S_OK
, TRUE
);
6135 IAsyncOperation_boolean_Release( bool_async
);
6136 set_hid_expect( file
, NULL
, 0 );
6138 ref
= IForceFeedbackEffect_Release( effect
);
6139 ok( ref
== 0, "Release returned %lu\n", ref
);
6141 IPeriodicForceEffectFactory_Release( periodic_factory
);
6144 hr
= pWindowsCreateString( condition_effect_class_name
, wcslen( condition_effect_class_name
), &str
);
6145 ok( hr
== S_OK
, "WindowsCreateString returned %#lx\n", hr
);
6146 hr
= pRoGetActivationFactory( str
, &IID_IConditionForceEffectFactory
, (void **)&condition_factory
);
6147 ok( hr
== S_OK
, "RoGetActivationFactory returned %#lx\n", hr
);
6148 pWindowsDeleteString( str
);
6150 check_interface( condition_factory
, &IID_IUnknown
, TRUE
);
6151 check_interface( condition_factory
, &IID_IInspectable
, TRUE
);
6152 check_interface( condition_factory
, &IID_IAgileObject
, TRUE
);
6153 check_interface( condition_factory
, &IID_IActivationFactory
, TRUE
);
6154 check_interface( condition_factory
, &IID_IConditionForceEffectFactory
, TRUE
);
6155 check_interface( condition_factory
, &IID_IPeriodicForceEffectFactory
, FALSE
);
6157 hr
= IConditionForceEffectFactory_QueryInterface( condition_factory
, &IID_IActivationFactory
, (void **)&activation_factory
);
6158 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
6159 hr
= IActivationFactory_ActivateInstance( activation_factory
, &tmp_inspectable
);
6160 ok( hr
== E_NOTIMPL
, "ActivateInstance returned %#lx\n", hr
);
6161 IActivationFactory_Release( activation_factory
);
6164 hr
= IConditionForceEffectFactory_CreateInstance( condition_factory
, ConditionForceEffectKind_Spring
, &effect
);
6165 ok( hr
== S_OK
, "CreateInstance returned %#lx\n", hr
);
6167 check_interface( effect
, &IID_IUnknown
, TRUE
);
6168 check_interface( effect
, &IID_IInspectable
, TRUE
);
6169 check_interface( effect
, &IID_IAgileObject
, TRUE
);
6170 check_interface( effect
, &IID_IForceFeedbackEffect
, TRUE
);
6171 check_interface( effect
, &IID_IConditionForceEffect
, TRUE
);
6172 check_interface( effect
, &IID_IPeriodicForceEffect
, FALSE
);
6173 check_runtimeclass( effect
, condition_effect_class_name
);
6175 hr
= IForceFeedbackEffect_QueryInterface( effect
, &IID_IConditionForceEffect
, (void **)&condition_effect
);
6176 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
6178 hr
= IConditionForceEffect_get_Kind( condition_effect
, &condition_kind
);
6179 ok( hr
== S_OK
, "get_Kind returned %#lx\n", hr
);
6180 ok( condition_kind
== ConditionForceEffectKind_Spring
, "got kind %u\n", condition_kind
);
6181 hr
= IConditionForceEffect_SetParameters( condition_effect
, direction
, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6 );
6182 ok( hr
== S_OK
, "SetParameters returned %#lx\n", hr
);
6183 IConditionForceEffect_Release( condition_effect
);
6185 set_hid_expect( file
, expect_create_condition
, sizeof(expect_create_condition
) );
6186 hr
= IForceFeedbackMotor_LoadEffectAsync( motor
, effect
, &result_async
);
6187 ok( hr
== S_OK
, "LoadEffectAsync returned %#lx\n", hr
);
6188 result_async_handler
= default_result_async_handler
;
6189 result_async_handler
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
6190 ok( !!result_async_handler
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
6191 hr
= IAsyncOperation_ForceFeedbackLoadEffectResult_put_Completed( result_async
, &result_async_handler
.IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface
);
6192 ok( hr
== S_OK
, "put_Completed returned %#lx\n", hr
);
6193 ret
= WaitForSingleObject( result_async_handler
.event
, 5000 );
6194 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
6195 ret
= CloseHandle( result_async_handler
.event
);
6196 ok( ret
, "CloseHandle failed, error %lu\n", GetLastError() );
6197 check_result_async( result_async
, 1, Completed
, S_OK
, ForceFeedbackLoadEffectResult_Succeeded
);
6198 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async
);
6199 set_hid_expect( file
, NULL
, 0 );
6201 set_hid_expect( file
, &expect_effect_start
, sizeof(expect_effect_start
) );
6202 hr
= IForceFeedbackEffect_Start( effect
);
6204 ok( hr
== S_OK
, "Start returned %#lx\n", hr
);
6205 set_hid_expect( file
, &expect_effect_start
, sizeof(expect_effect_start
) );
6206 hr
= IForceFeedbackEffect_Start( effect
);
6208 ok( hr
== S_OK
, "Start returned %#lx\n", hr
);
6210 set_hid_expect( file
, &expect_effect_stop
, sizeof(expect_effect_stop
) );
6211 hr
= IForceFeedbackEffect_Stop( effect
);
6213 ok( hr
== S_OK
, "Stop returned %#lx\n", hr
);
6214 set_hid_expect( file
, &expect_effect_stop
, sizeof(expect_effect_stop
) );
6215 hr
= IForceFeedbackEffect_Stop( effect
);
6217 ok( hr
== S_OK
, "Stop returned %#lx\n", hr
);
6219 set_hid_expect( file
, expect_unload
, sizeof(expect_unload
) );
6220 hr
= IForceFeedbackMotor_TryUnloadEffectAsync( motor
, effect
, &bool_async
);
6221 ok( hr
== S_OK
, "TryUnloadEffectAsync returned %#lx\n", hr
);
6222 bool_async_handler
= default_bool_async_handler
;
6223 bool_async_handler
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
6224 ok( !!bool_async_handler
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
6225 hr
= IAsyncOperation_boolean_put_Completed( bool_async
, &bool_async_handler
.IAsyncOperationCompletedHandler_boolean_iface
);
6226 ok( hr
== S_OK
, "put_Completed returned %#lx\n", hr
);
6227 ret
= WaitForSingleObject( bool_async_handler
.event
, 5000 );
6228 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
6229 ret
= CloseHandle( bool_async_handler
.event
);
6230 ok( ret
, "CloseHandle failed, error %lu\n", GetLastError() );
6231 check_bool_async( bool_async
, 1, Completed
, S_OK
, TRUE
);
6232 IAsyncOperation_boolean_Release( bool_async
);
6233 set_hid_expect( file
, NULL
, 0 );
6235 ref
= IForceFeedbackEffect_Release( effect
);
6236 ok( ref
== 0, "Release returned %lu\n", ref
);
6238 IConditionForceEffectFactory_Release( condition_factory
);
6241 hr
= pWindowsCreateString( constant_effect_class_name
, wcslen( constant_effect_class_name
), &str
);
6242 ok( hr
== S_OK
, "WindowsCreateString returned %#lx\n", hr
);
6243 hr
= pRoGetActivationFactory( str
, &IID_IActivationFactory
, (void **)&activation_factory
);
6244 ok( hr
== S_OK
, "RoGetActivationFactory returned %#lx\n", hr
);
6245 pWindowsDeleteString( str
);
6247 hr
= IActivationFactory_ActivateInstance( activation_factory
, &tmp_inspectable
);
6248 ok( hr
== S_OK
, "ActivateInstance returned %#lx\n", hr
);
6249 IActivationFactory_Release( activation_factory
);
6251 hr
= IInspectable_QueryInterface( tmp_inspectable
, &IID_IForceFeedbackEffect
, (void **)&effect
);
6252 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
6253 IInspectable_Release( tmp_inspectable
);
6255 hr
= IForceFeedbackEffect_QueryInterface( effect
, &IID_IConstantForceEffect
, (void **)&constant_effect
);
6256 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
6258 hr
= IConstantForceEffect_SetParameters( constant_effect
, direction
, duration
);
6259 ok( hr
== S_OK
, "SetParameters returned %#lx\n", hr
);
6260 hr
= IConstantForceEffect_SetParametersWithEnvelope( constant_effect
, direction
, 0.1, 0.2, 0.3,
6261 delay
, attack_duration
, duration
, release_duration
, 1 );
6262 ok( hr
== S_OK
, "SetParametersWithEnvelope returned %#lx\n", hr
);
6263 IConstantForceEffect_Release( constant_effect
);
6266 hr
= IForceFeedbackEffect_get_Gain( effect
, &gain
);
6267 ok( hr
== S_OK
, "get_Gain returned %#lx\n", hr
);
6268 ok( gain
== 1.0, "get_MasterGain returned %f\n", gain
);
6269 hr
= IForceFeedbackEffect_put_Gain( effect
, 0.5 );
6270 ok( hr
== S_FALSE
, "put_Gain returned %#lx\n", hr
);
6272 hr
= IForceFeedbackEffect_get_State( effect
, &state
);
6274 ok( hr
== S_OK
, "get_State returned %#lx\n", hr
);
6276 ok( state
== ForceFeedbackEffectState_Stopped
, "get_State returned %#lx\n", hr
);
6277 hr
= IForceFeedbackEffect_Start( effect
);
6279 ok( hr
== 0x86854003, "Start returned %#lx\n", hr
);
6280 hr
= IForceFeedbackEffect_Stop( effect
);
6282 ok( hr
== 0x86854003, "Stop returned %#lx\n", hr
);
6284 set_hid_expect( file
, expect_create_constant
, sizeof(expect_create_constant
) );
6285 hr
= IForceFeedbackMotor_LoadEffectAsync( motor
, effect
, &result_async
);
6286 ok( hr
== S_OK
, "LoadEffectAsync returned %#lx\n", hr
);
6287 result_async_handler
= default_result_async_handler
;
6288 result_async_handler
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
6289 ok( !!result_async_handler
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
6290 hr
= IAsyncOperation_ForceFeedbackLoadEffectResult_put_Completed( result_async
, &result_async_handler
.IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface
);
6291 ok( hr
== S_OK
, "put_Completed returned %#lx\n", hr
);
6292 ret
= WaitForSingleObject( result_async_handler
.event
, 5000 );
6293 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
6294 ret
= CloseHandle( result_async_handler
.event
);
6295 ok( ret
, "CloseHandle failed, error %lu\n", GetLastError() );
6296 check_result_async( result_async
, 1, Completed
, S_OK
, ForceFeedbackLoadEffectResult_Succeeded
);
6297 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async
);
6298 set_hid_expect( file
, NULL
, 0 );
6300 set_hid_expect( file
, &expect_effect_start
, sizeof(expect_effect_start
) );
6301 hr
= IForceFeedbackEffect_Start( effect
);
6303 ok( hr
== S_OK
, "Start returned %#lx\n", hr
);
6304 set_hid_expect( file
, &expect_effect_start
, sizeof(expect_effect_start
) );
6305 hr
= IForceFeedbackEffect_Start( effect
);
6307 ok( hr
== S_OK
, "Start returned %#lx\n", hr
);
6309 set_hid_expect( file
, &expect_effect_stop
, sizeof(expect_effect_stop
) );
6310 hr
= IForceFeedbackEffect_Stop( effect
);
6312 ok( hr
== S_OK
, "Stop returned %#lx\n", hr
);
6313 set_hid_expect( file
, &expect_effect_stop
, sizeof(expect_effect_stop
) );
6314 hr
= IForceFeedbackEffect_Stop( effect
);
6316 ok( hr
== S_OK
, "Stop returned %#lx\n", hr
);
6318 set_hid_expect( file
, expect_unload
, sizeof(expect_unload
) );
6319 hr
= IForceFeedbackMotor_TryUnloadEffectAsync( motor
, effect
, &bool_async
);
6320 ok( hr
== S_OK
, "TryUnloadEffectAsync returned %#lx\n", hr
);
6321 bool_async_handler
= default_bool_async_handler
;
6322 bool_async_handler
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
6323 ok( !!bool_async_handler
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
6324 hr
= IAsyncOperation_boolean_put_Completed( bool_async
, &bool_async_handler
.IAsyncOperationCompletedHandler_boolean_iface
);
6325 ok( hr
== S_OK
, "put_Completed returned %#lx\n", hr
);
6326 ret
= WaitForSingleObject( bool_async_handler
.event
, 5000 );
6327 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
6328 ret
= CloseHandle( bool_async_handler
.event
);
6329 ok( ret
, "CloseHandle failed, error %lu\n", GetLastError() );
6330 check_bool_async( bool_async
, 1, Completed
, S_OK
, TRUE
);
6331 IAsyncOperation_boolean_Release( bool_async
);
6332 set_hid_expect( file
, NULL
, 0 );
6334 ref
= IForceFeedbackEffect_Release( effect
);
6335 ok( ref
== 0, "Release returned %lu\n", ref
);
6338 hr
= pWindowsCreateString( ramp_effect_class_name
, wcslen( ramp_effect_class_name
), &str
);
6339 ok( hr
== S_OK
, "WindowsCreateString returned %#lx\n", hr
);
6340 hr
= pRoGetActivationFactory( str
, &IID_IActivationFactory
, (void **)&activation_factory
);
6341 ok( hr
== S_OK
, "RoGetActivationFactory returned %#lx\n", hr
);
6342 pWindowsDeleteString( str
);
6344 hr
= IActivationFactory_ActivateInstance( activation_factory
, &tmp_inspectable
);
6345 ok( hr
== S_OK
, "ActivateInstance returned %#lx\n", hr
);
6346 IActivationFactory_Release( activation_factory
);
6348 hr
= IInspectable_QueryInterface( tmp_inspectable
, &IID_IForceFeedbackEffect
, (void **)&effect
);
6349 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
6350 IInspectable_Release( tmp_inspectable
);
6352 hr
= IForceFeedbackEffect_QueryInterface( effect
, &IID_IRampForceEffect
, (void **)&ramp_effect
);
6353 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
6355 hr
= IRampForceEffect_SetParameters( ramp_effect
, direction
, end_direction
, duration
);
6356 ok( hr
== S_OK
, "SetParameters returned %#lx\n", hr
);
6357 hr
= IRampForceEffect_SetParametersWithEnvelope( ramp_effect
, direction
, end_direction
, 0.1, 0.2, 0.3,
6358 delay
, attack_duration
, duration
, release_duration
, 1 );
6359 ok( hr
== S_OK
, "SetParametersWithEnvelope returned %#lx\n", hr
);
6360 IRampForceEffect_Release( ramp_effect
);
6362 set_hid_expect( file
, expect_create_ramp
, sizeof(expect_create_ramp
) );
6363 hr
= IForceFeedbackMotor_LoadEffectAsync( motor
, effect
, &result_async
);
6364 ok( hr
== S_OK
, "LoadEffectAsync returned %#lx\n", hr
);
6365 result_async_handler
= default_result_async_handler
;
6366 result_async_handler
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
6367 ok( !!result_async_handler
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
6368 hr
= IAsyncOperation_ForceFeedbackLoadEffectResult_put_Completed( result_async
, &result_async_handler
.IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface
);
6369 ok( hr
== S_OK
, "put_Completed returned %#lx\n", hr
);
6370 ret
= WaitForSingleObject( result_async_handler
.event
, 5000 );
6371 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
6372 ret
= CloseHandle( result_async_handler
.event
);
6373 ok( ret
, "CloseHandle failed, error %lu\n", GetLastError() );
6374 check_result_async( result_async
, 1, Completed
, S_OK
, ForceFeedbackLoadEffectResult_Succeeded
);
6375 IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async
);
6376 set_hid_expect( file
, NULL
, 0 );
6378 set_hid_expect( file
, &expect_effect_start
, sizeof(expect_effect_start
) );
6379 hr
= IForceFeedbackEffect_Start( effect
);
6381 ok( hr
== S_OK
, "Start returned %#lx\n", hr
);
6382 set_hid_expect( file
, &expect_effect_start
, sizeof(expect_effect_start
) );
6383 hr
= IForceFeedbackEffect_Start( effect
);
6385 ok( hr
== S_OK
, "Start returned %#lx\n", hr
);
6387 set_hid_expect( file
, &expect_effect_stop
, sizeof(expect_effect_stop
) );
6388 hr
= IForceFeedbackEffect_Stop( effect
);
6390 ok( hr
== S_OK
, "Stop returned %#lx\n", hr
);
6391 set_hid_expect( file
, &expect_effect_stop
, sizeof(expect_effect_stop
) );
6392 hr
= IForceFeedbackEffect_Stop( effect
);
6394 ok( hr
== S_OK
, "Stop returned %#lx\n", hr
);
6396 set_hid_expect( file
, expect_unload
, sizeof(expect_unload
) );
6397 hr
= IForceFeedbackMotor_TryUnloadEffectAsync( motor
, effect
, &bool_async
);
6398 ok( hr
== S_OK
, "TryUnloadEffectAsync returned %#lx\n", hr
);
6399 bool_async_handler
= default_bool_async_handler
;
6400 bool_async_handler
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
6401 ok( !!bool_async_handler
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
6402 hr
= IAsyncOperation_boolean_put_Completed( bool_async
, &bool_async_handler
.IAsyncOperationCompletedHandler_boolean_iface
);
6403 ok( hr
== S_OK
, "put_Completed returned %#lx\n", hr
);
6404 ret
= WaitForSingleObject( bool_async_handler
.event
, 5000 );
6405 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
6406 ret
= CloseHandle( bool_async_handler
.event
);
6407 ok( ret
, "CloseHandle failed, error %lu\n", GetLastError() );
6408 check_bool_async( bool_async
, 1, Completed
, S_OK
, TRUE
);
6409 IAsyncOperation_boolean_Release( bool_async
);
6410 set_hid_expect( file
, NULL
, 0 );
6412 ref
= IForceFeedbackEffect_Release( effect
);
6413 ok( ref
== 0, "Release returned %lu\n", ref
);
6416 IForceFeedbackMotor_Release( motor
);
6418 IRawGameController_Release( raw_controller
);
6420 CloseHandle( file
);
6421 IRawGameControllerStatics_Release( controller_statics
);
6424 hid_device_stop( &desc
);
6425 cleanup_registry_keys();
6428 START_TEST( force_feedback
)
6430 if (!dinput_test_init()) return;
6431 if (!bus_device_start()) goto done
;
6433 CoInitialize( NULL
);
6434 if (test_force_feedback_joystick( 0x800 ))
6436 test_force_feedback_joystick( 0x500 );
6437 test_force_feedback_joystick( 0x700 );
6438 test_device_managed_effect();
6439 test_windows_gaming_input();