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