2 * Copyright 2022 RĂ©mi Bernon for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define DIRECTINPUT_VERSION 0x0800
25 #define WIN32_NO_STATUS
36 #include "winstring.h"
40 #include "dinput_test.h"
42 #define WIDL_using_Windows_Foundation
43 #define WIDL_using_Windows_Foundation_Collections
44 #include "windows.foundation.h"
45 #define WIDL_using_Windows_Devices_Haptics
46 #define WIDL_using_Windows_Gaming_Input
47 #include "windows.gaming.input.h"
52 DEFINE_GUID(GUID_action_mapping_1
,0x00000001,0x0002,0x0003,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b);
53 DEFINE_GUID(GUID_action_mapping_2
,0x00010001,0x0002,0x0003,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b);
54 DEFINE_GUID(GUID_map_other_device
,0x00020001,0x0002,0x0003,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b);
56 static HRESULT (WINAPI
*pRoGetActivationFactory
)( HSTRING
, REFIID
, void** );
57 static HRESULT (WINAPI
*pRoInitialize
)( RO_INIT_TYPE
);
58 static HRESULT (WINAPI
*pWindowsCreateString
)( const WCHAR
*, UINT32
, HSTRING
* );
59 static HRESULT (WINAPI
*pWindowsDeleteString
)( HSTRING str
);
60 static const WCHAR
* (WINAPI
*pWindowsGetStringRawBuffer
)( HSTRING
, UINT32
* );
62 static BOOL
load_combase_functions(void)
64 HMODULE combase
= GetModuleHandleW( L
"combase.dll" );
66 #define LOAD_FUNC(m, f) if (!(p ## f = (void *)GetProcAddress( m, #f ))) goto failed;
67 LOAD_FUNC( combase
, RoGetActivationFactory
);
68 LOAD_FUNC( combase
, RoInitialize
);
69 LOAD_FUNC( combase
, WindowsCreateString
);
70 LOAD_FUNC( combase
, WindowsDeleteString
);
71 LOAD_FUNC( combase
, WindowsGetStringRawBuffer
);
77 win_skip("Failed to load combase.dll functions, skipping tests\n");
81 struct check_object_todo
92 struct check_objects_params
97 const DIDEVICEOBJECTINSTANCEW
*expect_objs
;
98 const struct check_object_todo
*todo_objs
;
102 #define check_object( a, b, c ) check_object_( __LINE__, a, b, c )
103 static void check_object_( int line
, const DIDEVICEOBJECTINSTANCEW
*actual
,
104 const DIDEVICEOBJECTINSTANCEW
*expected
,
105 const struct check_object_todo
*todo
)
107 static const struct check_object_todo todo_none
= {0};
108 if (!todo
) todo
= &todo_none
;
110 check_member_( __FILE__
, line
, *actual
, *expected
, "%lu", dwSize
);
111 todo_wine_if( todo
->guid
)
112 check_member_guid_( __FILE__
, line
, *actual
, *expected
, guidType
);
113 todo_wine_if( todo
->ofs
)
114 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwOfs
);
115 todo_wine_if( todo
->type
)
116 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwType
);
117 todo_wine_if( todo
->flags
)
118 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwFlags
);
119 if (!localized
) todo_wine_if( todo
->name
) check_member_wstr_( __FILE__
, line
, *actual
, *expected
, tszName
);
120 check_member_( __FILE__
, line
, *actual
, *expected
, "%lu", dwFFMaxForce
);
121 check_member_( __FILE__
, line
, *actual
, *expected
, "%lu", dwFFForceResolution
);
122 check_member_( __FILE__
, line
, *actual
, *expected
, "%u", wCollectionNumber
);
123 check_member_( __FILE__
, line
, *actual
, *expected
, "%u", wDesignatorIndex
);
124 todo_wine_if( todo
->usage_page
)
125 check_member_( __FILE__
, line
, *actual
, *expected
, "%#04x", wUsagePage
);
126 todo_wine_if( todo
->usage
)
127 check_member_( __FILE__
, line
, *actual
, *expected
, "%#04x", wUsage
);
128 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwDimension
);
129 check_member_( __FILE__
, line
, *actual
, *expected
, "%#04x", wExponent
);
130 check_member_( __FILE__
, line
, *actual
, *expected
, "%u", wReportId
);
133 static BOOL CALLBACK
check_objects( const DIDEVICEOBJECTINSTANCEW
*obj
, void *args
)
135 static const DIDEVICEOBJECTINSTANCEW unexpected_obj
= {0};
136 static const struct check_object_todo todo_none
= {0};
137 struct check_objects_params
*params
= args
;
138 const DIDEVICEOBJECTINSTANCEW
*exp
= params
->expect_objs
+ params
->index
;
139 const struct check_object_todo
*todo
;
141 if (!params
->todo_objs
) todo
= &todo_none
;
142 else todo
= params
->todo_objs
+ params
->index
;
144 todo_wine_if( params
->todo_extra
&& params
->index
>= params
->expect_count
)
145 ok( params
->index
< params
->expect_count
, "unexpected extra object\n" );
146 if (params
->index
>= params
->expect_count
) return DIENUM_STOP
;
148 winetest_push_context( "obj[%d]", params
->index
);
150 ok( params
->index
< params
->expect_count
, "unexpected extra object\n" );
151 if (params
->index
>= params
->expect_count
) exp
= &unexpected_obj
;
153 check_object( obj
, exp
, todo
);
155 winetest_pop_context();
158 return DIENUM_CONTINUE
;
161 static BOOL CALLBACK
check_object_count( const DIDEVICEOBJECTINSTANCEW
*obj
, void *args
)
165 return DIENUM_CONTINUE
;
168 struct check_effects_params
172 const DIEFFECTINFOW
*expect_effects
;
175 static BOOL CALLBACK
check_effects( const DIEFFECTINFOW
*effect
, void *args
)
177 static const DIEFFECTINFOW unexpected_effect
= {0};
178 struct check_effects_params
*params
= args
;
179 const DIEFFECTINFOW
*exp
= params
->expect_effects
+ params
->index
;
181 winetest_push_context( "effect[%d]", params
->index
);
183 ok( params
->index
< params
->expect_count
, "unexpected extra object\n" );
184 if (params
->index
>= params
->expect_count
) exp
= &unexpected_effect
;
186 check_member( *effect
, *exp
, "%lu", dwSize
);
187 check_member_guid( *effect
, *exp
, guid
);
188 check_member( *effect
, *exp
, "%#lx", dwEffType
);
189 check_member( *effect
, *exp
, "%#lx", dwStaticParams
);
190 check_member( *effect
, *exp
, "%#lx", dwDynamicParams
);
191 check_member_wstr( *effect
, *exp
, tszName
);
193 winetest_pop_context();
196 return DIENUM_CONTINUE
;
199 static BOOL CALLBACK
check_effect_count( const DIEFFECTINFOW
*effect
, void *args
)
203 return DIENUM_CONTINUE
;
206 static BOOL CALLBACK
check_no_created_effect_objects( IDirectInputEffect
*effect
, void *context
)
208 ok( 0, "unexpected effect %p\n", effect
);
209 return DIENUM_CONTINUE
;
212 #define check_diactionw( a, b ) check_diactionw_( __LINE__, a, b )
213 static void check_diactionw_( int line
, const DIACTIONW
*actual
, const DIACTIONW
*expected
)
215 check_member_( __FILE__
, line
, *actual
, *expected
, "%#Ix", uAppData
);
216 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwSemantic
);
217 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwFlags
);
218 if (actual
->lptszActionName
&& expected
->lptszActionName
)
219 check_member_wstr_( __FILE__
, line
, *actual
, *expected
, lptszActionName
);
221 check_member_( __FILE__
, line
, *actual
, *expected
, "%p", lptszActionName
);
222 check_member_guid_( __FILE__
, line
, *actual
, *expected
, guidInstance
);
223 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwObjID
);
224 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwHow
);
227 #define check_diactionformatw( a, b ) check_diactionformatw_( __LINE__, a, b )
228 static void check_diactionformatw_( int line
, const DIACTIONFORMATW
*actual
, const DIACTIONFORMATW
*expected
)
231 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwSize
);
232 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwActionSize
);
233 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwDataSize
);
234 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwNumActions
);
235 for (i
= 0; i
< min( actual
->dwNumActions
, expected
->dwNumActions
); ++i
)
237 winetest_push_context( "action[%lu]", i
);
238 check_diactionw_( line
, actual
->rgoAction
+ i
, expected
->rgoAction
+ i
);
239 winetest_pop_context();
240 if (expected
->dwActionSize
!= sizeof(DIACTIONW
)) break;
241 if (actual
->dwActionSize
!= sizeof(DIACTIONW
)) break;
243 check_member_guid_( __FILE__
, line
, *actual
, *expected
, guidActionMap
);
244 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwGenre
);
245 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwBufferSize
);
246 check_member_( __FILE__
, line
, *actual
, *expected
, "%+ld", lAxisMin
);
247 check_member_( __FILE__
, line
, *actual
, *expected
, "%+ld", lAxisMax
);
248 check_member_( __FILE__
, line
, *actual
, *expected
, "%p", hInstString
);
249 check_member_( __FILE__
, line
, *actual
, *expected
, "%ld", ftTimeStamp
.dwLowDateTime
);
250 check_member_( __FILE__
, line
, *actual
, *expected
, "%ld", ftTimeStamp
.dwHighDateTime
);
252 check_member_( __FILE__
, line
, *actual
, *expected
, "%#lx", dwCRC
);
253 check_member_wstr_( __FILE__
, line
, *actual
, *expected
, tszActionMap
);
256 static BOOL CALLBACK
enum_device_count( const DIDEVICEINSTANCEW
*devinst
, void *context
)
258 DWORD
*count
= context
;
260 return DIENUM_CONTINUE
;
263 static void check_dinput_devices( DWORD version
, DIDEVICEINSTANCEW
*devinst
)
265 DIPROPDWORD prop_dword
=
269 .dwSize
= sizeof(DIPROPDWORD
),
270 .dwHeaderSize
= sizeof(DIPROPHEADER
),
271 .dwHow
= DIPH_DEVICE
,
274 IDirectInputDevice8W
*device
;
280 if (version
>= 0x800)
282 hr
= DirectInput8Create( instance
, version
, &IID_IDirectInput8W
, (void **)&di8
, NULL
);
283 ok( hr
== DI_OK
, "DirectInput8Create returned %#lx\n", hr
);
285 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, NULL
, NULL
, DIEDFL_ALLDEVICES
);
286 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
287 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, enum_device_count
, &count
, 0xdeadbeef );
288 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
289 hr
= IDirectInput8_EnumDevices( di8
, 0xdeadbeef, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
290 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
293 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
294 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
295 ok( count
== 3, "got count %lu, expected 0\n", count
);
297 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_DEVICE
, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
298 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
299 ok( count
== 0, "got count %lu, expected 0\n", count
);
301 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_POINTER
, enum_device_count
, &count
,
302 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
| DIEDFL_INCLUDEHIDDEN
);
303 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
305 ok( count
== 3, "got count %lu, expected 3\n", count
);
307 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_KEYBOARD
, enum_device_count
, &count
,
308 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
| DIEDFL_INCLUDEHIDDEN
);
309 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
311 ok( count
== 3, "got count %lu, expected 3\n", count
);
313 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_GAMECTRL
, enum_device_count
, &count
,
314 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
| DIEDFL_INCLUDEHIDDEN
);
315 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
316 ok( count
== 1, "got count %lu, expected 1\n", count
);
319 hr
= IDirectInput8_EnumDevices( di8
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
320 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
321 ok( count
== 1, "got count %lu, expected 1\n", count
);
324 hr
= IDirectInput8_EnumDevices( di8
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_FORCEFEEDBACK
);
325 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
326 if (IsEqualGUID( &devinst
->guidFFDriver
, &GUID_NULL
)) ok( count
== 0, "got count %lu, expected 0\n", count
);
327 else ok( count
== 1, "got count %lu, expected 1\n", count
);
330 hr
= IDirectInput8_EnumDevices( di8
, (devinst
->dwDevType
& 0xff) + 1, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
331 if ((devinst
->dwDevType
& 0xff) != DI8DEVTYPE_SUPPLEMENTAL
) ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
332 else ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
333 ok( count
== 0, "got count %lu, expected 0\n", count
);
335 hr
= IDirectInput8_CreateDevice( di8
, &devinst
->guidInstance
, NULL
, NULL
);
336 ok( hr
== E_POINTER
, "CreateDevice returned %#lx\n", hr
);
337 hr
= IDirectInput8_CreateDevice( di8
, NULL
, &device
, NULL
);
338 ok( hr
== E_POINTER
, "CreateDevice returned %#lx\n", hr
);
339 hr
= IDirectInput8_CreateDevice( di8
, &GUID_NULL
, &device
, NULL
);
340 ok( hr
== DIERR_DEVICENOTREG
, "CreateDevice returned %#lx\n", hr
);
342 hr
= IDirectInput8_CreateDevice( di8
, &devinst
->guidInstance
, &device
, NULL
);
343 ok( hr
== DI_OK
, "CreateDevice returned %#lx\n", hr
);
345 prop_dword
.dwData
= 0xdeadbeef;
346 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
347 ok( hr
== DI_OK
, "GetProperty DIPROP_VIDPID returned %#lx\n", hr
);
348 ok( prop_dword
.dwData
== EXPECT_VIDPID
, "got %#lx expected %#lx\n", prop_dword
.dwData
, EXPECT_VIDPID
);
350 ref
= IDirectInputDevice8_Release( device
);
351 ok( ref
== 0, "Release returned %ld\n", ref
);
352 ref
= IDirectInput8_Release( di8
);
353 ok( ref
== 0, "Release returned %ld\n", ref
);
357 hr
= DirectInputCreateEx( instance
, version
, &IID_IDirectInput2W
, (void **)&di
, NULL
);
358 ok( hr
== DI_OK
, "DirectInputCreateEx returned %#lx\n", hr
);
360 hr
= IDirectInput_EnumDevices( di
, 0, NULL
, NULL
, DIEDFL_ALLDEVICES
);
361 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
362 hr
= IDirectInput_EnumDevices( di
, 0, enum_device_count
, &count
, 0xdeadbeef );
363 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
364 hr
= IDirectInput_EnumDevices( di
, 0xdeadbeef, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
365 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
366 hr
= IDirectInput_EnumDevices( di
, 0, enum_device_count
, &count
, DIEDFL_INCLUDEHIDDEN
);
367 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
370 hr
= IDirectInput_EnumDevices( di
, 0, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
371 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
372 ok( count
== 3, "got count %lu, expected 0\n", count
);
374 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_DEVICE
, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
375 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
376 ok( count
== 0, "got count %lu, expected 0\n", count
);
378 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_MOUSE
, enum_device_count
, &count
,
379 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
);
380 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
382 ok( count
== 3, "got count %lu, expected 3\n", count
);
384 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_KEYBOARD
, enum_device_count
, &count
,
385 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
);
386 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
388 ok( count
== 3, "got count %lu, expected 3\n", count
);
390 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_JOYSTICK
, enum_device_count
, &count
,
391 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
);
392 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
393 ok( count
== 1, "got count %lu, expected 1\n", count
);
396 hr
= IDirectInput_EnumDevices( di
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
397 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
398 ok( count
== 1, "got count %lu, expected 1\n", count
);
401 hr
= IDirectInput_EnumDevices( di
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_FORCEFEEDBACK
);
402 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
403 if (IsEqualGUID( &devinst
->guidFFDriver
, &GUID_NULL
)) ok( count
== 0, "got count %lu, expected 0\n", count
);
404 else ok( count
== 1, "got count %lu, expected 1\n", count
);
406 hr
= IDirectInput_EnumDevices( di
, 0x14, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
407 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#lx\n", hr
);
408 ref
= IDirectInput_Release( di
);
409 ok( ref
== 0, "Release returned %ld\n", ref
);
413 static BOOL CALLBACK
enum_devices_by_semantic( const DIDEVICEINSTANCEW
*instance
, IDirectInputDevice8W
*device
,
414 DWORD flags
, DWORD remaining
, void *context
)
416 const DIDEVICEINSTANCEW expect_joystick
=
418 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
419 .guidInstance
= expect_guid_product
,
420 .guidProduct
= expect_guid_product
,
421 .dwDevType
= DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
,
422 .tszInstanceName
= L
"Wine Test",
423 .tszProductName
= L
"Wine Test",
424 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
425 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
427 const DIDEVICEINSTANCEW expect_keyboard
=
429 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
430 .guidInstance
= GUID_SysKeyboard
,
431 .guidProduct
= GUID_SysKeyboard
,
432 .dwDevType
= (DI8DEVTYPEKEYBOARD_PCENH
<< 8) | DI8DEVTYPE_KEYBOARD
,
433 .tszInstanceName
= L
"Keyboard",
434 .tszProductName
= L
"Keyboard",
436 const DIDEVICEINSTANCEW expect_mouse
=
438 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
439 .guidInstance
= GUID_SysMouse
,
440 .guidProduct
= GUID_SysMouse
,
441 .dwDevType
= (DI8DEVTYPEMOUSE_UNKNOWN
<< 8) | DI8DEVTYPE_MOUSE
,
442 .tszInstanceName
= L
"Mouse",
443 .tszProductName
= L
"Mouse",
445 const DIDEVICEINSTANCEW
*expect_instance
= NULL
;
447 ok( remaining
<= 2, "got remaining %lu\n", remaining
);
451 expect_instance
= &expect_joystick
;
452 ok( flags
== (context
? 3 : 0), "got flags %#lx\n", flags
);
454 else if (remaining
== 1)
456 expect_instance
= &expect_keyboard
;
457 ok( flags
== 1, "got flags %#lx\n", flags
);
459 else if (remaining
== 0)
461 expect_instance
= &expect_mouse
;
462 ok( flags
== 1, "got flags %#lx\n", flags
);
465 check_member( *instance
, *expect_instance
, "%#lx", dwSize
);
466 if (expect_instance
!= &expect_joystick
) check_member_guid( *instance
, *expect_instance
, guidInstance
);
467 check_member_guid( *instance
, *expect_instance
, guidProduct
);
468 todo_wine_if( expect_instance
== &expect_mouse
)
469 check_member( *instance
, *expect_instance
, "%#lx", dwDevType
);
472 check_member_wstr( *instance
, *expect_instance
, tszInstanceName
);
473 todo_wine_if( expect_instance
!= &expect_joystick
)
474 check_member_wstr( *instance
, *expect_instance
, tszProductName
);
476 check_member_guid( *instance
, *expect_instance
, guidFFDriver
);
477 check_member( *instance
, *expect_instance
, "%#x", wUsagePage
);
478 check_member( *instance
, *expect_instance
, "%#x", wUsage
);
480 return DIENUM_CONTINUE
;
483 static void test_action_map( IDirectInputDevice8W
*device
, HANDLE file
, HANDLE event
)
485 const DIACTIONW expect_actions
[] =
488 .dwSemantic
= DIBUTTON_ANY( 1 ),
489 .guidInstance
= expect_guid_product
,
490 .dwHow
= DIAH_DEFAULT
,
491 .dwObjID
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ),
494 .dwSemantic
= DIBUTTON_ANY( 2 ),
495 .guidInstance
= expect_guid_product
,
496 .dwHow
= DIAH_DEFAULT
,
497 .dwObjID
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 1 ),
500 .dwSemantic
= DIAXIS_ANY_X_1
,
503 .dwSemantic
= DIPOV_ANY_1
,
504 .guidInstance
= expect_guid_product
,
505 .dwHow
= DIAH_DEFAULT
,
506 .dwObjID
= DIDFT_POV
| DIDFT_MAKEINSTANCE( 0 ),
509 .dwSemantic
= DIAXIS_DRIVINGR_ACCELERATE
,
512 .dwSemantic
= DIAXIS_ANY_Z_2
,
513 .guidInstance
= expect_guid_product
,
514 .dwHow
= DIAH_DEFAULT
,
515 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ),
518 .dwSemantic
= DIAXIS_ANY_4
,
519 .guidInstance
= expect_guid_product
,
520 .dwHow
= DIAH_DEFAULT
,
521 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 6 ),
524 .dwSemantic
= DIAXIS_DRIVINGR_STEER
,
525 .guidInstance
= expect_guid_product
,
526 .dwHow
= DIAH_DEFAULT
,
527 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ),
530 .dwSemantic
= DIAXIS_ANY_Y_1
,
531 .guidInstance
= expect_guid_product
,
532 .dwHow
= DIAH_DEFAULT
,
533 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ),
536 .dwSemantic
= DIMOUSE_WHEEL
,
539 .dwSemantic
= 0x81000410,
542 const DIACTIONW expect_actions_3
[] =
545 .dwSemantic
= DIAXIS_DRIVINGR_STEER
,
546 .guidInstance
= expect_guid_product
,
547 .dwHow
= DIAH_DEFAULT
,
548 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ),
551 .dwSemantic
= DIAXIS_ANY_Y_1
,
552 .guidInstance
= expect_guid_product
,
553 .dwHow
= DIAH_DEFAULT
,
554 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ),
557 .dwSemantic
= DIMOUSE_WHEEL
,
558 .dwObjID
= DIDFT_RELAXIS
| DIDFT_MAKEINSTANCE( 2 ),
561 .dwSemantic
= 0x81000410,
562 .dwObjID
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0x10 ),
565 const DIACTIONW expect_actions_4
[] =
568 .dwSemantic
= DIAXIS_DRIVINGR_STEER
,
569 .guidInstance
= expect_guid_product
,
570 .dwHow
= DIAH_DEFAULT
,
571 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ),
574 .dwSemantic
= DIAXIS_ANY_Y_1
,
575 .guidInstance
= expect_guid_product
,
576 .dwHow
= DIAH_DEFAULT
,
577 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ),
580 .dwSemantic
= DIMOUSE_WHEEL
,
581 .guidInstance
= GUID_SysMouse
,
582 .dwObjID
= DIDFT_RELAXIS
| DIDFT_MAKEINSTANCE( 2 ),
583 .dwHow
= DIAH_DEFAULT
,
586 .dwSemantic
= 0x81000410,
587 .guidInstance
= GUID_SysKeyboard
,
588 .dwObjID
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0x10 ),
589 .dwHow
= DIAH_DEFAULT
,
592 const DIACTIONW expect_filled_actions
[ARRAY_SIZE(expect_actions
)] =
595 .dwSemantic
= DIBUTTON_ANY( 1 ),
596 .guidInstance
= expect_guid_product
,
597 .dwHow
= DIAH_APPREQUESTED
,
598 .dwObjID
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 1 ),
599 .dwFlags
= DIA_APPMAPPED
,
600 .lptszActionName
= L
"Button 1",
604 .dwSemantic
= DIBUTTON_ANY( 2 ),
605 .guidInstance
= expect_guid_product
,
606 .dwObjID
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ),
607 .dwFlags
= DIA_APPNOMAP
,
608 .lptszActionName
= L
"Button 2",
612 .dwSemantic
= DIAXIS_ANY_X_1
,
613 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ),
614 .dwFlags
= DIA_FORCEFEEDBACK
,
615 .lptszActionName
= L
"Wheel",
619 .dwSemantic
= DIPOV_ANY_1
,
620 .guidInstance
= expect_guid_product
,
621 .dwHow
= DIAH_APPREQUESTED
,
622 .dwObjID
= DIDFT_POV
| DIDFT_MAKEINSTANCE( 0 ),
623 .dwFlags
= DIA_APPMAPPED
| DIA_APPFIXED
,
624 .lptszActionName
= L
"POV",
628 .dwSemantic
= DIAXIS_DRIVINGR_ACCELERATE
,
629 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ),
630 .dwFlags
= DIA_NORANGE
,
631 .lptszActionName
= L
"Accelerate",
635 .dwSemantic
= DIAXIS_ANY_Z_2
,
636 .guidInstance
= expect_guid_product
,
637 .dwHow
= DIAH_DEFAULT
,
638 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ),
639 .dwFlags
= DIA_APPFIXED
,
640 .lptszActionName
= L
"Z",
644 .dwSemantic
= DIAXIS_ANY_4
,
645 .guidInstance
= expect_guid_product
,
646 .dwHow
= DIAH_DEFAULT
,
647 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 6 ),
648 .dwFlags
= DIA_APPFIXED
,
649 .lptszActionName
= L
"Axis 4",
653 .dwSemantic
= DIAXIS_DRIVINGR_STEER
,
654 .guidInstance
= expect_guid_product
,
655 .dwHow
= DIAH_DEFAULT
,
656 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ),
657 .lptszActionName
= L
"Steer",
661 .dwSemantic
= DIAXIS_ANY_Y_1
,
662 .guidInstance
= expect_guid_product
,
663 .dwHow
= DIAH_DEFAULT
,
664 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ),
665 .lptszActionName
= L
"Y Axis",
669 .dwSemantic
= DIMOUSE_WHEEL
,
670 .lptszActionName
= L
"Wheel",
674 .dwSemantic
= 0x81000410,
675 .lptszActionName
= L
"Key",
676 .dwFlags
= DIA_APPFIXED
,
680 const DIACTIONFORMATW expect_action_format_1
=
682 .dwSize
= sizeof(DIACTIONFORMATW
),
683 .dwActionSize
= sizeof(DIACTIONW
),
686 .rgoAction
= (DIACTIONW
*)expect_actions
,
687 .dwGenre
= DIVIRTUAL_DRIVING_RACE
,
688 .guidActionMap
= GUID_action_mapping_1
,
691 const DIACTIONFORMATW expect_action_format_2
=
693 .dwSize
= sizeof(DIACTIONFORMATW
),
694 .dwActionSize
= sizeof(DIACTIONW
),
695 .dwNumActions
= ARRAY_SIZE(expect_actions
),
696 .dwDataSize
= 4 * ARRAY_SIZE(expect_actions
),
697 .rgoAction
= (DIACTIONW
*)expect_actions
,
698 .dwGenre
= DIVIRTUAL_DRIVING_RACE
,
699 .guidActionMap
= GUID_action_mapping_2
,
702 const DIACTIONFORMATW expect_action_format_3
=
704 .dwSize
= sizeof(DIACTIONFORMATW
),
705 .dwActionSize
= sizeof(DIACTIONW
),
706 .dwNumActions
= ARRAY_SIZE(expect_actions_3
),
707 .dwDataSize
= 4 * ARRAY_SIZE(expect_actions_3
),
708 .rgoAction
= (DIACTIONW
*)expect_actions_3
,
709 .dwGenre
= DIVIRTUAL_DRIVING_RACE
,
710 .guidActionMap
= GUID_action_mapping_2
,
713 const DIACTIONFORMATW expect_action_format_4
=
715 .dwSize
= sizeof(DIACTIONFORMATW
),
716 .dwActionSize
= sizeof(DIACTIONW
),
717 .dwNumActions
= ARRAY_SIZE(expect_actions_4
),
718 .dwDataSize
= 4 * ARRAY_SIZE(expect_actions_4
),
719 .rgoAction
= (DIACTIONW
*)expect_actions_4
,
720 .dwGenre
= DIVIRTUAL_DRIVING_RACE
,
721 .guidActionMap
= GUID_action_mapping_2
,
724 const DIACTIONFORMATW expect_action_format_2_filled
=
726 .dwSize
= sizeof(DIACTIONFORMATW
),
727 .dwActionSize
= sizeof(DIACTIONW
),
728 .dwNumActions
= ARRAY_SIZE(expect_actions
),
729 .dwDataSize
= 4 * ARRAY_SIZE(expect_actions
),
730 .rgoAction
= (DIACTIONW
*)expect_filled_actions
,
731 .dwGenre
= DIVIRTUAL_DRIVING_RACE
,
732 .guidActionMap
= GUID_action_mapping_2
,
736 .tszActionMap
= L
"Action Map Filled",
739 struct hid_expect injected_input
[] =
742 .code
= IOCTL_HID_READ_REPORT
,
743 .report_buf
= {1,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0},
746 .code
= IOCTL_HID_READ_REPORT
,
747 .report_buf
= {1,0x10,0x10,0x38,0x38,0x10,0x10,0x10,0xf8},
750 .code
= IOCTL_HID_READ_REPORT
,
751 .report_buf
= {1,0x10,0x10,0x01,0x01,0x10,0x10,0x10,0x00},
754 .code
= IOCTL_HID_READ_REPORT
,
755 .report_buf
= {1,0x10,0x10,0x01,0x01,0x10,0x10,0x10,0x00},
758 .code
= IOCTL_HID_READ_REPORT
,
759 .report_buf
= {1,0x10,0x10,0x80,0x80,0x10,0x10,0x10,0xff},
762 .code
= IOCTL_HID_READ_REPORT
,
763 .report_buf
= {1,0x10,0x10,0x10,0xee,0x10,0x10,0x10,0x54},
766 const DWORD expect_state
[ARRAY_SIZE(injected_input
)][ARRAY_SIZE(expect_actions
)] =
768 { 0, 0, 0, -1, 0, 0, 0, 0},
769 { 0, 0, 0, -1, 0, 0, 0, 0},
770 {+128, 0, 0, +31500, 0, 0, 0, +128},
771 { 0, 0, 0, -1, 0, 0, 0, -43},
772 { 0, 0, 0, -1, 0, 0, 0, -43},
773 {+128, 0, 0, -1, 0, 0, 0, -128},
775 const DIDEVICEOBJECTDATA expect_objdata
[11] =
777 {.dwOfs
= 0x20, .dwData
= +128, .uAppData
= 9},
778 {.dwOfs
= 0x1c, .dwData
= +128, .uAppData
= 8},
779 {.dwOfs
= 0xc, .dwData
= +31500, .uAppData
= 4},
780 {.dwOfs
= 0, .dwData
= +128, .uAppData
= 1},
781 {.dwOfs
= 0x20, .dwData
= -67, .uAppData
= 9},
782 {.dwOfs
= 0x1c, .dwData
= -43, .uAppData
= 8},
783 {.dwOfs
= 0xc, .dwData
= -1, .uAppData
= 4},
784 {.dwOfs
= 0, .dwData
= 0, .uAppData
= 1},
785 {.dwOfs
= 0x20, .dwData
= -128, .uAppData
= 9},
786 {.dwOfs
= 0x1c, .dwData
= -128, .uAppData
= 8},
787 {.dwOfs
= 0, .dwData
= +128, .uAppData
= 1},
789 DIACTIONW voice_actions
[] =
791 {.dwSemantic
= DIVOICE_CHANNEL1
},
793 DIACTIONFORMATW voice_action_format
=
795 .dwSize
= sizeof(DIACTIONFORMATW
),
796 .dwActionSize
= sizeof(*voice_actions
),
799 .rgoAction
= voice_actions
,
800 .dwGenre
= DIVIRTUAL_DRIVING_RACE
,
801 .guidActionMap
= GUID_action_mapping_1
,
803 DIACTIONW default_actions
[ARRAY_SIZE(expect_actions
)] =
805 {.dwSemantic
= DIBUTTON_ANY( 1 )},
806 {.dwSemantic
= DIBUTTON_ANY( 2 )},
807 {.dwSemantic
= DIAXIS_ANY_X_1
},
808 {.dwSemantic
= DIPOV_ANY_1
},
809 {.dwSemantic
= DIAXIS_DRIVINGR_ACCELERATE
},
810 {.dwSemantic
= DIAXIS_ANY_Z_2
},
811 {.dwSemantic
= DIAXIS_ANY_4
},
812 {.dwSemantic
= DIAXIS_DRIVINGR_STEER
},
813 {.dwSemantic
= DIAXIS_ANY_Y_1
},
814 {.dwSemantic
= DIMOUSE_WHEEL
},
815 {.dwSemantic
= 0x81000410},
817 DIACTIONFORMATW action_format_1
=
819 .dwSize
= sizeof(DIACTIONFORMATW
),
820 .dwActionSize
= sizeof(*default_actions
),
823 .rgoAction
= default_actions
,
824 .dwGenre
= DIVIRTUAL_DRIVING_RACE
,
825 .guidActionMap
= GUID_action_mapping_1
,
827 DIACTIONFORMATW action_format_2
=
829 .dwSize
= sizeof(DIACTIONFORMATW
),
830 .dwActionSize
= sizeof(*default_actions
),
831 .dwNumActions
= ARRAY_SIZE(expect_actions
),
832 .dwDataSize
= 4 * ARRAY_SIZE(expect_actions
),
833 .rgoAction
= default_actions
,
834 .dwGenre
= DIVIRTUAL_DRIVING_RACE
,
835 .guidActionMap
= GUID_action_mapping_2
,
837 DIACTIONFORMATW action_format_3
=
839 .dwSize
= sizeof(DIACTIONFORMATW
),
840 .dwActionSize
= sizeof(*default_actions
),
841 .dwNumActions
= ARRAY_SIZE(expect_actions_3
),
842 .dwDataSize
= 4 * ARRAY_SIZE(expect_actions_3
),
843 .rgoAction
= default_actions
,
844 .dwGenre
= DIVIRTUAL_DRIVING_RACE
,
845 .guidActionMap
= GUID_action_mapping_2
,
847 DIACTIONW filled_actions
[ARRAY_SIZE(expect_actions
)] =
850 .dwSemantic
= DIBUTTON_ANY( 1 ),
851 .guidInstance
= expect_guid_product
,
852 .dwHow
= DIAH_USERCONFIG
,
853 .dwObjID
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 1 ),
854 .dwFlags
= DIA_APPMAPPED
,
855 .lptszActionName
= L
"Button 1",
859 .dwSemantic
= DIBUTTON_ANY( 2 ),
860 .guidInstance
= expect_guid_product
,
861 .dwObjID
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ),
862 .dwFlags
= DIA_APPNOMAP
,
863 .lptszActionName
= L
"Button 2",
867 .dwSemantic
= DIAXIS_ANY_X_1
,
868 .guidInstance
= expect_guid_product
,
869 .dwHow
= DIAH_HWDEFAULT
,
870 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ),
871 .dwFlags
= DIA_FORCEFEEDBACK
,
872 .lptszActionName
= L
"Wheel",
876 .dwSemantic
= DIPOV_ANY_1
,
877 .guidInstance
= expect_guid_product
,
879 .dwObjID
= DIDFT_POV
| DIDFT_MAKEINSTANCE( 0 ),
880 .dwFlags
= DIA_APPMAPPED
| DIA_APPFIXED
,
881 .lptszActionName
= L
"POV",
885 .dwSemantic
= DIAXIS_DRIVINGR_ACCELERATE
,
886 .guidInstance
= expect_guid_product
,
887 .dwHow
= DIAH_USERCONFIG
,
888 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ),
889 .dwFlags
= DIA_NORANGE
,
890 .lptszActionName
= L
"Accelerate",
894 .dwSemantic
= DIAXIS_ANY_Z_2
,
895 .guidInstance
= expect_guid_product
,
896 .dwHow
= DIAH_UNMAPPED
,
897 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 3 ),
898 .dwFlags
= DIA_APPFIXED
,
899 .lptszActionName
= L
"Z",
903 .dwSemantic
= DIAXIS_ANY_4
,
904 .guidInstance
= expect_guid_product
,
905 .dwHow
= DIAH_DEFAULT
,
906 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 5 ),
907 .dwFlags
= DIA_APPFIXED
,
908 .lptszActionName
= L
"Axis 4",
912 .dwSemantic
= DIAXIS_DRIVINGR_STEER
,
913 .guidInstance
= expect_guid_product
,
914 .dwHow
= DIAH_USERCONFIG
,
915 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 4 ),
916 .lptszActionName
= L
"Steer",
920 .dwSemantic
= DIAXIS_ANY_Y_1
,
921 .guidInstance
= expect_guid_product
,
922 .dwObjID
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ),
923 .lptszActionName
= L
"Y Axis",
927 .dwSemantic
= DIMOUSE_WHEEL
,
928 .guidInstance
= expect_guid_product
,
929 .lptszActionName
= L
"Wheel",
933 .dwSemantic
= 0x81000410,
934 .guidInstance
= expect_guid_product
,
935 .lptszActionName
= L
"Key",
936 .dwFlags
= DIA_APPFIXED
,
940 DIACTIONFORMATW action_format_2_filled
=
942 .dwSize
= sizeof(DIACTIONFORMATW
),
943 .dwActionSize
= sizeof(*default_actions
),
944 .dwNumActions
= ARRAY_SIZE(expect_actions
),
945 .dwDataSize
= 4 * ARRAY_SIZE(expect_actions
),
946 .rgoAction
= filled_actions
,
947 .dwGenre
= DIVIRTUAL_DRIVING_RACE
,
948 .guidActionMap
= GUID_action_mapping_2
,
952 .tszActionMap
= L
"Action Map Filled",
954 DIPROPRANGE prop_range
=
958 .dwHeaderSize
= sizeof(DIPROPHEADER
),
959 .dwSize
= sizeof(DIPROPRANGE
),
960 .dwHow
= DIPH_DEVICE
,
963 DIPROPDWORD prop_dword
=
967 .dwHeaderSize
= sizeof(DIPROPHEADER
),
968 .dwSize
= sizeof(DIPROPDWORD
),
969 .dwHow
= DIPH_DEVICE
,
972 DIPROPSTRING prop_username
=
976 .dwHeaderSize
= sizeof(DIPROPHEADER
),
977 .dwSize
= sizeof(DIPROPSTRING
),
978 .dwHow
= DIPH_DEVICE
,
981 DIPROPPOINTER prop_pointer
=
985 .dwHeaderSize
= sizeof(DIPROPHEADER
),
986 .dwSize
= sizeof(DIPROPPOINTER
),
989 DIDEVICEOBJECTDATA objdata
[ARRAY_SIZE(expect_objdata
)];
990 DIACTIONW actions
[ARRAY_SIZE(expect_actions
)];
991 DWORD state
[ARRAY_SIZE(expect_actions
)];
992 IDirectInputDevice8W
*mouse
, *keyboard
;
993 DIACTIONFORMATW action_format
;
994 IDirectInput8W
*dinput
;
999 res
= ARRAY_SIZE(username
);
1000 GetUserNameW( username
, &res
);
1002 memset( prop_username
.wsz
, 0, sizeof(prop_username
.wsz
) );
1003 hr
= IDirectInputDevice_GetProperty( device
, DIPROP_USERNAME
, &prop_username
.diph
);
1004 ok( hr
== DI_NOEFFECT
, "GetProperty returned %#lx\n", hr
);
1005 ok( !wcscmp( prop_username
.wsz
, L
"" ), "got username %s\n", debugstr_w(prop_username
.wsz
) );
1008 hr
= IDirectInputDevice8_BuildActionMap( device
, NULL
, L
"username", DIDBAM_DEFAULT
);
1009 ok( hr
== DIERR_INVALIDPARAM
, "BuildActionMap returned %#lx\n", hr
);
1010 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format_1
, L
"username", 0xdeadbeef );
1011 ok( hr
== DIERR_INVALIDPARAM
, "BuildActionMap returned %#lx\n", hr
);
1012 flags
= DIDBAM_HWDEFAULTS
| DIDBAM_INITIALIZE
;
1013 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format_1
, L
"username", flags
);
1014 ok( hr
== DIERR_INVALIDPARAM
, "BuildActionMap returned %#lx\n", hr
);
1015 flags
= DIDBAM_HWDEFAULTS
| DIDBAM_PRESERVE
;
1016 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format_1
, L
"username", flags
);
1017 ok( hr
== DIERR_INVALIDPARAM
, "BuildActionMap returned %#lx\n", hr
);
1018 flags
= DIDBAM_INITIALIZE
| DIDBAM_PRESERVE
;
1019 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format_1
, L
"username", flags
);
1020 ok( hr
== DIERR_INVALIDPARAM
, "BuildActionMap returned %#lx\n", hr
);
1022 hr
= IDirectInputDevice8_SetActionMap( device
, NULL
, NULL
, DIDSAM_DEFAULT
);
1023 ok( hr
== DIERR_INVALIDPARAM
, "SetActionMap returned %#lx\n", hr
);
1024 flags
= DIDSAM_FORCESAVE
| DIDSAM_NOUSER
;
1025 hr
= IDirectInputDevice8_SetActionMap( device
, &action_format_1
, NULL
, flags
);
1026 ok( hr
== DIERR_INVALIDPARAM
, "SetActionMap returned %#lx\n", hr
);
1029 /* action format with no suitable actions */
1031 hr
= IDirectInputDevice8_BuildActionMap( device
, &voice_action_format
, NULL
, DIDBAM_DEFAULT
);
1032 ok( hr
== DI_NOEFFECT
, "BuildActionMap returned %#lx\n", hr
);
1034 /* first SetActionMap call for a user always return DI_SETTINGSNOTSAVED */
1036 hr
= IDirectInputDevice8_SetActionMap( device
, &voice_action_format
, NULL
, DIDSAM_FORCESAVE
);
1037 ok( hr
== DI_SETTINGSNOTSAVED
, "SetActionMap returned %#lx\n", hr
);
1039 memset( prop_username
.wsz
, 0, sizeof(prop_username
.wsz
) );
1040 hr
= IDirectInputDevice_GetProperty( device
, DIPROP_USERNAME
, &prop_username
.diph
);
1041 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1042 ok( !wcscmp( prop_username
.wsz
, username
), "got username %s\n", debugstr_w(prop_username
.wsz
) );
1044 hr
= IDirectInputDevice8_SetActionMap( device
, &voice_action_format
, NULL
, DIDSAM_DEFAULT
);
1045 ok( hr
== DI_NOEFFECT
, "SetActionMap returned %#lx\n", hr
);
1046 hr
= IDirectInputDevice8_SetActionMap( device
, &voice_action_format
, NULL
, DIDSAM_FORCESAVE
);
1047 ok( hr
== DI_SETTINGSNOTSAVED
, "SetActionMap returned %#lx\n", hr
);
1049 memset( prop_username
.wsz
, 0, sizeof(prop_username
.wsz
) );
1050 hr
= IDirectInputDevice_GetProperty( device
, DIPROP_USERNAME
, &prop_username
.diph
);
1051 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1052 ok( !wcscmp( prop_username
.wsz
, username
), "got username %s\n", debugstr_w(prop_username
.wsz
) );
1055 action_format
= action_format_1
;
1056 action_format
.rgoAction
= actions
;
1057 memset( actions
, 0, sizeof(actions
) );
1058 actions
[0] = default_actions
[0];
1059 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format
, NULL
, DIDBAM_DEFAULT
);
1060 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1061 check_diactionformatw( &action_format
, &expect_action_format_1
);
1062 hr
= IDirectInputDevice8_SetActionMap( device
, &action_format
, NULL
, DIDSAM_DEFAULT
);
1063 ok( hr
== DI_OK
, "SetActionMap returned %#lx\n", hr
);
1064 check_diactionformatw( &action_format
, &expect_action_format_1
);
1067 action_format
= action_format_1
;
1068 action_format
.rgoAction
= actions
;
1069 memset( actions
, 0, sizeof(actions
) );
1070 actions
[0] = default_actions
[0];
1071 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format
, L
"username", DIDBAM_DEFAULT
);
1072 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1073 check_diactionformatw( &action_format
, &expect_action_format_1
);
1075 /* first SetActionMap call for a user always return DI_SETTINGSNOTSAVED */
1077 hr
= IDirectInputDevice8_SetActionMap( device
, &action_format
, L
"username", DIDSAM_DEFAULT
);
1079 ok( hr
== DI_SETTINGSNOTSAVED
, "SetActionMap returned %#lx\n", hr
);
1080 hr
= IDirectInputDevice8_SetActionMap( device
, &action_format
, L
"username", DIDSAM_DEFAULT
);
1081 ok( hr
== DI_OK
, "SetActionMap returned %#lx\n", hr
);
1083 /* same SetActionMap call returns DI_OK */
1085 hr
= IDirectInputDevice8_SetActionMap( device
, &action_format
, L
"username", DIDSAM_DEFAULT
);
1086 ok( hr
== DI_OK
, "SetActionMap returned %#lx\n", hr
);
1088 /* DIDSAM_FORCESAVE always returns DI_SETTINGSNOTSAVED */
1090 hr
= IDirectInputDevice8_SetActionMap( device
, &action_format
, L
"username", DIDSAM_FORCESAVE
);
1091 ok( hr
== DI_SETTINGSNOTSAVED
, "SetActionMap returned %#lx\n", hr
);
1092 hr
= IDirectInputDevice8_SetActionMap( device
, &action_format
, L
"username", DIDSAM_FORCESAVE
);
1093 ok( hr
== DI_SETTINGSNOTSAVED
, "SetActionMap returned %#lx\n", hr
);
1094 check_diactionformatw( &action_format
, &expect_action_format_1
);
1097 /* action format dwDataSize and dwNumActions have to match, actions require a dwSemantic */
1099 action_format
= action_format_2
;
1100 action_format
.rgoAction
= actions
;
1101 memset( actions
, 0, sizeof(actions
) );
1102 actions
[0] = default_actions
[0];
1103 action_format
.dwDataSize
= 8;
1104 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format
, L
"username", DIDBAM_DEFAULT
);
1105 ok( hr
== DIERR_INVALIDPARAM
, "BuildActionMap returned %#lx\n", hr
);
1106 action_format
.dwNumActions
= 2;
1107 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format
, L
"username", DIDBAM_DEFAULT
);
1108 ok( hr
== DIERR_INVALIDPARAM
, "BuildActionMap returned %#lx\n", hr
);
1109 action_format
.dwNumActions
= 1;
1110 action_format
.dwDataSize
= 4;
1113 action_format
= action_format_2
;
1114 action_format
.rgoAction
= actions
;
1115 memcpy( actions
, default_actions
, sizeof(default_actions
) );
1116 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format
, L
"username", DIDBAM_DEFAULT
);
1117 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1118 check_diactionformatw( &action_format
, &expect_action_format_2
);
1120 action_format
= action_format_2
;
1121 action_format
.rgoAction
= actions
;
1122 memcpy( actions
, default_actions
, sizeof(default_actions
) );
1123 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format
, L
"username", DIDBAM_PRESERVE
);
1124 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1125 check_diactionformatw( &action_format
, &expect_action_format_2
);
1127 hr
= IDirectInputDevice8_SetActionMap( device
, &action_format
, L
"username", DIDSAM_DEFAULT
);
1128 ok( hr
== DI_OK
, "SetActionMap returned %#lx\n", hr
);
1131 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
1132 prop_pointer
.diph
.dwObj
= MAKELONG(HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
1133 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
1134 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1135 ok( prop_pointer
.uData
== 0, "got uData %#Ix\n", prop_pointer
.uData
);
1137 prop_range
.diph
.dwHow
= DIPH_BYID
;
1138 prop_range
.diph
.dwObj
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 );
1139 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
1140 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1141 ok( prop_range
.lMin
== +1000, "got lMin %+ld\n", prop_range
.lMin
);
1142 ok( prop_range
.lMax
== +51000, "got lMax %+ld\n", prop_range
.lMax
);
1144 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
1145 prop_range
.diph
.dwObj
= MAKELONG(HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
1146 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
1147 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1148 ok( prop_range
.lMin
== -14000, "got lMin %+ld\n", prop_range
.lMin
);
1149 ok( prop_range
.lMax
== -4000, "got lMax %+ld\n", prop_range
.lMax
);
1151 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
1152 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1153 ok( prop_dword
.dwData
== 0, "got dwData %#lx\n", prop_dword
.dwData
);
1156 /* saving action map actually does nothing */
1158 action_format
= action_format_2_filled
;
1159 action_format
.rgoAction
= actions
;
1160 memcpy( actions
, filled_actions
, sizeof(filled_actions
) );
1161 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format
, L
"username", DIDBAM_DEFAULT
);
1162 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1163 check_diactionformatw( &action_format
, &expect_action_format_2_filled
);
1164 hr
= IDirectInputDevice8_SetActionMap( device
, &action_format
, L
"username", DIDSAM_DEFAULT
);
1165 ok( hr
== DI_OK
, "SetActionMap returned %#lx\n", hr
);
1166 check_diactionformatw( &action_format
, &expect_action_format_2_filled
);
1167 hr
= IDirectInputDevice8_SetActionMap( device
, &action_format
, L
"username", DIDSAM_FORCESAVE
);
1168 ok( hr
== DI_SETTINGSNOTSAVED
, "SetActionMap returned %#lx\n", hr
);
1169 check_diactionformatw( &action_format
, &expect_action_format_2_filled
);
1172 prop_pointer
.diph
.dwHow
= DIPH_DEVICE
;
1173 prop_pointer
.diph
.dwObj
= 0;
1174 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
1175 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty returned %#lx\n", hr
);
1177 prop_pointer
.diph
.dwHow
= DIPH_BYID
;
1178 prop_pointer
.diph
.dwObj
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 3 );
1179 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
1180 ok( hr
== DIERR_NOTFOUND
, "GetProperty returned %#lx\n", hr
);
1182 prop_pointer
.diph
.dwHow
= DIPH_BYID
;
1183 prop_pointer
.diph
.dwObj
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 );
1184 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
1185 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1186 ok( prop_pointer
.uData
== 6, "got uData %#Ix\n", prop_pointer
.uData
);
1188 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
1189 prop_pointer
.diph
.dwObj
= MAKELONG(HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
1190 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
1191 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1192 ok( prop_pointer
.uData
== 8, "got uData %#Ix\n", prop_pointer
.uData
);
1194 prop_range
.diph
.dwHow
= DIPH_BYID
;
1195 prop_range
.diph
.dwObj
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 );
1196 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
1197 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1198 ok( prop_range
.lMin
== -128, "got lMin %+ld\n", prop_range
.lMin
);
1199 ok( prop_range
.lMax
== +128, "got lMax %+ld\n", prop_range
.lMax
);
1201 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
1202 prop_range
.diph
.dwObj
= MAKELONG(HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
1203 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
1204 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1205 ok( prop_range
.lMin
== -128, "got lMin %+ld\n", prop_range
.lMin
);
1206 ok( prop_range
.lMax
== +128, "got lMax %+ld\n", prop_range
.lMax
);
1208 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
1209 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1210 ok( prop_dword
.dwData
== 32, "got dwData %#lx\n", prop_dword
.dwData
);
1213 action_format
= action_format_2
;
1214 action_format
.rgoAction
= actions
;
1215 memcpy( actions
, default_actions
, sizeof(default_actions
) );
1216 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format
, L
"username", DIDBAM_HWDEFAULTS
);
1217 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1218 check_diactionformatw( &action_format
, &expect_action_format_2
);
1220 action_format
= action_format_2
;
1221 action_format
.rgoAction
= actions
;
1222 memcpy( actions
, default_actions
, sizeof(default_actions
) );
1223 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format
, L
"username", DIDBAM_INITIALIZE
);
1224 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1225 check_diactionformatw( &action_format
, &expect_action_format_2
);
1227 action_format
= action_format_2
;
1228 action_format
.rgoAction
= actions
;
1229 memcpy( actions
, default_actions
, sizeof(default_actions
) );
1230 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format
, L
"username", DIDBAM_PRESERVE
);
1231 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1232 check_diactionformatw( &action_format
, &expect_action_format_2
);
1235 hr
= IDirectInputDevice8_Acquire( device
);
1236 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
1238 hr
= IDirectInputDevice8_SetActionMap( device
, &action_format
, L
"username", DIDSAM_DEFAULT
);
1239 ok( hr
== DIERR_ACQUIRED
, "SetActionMap returned %#lx\n", hr
);
1241 send_hid_input( file
, &injected_input
[0], sizeof(*injected_input
) );
1242 res
= WaitForSingleObject( event
, 100 );
1243 if (res
== WAIT_TIMEOUT
) /* Acquire is asynchronous */
1245 send_hid_input( file
, &injected_input
[0], sizeof(*injected_input
) );
1246 res
= WaitForSingleObject( event
, 100 );
1248 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
1250 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
1252 winetest_push_context( "state[%ld]", i
);
1254 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(state
), state
);
1255 ok( hr
== DI_OK
, "GetDeviceState returned: %#lx\n", hr
);
1256 ok( state
[0] == expect_state
[i
][0], "got state[0] %+ld\n", state
[0] );
1257 ok( state
[1] == expect_state
[i
][1], "got state[1] %+ld\n", state
[1] );
1258 ok( state
[2] == expect_state
[i
][2], "got state[2] %+ld\n", state
[2] );
1259 ok( state
[3] == expect_state
[i
][3], "got state[3] %+ld\n", state
[3] );
1260 ok( state
[4] == expect_state
[i
][4], "got state[4] %+ld\n", state
[4] );
1261 ok( state
[5] == expect_state
[i
][5], "got state[5] %+ld\n", state
[5] );
1262 ok( state
[6] == expect_state
[i
][6], "got state[6] %+ld\n", state
[6] );
1263 ok( state
[7] == expect_state
[i
][7] ||
1264 broken(state
[7] == -45 && expect_state
[i
][7] == -43) /* 32-bit rounding */,
1265 "got state[7] %+ld\n", state
[7] );
1267 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
1269 res
= WaitForSingleObject( event
, 100 );
1270 if (i
== 0 || i
== 3) ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject succeeded\n" );
1271 else ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
1272 ResetEvent( event
);
1273 winetest_pop_context();
1276 res
= ARRAY_SIZE(objdata
);
1277 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(*objdata
), objdata
, &res
, DIGDD_PEEK
);
1279 ok( hr
== DI_BUFFEROVERFLOW
, "GetDeviceData returned %#lx\n", hr
);
1280 ok( res
== ARRAY_SIZE(objdata
), "got %lu expected %u\n", res
, 8 );
1283 winetest_push_context( "%lu", res
);
1284 check_member( objdata
[res
], expect_objdata
[res
], "%#lx", dwOfs
);
1285 ok( objdata
[res
].dwData
== expect_objdata
[res
].dwData
||
1286 broken(objdata
[res
].dwData
== -45 && expect_objdata
[res
].dwData
== -43) /* 32-bit rounding */ ||
1287 broken(objdata
[res
].dwData
== -71 && expect_objdata
[res
].dwData
== -67) /* 32-bit rounding */,
1288 "got dwData %+ld\n", objdata
[res
].dwData
);
1289 check_member( objdata
[res
], expect_objdata
[res
], "%#Ix", uAppData
);
1290 winetest_pop_context();
1293 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format
, L
"username", DIDBAM_DEFAULT
);
1294 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1296 hr
= IDirectInputDevice8_Unacquire( device
);
1297 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
1300 /* setting the data format resets action map */
1302 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
1303 prop_pointer
.diph
.dwObj
= MAKELONG(HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
1304 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
1305 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1306 ok( prop_pointer
.uData
== 8, "got uData %#Ix\n", prop_pointer
.uData
);
1308 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
1309 ok( hr
== DI_OK
, "SetDataFormat returned %#lx\n", hr
);
1311 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
1312 prop_pointer
.diph
.dwObj
= MAKELONG(HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
1313 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
1314 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1315 ok( prop_pointer
.uData
== -1, "got uData %#Ix\n", prop_pointer
.uData
);
1317 prop_range
.diph
.dwHow
= DIPH_BYID
;
1318 prop_range
.diph
.dwObj
= DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 );
1319 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
1320 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1321 ok( prop_range
.lMin
== -128, "got lMin %+ld\n", prop_range
.lMin
);
1322 ok( prop_range
.lMax
== +128, "got lMax %+ld\n", prop_range
.lMax
);
1324 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
1325 prop_range
.diph
.dwObj
= MAKELONG(HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
1326 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
1327 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1328 ok( prop_range
.lMin
== -128, "got lMin %+ld\n", prop_range
.lMin
);
1329 ok( prop_range
.lMax
== +128, "got lMax %+ld\n", prop_range
.lMax
);
1331 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
1332 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1333 ok( prop_dword
.dwData
== 32, "got dwData %#lx\n", prop_dword
.dwData
);
1336 /* DIDSAM_NOUSER flag clears the device user property */
1338 memset( prop_username
.wsz
, 0, sizeof(prop_username
.wsz
) );
1339 hr
= IDirectInputDevice_GetProperty( device
, DIPROP_USERNAME
, &prop_username
.diph
);
1340 ok( hr
== DI_OK
, "GetProperty returned %#lx\n", hr
);
1341 ok( !wcscmp( prop_username
.wsz
, L
"username" ), "got username %s\n", debugstr_w(prop_username
.wsz
) );
1343 hr
= IDirectInputDevice8_SetActionMap( device
, &action_format
, L
"username", DIDSAM_NOUSER
);
1344 ok( hr
== DI_OK
, "SetActionMap returned %#lx\n", hr
);
1346 memset( prop_username
.wsz
, 0, sizeof(prop_username
.wsz
) );
1347 hr
= IDirectInputDevice_GetProperty( device
, DIPROP_USERNAME
, &prop_username
.diph
);
1348 ok( hr
== DI_NOEFFECT
, "GetProperty returned %#lx\n", hr
);
1349 ok( !wcscmp( prop_username
.wsz
, L
"" ), "got username %s\n", debugstr_w(prop_username
.wsz
) );
1352 /* test BuildActionMap with multiple devices and EnumDevicesBySemantics */
1354 hr
= DirectInput8Create( instance
, 0x800, &IID_IDirectInput8W
, (void **)&dinput
, NULL
);
1355 ok( hr
== DI_OK
, "DirectInput8Create returned %#lx\n", hr
);
1357 hr
= IDirectInput8_CreateDevice( dinput
, &GUID_SysMouse
, &mouse
, NULL
);
1358 ok( hr
== DI_OK
, "DirectInput8Create returned %#lx\n", hr
);
1359 hr
= IDirectInput8_CreateDevice( dinput
, &GUID_SysKeyboard
, &keyboard
, NULL
);
1360 ok( hr
== DI_OK
, "DirectInput8Create returned %#lx\n", hr
);
1362 action_format
= action_format_3
;
1363 action_format
.rgoAction
= actions
;
1364 memcpy( actions
, default_actions
+ 7, sizeof(expect_actions_3
) );
1365 hr
= IDirectInputDevice8_BuildActionMap( mouse
, &action_format
, L
"username", DIDBAM_DEFAULT
);
1366 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1367 hr
= IDirectInputDevice8_BuildActionMap( keyboard
, &action_format
, L
"username", DIDBAM_DEFAULT
);
1368 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1369 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format
, L
"username", DIDBAM_DEFAULT
);
1370 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1371 check_diactionformatw( &action_format
, &expect_action_format_3
);
1373 action_format
= action_format_3
;
1374 action_format
.rgoAction
= actions
;
1375 memcpy( actions
, default_actions
+ 7, sizeof(expect_actions_4
) );
1376 hr
= IDirectInputDevice8_BuildActionMap( mouse
, &action_format
, L
"username", DIDBAM_PRESERVE
);
1377 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1378 hr
= IDirectInputDevice8_BuildActionMap( keyboard
, &action_format
, L
"username", DIDBAM_PRESERVE
);
1379 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1380 hr
= IDirectInputDevice8_BuildActionMap( device
, &action_format
, L
"username", DIDBAM_PRESERVE
);
1381 ok( hr
== DI_OK
, "BuildActionMap returned %#lx\n", hr
);
1382 check_diactionformatw( &action_format
, &expect_action_format_4
);
1384 IDirectInputDevice8_Release( keyboard
);
1385 IDirectInputDevice8_Release( mouse
);
1387 action_format
= action_format_2
;
1388 action_format
.rgoAction
= actions
;
1389 memcpy( actions
, default_actions
, sizeof(default_actions
) );
1390 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, NULL
, &action_format
, enum_devices_by_semantic
, (void *)0xdeadbeef, 0 );
1391 ok( hr
== DI_OK
, "EnumDevicesBySemantics returned %#lx\n", hr
);
1393 action_format
= action_format_3
;
1394 action_format
.rgoAction
= actions
;
1395 memcpy( actions
, default_actions
+ 7, sizeof(expect_actions_4
) );
1396 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, NULL
, &action_format
, enum_devices_by_semantic
, (void *)0xdeadbeef, 0 );
1397 ok( hr
== DI_OK
, "EnumDevicesBySemantics returned %#lx\n", hr
);
1399 action_format
= action_format_3
;
1400 action_format
.rgoAction
= actions
;
1401 memcpy( actions
, default_actions
+ 9, 2 * sizeof(DIACTIONW
) );
1402 action_format
.dwNumActions
= 2;
1403 action_format
.dwDataSize
= 8;
1404 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, NULL
, &action_format
, enum_devices_by_semantic
, NULL
, 0 );
1405 ok( hr
== DI_OK
, "EnumDevicesBySemantics returned %#lx\n", hr
);
1407 IDirectInput8_Release( dinput
);
1410 static void test_simple_joystick( DWORD version
)
1412 #include "psh_hid_macros.h"
1413 static const unsigned char report_desc
[] =
1415 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
1416 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
1417 COLLECTION(1, Application
),
1418 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
1419 COLLECTION(1, Report
),
1422 USAGE(1, HID_USAGE_GENERIC_WHEEL
),
1423 USAGE(4, (0xff01u
<<16)|(0x1234)),
1424 USAGE(1, HID_USAGE_GENERIC_X
),
1425 USAGE(1, HID_USAGE_GENERIC_Y
),
1426 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_RUDDER
),
1427 USAGE(4, (HID_USAGE_PAGE_DIGITIZER
<<16)|HID_USAGE_DIGITIZER_TIP_PRESSURE
),
1428 USAGE(4, (HID_USAGE_PAGE_CONSUMER
<<16)|HID_USAGE_CONSUMER_VOLUME
),
1429 LOGICAL_MINIMUM(1, 0xe7),
1430 LOGICAL_MAXIMUM(1, 0x38),
1431 PHYSICAL_MINIMUM(1, 0xe7),
1432 PHYSICAL_MAXIMUM(1, 0x38),
1435 INPUT(1, Data
|Var
|Abs
),
1437 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
1438 LOGICAL_MINIMUM(1, 1),
1439 LOGICAL_MAXIMUM(1, 8),
1440 PHYSICAL_MINIMUM(1, 0),
1441 PHYSICAL_MAXIMUM(1, 8),
1444 INPUT(1, Data
|Var
|Abs
|Null
),
1446 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
1447 USAGE_MINIMUM(1, 1),
1448 USAGE_MAXIMUM(1, 2),
1449 LOGICAL_MINIMUM(1, 0),
1450 LOGICAL_MAXIMUM(1, 1),
1451 PHYSICAL_MINIMUM(1, 0),
1452 PHYSICAL_MAXIMUM(1, 1),
1455 INPUT(1, Data
|Var
|Abs
),
1458 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
1459 USAGE(1, HID_USAGE_GENERIC_RZ
),
1460 COLLECTION(1, Physical
),
1464 C_ASSERT(sizeof(report_desc
) < MAX_HID_DESCRIPTOR_LEN
);
1465 #include "pop_hid_macros.h"
1467 struct hid_device_desc desc
=
1469 .use_report_id
= TRUE
,
1470 .caps
= { .InputReportByteLength
= 9 },
1471 .attributes
= default_attributes
,
1473 const DIDEVCAPS expect_caps
=
1475 .dwSize
= sizeof(DIDEVCAPS
),
1476 .dwFlags
= DIDC_ATTACHED
| DIDC_EMULATED
,
1477 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
1478 : DIDEVTYPE_HID
| (DIDEVTYPEJOYSTICK_RUDDER
<< 8) | DIDEVTYPE_JOYSTICK
,
1483 struct hid_expect injected_input
[] =
1486 .code
= IOCTL_HID_READ_REPORT
,
1487 .report_buf
= {1,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0},
1490 .code
= IOCTL_HID_READ_REPORT
,
1491 .report_buf
= {1,0x10,0x10,0x38,0x38,0x10,0x10,0x10,0xf8},
1494 .code
= IOCTL_HID_READ_REPORT
,
1495 .report_buf
= {1,0x10,0x10,0x01,0x01,0x10,0x10,0x10,0x00},
1498 .code
= IOCTL_HID_READ_REPORT
,
1499 .report_buf
= {1,0x10,0x10,0x01,0x01,0x10,0x10,0x10,0x00},
1502 .code
= IOCTL_HID_READ_REPORT
,
1503 .report_buf
= {1,0x10,0x10,0x80,0x80,0x10,0x10,0x10,0xff},
1506 .code
= IOCTL_HID_READ_REPORT
,
1507 .report_buf
= {1,0x10,0x10,0x10,0xee,0x10,0x10,0x10,0x54},
1510 static const struct DIJOYSTATE2 expect_state
[] =
1512 {.lX
= 32767, .lY
= 32767, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
1513 {.lX
= 32767, .lY
= 32767, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
1514 {.lX
= 65535, .lY
= 65535, .lZ
= 32767, .rgdwPOV
= {31500, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
1515 {.lX
= 20779, .lY
= 20779, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
1516 {.lX
= 20779, .lY
= 20779, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
1517 {.lX
= 0, .lY
= 0, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
1518 {.lX
= 32767, .lY
= 5594, .lZ
= 32767, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80}},
1520 static const struct DIJOYSTATE2 expect_state_abs
[] =
1522 {.lX
= -9000, .lY
= 26000, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
1523 {.lX
= -9000, .lY
= 26000, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
1524 {.lX
= -4000, .lY
= 51000, .lZ
= 26000, .rgdwPOV
= {31500, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
1525 {.lX
= -10667, .lY
= 12905, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
1526 {.lX
= -10667, .lY
= 12905, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
1527 {.lX
= -14000, .lY
= 1000, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
1528 {.lX
= -9000, .lY
= 1000, .lZ
= 26000, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80}},
1530 static const struct DIJOYSTATE2 expect_state_rel
[] =
1532 {.lX
= 0, .lY
= 0, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80, 0}},
1533 {.lX
= 9016, .lY
= -984, .lZ
= -25984, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
1534 {.lX
= 40, .lY
= 40, .rgdwPOV
= {31500, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
1535 {.lX
= -55, .lY
= -55, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
1536 {.lX
= 0, .lY
= 0, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
1537 {.lX
= -129, .lY
= -129, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
1538 {.lX
= 144, .lY
= 110, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80}},
1540 static const DIDEVICEOBJECTDATA expect_objdata
[] =
1542 {.dwOfs
= 0x4, .dwData
= 0xffff, .dwSequence
= 0xa},
1543 {.dwOfs
= 0x4, .dwData
= 0xffff, .dwSequence
= 0xa},
1544 {.dwOfs
= 0, .dwData
= 0xffff, .dwSequence
= 0xa},
1545 {.dwOfs
= 0x20, .dwData
= 31500, .dwSequence
= 0xa},
1546 {.dwOfs
= 0x30, .dwData
= 0x80, .dwSequence
= 0xa},
1547 {.dwOfs
= 0x4, .dwData
= 0x512b, .dwSequence
= 0xd},
1548 {.dwOfs
= 0, .dwData
= 0x512b, .dwSequence
= 0xd},
1549 {.dwOfs
= 0x20, .dwData
= -1, .dwSequence
= 0xd},
1550 {.dwOfs
= 0x30, .dwData
= 0, .dwSequence
= 0xd},
1551 {.dwOfs
= 0x31, .dwData
= 0, .dwSequence
= 0xd},
1552 {.dwOfs
= 0x4, .dwData
= 0, .dwSequence
= 0xf},
1553 {.dwOfs
= 0, .dwData
= 0, .dwSequence
= 0xf},
1554 {.dwOfs
= 0x30, .dwData
= 0x80, .dwSequence
= 0xf},
1555 {.dwOfs
= 0x31, .dwData
= 0x80, .dwSequence
= 0xf},
1558 const DIDEVICEINSTANCEW expect_devinst
=
1560 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
1561 .guidInstance
= expect_guid_product
,
1562 .guidProduct
= expect_guid_product
,
1563 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
1564 : DIDEVTYPE_HID
| (DIDEVTYPEJOYSTICK_RUDDER
<< 8) | DIDEVTYPE_JOYSTICK
,
1565 .tszInstanceName
= L
"Wine Test",
1566 .tszProductName
= L
"Wine Test",
1567 .guidFFDriver
= GUID_NULL
,
1568 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
1569 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1571 const DIDEVICEOBJECTINSTANCEW expect_objects
[] =
1574 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1575 .guidType
= GUID_Unknown
,
1576 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(6),
1577 .tszName
= L
"Volume",
1578 .wCollectionNumber
= 1,
1579 .wUsagePage
= HID_USAGE_PAGE_CONSUMER
,
1580 .wUsage
= HID_USAGE_CONSUMER_VOLUME
,
1584 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1585 .guidType
= GUID_Unknown
,
1587 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(7),
1588 .tszName
= L
"Tip Pressure",
1589 .wCollectionNumber
= 1,
1590 .wUsagePage
= HID_USAGE_PAGE_DIGITIZER
,
1591 .wUsage
= HID_USAGE_DIGITIZER_TIP_PRESSURE
,
1595 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1596 .guidType
= GUID_RzAxis
,
1598 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(5),
1599 .dwFlags
= DIDOI_ASPECTPOSITION
,
1600 .tszName
= L
"Rudder",
1601 .wCollectionNumber
= 1,
1602 .wUsagePage
= HID_USAGE_PAGE_SIMULATION
,
1603 .wUsage
= HID_USAGE_SIMULATION_RUDDER
,
1607 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1608 .guidType
= GUID_YAxis
,
1610 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(1),
1611 .dwFlags
= DIDOI_ASPECTPOSITION
,
1612 .tszName
= L
"Y Axis",
1613 .wCollectionNumber
= 1,
1614 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
1615 .wUsage
= HID_USAGE_GENERIC_Y
,
1619 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1620 .guidType
= GUID_XAxis
,
1622 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(0),
1623 .dwFlags
= DIDOI_ASPECTPOSITION
,
1624 .tszName
= L
"X Axis",
1625 .wCollectionNumber
= 1,
1626 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
1627 .wUsage
= HID_USAGE_GENERIC_X
,
1631 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1632 .guidType
= GUID_ZAxis
,
1634 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(2),
1635 .dwFlags
= DIDOI_ASPECTPOSITION
,
1636 .tszName
= L
"Wheel",
1637 .wCollectionNumber
= 1,
1638 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
1639 .wUsage
= HID_USAGE_GENERIC_WHEEL
,
1643 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1644 .guidType
= GUID_POV
,
1646 .dwType
= DIDFT_POV
|DIDFT_MAKEINSTANCE(0),
1647 .tszName
= L
"Hat Switch",
1648 .wCollectionNumber
= 1,
1649 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
1650 .wUsage
= HID_USAGE_GENERIC_HATSWITCH
,
1654 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1655 .guidType
= GUID_Button
,
1657 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(0),
1658 .tszName
= L
"Button 0",
1659 .wCollectionNumber
= 1,
1660 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
1665 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1666 .guidType
= GUID_Button
,
1668 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(1),
1669 .tszName
= L
"Button 1",
1670 .wCollectionNumber
= 1,
1671 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
1676 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1677 .guidType
= GUID_Unknown
,
1678 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(0),
1679 .tszName
= L
"Collection 0 - Joystick",
1680 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
1681 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1684 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1685 .guidType
= GUID_Unknown
,
1686 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(1),
1687 .tszName
= L
"Collection 1 - Joystick",
1688 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
1689 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1692 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1693 .guidType
= GUID_Unknown
,
1694 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(2),
1695 .tszName
= L
"Collection 2 - Z Rotation",
1696 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
1697 .wUsage
= HID_USAGE_GENERIC_RZ
,
1700 const DIDEVICEOBJECTINSTANCEW expect_objects_5
[] =
1703 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1704 .guidType
= GUID_XAxis
,
1706 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(0),
1707 .dwFlags
= DIDOI_ASPECTPOSITION
,
1708 .tszName
= L
"X Axis",
1709 .wCollectionNumber
= 1,
1710 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
1711 .wUsage
= HID_USAGE_GENERIC_X
,
1715 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1716 .guidType
= GUID_YAxis
,
1718 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(1),
1719 .dwFlags
= DIDOI_ASPECTPOSITION
,
1720 .tszName
= L
"Y Axis",
1721 .wCollectionNumber
= 1,
1722 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
1723 .wUsage
= HID_USAGE_GENERIC_Y
,
1727 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1728 .guidType
= GUID_ZAxis
,
1730 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(2),
1731 .dwFlags
= DIDOI_ASPECTPOSITION
,
1732 .tszName
= L
"Wheel",
1733 .wCollectionNumber
= 1,
1734 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
1735 .wUsage
= HID_USAGE_GENERIC_WHEEL
,
1739 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1740 .guidType
= GUID_RzAxis
,
1742 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(5),
1743 .dwFlags
= DIDOI_ASPECTPOSITION
,
1744 .tszName
= L
"Rudder",
1745 .wCollectionNumber
= 1,
1746 .wUsagePage
= HID_USAGE_PAGE_SIMULATION
,
1747 .wUsage
= HID_USAGE_SIMULATION_RUDDER
,
1751 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1752 .guidType
= GUID_POV
,
1753 .dwOfs
= DIJOFS_POV(0),
1754 .dwType
= DIDFT_POV
|DIDFT_MAKEINSTANCE(0),
1755 .tszName
= L
"Hat Switch",
1756 .wCollectionNumber
= 1,
1757 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
1758 .wUsage
= HID_USAGE_GENERIC_HATSWITCH
,
1762 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1763 .guidType
= GUID_Button
,
1764 .dwOfs
= DIJOFS_BUTTON(0),
1765 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(0),
1766 .tszName
= L
"Button 0",
1767 .wCollectionNumber
= 1,
1768 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
1773 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
1774 .guidType
= GUID_Button
,
1775 .dwOfs
= DIJOFS_BUTTON(1),
1776 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(1),
1777 .tszName
= L
"Button 1",
1778 .wCollectionNumber
= 1,
1779 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
1784 struct check_object_todo todo_objects_5
[ARRAY_SIZE(expect_objects_5
)] =
1786 {.guid
= TRUE
, .type
= TRUE
, .flags
= TRUE
, .usage
= TRUE
, .usage_page
= TRUE
, .name
= TRUE
},
1787 {.guid
= TRUE
, .type
= TRUE
, .flags
= TRUE
, .usage
= TRUE
, .usage_page
= TRUE
, .name
= TRUE
},
1788 {.guid
= TRUE
, .type
= TRUE
, .usage
= TRUE
, .usage_page
= TRUE
, .name
= TRUE
},
1789 {.guid
= TRUE
, .ofs
= TRUE
, .type
= TRUE
, .usage
= TRUE
, .usage_page
= TRUE
, .name
= TRUE
},
1790 {.guid
= TRUE
, .ofs
= TRUE
, .type
= TRUE
, .flags
= TRUE
, .usage
= TRUE
, .name
= TRUE
},
1791 {.guid
= TRUE
, .ofs
= TRUE
, .type
= TRUE
, .flags
= TRUE
, .usage
= TRUE
, .usage_page
= TRUE
, .name
= TRUE
},
1792 {.guid
= TRUE
, .ofs
= TRUE
, .type
= TRUE
, .usage
= TRUE
, .usage_page
= TRUE
, .name
= TRUE
},
1794 struct check_object_todo todo_ofs
= {.ofs
= TRUE
};
1795 struct check_objects_params check_objects_params
=
1798 .expect_count
= version
< 0x700 ? ARRAY_SIZE(expect_objects_5
) : ARRAY_SIZE(expect_objects
),
1799 .expect_objs
= version
< 0x700 ? expect_objects_5
: expect_objects
,
1800 .todo_objs
= version
< 0x700 ? todo_objects_5
: NULL
,
1801 .todo_extra
= version
< 0x700,
1804 const DIEFFECTINFOW expect_effects
[] = {};
1805 struct check_effects_params check_effects_params
=
1807 .expect_count
= ARRAY_SIZE(expect_effects
),
1808 .expect_effects
= expect_effects
,
1810 DIPROPGUIDANDPATH prop_guid_path
=
1814 .dwSize
= sizeof(DIPROPGUIDANDPATH
),
1815 .dwHeaderSize
= sizeof(DIPROPHEADER
),
1816 .dwHow
= DIPH_DEVICE
,
1819 DIPROPSTRING prop_string
=
1823 .dwSize
= sizeof(DIPROPSTRING
),
1824 .dwHeaderSize
= sizeof(DIPROPHEADER
),
1825 .dwHow
= DIPH_DEVICE
,
1828 DIPROPDWORD prop_dword
=
1832 .dwSize
= sizeof(DIPROPDWORD
),
1833 .dwHeaderSize
= sizeof(DIPROPHEADER
),
1834 .dwHow
= DIPH_DEVICE
,
1837 DIPROPRANGE prop_range
=
1841 .dwSize
= sizeof(DIPROPRANGE
),
1842 .dwHeaderSize
= sizeof(DIPROPHEADER
),
1843 .dwHow
= DIPH_DEVICE
,
1846 DIPROPPOINTER prop_pointer
=
1850 .dwSize
= sizeof(DIPROPPOINTER
),
1851 .dwHeaderSize
= sizeof(DIPROPHEADER
),
1854 DIOBJECTDATAFORMAT objdataformat
[32] = {{0}};
1855 DIDEVICEOBJECTDATA objdata
[32] = {{0}};
1856 DIDEVICEOBJECTINSTANCEW objinst
= {0};
1857 DIDEVICEOBJECTINSTANCEW expect_obj
;
1858 DIDEVICEINSTANCEW devinst
= {0};
1859 DIEFFECTINFOW effectinfo
= {0};
1860 DIDATAFORMAT dataformat
= {0};
1861 IDirectInputDevice8W
*device
;
1862 IDirectInputEffect
*effect
;
1863 DIEFFESCAPE escape
= {0};
1864 ULONG i
, size
, res
, ref
;
1865 DIDEVCAPS caps
= {0};
1873 winetest_push_context( "%#lx", version
);
1875 cleanup_registry_keys();
1877 desc
.report_descriptor_len
= sizeof(report_desc
);
1878 memcpy( desc
.report_descriptor_buf
, report_desc
, sizeof(report_desc
) );
1879 fill_context( desc
.context
, ARRAY_SIZE(desc
.context
) );
1881 if (!hid_device_start( &desc
, 1 )) goto done
;
1882 if (FAILED(hr
= dinput_test_create_device( version
, &devinst
, &device
))) goto done
;
1884 check_dinput_devices( version
, &devinst
);
1886 hr
= IDirectInputDevice8_Initialize( device
, instance
, 0x800 - (version
- 0x700), &GUID_NULL
);
1887 if (version
== 0x800)
1890 ok( hr
== DIERR_BETADIRECTINPUTVERSION
, "Initialize returned %#lx\n", hr
);
1895 ok( hr
== DIERR_OLDDIRECTINPUTVERSION
, "Initialize returned %#lx\n", hr
);
1897 hr
= IDirectInputDevice8_Initialize( device
, instance
, version
, NULL
);
1899 ok( hr
== E_POINTER
, "Initialize returned %#lx\n", hr
);
1900 hr
= IDirectInputDevice8_Initialize( device
, NULL
, version
, &GUID_NULL
);
1902 ok( hr
== DIERR_INVALIDPARAM
, "Initialize returned %#lx\n", hr
);
1903 hr
= IDirectInputDevice8_Initialize( device
, instance
, version
, &GUID_NULL
);
1905 ok( hr
== REGDB_E_CLASSNOTREG
, "Initialize returned %#lx\n", hr
);
1907 hr
= IDirectInputDevice8_Initialize( device
, instance
, version
, &devinst
.guidInstance
);
1908 ok( hr
== DI_OK
, "Initialize returned %#lx\n", hr
);
1909 guid
= devinst
.guidInstance
;
1910 memset( &devinst
, 0, sizeof(devinst
) );
1911 devinst
.dwSize
= sizeof(DIDEVICEINSTANCEW
);
1912 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
1913 ok( hr
== DI_OK
, "GetDeviceInfo returned %#lx\n", hr
);
1914 ok( IsEqualGUID( &guid
, &devinst
.guidInstance
), "got %s expected %s\n", debugstr_guid( &guid
),
1915 debugstr_guid( &devinst
.guidInstance
) );
1916 hr
= IDirectInputDevice8_Initialize( device
, instance
, version
, &devinst
.guidProduct
);
1917 ok( hr
== DI_OK
, "Initialize returned %#lx\n", hr
);
1919 hr
= IDirectInputDevice8_GetDeviceInfo( device
, NULL
);
1920 ok( hr
== E_POINTER
, "GetDeviceInfo returned %#lx\n", hr
);
1921 devinst
.dwSize
= sizeof(DIDEVICEINSTANCEW
) + 1;
1922 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
1923 ok( hr
== DIERR_INVALIDPARAM
, "GetDeviceInfo returned %#lx\n", hr
);
1925 devinst
.dwSize
= sizeof(DIDEVICEINSTANCE_DX3W
);
1926 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
1927 ok( hr
== DI_OK
, "GetDeviceInfo returned %#lx\n", hr
);
1929 check_member_guid( devinst
, expect_devinst
, guidInstance
);
1930 check_member_guid( devinst
, expect_devinst
, guidProduct
);
1931 todo_wine_if( version
< 0x0800 )
1932 check_member( devinst
, expect_devinst
, "%#lx", dwDevType
);
1933 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
1934 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
1936 memset( &devinst
, 0, sizeof(devinst
) );
1937 devinst
.dwSize
= sizeof(DIDEVICEINSTANCEW
);
1938 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
1939 ok( hr
== DI_OK
, "GetDeviceInfo returned %#lx\n", hr
);
1940 check_member( devinst
, expect_devinst
, "%lu", dwSize
);
1942 check_member_guid( devinst
, expect_devinst
, guidInstance
);
1943 check_member_guid( devinst
, expect_devinst
, guidProduct
);
1944 todo_wine_if( version
< 0x0800 )
1945 check_member( devinst
, expect_devinst
, "%#lx", dwDevType
);
1946 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
1947 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
1948 check_member_guid( devinst
, expect_devinst
, guidFFDriver
);
1949 check_member( devinst
, expect_devinst
, "%04x", wUsagePage
);
1950 check_member( devinst
, expect_devinst
, "%04x", wUsage
);
1952 hr
= IDirectInputDevice8_GetCapabilities( device
, NULL
);
1953 ok( hr
== E_POINTER
, "GetCapabilities returned %#lx\n", hr
);
1954 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
1955 ok( hr
== DIERR_INVALIDPARAM
, "GetCapabilities returned %#lx\n", hr
);
1956 caps
.dwSize
= sizeof(DIDEVCAPS
);
1957 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
1958 ok( hr
== DI_OK
, "GetCapabilities returned %#lx\n", hr
);
1959 check_member( caps
, expect_caps
, "%lu", dwSize
);
1960 check_member( caps
, expect_caps
, "%#lx", dwFlags
);
1961 todo_wine_if( version
< 0x0800 )
1962 check_member( caps
, expect_caps
, "%#lx", dwDevType
);
1963 check_member( caps
, expect_caps
, "%lu", dwAxes
);
1964 check_member( caps
, expect_caps
, "%lu", dwButtons
);
1965 check_member( caps
, expect_caps
, "%lu", dwPOVs
);
1966 check_member( caps
, expect_caps
, "%lu", dwFFSamplePeriod
);
1967 check_member( caps
, expect_caps
, "%lu", dwFFMinTimeResolution
);
1968 check_member( caps
, expect_caps
, "%lu", dwFirmwareRevision
);
1969 check_member( caps
, expect_caps
, "%lu", dwHardwareRevision
);
1970 check_member( caps
, expect_caps
, "%lu", dwFFDriverVersion
);
1972 hr
= IDirectInputDevice8_GetProperty( device
, NULL
, NULL
);
1973 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#lx\n", hr
);
1974 hr
= IDirectInputDevice8_GetProperty( device
, &GUID_NULL
, NULL
);
1975 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#lx\n", hr
);
1976 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, NULL
);
1977 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#lx\n", hr
);
1978 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_string
.diph
);
1979 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DIERR_INVALIDPARAM
),
1980 "GetProperty DIPROP_VIDPID returned %#lx\n", hr
);
1981 prop_dword
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
) - 1;
1982 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
1983 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#lx\n", hr
);
1984 prop_dword
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
);
1986 prop_dword
.dwData
= 0xdeadbeef;
1987 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
1988 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DI_OK
),
1989 "GetProperty DIPROP_VIDPID returned %#lx\n", hr
);
1992 ok( prop_dword
.dwData
== EXPECT_VIDPID
, "got %#lx expected %#lx\n",
1993 prop_dword
.dwData
, EXPECT_VIDPID
);
1996 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
1997 ok( hr
== DI_OK
, "GetProperty DIPROP_GUIDANDPATH returned %#lx\n", hr
);
1998 ok( IsEqualGUID( &prop_guid_path
.guidClass
, &GUID_DEVCLASS_HIDCLASS
), "got guid %s\n",
1999 debugstr_guid( &prop_guid_path
.guidClass
) );
2001 ok( !wcsncmp( prop_guid_path
.wszPath
, expect_path
, wcslen( expect_path
) ), "got path %s\n",
2002 debugstr_w(prop_guid_path
.wszPath
) );
2004 ok( !wcscmp( wcsrchr( prop_guid_path
.wszPath
, '&' ), expect_path_end
), "got path %s\n",
2005 debugstr_w(prop_guid_path
.wszPath
) );
2007 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_INSTANCENAME
, &prop_string
.diph
);
2008 ok( hr
== DI_OK
, "GetProperty DIPROP_INSTANCENAME returned %#lx\n", hr
);
2009 ok( !wcscmp( prop_string
.wsz
, expect_devinst
.tszInstanceName
), "got instance %s\n",
2010 debugstr_w(prop_string
.wsz
) );
2011 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PRODUCTNAME
, &prop_string
.diph
);
2012 ok( hr
== DI_OK
, "GetProperty DIPROP_PRODUCTNAME returned %#lx\n", hr
);
2013 ok( !wcscmp( prop_string
.wsz
, expect_devinst
.tszProductName
), "got product %s\n",
2014 debugstr_w(prop_string
.wsz
) );
2015 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_TYPENAME
, &prop_string
.diph
);
2016 todo_wine_if( version
>= 0x0800 )
2017 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DI_OK
),
2018 "GetProperty DIPROP_TYPENAME returned %#lx\n", hr
);
2022 ok( !wcscmp( prop_string
.wsz
, expect_vidpid_str
), "got type %s\n", debugstr_w(prop_string
.wsz
) );
2024 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_USERNAME
, &prop_string
.diph
);
2025 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DI_NOEFFECT
),
2026 "GetProperty DIPROP_USERNAME returned %#lx\n", hr
);
2027 if (hr
== DI_NOEFFECT
)
2030 ok( !wcscmp( prop_string
.wsz
, L
"" ), "got user %s\n", debugstr_w(prop_string
.wsz
) );
2033 prop_dword
.dwData
= 0xdeadbeef;
2034 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_JOYSTICKID
, &prop_dword
.diph
);
2035 ok( hr
== DI_OK
, "GetProperty DIPROP_JOYSTICKID returned %#lx\n", hr
);
2037 ok( prop_dword
.dwData
== 0, "got %#lx expected 0\n", prop_dword
.dwData
);
2039 prop_dword
.dwData
= 0xdeadbeef;
2040 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
2042 ok( hr
== DI_OK
, "GetProperty DIPROP_AXISMODE returned %#lx\n", hr
);
2044 ok( prop_dword
.dwData
== DIPROPAXISMODE_ABS
, "got %lu expected %u\n", prop_dword
.dwData
, DIPROPAXISMODE_ABS
);
2045 prop_dword
.dwData
= 0xdeadbeef;
2046 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
2047 ok( hr
== DI_OK
, "GetProperty DIPROP_BUFFERSIZE returned %#lx\n", hr
);
2048 ok( prop_dword
.dwData
== 0, "got %#lx expected %#x\n", prop_dword
.dwData
, 0 );
2049 prop_dword
.dwData
= 0xdeadbeef;
2050 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
2051 ok( hr
== DI_OK
, "GetProperty DIPROP_FFGAIN returned %#lx\n", hr
);
2052 ok( prop_dword
.dwData
== 10000, "got %lu expected %u\n", prop_dword
.dwData
, 10000 );
2054 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATION
, &prop_dword
.diph
);
2055 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty DIPROP_CALIBRATION returned %#lx\n", hr
);
2056 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
2057 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_AUTOCENTER returned %#lx\n", hr
);
2058 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
2059 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_DEADZONE returned %#lx\n", hr
);
2060 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
2061 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr
);
2062 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GRANULARITY
, &prop_dword
.diph
);
2063 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_GRANULARITY returned %#lx\n", hr
);
2064 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
2065 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_SATURATION returned %#lx\n", hr
);
2066 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
2067 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_CALIBRATIONMODE returned %#lx\n", hr
);
2068 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
2069 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_RANGE returned %#lx\n", hr
);
2070 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_KEYNAME
, &prop_string
.diph
);
2071 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DIERR_INVALIDPARAM
),
2072 "GetProperty DIPROP_KEYNAME returned %#lx\n", hr
);
2073 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_LOGICALRANGE
, &prop_range
.diph
);
2074 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_LOGICALRANGE returned %#lx\n", hr
);
2075 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PHYSICALRANGE
, &prop_range
.diph
);
2076 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_PHYSICALRANGE returned %#lx\n", hr
);
2078 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
2079 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2080 prop_dword
.dwData
= 0xdeadbeef;
2081 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
2082 ok( hr
== DI_OK
, "GetProperty DIPROP_DEADZONE returned %#lx\n", hr
);
2083 ok( prop_dword
.dwData
== 0, "got %lu expected %u\n", prop_dword
.dwData
, 0 );
2084 prop_dword
.dwData
= 0xdeadbeef;
2085 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GRANULARITY
, &prop_dword
.diph
);
2086 ok( hr
== DI_OK
, "GetProperty DIPROP_GRANULARITY returned %#lx\n", hr
);
2087 ok( prop_dword
.dwData
== 1, "got %lu expected %u\n", prop_dword
.dwData
, 1 );
2088 prop_dword
.dwData
= 0xdeadbeef;
2089 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
2090 ok( hr
== DI_OK
, "GetProperty DIPROP_SATURATION returned %#lx\n", hr
);
2091 ok( prop_dword
.dwData
== 10000, "got %lu expected %u\n", prop_dword
.dwData
, 10000 );
2092 prop_dword
.dwData
= 0xdeadbeef;
2093 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
2094 ok( hr
== DI_OK
, "GetProperty DIPROP_CALIBRATIONMODE returned %#lx\n", hr
);
2095 ok( prop_dword
.dwData
== DIPROPCALIBRATIONMODE_COOKED
, "got %lu expected %u\n",
2096 prop_dword
.dwData
, DIPROPCALIBRATIONMODE_COOKED
);
2098 prop_string
.diph
.dwHow
= DIPH_BYUSAGE
;
2099 prop_string
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2100 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_KEYNAME
, &prop_string
.diph
);
2101 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DI_OK
),
2102 "GetProperty DIPROP_KEYNAME returned %#lx\n", hr
);
2105 ok( !wcscmp( prop_string
.wsz
, expect_objects
[4].tszName
), "got DIPROP_KEYNAME %s\n",
2106 debugstr_w(prop_string
.wsz
) );
2108 prop_string
.diph
.dwObj
= MAKELONG( 0x1, HID_USAGE_PAGE_BUTTON
);
2109 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_KEYNAME
, &prop_string
.diph
);
2111 ok( hr
== DIERR_NOTFOUND
, "GetProperty DIPROP_KEYNAME returned %#lx\n", hr
);
2112 prop_string
.diph
.dwHow
= DIPH_BYUSAGE
;
2113 prop_string
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2114 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_KEYNAME
, &prop_string
.diph
);
2115 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_KEYNAME returned %#lx\n", hr
);
2117 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
2118 prop_range
.diph
.dwObj
= MAKELONG( 0, 0 );
2119 prop_range
.lMin
= 0xdeadbeef;
2120 prop_range
.lMax
= 0xdeadbeef;
2121 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
2122 todo_wine_if( version
< 0x0800 )
2123 ok( hr
== (version
< 0x0800 ? DI_OK
: DIERR_NOTFOUND
),
2124 "GetProperty DIPROP_RANGE returned %#lx\n", hr
);
2125 prop_range
.diph
.dwObj
= MAKELONG( 0, HID_USAGE_PAGE_GENERIC
);
2126 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
2127 ok( hr
== DIERR_NOTFOUND
, "GetProperty DIPROP_RANGE returned %#lx\n", hr
);
2128 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_PAGE_GENERIC
, HID_USAGE_GENERIC_X
);
2129 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
2130 ok( hr
== DIERR_NOTFOUND
, "GetProperty DIPROP_RANGE returned %#lx\n", hr
);
2131 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2132 prop_range
.lMin
= 0xdeadbeef;
2133 prop_range
.lMax
= 0xdeadbeef;
2134 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
2135 ok( hr
== DI_OK
, "GetProperty DIPROP_RANGE returned %#lx\n", hr
);
2136 ok( prop_range
.lMin
== 0, "got %ld expected %d\n", prop_range
.lMin
, 0 );
2137 ok( prop_range
.lMax
== 65535, "got %ld expected %d\n", prop_range
.lMax
, 65535 );
2138 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_LOGICALRANGE
, &prop_range
.diph
);
2139 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DI_OK
),
2140 "GetProperty DIPROP_LOGICALRANGE returned %#lx\n", hr
);
2143 ok( prop_range
.lMin
== -25, "got %ld expected %d\n", prop_range
.lMin
, -25 );
2144 ok( prop_range
.lMax
== 56, "got %ld expected %d\n", prop_range
.lMax
, 56 );
2146 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PHYSICALRANGE
, &prop_range
.diph
);
2147 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DI_OK
),
2148 "GetProperty DIPROP_PHYSICALRANGE returned %#lx\n", hr
);
2151 ok( prop_range
.lMin
== -25, "got %ld expected %d\n", prop_range
.lMin
, -25 );
2152 ok( prop_range
.lMax
== 56, "got %ld expected %d\n", prop_range
.lMax
, 56 );
2155 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
2156 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2157 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
2158 todo_wine_if( version
>= 0x0800 )
2159 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DIERR_NOTINITIALIZED
),
2160 "GetProperty DIPROP_APPDATA returned %#lx\n", hr
);
2162 hr
= IDirectInputDevice8_EnumObjects( device
, NULL
, NULL
, DIDFT_ALL
);
2163 ok( hr
== DIERR_INVALIDPARAM
, "EnumObjects returned %#lx\n", hr
);
2164 hr
= IDirectInputDevice8_EnumObjects( device
, check_object_count
, &res
, 0x20 );
2165 ok( hr
== DIERR_INVALIDPARAM
, "EnumObjects returned %#lx\n", hr
);
2167 hr
= IDirectInputDevice8_EnumObjects( device
, check_object_count
, &res
, DIDFT_AXIS
| DIDFT_PSHBUTTON
);
2168 ok( hr
== DI_OK
, "EnumObjects returned %#lx\n", hr
);
2169 todo_wine_if( version
< 0x0700 )
2170 ok( res
== (version
< 0x0700 ? 6 : 8), "got %lu objects\n", res
);
2171 hr
= IDirectInputDevice8_EnumObjects( device
, check_objects
, &check_objects_params
, DIDFT_ALL
);
2172 ok( hr
== DI_OK
, "EnumObjects returned %#lx\n", hr
);
2173 ok( check_objects_params
.index
>= check_objects_params
.expect_count
, "missing %u objects\n",
2174 check_objects_params
.expect_count
- check_objects_params
.index
);
2176 hr
= IDirectInputDevice8_GetObjectInfo( device
, NULL
, 0, DIPH_DEVICE
);
2177 ok( hr
== E_POINTER
, "GetObjectInfo returned: %#lx\n", hr
);
2178 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, 0, DIPH_DEVICE
);
2179 ok( hr
== DIERR_INVALIDPARAM
, "GetObjectInfo returned: %#lx\n", hr
);
2180 objinst
.dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
);
2181 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, 0, DIPH_DEVICE
);
2182 ok( hr
== DIERR_INVALIDPARAM
, "GetObjectInfo returned: %#lx\n", hr
);
2184 res
= MAKELONG( HID_USAGE_GENERIC_Z
, HID_USAGE_PAGE_GENERIC
);
2185 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, res
, DIPH_BYUSAGE
);
2186 todo_wine_if( version
< 0x0800 )
2187 ok( hr
== (version
< 0x0800 ? DI_OK
: DIERR_NOTFOUND
), "GetObjectInfo returned: %#lx\n", hr
);
2188 res
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2189 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, res
, DIPH_BYUSAGE
);
2190 ok( hr
== DI_OK
, "GetObjectInfo returned: %#lx\n", hr
);
2192 if (version
< 0x0700) expect_obj
= expect_objects_5
[0];
2193 else expect_obj
= expect_objects
[4];
2194 check_object( &objinst
, &expect_obj
, version
< 0x0700 ? &todo_ofs
: NULL
);
2196 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, 0x14, DIPH_BYOFFSET
);
2197 ok( hr
== DIERR_NOTFOUND
, "GetObjectInfo returned: %#lx\n", hr
);
2198 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, 0, DIPH_BYOFFSET
);
2199 ok( hr
== DIERR_NOTFOUND
, "GetObjectInfo returned: %#lx\n", hr
);
2200 res
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 3 );
2201 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, res
, DIPH_BYID
);
2202 ok( hr
== DIERR_NOTFOUND
, "GetObjectInfo returned: %#lx\n", hr
);
2203 res
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 1 );
2204 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, res
, DIPH_BYID
);
2205 ok( hr
== DI_OK
, "GetObjectInfo returned: %#lx\n", hr
);
2207 if (version
< 0x0700) expect_obj
= expect_objects_5
[6];
2208 else expect_obj
= expect_objects
[8];
2209 check_object( &objinst
, &expect_obj
, version
< 0x0700 ? &todo_ofs
: NULL
);
2211 hr
= IDirectInputDevice8_EnumEffects( device
, NULL
, NULL
, DIEFT_ALL
);
2212 ok( hr
== DIERR_INVALIDPARAM
, "EnumEffects returned %#lx\n", hr
);
2214 hr
= IDirectInputDevice8_EnumEffects( device
, check_effect_count
, &res
, 0xfe );
2215 ok( hr
== DI_OK
, "EnumEffects returned %#lx\n", hr
);
2216 ok( res
== 0, "got %lu expected %u\n", res
, 0 );
2218 hr
= IDirectInputDevice8_EnumEffects( device
, check_effect_count
, &res
, DIEFT_PERIODIC
);
2219 ok( hr
== DI_OK
, "EnumEffects returned %#lx\n", hr
);
2220 ok( res
== 0, "got %lu expected %u\n", res
, 0 );
2221 hr
= IDirectInputDevice8_EnumEffects( device
, check_effects
, &check_effects_params
, DIEFT_ALL
);
2222 ok( hr
== DI_OK
, "EnumEffects returned %#lx\n", hr
);
2223 ok( check_effects_params
.index
>= check_effects_params
.expect_count
, "missing %u effects\n",
2224 check_effects_params
.expect_count
- check_effects_params
.index
);
2226 hr
= IDirectInputDevice8_GetEffectInfo( device
, NULL
, &GUID_Sine
);
2227 ok( hr
== E_POINTER
, "GetEffectInfo returned %#lx\n", hr
);
2228 effectinfo
.dwSize
= sizeof(DIEFFECTINFOW
) + 1;
2229 hr
= IDirectInputDevice8_GetEffectInfo( device
, &effectinfo
, &GUID_Sine
);
2230 ok( hr
== DIERR_INVALIDPARAM
, "GetEffectInfo returned %#lx\n", hr
);
2231 effectinfo
.dwSize
= sizeof(DIEFFECTINFOW
);
2232 hr
= IDirectInputDevice8_GetEffectInfo( device
, &effectinfo
, &GUID_NULL
);
2233 ok( hr
== DIERR_DEVICENOTREG
, "GetEffectInfo returned %#lx\n", hr
);
2234 hr
= IDirectInputDevice8_GetEffectInfo( device
, &effectinfo
, &GUID_Sine
);
2235 ok( hr
== DIERR_DEVICENOTREG
, "GetEffectInfo returned %#lx\n", hr
);
2237 hr
= IDirectInputDevice8_SetDataFormat( device
, NULL
);
2238 ok( hr
== E_POINTER
, "SetDataFormat returned: %#lx\n", hr
);
2239 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2240 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#lx\n", hr
);
2241 dataformat
.dwSize
= sizeof(DIDATAFORMAT
);
2242 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2243 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#lx\n", hr
);
2244 dataformat
.dwObjSize
= sizeof(DIOBJECTDATAFORMAT
);
2245 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2246 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
2247 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
2248 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
2250 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, DIJOFS_Y
, DIPH_BYOFFSET
);
2251 ok( hr
== DI_OK
, "GetObjectInfo returned: %#lx\n", hr
);
2253 if (version
< 0x0700) expect_obj
= expect_objects_5
[1];
2254 else expect_obj
= expect_objects
[3];
2255 if (version
< 0x0800) expect_obj
.dwOfs
= DIJOFS_Y
;
2256 check_object( &objinst
, &expect_obj
, version
< 0x0800 ? &todo_ofs
: NULL
);
2258 hr
= IDirectInputDevice8_SetEventNotification( device
, (HANDLE
)0xdeadbeef );
2260 ok( hr
== E_HANDLE
, "SetEventNotification returned: %#lx\n", hr
);
2261 event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2262 ok( event
!= NULL
, "CreateEventW failed, last error %lu\n", GetLastError() );
2263 hr
= IDirectInputDevice8_SetEventNotification( device
, event
);
2264 ok( hr
== DI_OK
, "SetEventNotification returned: %#lx\n", hr
);
2266 file
= CreateFileW( prop_guid_path
.wszPath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
2267 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
2268 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
2269 ok( file
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError() );
2271 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, 0 );
2272 ok( hr
== DIERR_INVALIDPARAM
, "SetCooperativeLevel returned: %#lx\n", hr
);
2273 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
);
2274 ok( hr
== DIERR_INVALIDPARAM
, "SetCooperativeLevel returned: %#lx\n", hr
);
2275 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_FOREGROUND
| DISCL_NONEXCLUSIVE
);
2276 ok( hr
== E_HANDLE
, "SetCooperativeLevel returned: %#lx\n", hr
);
2277 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
2278 ok( hr
== E_HANDLE
, "SetCooperativeLevel returned: %#lx\n", hr
);
2279 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_FOREGROUND
| DISCL_EXCLUSIVE
);
2280 ok( hr
== E_HANDLE
, "SetCooperativeLevel returned: %#lx\n", hr
);
2282 hwnd
= CreateWindowW( L
"static", L
"dinput", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 10, 10, 200, 200,
2283 NULL
, NULL
, NULL
, NULL
);
2285 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_FOREGROUND
| DISCL_NONEXCLUSIVE
);
2286 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#lx\n", hr
);
2287 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
2288 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#lx\n", hr
);
2289 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_FOREGROUND
| DISCL_EXCLUSIVE
);
2290 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#lx\n", hr
);
2292 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
| DISCL_NONEXCLUSIVE
);
2293 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#lx\n", hr
);
2294 hr
= IDirectInputDevice8_Unacquire( device
);
2295 ok( hr
== DI_NOEFFECT
, "Unacquire returned: %#lx\n", hr
);
2296 hr
= IDirectInputDevice8_Acquire( device
);
2297 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
2298 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_FOREGROUND
| DISCL_EXCLUSIVE
);
2299 ok( hr
== DIERR_ACQUIRED
, "SetCooperativeLevel returned: %#lx\n", hr
);
2300 hr
= IDirectInputDevice8_Unacquire( device
);
2301 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2303 DestroyWindow( hwnd
);
2305 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
| DISCL_NONEXCLUSIVE
);
2306 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#lx\n", hr
);
2308 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
2309 ok( hr
== DIERR_NOTACQUIRED
, "GetDeviceState returned: %#lx\n", hr
);
2311 hr
= IDirectInputDevice8_Poll( device
);
2312 ok( hr
== DIERR_NOTACQUIRED
, "Poll returned: %#lx\n", hr
);
2314 hr
= IDirectInputDevice8_Acquire( device
);
2315 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
2317 hr
= IDirectInputDevice8_Poll( device
);
2318 todo_wine_if( version
< 0x0700 )
2319 ok( hr
== (version
< 0x0700 ? DI_OK
: DI_NOEFFECT
), "Poll returned: %#lx\n", hr
);
2321 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
) + 1, &state
);
2322 ok( hr
== DIERR_INVALIDPARAM
, "GetDeviceState returned: %#lx\n", hr
);
2324 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
2326 winetest_push_context( "state[%ld]", i
);
2327 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
2328 ok( hr
== DI_OK
, "GetDeviceState returned: %#lx\n", hr
);
2329 check_member( state
, expect_state
[i
], "%ld", lX
);
2330 check_member( state
, expect_state
[i
], "%ld", lY
);
2331 check_member( state
, expect_state
[i
], "%ld", lZ
);
2332 check_member( state
, expect_state
[i
], "%ld", lRx
);
2333 check_member( state
, expect_state
[i
], "%#lx", rgdwPOV
[0] );
2334 check_member( state
, expect_state
[i
], "%#lx", rgdwPOV
[1] );
2335 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[0] );
2336 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[1] );
2337 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[2] );
2339 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
2341 res
= WaitForSingleObject( event
, 100 );
2342 if (i
== 0 || i
== 3) ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject succeeded\n" );
2343 else ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
2344 ResetEvent( event
);
2345 winetest_pop_context();
2348 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
2349 ok( hr
== DI_OK
, "GetDeviceState returned: %#lx\n", hr
);
2350 winetest_push_context( "state[%ld]", i
);
2351 check_member( state
, expect_state
[i
], "%ld", lX
);
2352 check_member( state
, expect_state
[i
], "%ld", lY
);
2353 check_member( state
, expect_state
[i
], "%ld", lZ
);
2354 check_member( state
, expect_state
[i
], "%ld", lRx
);
2355 check_member( state
, expect_state
[i
], "%#lx", rgdwPOV
[0] );
2356 check_member( state
, expect_state
[i
], "%#lx", rgdwPOV
[1] );
2357 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[0] );
2358 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[1] );
2359 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[2] );
2360 winetest_pop_context();
2363 size
= version
< 0x0800 ? sizeof(DIDEVICEOBJECTDATA_DX3
) : sizeof(DIDEVICEOBJECTDATA
);
2364 hr
= IDirectInputDevice8_GetDeviceData( device
, size
- 1, objdata
, &res
, DIGDD_PEEK
);
2365 todo_wine_if( version
>= 0x0800 )
2366 ok( hr
== (version
< 0x0800 ? DI_OK
: DIERR_INVALIDPARAM
), "GetDeviceData returned %#lx\n", hr
);
2368 hr
= IDirectInputDevice8_GetDeviceData( device
, size
, objdata
, &res
, DIGDD_PEEK
);
2369 ok( hr
== DIERR_NOTBUFFERED
, "GetDeviceData returned %#lx\n", hr
);
2371 hr
= IDirectInputDevice8_Unacquire( device
);
2372 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2373 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
2374 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2375 prop_dword
.dwData
= 1;
2376 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
2377 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_BUFFERSIZE returned %#lx\n", hr
);
2378 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
2379 prop_dword
.diph
.dwObj
= 0;
2380 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
2381 ok( hr
== DI_OK
, "SetProperty DIPROP_BUFFERSIZE returned %#lx\n", hr
);
2382 hr
= IDirectInputDevice8_Acquire( device
);
2383 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2386 hr
= IDirectInputDevice8_GetDeviceData( device
, size
, objdata
, &res
, DIGDD_PEEK
);
2387 ok( hr
== DI_OK
, "GetDeviceData returned %#lx\n", hr
);
2388 ok( res
== 0, "got %lu expected %u\n", res
, 0 );
2390 send_hid_input( file
, &injected_input
[0], sizeof(*injected_input
) );
2391 res
= WaitForSingleObject( event
, 100 );
2392 if (res
== WAIT_TIMEOUT
) /* Acquire is asynchronous */
2394 send_hid_input( file
, &injected_input
[0], sizeof(*injected_input
) );
2395 res
= WaitForSingleObject( event
, 5000 );
2397 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
2398 ResetEvent( event
);
2401 hr
= IDirectInputDevice8_GetDeviceData( device
, size
, objdata
, &res
, DIGDD_PEEK
);
2402 todo_wine_if( version
< 0x0800 )
2403 ok( hr
== DI_BUFFEROVERFLOW
, "GetDeviceData returned %#lx\n", hr
);
2404 ok( res
== 0, "got %lu expected %u\n", res
, 0 );
2406 hr
= IDirectInputDevice8_GetDeviceData( device
, size
, objdata
, &res
, 0 );
2407 todo_wine_if( version
>= 0x0800 )
2408 ok( hr
== DI_OK
, "GetDeviceData returned %#lx\n", hr
);
2409 ok( res
== 0, "got %lu expected %u\n", res
, 0 );
2411 hr
= IDirectInputDevice8_Unacquire( device
);
2412 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2413 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
2414 prop_dword
.diph
.dwObj
= 0;
2415 prop_dword
.dwData
= 10;
2416 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
2417 ok( hr
== DI_OK
, "SetProperty DIPROP_BUFFERSIZE returned %#lx\n", hr
);
2418 hr
= IDirectInputDevice8_Acquire( device
);
2419 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2421 send_hid_input( file
, &injected_input
[1], sizeof(*injected_input
) );
2422 res
= WaitForSingleObject( event
, 100 );
2423 if (res
== WAIT_TIMEOUT
) /* Acquire is asynchronous */
2425 send_hid_input( file
, &injected_input
[1], sizeof(*injected_input
) );
2426 res
= WaitForSingleObject( event
, 5000 );
2428 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
2429 ResetEvent( event
);
2432 hr
= IDirectInputDevice8_GetDeviceData( device
, size
, objdata
, &res
, DIGDD_PEEK
);
2433 ok( hr
== DI_OK
, "GetDeviceData returned %#lx\n", hr
);
2434 ok( res
== 1, "got %lu expected %u\n", res
, 1 );
2435 check_member( objdata
[0], expect_objdata
[0], "%#lx", dwOfs
);
2436 check_member( objdata
[0], expect_objdata
[0], "%#lx", dwData
);
2437 if (version
>= 0x0800) ok( objdata
[0].uAppData
== -1, "got %p\n", (void *)objdata
[0].uAppData
);
2439 hr
= IDirectInputDevice8_GetDeviceData( device
, size
, objdata
, &res
, 0 );
2440 ok( hr
== DI_OK
, "GetDeviceData returned %#lx\n", hr
);
2441 ok( res
== 4, "got %lu expected %u\n", res
, 4 );
2442 for (i
= 0; i
< 4; ++i
)
2444 DIDEVICEOBJECTDATA
*ptr
= (DIDEVICEOBJECTDATA
*)((char *)objdata
+ size
* i
);
2445 winetest_push_context( "objdata[%ld]", i
);
2446 check_member( *ptr
, expect_objdata
[1 + i
], "%#lx", dwOfs
);
2447 check_member( *ptr
, expect_objdata
[1 + i
], "%#lx", dwData
);
2448 if (version
>= 0x0800) ok( ptr
->uAppData
== -1, "got %p\n", (void *)ptr
->uAppData
);
2449 winetest_pop_context();
2452 send_hid_input( file
, &injected_input
[2], sizeof(*injected_input
) );
2453 res
= WaitForSingleObject( event
, 5000 );
2454 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
2455 ResetEvent( event
);
2456 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
2457 res
= WaitForSingleObject( event
, 5000 );
2458 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
2459 ResetEvent( event
);
2462 hr
= IDirectInputDevice8_GetDeviceData( device
, size
, objdata
, &res
, 0 );
2463 todo_wine_if( version
< 0x0800 )
2464 ok( hr
== DI_BUFFEROVERFLOW
, "GetDeviceData returned %#lx\n", hr
);
2465 ok( res
== 1, "got %lu expected %u\n", res
, 1 );
2467 check_member( objdata
[0], expect_objdata
[5], "%#lx", dwOfs
);
2469 check_member( objdata
[0], expect_objdata
[5], "%#lx", dwData
);
2470 if (version
>= 0x0800) ok( objdata
[0].uAppData
== -1, "got %p\n", (void *)objdata
[0].uAppData
);
2471 res
= ARRAY_SIZE(objdata
);
2472 hr
= IDirectInputDevice8_GetDeviceData( device
, size
, objdata
, &res
, 0 );
2473 ok( hr
== DI_OK
, "GetDeviceData returned %#lx\n", hr
);
2474 ok( res
== 8, "got %lu expected %u\n", res
, 8 );
2475 for (i
= 0; i
< 8; ++i
)
2477 DIDEVICEOBJECTDATA
*ptr
= (DIDEVICEOBJECTDATA
*)((char *)objdata
+ size
* i
);
2478 winetest_push_context( "objdata[%ld]", i
);
2480 check_member( *ptr
, expect_objdata
[6 + i
], "%#lx", dwOfs
);
2481 todo_wine_if( i
== 1 || i
== 2 || i
== 6 )
2482 check_member( *ptr
, expect_objdata
[6 + i
], "%#lx", dwData
);
2483 if (version
>= 0x0800) ok( ptr
->uAppData
== -1, "got %p\n", (void *)ptr
->uAppData
);
2484 winetest_pop_context();
2487 send_hid_input( file
, &injected_input
[3], sizeof(*injected_input
) );
2488 res
= WaitForSingleObject( event
, 5000 );
2489 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
2490 ResetEvent( event
);
2492 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
2493 ok( hr
== DI_OK
, "GetDeviceState returned: %#lx\n", hr
);
2494 check_member( state
, expect_state
[3], "%ld", lX
);
2495 check_member( state
, expect_state
[3], "%ld", lY
);
2496 check_member( state
, expect_state
[3], "%ld", lZ
);
2497 check_member( state
, expect_state
[3], "%ld", lRx
);
2498 check_member( state
, expect_state
[3], "%ld", rgdwPOV
[0] );
2499 check_member( state
, expect_state
[3], "%ld", rgdwPOV
[1] );
2500 check_member( state
, expect_state
[3], "%#x", rgbButtons
[0] );
2501 check_member( state
, expect_state
[3], "%#x", rgbButtons
[1] );
2502 check_member( state
, expect_state
[3], "%#x", rgbButtons
[2] );
2504 hr
= IDirectInputDevice8_Unacquire( device
);
2505 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2507 dataformat
.dwSize
= sizeof(DIDATAFORMAT
);
2508 dataformat
.dwObjSize
= sizeof(DIOBJECTDATAFORMAT
);
2509 dataformat
.dwFlags
= DIDF_ABSAXIS
;
2510 dataformat
.dwDataSize
= sizeof(buffer
);
2511 dataformat
.dwNumObjs
= 0;
2512 dataformat
.rgodf
= objdataformat
;
2513 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2514 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
2516 dataformat
.dwNumObjs
= 1;
2517 dataformat
.dwDataSize
= 8;
2518 objdataformat
[0].pguid
= NULL
;
2519 objdataformat
[0].dwOfs
= 2;
2520 objdataformat
[0].dwType
= DIDFT_AXIS
| DIDFT_ANYINSTANCE
;
2521 objdataformat
[0].dwFlags
= 0;
2522 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2524 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#lx\n", hr
);
2525 objdataformat
[0].dwOfs
= 4;
2526 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2527 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
2528 dataformat
.dwDataSize
= 10;
2529 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2531 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#lx\n", hr
);
2532 dataformat
.dwDataSize
= 8;
2533 objdataformat
[0].dwOfs
= 2;
2534 objdataformat
[0].dwType
= DIDFT_OPTIONAL
| 0xff | DIDFT_ANYINSTANCE
;
2535 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2537 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#lx\n", hr
);
2539 dataformat
.dwNumObjs
= 2;
2540 dataformat
.dwDataSize
= 5;
2541 objdataformat
[0].pguid
= NULL
;
2542 objdataformat
[0].dwOfs
= 4;
2543 objdataformat
[0].dwType
= DIDFT_BUTTON
| DIDFT_ANYINSTANCE
;
2544 objdataformat
[0].dwFlags
= 0;
2545 objdataformat
[1].pguid
= NULL
;
2546 objdataformat
[1].dwOfs
= 0;
2547 objdataformat
[1].dwType
= DIDFT_AXIS
| DIDFT_MAKEINSTANCE( 0 );
2548 objdataformat
[1].dwFlags
= 0;
2549 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2551 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#lx\n", hr
);
2552 dataformat
.dwDataSize
= 8;
2553 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2554 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
2556 dataformat
.dwNumObjs
= 4;
2557 dataformat
.dwDataSize
= 12;
2558 objdataformat
[0].pguid
= NULL
;
2559 objdataformat
[0].dwOfs
= 0;
2560 objdataformat
[0].dwType
= DIDFT_AXIS
| DIDFT_MAKEINSTANCE( 0 );
2561 objdataformat
[0].dwFlags
= 0;
2562 objdataformat
[1].pguid
= NULL
;
2563 objdataformat
[1].dwOfs
= 0;
2564 objdataformat
[1].dwType
= DIDFT_AXIS
| DIDFT_MAKEINSTANCE( 0 );
2565 objdataformat
[1].dwFlags
= 0;
2566 objdataformat
[2].pguid
= &GUID_ZAxis
;
2567 objdataformat
[2].dwOfs
= 8;
2568 objdataformat
[2].dwType
= 0xff | DIDFT_ANYINSTANCE
;
2569 objdataformat
[2].dwFlags
= 0;
2570 objdataformat
[3].pguid
= &GUID_POV
;
2571 objdataformat
[3].dwOfs
= 0;
2572 objdataformat
[3].dwType
= 0xff | DIDFT_ANYINSTANCE
;
2573 objdataformat
[3].dwFlags
= 0;
2574 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2575 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#lx\n", hr
);
2576 objdataformat
[1].dwType
= DIDFT_AXIS
| DIDFT_MAKEINSTANCE( 12 );
2577 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2578 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#lx\n", hr
);
2579 objdataformat
[1].dwType
= DIDFT_AXIS
| DIDFT_MAKEINSTANCE( 0xff );
2580 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2581 ok( hr
== (version
< 0x0700 ? DI_OK
: DIERR_INVALIDPARAM
),
2582 "SetDataFormat returned: %#lx\n", hr
);
2583 objdataformat
[1].dwType
= DIDFT_AXIS
| DIDFT_MAKEINSTANCE( 1 );
2584 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2585 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
2586 objdataformat
[1].pguid
= &GUID_RzAxis
;
2587 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2588 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#lx\n", hr
);
2589 objdataformat
[1].pguid
= &GUID_Unknown
;
2590 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2591 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#lx\n", hr
);
2592 objdataformat
[1].pguid
= &GUID_YAxis
;
2593 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2594 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
2595 objdataformat
[1].pguid
= NULL
;
2596 objdataformat
[1].dwType
= DIDFT_OPTIONAL
| DIDFT_AXIS
| DIDFT_MAKEINSTANCE( 0 );
2597 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2598 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
2600 dataformat
.dwNumObjs
= 0;
2601 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2602 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
2603 hr
= IDirectInputDevice8_Acquire( device
);
2604 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2606 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
2607 res
= WaitForSingleObject( event
, 100 );
2609 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject failed\n" );
2610 ResetEvent( event
);
2612 hr
= IDirectInputDevice8_GetDeviceState( device
, dataformat
.dwDataSize
, buffer
);
2613 ok( hr
== DI_OK
, "GetDeviceState returned: %#lx\n", hr
);
2614 hr
= IDirectInputDevice8_Unacquire( device
);
2615 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2617 dataformat
.dwNumObjs
= 4;
2618 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
2619 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
2620 hr
= IDirectInputDevice8_Acquire( device
);
2621 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2623 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
2624 res
= WaitForSingleObject( event
, 100 );
2625 if (res
== WAIT_TIMEOUT
) /* Acquire is asynchronous */
2627 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
2628 res
= WaitForSingleObject( event
, 100 );
2631 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
2632 ResetEvent( event
);
2634 send_hid_input( file
, &injected_input
[3], sizeof(*injected_input
) );
2635 res
= WaitForSingleObject( event
, 5000 );
2636 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
2637 ResetEvent( event
);
2639 hr
= IDirectInputDevice8_GetDeviceState( device
, dataformat
.dwDataSize
, buffer
);
2640 ok( hr
== DI_OK
, "GetDeviceState returned: %#lx\n", hr
);
2641 ok( ((ULONG
*)buffer
)[0] == 0x512b, "got %#lx, expected %#x\n", ((ULONG
*)buffer
)[0], 0x512b );
2642 ok( ((ULONG
*)buffer
)[1] == 0, "got %#lx, expected %#x\n", ((ULONG
*)buffer
)[1], 0 );
2643 ok( ((ULONG
*)buffer
)[2] == 0x7fff, "got %#lx, expected %#x\n", ((ULONG
*)buffer
)[2], 0x7fff );
2644 hr
= IDirectInputDevice8_Unacquire( device
);
2645 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2646 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_LOGICALRANGE
, &prop_range
.diph
);
2647 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_LOGICALRANGE returned %#lx\n", hr
);
2648 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_PHYSICALRANGE
, &prop_range
.diph
);
2649 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_PHYSICALRANGE returned %#lx\n", hr
);
2651 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
2652 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
2653 hr
= IDirectInputDevice8_Acquire( device
);
2654 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2656 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
2657 res
= WaitForSingleObject( event
, 100 );
2658 if (res
== WAIT_TIMEOUT
) /* Acquire is asynchronous */
2660 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
2661 res
= WaitForSingleObject( event
, 5000 );
2663 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
2664 ResetEvent( event
);
2666 send_hid_input( file
, &injected_input
[3], sizeof(*injected_input
) );
2667 res
= WaitForSingleObject( event
, 5000 );
2668 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
2669 ResetEvent( event
);
2671 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
2672 ok( hr
== DI_OK
, "GetDeviceState returned: %#lx\n", hr
);
2673 check_member( state
, expect_state
[3], "%ld", lX
);
2674 check_member( state
, expect_state
[3], "%ld", lY
);
2675 check_member( state
, expect_state
[3], "%ld", lZ
);
2676 check_member( state
, expect_state
[3], "%ld", lRx
);
2677 check_member( state
, expect_state
[3], "%ld", rgdwPOV
[0] );
2678 check_member( state
, expect_state
[3], "%ld", rgdwPOV
[1] );
2679 check_member( state
, expect_state
[3], "%#x", rgbButtons
[0] );
2680 check_member( state
, expect_state
[3], "%#x", rgbButtons
[1] );
2681 check_member( state
, expect_state
[3], "%#x", rgbButtons
[2] );
2683 prop_range
.diph
.dwHow
= DIPH_DEVICE
;
2684 prop_range
.diph
.dwObj
= 0;
2685 prop_range
.lMin
= 1000;
2686 prop_range
.lMax
= 51000;
2687 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
2688 ok( hr
== DI_OK
, "SetProperty DIPROP_RANGE returned %#lx\n", hr
);
2689 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
2690 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2691 prop_range
.lMin
= -4000;
2692 prop_range
.lMax
= -14000;
2693 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
2694 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_RANGE returned %#lx\n", hr
);
2695 prop_range
.lMin
= -14000;
2696 prop_range
.lMax
= -4000;
2697 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
2698 ok( hr
== DI_OK
, "SetProperty DIPROP_RANGE returned %#lx\n", hr
);
2699 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_LOGICALRANGE
, &prop_range
.diph
);
2700 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DIERR_ACQUIRED
),
2701 "SetProperty DIPROP_LOGICALRANGE returned %#lx\n", hr
);
2702 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_PHYSICALRANGE
, &prop_range
.diph
);
2703 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DIERR_ACQUIRED
),
2704 "SetProperty DIPROP_PHYSICALRANGE returned %#lx\n", hr
);
2706 prop_range
.diph
.dwHow
= DIPH_DEVICE
;
2707 prop_range
.diph
.dwObj
= 0;
2708 prop_range
.lMin
= 0xdeadbeef;
2709 prop_range
.lMax
= 0xdeadbeef;
2710 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
2711 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_RANGE returned %#lx\n", hr
);
2712 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
2713 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2714 prop_range
.lMin
= 0xdeadbeef;
2715 prop_range
.lMax
= 0xdeadbeef;
2716 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
2717 ok( hr
== DI_OK
, "GetProperty DIPROP_RANGE returned %#lx\n", hr
);
2718 ok( prop_range
.lMin
== -14000, "got %ld expected %d\n", prop_range
.lMin
, -14000 );
2719 ok( prop_range
.lMax
== -4000, "got %ld expected %d\n", prop_range
.lMax
, -4000 );
2720 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
2721 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_Y
, HID_USAGE_PAGE_GENERIC
);
2722 prop_range
.lMin
= 0xdeadbeef;
2723 prop_range
.lMax
= 0xdeadbeef;
2724 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
2725 ok( hr
== DI_OK
, "GetProperty DIPROP_RANGE returned %#lx\n", hr
);
2726 ok( prop_range
.lMin
== 1000, "got %ld expected %d\n", prop_range
.lMin
, 1000 );
2727 ok( prop_range
.lMax
== 51000, "got %ld expected %d\n", prop_range
.lMax
, 51000 );
2729 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
2730 ok( hr
== DI_OK
, "GetDeviceState returned: %#lx\n", hr
);
2731 ok( state
.lX
== expect_state_abs
[1].lX
|| broken( state
.lX
== 16853 ) /* w8 */, "got lX %ld\n", state
.lX
);
2732 ok( state
.lY
== expect_state_abs
[1].lY
|| broken( state
.lY
== 16853 ) /* w8 */, "got lY %ld\n", state
.lY
);
2733 check_member( state
, expect_state_abs
[1], "%ld", lZ
);
2734 check_member( state
, expect_state_abs
[1], "%ld", lRx
);
2735 check_member( state
, expect_state_abs
[1], "%ld", rgdwPOV
[0] );
2736 check_member( state
, expect_state_abs
[1], "%ld", rgdwPOV
[1] );
2737 check_member( state
, expect_state_abs
[1], "%#x", rgbButtons
[0] );
2738 check_member( state
, expect_state_abs
[1], "%#x", rgbButtons
[1] );
2739 check_member( state
, expect_state_abs
[1], "%#x", rgbButtons
[2] );
2741 hr
= IDirectInputDevice8_SetProperty( device
, NULL
, NULL
);
2742 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty returned %#lx\n", hr
);
2743 hr
= IDirectInputDevice8_SetProperty( device
, &GUID_NULL
, NULL
);
2744 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty returned %#lx\n", hr
);
2745 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_VIDPID
, NULL
);
2746 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty returned %#lx\n", hr
);
2747 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_VIDPID
, &prop_string
.diph
);
2748 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DIERR_INVALIDPARAM
),
2749 "SetProperty DIPROP_VIDPID returned %#lx\n", hr
);
2751 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
2752 prop_dword
.diph
.dwObj
= 0;
2753 prop_dword
.dwData
= 0xdeadbeef;
2754 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
2755 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DIERR_READONLY
),
2756 "SetProperty DIPROP_VIDPID returned %#lx\n", hr
);
2757 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
2758 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_GUIDANDPATH returned %#lx\n", hr
);
2760 prop_string
.diph
.dwHow
= DIPH_DEVICE
;
2761 prop_string
.diph
.dwObj
= 0;
2762 wcscpy( prop_string
.wsz
, L
"instance name" );
2763 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_INSTANCENAME
, &prop_string
.diph
);
2764 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_INSTANCENAME returned %#lx\n", hr
);
2766 wcscpy( prop_string
.wsz
, L
"product name" );
2767 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_PRODUCTNAME
, &prop_string
.diph
);
2769 ok( hr
== DI_OK
, "SetProperty DIPROP_PRODUCTNAME returned %#lx\n", hr
);
2770 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PRODUCTNAME
, &prop_string
.diph
);
2771 ok( hr
== DI_OK
, "GetProperty DIPROP_PRODUCTNAME returned %#lx\n", hr
);
2772 ok( !wcscmp( prop_string
.wsz
, expect_devinst
.tszProductName
), "got product %s\n",
2773 debugstr_w(prop_string
.wsz
) );
2775 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_TYPENAME
, &prop_string
.diph
);
2776 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DIERR_READONLY
),
2777 "SetProperty DIPROP_TYPENAME returned %#lx\n", hr
);
2778 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_USERNAME
, &prop_string
.diph
);
2779 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DIERR_READONLY
),
2780 "SetProperty DIPROP_USERNAME returned %#lx\n", hr
);
2781 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
2782 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_FFLOAD returned %#lx\n", hr
);
2783 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_GRANULARITY
, &prop_dword
.diph
);
2784 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_GRANULARITY returned %#lx\n", hr
);
2786 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_JOYSTICKID
, &prop_dword
.diph
);
2788 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_JOYSTICKID returned %#lx\n", hr
);
2789 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
2790 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_AXISMODE returned %#lx\n", hr
);
2791 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
2792 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_BUFFERSIZE returned %#lx\n", hr
);
2793 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
2794 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_AUTOCENTER returned %#lx\n", hr
);
2795 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
2796 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2797 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
2798 todo_wine_if( version
>= 0x0800 )
2799 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DIERR_ACQUIRED
),
2800 "SetProperty DIPROP_APPDATA returned %#lx\n", hr
);
2802 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
2803 prop_dword
.diph
.dwObj
= 0;
2804 prop_dword
.dwData
= 10001;
2805 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
2806 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_DEADZONE returned %#lx\n", hr
);
2807 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
2808 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_SATURATION returned %#lx\n", hr
);
2809 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
2810 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_CALIBRATIONMODE returned %#lx\n", hr
);
2811 prop_dword
.dwData
= 1000;
2812 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
2813 ok( hr
== DI_OK
, "SetProperty DIPROP_DEADZONE returned %#lx\n", hr
);
2814 prop_dword
.dwData
= 6000;
2815 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
2816 ok( hr
== DI_OK
, "SetProperty DIPROP_SATURATION returned %#lx\n", hr
);
2817 prop_dword
.dwData
= DIPROPCALIBRATIONMODE_COOKED
;
2818 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
2819 ok( hr
== DI_OK
, "SetProperty DIPROP_CALIBRATIONMODE returned %#lx\n", hr
);
2821 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
2822 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_DEADZONE returned %#lx\n", hr
);
2823 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
2824 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_SATURATION returned %#lx\n", hr
);
2825 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
2826 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_CALIBRATIONMODE returned %#lx\n", hr
);
2828 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
2829 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2830 prop_dword
.dwData
= 2000;
2831 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
2832 ok( hr
== DI_OK
, "SetProperty DIPROP_DEADZONE returned %#lx\n", hr
);
2833 ok( prop_dword
.dwData
== 2000, "got %lu expected %u\n", prop_dword
.dwData
, 2000 );
2834 prop_dword
.dwData
= 7000;
2835 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
2836 ok( hr
== DI_OK
, "SetProperty DIPROP_SATURATION returned %#lx\n", hr
);
2838 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
2839 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2840 prop_dword
.dwData
= 0xdeadbeef;
2841 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
2842 ok( hr
== DI_OK
, "GetProperty DIPROP_DEADZONE returned %#lx\n", hr
);
2843 ok( prop_dword
.dwData
== 2000, "got %lu expected %u\n", prop_dword
.dwData
, 2000 );
2844 prop_dword
.dwData
= 0xdeadbeef;
2845 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
2846 ok( hr
== DI_OK
, "GetProperty DIPROP_SATURATION returned %#lx\n", hr
);
2847 ok( prop_dword
.dwData
== 7000, "got %lu expected %u\n", prop_dword
.dwData
, 7000 );
2849 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
2850 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_Y
, HID_USAGE_PAGE_GENERIC
);
2851 prop_dword
.dwData
= 0xdeadbeef;
2852 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
2853 ok( hr
== DI_OK
, "GetProperty DIPROP_DEADZONE returned %#lx\n", hr
);
2854 ok( prop_dword
.dwData
== 1000, "got %lu expected %u\n", prop_dword
.dwData
, 1000 );
2855 prop_dword
.dwData
= 0xdeadbeef;
2856 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
2857 ok( hr
== DI_OK
, "GetProperty DIPROP_SATURATION returned %#lx\n", hr
);
2858 ok( prop_dword
.dwData
== 6000, "got %lu expected %u\n", prop_dword
.dwData
, 6000 );
2860 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
2862 winetest_push_context( "state[%ld]", i
);
2863 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
2864 ok( hr
== DI_OK
, "GetDeviceState returned: %#lx\n", hr
);
2865 if (broken( state
.lX
== -10750 )) win_skip( "Ignoring 32-bit rounding\n" );
2868 check_member( state
, expect_state_abs
[i
], "%ld", lX
);
2869 check_member( state
, expect_state_abs
[i
], "%ld", lY
);
2871 check_member( state
, expect_state_abs
[i
], "%ld", lZ
);
2872 check_member( state
, expect_state_abs
[i
], "%ld", lRx
);
2873 check_member( state
, expect_state_abs
[i
], "%ld", rgdwPOV
[0] );
2874 check_member( state
, expect_state_abs
[i
], "%ld", rgdwPOV
[1] );
2875 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[0] );
2876 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[1] );
2877 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[2] );
2879 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
2881 res
= WaitForSingleObject( event
, 100 );
2882 if (i
== 0) ok( res
== WAIT_TIMEOUT
|| broken( res
== WAIT_OBJECT_0
) /* w8 */, "WaitForSingleObject succeeded\n" );
2883 else if (i
== 3) ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject succeeded\n" );
2884 else ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
2885 ResetEvent( event
);
2886 winetest_pop_context();
2889 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
2890 ok( hr
== DI_OK
, "GetDeviceState returned: %#lx\n", hr
);
2891 winetest_push_context( "state[%ld]", i
);
2892 check_member( state
, expect_state_abs
[i
], "%ld", lX
);
2893 check_member( state
, expect_state_abs
[i
], "%ld", lY
);
2894 check_member( state
, expect_state_abs
[i
], "%ld", lZ
);
2895 check_member( state
, expect_state_abs
[i
], "%ld", lRx
);
2896 check_member( state
, expect_state_abs
[i
], "%ld", rgdwPOV
[0] );
2897 check_member( state
, expect_state_abs
[i
], "%ld", rgdwPOV
[1] );
2898 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[0] );
2899 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[1] );
2900 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[2] );
2901 winetest_pop_context();
2903 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
2904 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2905 prop_dword
.dwData
= DIPROPCALIBRATIONMODE_RAW
;
2906 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
2907 ok( hr
== DI_OK
, "SetProperty DIPROP_CALIBRATIONMODE returned %#lx\n", hr
);
2908 prop_dword
.dwData
= 0xdeadbeef;
2909 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
2910 ok( hr
== DI_OK
, "GetProperty DIPROP_CALIBRATIONMODE returned %#lx\n", hr
);
2911 ok( prop_dword
.dwData
== DIPROPCALIBRATIONMODE_RAW
, "got %lu expected %u\n", prop_dword
.dwData
,
2912 DIPROPCALIBRATIONMODE_RAW
);
2914 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
2915 ok( hr
== DI_OK
, "GetDeviceState returned: %#lx\n", hr
);
2916 winetest_push_context( "state[%ld]", i
);
2917 todo_wine_if( version
>= 0x0700 )
2918 ok( state
.lX
== (version
< 0x0700 ? -9000 : 15), "got lX %ld\n", state
.lX
);
2919 check_member( state
, expect_state_abs
[0], "%ld", lY
);
2920 check_member( state
, expect_state_abs
[0], "%ld", lZ
);
2921 check_member( state
, expect_state_abs
[0], "%ld", lRx
);
2922 check_member( state
, expect_state_abs
[0], "%ld", rgdwPOV
[0] );
2923 check_member( state
, expect_state_abs
[0], "%ld", rgdwPOV
[1] );
2924 winetest_pop_context();
2926 prop_dword
.dwData
= DIPROPCALIBRATIONMODE_COOKED
;
2927 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
2928 ok( hr
== DI_OK
, "SetProperty DIPROP_CALIBRATIONMODE returned %#lx\n", hr
);
2930 send_hid_input( file
, &injected_input
[ARRAY_SIZE(injected_input
) - 1], sizeof(*injected_input
) );
2931 res
= WaitForSingleObject( event
, 5000 );
2932 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
2934 hr
= IDirectInputDevice8_Unacquire( device
);
2935 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2937 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
2938 prop_dword
.diph
.dwObj
= 0;
2939 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_JOYSTICKID
, &prop_dword
.diph
);
2940 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_JOYSTICKID returned %#lx\n", hr
);
2941 prop_dword
.dwData
= 0x1000;
2942 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
2943 ok( hr
== DI_OK
, "SetProperty DIPROP_BUFFERSIZE returned %#lx\n", hr
);
2944 prop_dword
.dwData
= 0xdeadbeef;
2945 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
2946 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_AUTOCENTER returned %#lx\n", hr
);
2947 prop_dword
.dwData
= DIPROPAUTOCENTER_ON
;
2948 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
2949 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_AUTOCENTER returned %#lx\n", hr
);
2950 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
2951 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2952 prop_pointer
.uData
= 0xfeedcafe;
2953 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
2954 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DI_OK
),
2955 "SetProperty DIPROP_APPDATA returned %#lx\n", hr
);
2957 prop_dword
.dwData
= 0xdeadbeef;
2958 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
2959 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_AXISMODE returned %#lx\n", hr
);
2960 prop_dword
.dwData
= DIPROPAXISMODE_REL
;
2961 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
2962 ok( hr
== DI_OK
, "SetProperty DIPROP_AXISMODE returned %#lx\n", hr
);
2964 hr
= IDirectInputDevice8_Acquire( device
);
2965 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
2967 prop_dword
.dwData
= 0xdeadbeef;
2968 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
2970 ok( hr
== DI_OK
, "GetProperty DIPROP_AXISMODE returned %#lx\n", hr
);
2972 ok( prop_dword
.dwData
== DIPROPAXISMODE_REL
, "got %lu expected %u\n", prop_dword
.dwData
, DIPROPAXISMODE_REL
);
2974 prop_dword
.dwData
= 0xdeadbeef;
2975 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
2976 ok( hr
== DI_OK
, "GetProperty DIPROP_BUFFERSIZE returned %#lx\n", hr
);
2977 ok( prop_dword
.dwData
== 0x1000, "got %#lx expected %#x\n", prop_dword
.dwData
, 0x1000 );
2979 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
2980 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
2981 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
2982 ok( hr
== (version
< 0x0800 ? DIERR_UNSUPPORTED
: DI_OK
),
2983 "GetProperty DIPROP_APPDATA returned %#lx\n", hr
);
2984 if (hr
== DI_OK
) ok( prop_pointer
.uData
== 0xfeedcafe, "got %p\n", (void *)prop_pointer
.uData
);
2986 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
2987 prop_dword
.diph
.dwObj
= 0;
2988 prop_dword
.dwData
= 0xdeadbeef;
2989 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
2990 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr
);
2991 prop_dword
.dwData
= 1000;
2992 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
2993 ok( hr
== DI_OK
, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr
);
2995 prop_dword
.dwData
= 0xdeadbeef;
2996 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATION
, &prop_dword
.diph
);
2998 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_CALIBRATION returned %#lx\n", hr
);
2999 prop_dword
.dwData
= 0xdeadbeef;
3000 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
3001 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_DEADZONE returned %#lx\n", hr
);
3002 prop_dword
.dwData
= 0xdeadbeef;
3003 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
3004 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_SATURATION returned %#lx\n", hr
);
3006 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
3008 winetest_push_context( "state[%ld]", i
);
3009 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
3010 ok( hr
== DI_OK
, "GetDeviceState returned: %#lx\n", hr
);
3012 check_member( state
, expect_state_rel
[i
], "%ld", lX
);
3014 check_member( state
, expect_state_rel
[i
], "%ld", lY
);
3016 check_member( state
, expect_state_rel
[i
], "%ld", lZ
);
3017 check_member( state
, expect_state_rel
[i
], "%ld", lRx
);
3018 check_member( state
, expect_state_rel
[i
], "%ld", rgdwPOV
[0] );
3019 check_member( state
, expect_state_rel
[i
], "%ld", rgdwPOV
[1] );
3020 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[0] );
3021 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[1] );
3022 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[2] );
3024 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
3026 res
= WaitForSingleObject( event
, 100 );
3027 if (i
== 0 && res
== WAIT_TIMEOUT
) /* Acquire is asynchronous */
3029 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
3030 res
= WaitForSingleObject( event
, 100 );
3032 if (i
== 3) ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject succeeded\n" );
3033 else ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
3034 ResetEvent( event
);
3035 winetest_pop_context();
3038 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
3039 ok( hr
== DI_OK
, "GetDeviceState returned: %#lx\n", hr
);
3040 winetest_push_context( "state[%ld]", i
);
3042 check_member( state
, expect_state_rel
[i
], "%ld", lX
);
3044 check_member( state
, expect_state_rel
[i
], "%ld", lY
);
3046 check_member( state
, expect_state_rel
[i
], "%ld", lZ
);
3047 check_member( state
, expect_state_rel
[i
], "%ld", lRx
);
3048 check_member( state
, expect_state_rel
[i
], "%ld", rgdwPOV
[0] );
3049 check_member( state
, expect_state_rel
[i
], "%ld", rgdwPOV
[1] );
3050 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[0] );
3051 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[1] );
3052 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[2] );
3053 winetest_pop_context();
3055 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, NULL
);
3056 ok( hr
== E_POINTER
, "GetForceFeedbackState returned %#lx\n", hr
);
3058 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
3059 ok( hr
== DIERR_UNSUPPORTED
, "GetForceFeedbackState returned %#lx\n", hr
);
3061 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, 0xdeadbeef );
3062 ok( hr
== DIERR_INVALIDPARAM
, "SendForceFeedbackCommand returned %#lx\n", hr
);
3063 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_RESET
);
3064 ok( hr
== DIERR_UNSUPPORTED
, "SendForceFeedbackCommand returned %#lx\n", hr
);
3066 objdata
[0].dwOfs
= 0xd;
3067 objdata
[0].dwData
= 0x80;
3069 hr
= IDirectInputDevice8_SendDeviceData( device
, size
, objdata
, &res
, 0xdeadbeef );
3071 ok( hr
== DIERR_INVALIDPARAM
, "SendDeviceData returned %#lx\n", hr
);
3073 hr
= IDirectInputDevice8_SendDeviceData( device
, size
, objdata
, &res
, 1 /*DISDD_CONTINUE*/ );
3075 ok( hr
== DIERR_INVALIDPARAM
, "SendDeviceData returned %#lx\n", hr
);
3077 hr
= IDirectInputDevice8_SendDeviceData( device
, size
, objdata
, &res
, 0 );
3079 ok( hr
== DIERR_INVALIDPARAM
, "SendDeviceData returned %#lx\n", hr
);
3081 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, NULL
, NULL
);
3082 ok( hr
== E_POINTER
, "CreateEffect returned %#lx\n", hr
);
3083 hr
= IDirectInputDevice8_CreateEffect( device
, NULL
, NULL
, &effect
, NULL
);
3084 ok( hr
== DIERR_UNSUPPORTED
, "CreateEffect returned %#lx\n", hr
);
3085 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_NULL
, NULL
, &effect
, NULL
);
3086 ok( hr
== DIERR_UNSUPPORTED
, "CreateEffect returned %#lx\n", hr
);
3087 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
3088 ok( hr
== DIERR_UNSUPPORTED
, "CreateEffect returned %#lx\n", hr
);
3090 hr
= IDirectInputDevice8_Unacquire( device
);
3091 ok( hr
== DI_OK
, "Unacquire returned: %#lx\n", hr
);
3093 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
3094 ok( hr
== DIERR_UNSUPPORTED
, "CreateEffect returned %#lx\n", hr
);
3096 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, NULL
, effect
, 0 );
3097 ok( hr
== DIERR_INVALIDPARAM
, "EnumCreatedEffectObjects returned %#lx\n", hr
);
3098 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_no_created_effect_objects
, effect
, 0xdeadbeef );
3099 ok( hr
== DIERR_INVALIDPARAM
, "EnumCreatedEffectObjects returned %#lx\n", hr
);
3100 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_no_created_effect_objects
, (void *)0xdeadbeef, 0 );
3101 ok( hr
== DI_OK
, "EnumCreatedEffectObjects returned %#lx\n", hr
);
3103 hr
= IDirectInputDevice8_Escape( device
, NULL
);
3105 ok( hr
== E_POINTER
, "Escape returned: %#lx\n", hr
);
3106 hr
= IDirectInputDevice8_Escape( device
, &escape
);
3108 ok( hr
== DIERR_INVALIDPARAM
, "Escape returned: %#lx\n", hr
);
3109 escape
.dwSize
= sizeof(DIEFFESCAPE
) + 1;
3110 hr
= IDirectInputDevice8_Escape( device
, &escape
);
3112 ok( hr
== DIERR_INVALIDPARAM
, "Escape returned: %#lx\n", hr
);
3113 escape
.dwSize
= sizeof(DIEFFESCAPE
);
3114 escape
.dwCommand
= 0;
3115 escape
.lpvInBuffer
= buffer
;
3116 escape
.cbInBuffer
= 10;
3117 escape
.lpvOutBuffer
= buffer
+ 10;
3118 escape
.cbOutBuffer
= 10;
3119 hr
= IDirectInputDevice8_Escape( device
, &escape
);
3121 ok( hr
== DIERR_UNSUPPORTED
, "Escape returned: %#lx\n", hr
);
3123 if (version
== 0x800) test_action_map( device
, file
, event
);
3125 ref
= IDirectInputDevice8_Release( device
);
3126 ok( ref
== 0, "Release returned %ld\n", ref
);
3128 CloseHandle( event
);
3129 CloseHandle( file
);
3132 hid_device_stop( &desc
, 1 );
3133 cleanup_registry_keys();
3134 winetest_pop_context();
3139 const BYTE
*report_desc_buf
;
3140 ULONG report_desc_len
;
3144 static BOOL
test_device_types( DWORD version
)
3146 #include "psh_hid_macros.h"
3147 static const unsigned char unknown_desc
[] =
3149 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3150 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3151 COLLECTION(1, Application
),
3152 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3153 COLLECTION(1, Physical
),
3154 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3155 USAGE_MINIMUM(1, 1),
3156 USAGE_MAXIMUM(1, 6),
3157 LOGICAL_MINIMUM(1, 0),
3158 LOGICAL_MAXIMUM(1, 1),
3159 PHYSICAL_MINIMUM(1, 0),
3160 PHYSICAL_MAXIMUM(1, 1),
3163 INPUT(1, Data
|Var
|Abs
),
3167 C_ASSERT(sizeof(unknown_desc
) < MAX_HID_DESCRIPTOR_LEN
);
3168 static const unsigned char limited_desc
[] =
3170 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3171 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3172 COLLECTION(1, Application
),
3173 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3174 COLLECTION(1, Physical
),
3175 USAGE(1, HID_USAGE_GENERIC_X
),
3176 USAGE(1, HID_USAGE_GENERIC_Y
),
3177 LOGICAL_MINIMUM(1, 0),
3178 LOGICAL_MAXIMUM(1, 127),
3179 PHYSICAL_MINIMUM(1, 0),
3180 PHYSICAL_MAXIMUM(1, 127),
3183 INPUT(1, Data
|Var
|Abs
),
3185 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3186 USAGE_MINIMUM(1, 1),
3187 USAGE_MAXIMUM(1, 6),
3188 LOGICAL_MINIMUM(1, 0),
3189 LOGICAL_MAXIMUM(1, 1),
3190 PHYSICAL_MINIMUM(1, 0),
3191 PHYSICAL_MAXIMUM(1, 1),
3194 INPUT(1, Data
|Var
|Abs
),
3198 C_ASSERT(sizeof(limited_desc
) < MAX_HID_DESCRIPTOR_LEN
);
3199 static const unsigned char gamepad_desc
[] =
3201 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3202 USAGE(1, HID_USAGE_GENERIC_GAMEPAD
),
3203 COLLECTION(1, Application
),
3204 USAGE(1, HID_USAGE_GENERIC_GAMEPAD
),
3205 COLLECTION(1, Physical
),
3206 USAGE(1, HID_USAGE_GENERIC_X
),
3207 USAGE(1, HID_USAGE_GENERIC_Y
),
3208 LOGICAL_MINIMUM(1, 0),
3209 LOGICAL_MAXIMUM(1, 127),
3210 PHYSICAL_MINIMUM(1, 0),
3211 PHYSICAL_MAXIMUM(1, 127),
3214 INPUT(1, Data
|Var
|Abs
),
3216 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3217 USAGE_MINIMUM(1, 1),
3218 USAGE_MAXIMUM(1, 6),
3219 LOGICAL_MINIMUM(1, 0),
3220 LOGICAL_MAXIMUM(1, 1),
3221 PHYSICAL_MINIMUM(1, 0),
3222 PHYSICAL_MAXIMUM(1, 1),
3225 INPUT(1, Data
|Var
|Abs
),
3229 C_ASSERT(sizeof(gamepad_desc
) < MAX_HID_DESCRIPTOR_LEN
);
3230 static const unsigned char joystick_desc
[] =
3232 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3233 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3234 COLLECTION(1, Application
),
3235 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3236 COLLECTION(1, Physical
),
3237 USAGE(1, HID_USAGE_GENERIC_X
),
3238 USAGE(1, HID_USAGE_GENERIC_Y
),
3239 USAGE(1, HID_USAGE_GENERIC_Z
),
3240 LOGICAL_MINIMUM(1, 0),
3241 LOGICAL_MAXIMUM(1, 127),
3242 PHYSICAL_MINIMUM(1, 0),
3243 PHYSICAL_MAXIMUM(1, 127),
3246 INPUT(1, Data
|Var
|Abs
),
3248 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
3249 LOGICAL_MINIMUM(1, 1),
3250 LOGICAL_MAXIMUM(1, 8),
3251 PHYSICAL_MINIMUM(1, 0),
3252 PHYSICAL_MAXIMUM(1, 8),
3255 INPUT(1, Data
|Var
|Abs
|Null
),
3257 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3258 USAGE_MINIMUM(1, 1),
3259 USAGE_MAXIMUM(1, 5),
3260 LOGICAL_MINIMUM(1, 0),
3261 LOGICAL_MAXIMUM(1, 1),
3262 PHYSICAL_MINIMUM(1, 0),
3263 PHYSICAL_MAXIMUM(1, 1),
3266 INPUT(1, Data
|Var
|Abs
),
3270 C_ASSERT(sizeof(joystick_desc
) < MAX_HID_DESCRIPTOR_LEN
);
3271 static const unsigned char wheel_steering_only_desc
[] =
3273 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3274 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3275 COLLECTION(1, Application
),
3276 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3277 COLLECTION(1, Physical
),
3278 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_STEERING
),
3279 LOGICAL_MINIMUM(1, 0),
3280 LOGICAL_MAXIMUM(1, 127),
3281 PHYSICAL_MINIMUM(1, 0),
3282 PHYSICAL_MAXIMUM(1, 127),
3285 INPUT(1, Data
|Var
|Abs
),
3287 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
3288 LOGICAL_MINIMUM(1, 1),
3289 LOGICAL_MAXIMUM(1, 8),
3290 PHYSICAL_MINIMUM(1, 0),
3291 PHYSICAL_MAXIMUM(1, 8),
3294 INPUT(1, Data
|Var
|Abs
|Null
),
3296 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3297 USAGE_MINIMUM(1, 1),
3298 USAGE_MAXIMUM(1, 5),
3299 LOGICAL_MINIMUM(1, 0),
3300 LOGICAL_MAXIMUM(1, 1),
3301 PHYSICAL_MINIMUM(1, 0),
3302 PHYSICAL_MAXIMUM(1, 1),
3305 INPUT(1, Data
|Var
|Abs
),
3309 C_ASSERT(sizeof(wheel_steering_only_desc
) < MAX_HID_DESCRIPTOR_LEN
);
3310 static const unsigned char wheel_dualpedals_desc
[] =
3312 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3313 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3314 COLLECTION(1, Application
),
3315 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3316 COLLECTION(1, Physical
),
3317 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_STEERING
),
3318 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_ACCELERATOR
),
3319 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_BRAKE
),
3320 USAGE(1, HID_USAGE_GENERIC_X
),
3321 LOGICAL_MINIMUM(1, 0),
3322 LOGICAL_MAXIMUM(1, 127),
3323 PHYSICAL_MINIMUM(1, 0),
3324 PHYSICAL_MAXIMUM(1, 127),
3327 INPUT(1, Data
|Var
|Abs
),
3329 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
3330 LOGICAL_MINIMUM(1, 1),
3331 LOGICAL_MAXIMUM(1, 8),
3332 PHYSICAL_MINIMUM(1, 0),
3333 PHYSICAL_MAXIMUM(1, 8),
3336 INPUT(1, Data
|Var
|Abs
|Null
),
3338 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3339 USAGE_MINIMUM(1, 1),
3340 USAGE_MAXIMUM(1, 5),
3341 LOGICAL_MINIMUM(1, 0),
3342 LOGICAL_MAXIMUM(1, 1),
3343 PHYSICAL_MINIMUM(1, 0),
3344 PHYSICAL_MAXIMUM(1, 1),
3347 INPUT(1, Data
|Var
|Abs
),
3351 C_ASSERT(sizeof(wheel_dualpedals_desc
) < MAX_HID_DESCRIPTOR_LEN
);
3352 static const unsigned char wheel_threepedals_desc
[] =
3354 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3355 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3356 COLLECTION(1, Application
),
3357 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3358 COLLECTION(1, Physical
),
3359 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_STEERING
),
3360 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_ACCELERATOR
),
3361 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_BRAKE
),
3362 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_CLUTCH
),
3363 USAGE(1, HID_USAGE_GENERIC_Y
),
3364 LOGICAL_MINIMUM(1, 0),
3365 LOGICAL_MAXIMUM(1, 127),
3366 PHYSICAL_MINIMUM(1, 0),
3367 PHYSICAL_MAXIMUM(1, 127),
3370 INPUT(1, Data
|Var
|Abs
),
3372 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
3373 LOGICAL_MINIMUM(1, 1),
3374 LOGICAL_MAXIMUM(1, 8),
3375 PHYSICAL_MINIMUM(1, 0),
3376 PHYSICAL_MAXIMUM(1, 8),
3379 INPUT(1, Data
|Var
|Abs
|Null
),
3381 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3382 USAGE_MINIMUM(1, 1),
3383 USAGE_MAXIMUM(1, 5),
3384 LOGICAL_MINIMUM(1, 0),
3385 LOGICAL_MAXIMUM(1, 1),
3386 PHYSICAL_MINIMUM(1, 0),
3387 PHYSICAL_MAXIMUM(1, 1),
3390 INPUT(1, Data
|Var
|Abs
),
3394 C_ASSERT(sizeof(wheel_threepedals_desc
) < MAX_HID_DESCRIPTOR_LEN
);
3395 #include "pop_hid_macros.h"
3397 static struct device_desc device_desc
[] =
3400 .report_desc_buf
= unknown_desc
,
3401 .report_desc_len
= sizeof(unknown_desc
),
3404 .InputReportByteLength
= 1,
3408 .report_desc_buf
= limited_desc
,
3409 .report_desc_len
= sizeof(limited_desc
),
3412 .InputReportByteLength
= 3,
3416 .report_desc_buf
= gamepad_desc
,
3417 .report_desc_len
= sizeof(gamepad_desc
),
3420 .InputReportByteLength
= 3,
3424 .report_desc_buf
= joystick_desc
,
3425 .report_desc_len
= sizeof(joystick_desc
),
3428 .InputReportByteLength
= 5,
3432 .report_desc_buf
= wheel_steering_only_desc
,
3433 .report_desc_len
= sizeof(wheel_steering_only_desc
),
3436 .InputReportByteLength
= 3,
3440 .report_desc_buf
= wheel_dualpedals_desc
,
3441 .report_desc_len
= sizeof(wheel_dualpedals_desc
),
3444 .InputReportByteLength
= 6,
3448 .report_desc_buf
= wheel_threepedals_desc
,
3449 .report_desc_len
= sizeof(wheel_threepedals_desc
),
3452 .InputReportByteLength
= 7,
3456 const DIDEVCAPS expect_caps
[] =
3459 .dwSize
= sizeof(DIDEVCAPS
),
3460 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
3461 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPESUPPLEMENTAL_UNKNOWN
<< 8)|DI8DEVTYPE_SUPPLEMENTAL
3462 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
3466 .dwSize
= sizeof(DIDEVCAPS
),
3467 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
3468 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEJOYSTICK_LIMITED
<< 8)|DI8DEVTYPE_JOYSTICK
3469 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
3474 .dwSize
= sizeof(DIDEVCAPS
),
3475 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
3476 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEGAMEPAD_STANDARD
<< 8)|DI8DEVTYPE_GAMEPAD
3477 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_GAMEPAD
<< 8)|DIDEVTYPE_JOYSTICK
,
3482 .dwSize
= sizeof(DIDEVCAPS
),
3483 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
3484 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEJOYSTICK_STANDARD
<< 8)|DI8DEVTYPE_JOYSTICK
3485 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
3491 .dwSize
= sizeof(DIDEVCAPS
),
3492 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
3493 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEDRIVING_LIMITED
<< 8)|DI8DEVTYPE_DRIVING
3494 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_WHEEL
<< 8)|DIDEVTYPE_JOYSTICK
,
3500 .dwSize
= sizeof(DIDEVCAPS
),
3501 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
3502 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEDRIVING_DUALPEDALS
<< 8)|DI8DEVTYPE_DRIVING
3503 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_WHEEL
<< 8)|DIDEVTYPE_JOYSTICK
,
3509 .dwSize
= sizeof(DIDEVCAPS
),
3510 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
3511 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEDRIVING_THREEPEDALS
<< 8)|DI8DEVTYPE_DRIVING
3512 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_WHEEL
<< 8)|DIDEVTYPE_JOYSTICK
,
3519 const DIDEVICEINSTANCEW expect_devinst
[] =
3522 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
3523 .guidInstance
= expect_guid_product
,
3524 .guidProduct
= expect_guid_product
,
3525 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPESUPPLEMENTAL_UNKNOWN
<< 8)|DI8DEVTYPE_SUPPLEMENTAL
3526 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
3527 .tszInstanceName
= L
"Wine Test",
3528 .tszProductName
= L
"Wine Test",
3529 .guidFFDriver
= GUID_NULL
,
3530 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3531 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3534 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
3535 .guidInstance
= expect_guid_product
,
3536 .guidProduct
= expect_guid_product
,
3537 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEJOYSTICK_LIMITED
<< 8)|DI8DEVTYPE_JOYSTICK
3538 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
3539 .tszInstanceName
= L
"Wine Test",
3540 .tszProductName
= L
"Wine Test",
3541 .guidFFDriver
= GUID_NULL
,
3542 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3543 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3546 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
3547 .guidInstance
= expect_guid_product
,
3548 .guidProduct
= expect_guid_product
,
3549 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEGAMEPAD_STANDARD
<< 8)|DI8DEVTYPE_GAMEPAD
3550 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_GAMEPAD
<< 8)|DIDEVTYPE_JOYSTICK
,
3551 .tszInstanceName
= L
"Wine Test",
3552 .tszProductName
= L
"Wine Test",
3553 .guidFFDriver
= GUID_NULL
,
3554 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3555 .wUsage
= HID_USAGE_GENERIC_GAMEPAD
,
3558 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
3559 .guidInstance
= expect_guid_product
,
3560 .guidProduct
= expect_guid_product
,
3561 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEJOYSTICK_STANDARD
<< 8)|DI8DEVTYPE_JOYSTICK
3562 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
3563 .tszInstanceName
= L
"Wine Test",
3564 .tszProductName
= L
"Wine Test",
3565 .guidFFDriver
= GUID_NULL
,
3566 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3567 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3570 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
3571 .guidInstance
= expect_guid_product
,
3572 .guidProduct
= expect_guid_product
,
3573 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEDRIVING_LIMITED
<< 8)|DI8DEVTYPE_DRIVING
3574 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_WHEEL
<< 8)|DIDEVTYPE_JOYSTICK
,
3575 .tszInstanceName
= L
"Wine Test",
3576 .tszProductName
= L
"Wine Test",
3577 .guidFFDriver
= GUID_NULL
,
3578 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3579 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3582 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
3583 .guidInstance
= expect_guid_product
,
3584 .guidProduct
= expect_guid_product
,
3585 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEDRIVING_DUALPEDALS
<< 8)|DI8DEVTYPE_DRIVING
3586 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_WHEEL
<< 8)|DIDEVTYPE_JOYSTICK
,
3587 .tszInstanceName
= L
"Wine Test",
3588 .tszProductName
= L
"Wine Test",
3589 .guidFFDriver
= GUID_NULL
,
3590 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3591 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3594 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
3595 .guidInstance
= expect_guid_product
,
3596 .guidProduct
= expect_guid_product
,
3597 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEDRIVING_THREEPEDALS
<< 8)|DI8DEVTYPE_DRIVING
3598 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_WHEEL
<< 8)|DIDEVTYPE_JOYSTICK
,
3599 .tszInstanceName
= L
"Wine Test",
3600 .tszProductName
= L
"Wine Test",
3601 .guidFFDriver
= GUID_NULL
,
3602 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3603 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3606 struct hid_device_desc desc
=
3608 .use_report_id
= TRUE
,
3609 .attributes
= default_attributes
,
3612 C_ASSERT(ARRAY_SIZE(expect_caps
) == ARRAY_SIZE(device_desc
));
3613 C_ASSERT(ARRAY_SIZE(expect_devinst
) == ARRAY_SIZE(device_desc
));
3615 DIDEVICEINSTANCEW devinst
= {.dwSize
= sizeof(DIDEVICEINSTANCEW
)};
3616 DIDEVCAPS caps
= {.dwSize
= sizeof(DIDEVCAPS
)};
3617 IDirectInputDevice8W
*device
;
3618 BOOL success
= TRUE
;
3622 winetest_push_context( "%#lx", version
);
3624 for (i
= 0; i
< ARRAY_SIZE(device_desc
) && success
; ++i
)
3626 winetest_push_context( "desc[%ld]", i
);
3627 cleanup_registry_keys();
3629 desc
.caps
= device_desc
[i
].hid_caps
;
3630 desc
.report_descriptor_len
= device_desc
[i
].report_desc_len
;
3631 memcpy( desc
.report_descriptor_buf
, device_desc
[i
].report_desc_buf
, device_desc
[i
].report_desc_len
);
3632 fill_context( desc
.context
, ARRAY_SIZE(desc
.context
) );
3634 if (!hid_device_start( &desc
, 1 ))
3640 if (FAILED(hr
= dinput_test_create_device( version
, &devinst
, &device
)))
3646 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
3647 ok( hr
== DI_OK
, "GetDeviceInfo returned %#lx\n", hr
);
3648 check_member( devinst
, expect_devinst
[i
], "%lu", dwSize
);
3649 check_member_guid( devinst
, expect_devinst
[i
], guidProduct
);
3650 todo_wine_if( version
<= 0x700 && i
== 3 )
3651 check_member( devinst
, expect_devinst
[i
], "%#lx", dwDevType
);
3652 check_member_guid( devinst
, expect_devinst
[i
], guidFFDriver
);
3653 check_member( devinst
, expect_devinst
[i
], "%04x", wUsagePage
);
3654 check_member( devinst
, expect_devinst
[i
], "%04x", wUsage
);
3656 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
3657 ok( hr
== DI_OK
, "GetCapabilities returned %#lx\n", hr
);
3658 check_member( caps
, expect_caps
[i
], "%lu", dwSize
);
3659 check_member( caps
, expect_caps
[i
], "%#lx", dwFlags
);
3660 todo_wine_if( version
<= 0x700 && i
== 3 )
3661 check_member( caps
, expect_caps
[i
], "%#lx", dwDevType
);
3662 check_member( caps
, expect_caps
[i
], "%lu", dwAxes
);
3663 check_member( caps
, expect_caps
[i
], "%lu", dwButtons
);
3664 check_member( caps
, expect_caps
[i
], "%lu", dwPOVs
);
3665 check_member( caps
, expect_caps
[i
], "%lu", dwFFSamplePeriod
);
3666 check_member( caps
, expect_caps
[i
], "%lu", dwFFMinTimeResolution
);
3667 check_member( caps
, expect_caps
[i
], "%lu", dwFirmwareRevision
);
3668 check_member( caps
, expect_caps
[i
], "%lu", dwHardwareRevision
);
3669 check_member( caps
, expect_caps
[i
], "%lu", dwFFDriverVersion
);
3671 ref
= IDirectInputDevice8_Release( device
);
3672 ok( ref
== 0, "Release returned %ld\n", ref
);
3675 hid_device_stop( &desc
, 1 );
3676 cleanup_registry_keys();
3677 winetest_pop_context();
3680 winetest_pop_context();
3685 struct three_sliders_state
3690 static const DIOBJECTDATAFORMAT df_three_sliders
[] =
3692 {&GUID_Slider
, FIELD_OFFSET(struct three_sliders_state
, slider
[0]), DIDFT_OPTIONAL
|DIDFT_AXIS
|DIDFT_ANYINSTANCE
, DIDOI_ASPECTPOSITION
},
3693 {&GUID_Slider
, FIELD_OFFSET(struct three_sliders_state
, slider
[1]), DIDFT_OPTIONAL
|DIDFT_AXIS
|DIDFT_ANYINSTANCE
, DIDOI_ASPECTPOSITION
},
3694 {&GUID_Slider
, FIELD_OFFSET(struct three_sliders_state
, slider
[2]), DIDFT_OPTIONAL
|DIDFT_AXIS
|DIDFT_ANYINSTANCE
, DIDOI_ASPECTPOSITION
},
3697 static const DIDATAFORMAT c_df_three_sliders
=
3699 sizeof(DIDATAFORMAT
),
3700 sizeof(DIOBJECTDATAFORMAT
),
3702 sizeof(struct three_sliders_state
),
3703 ARRAY_SIZE(df_three_sliders
),
3704 (DIOBJECTDATAFORMAT
*)df_three_sliders
,
3707 static void test_many_axes_joystick(void)
3709 #include "psh_hid_macros.h"
3710 static const unsigned char report_desc
[] =
3712 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3713 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3714 COLLECTION(1, Application
),
3715 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3716 COLLECTION(1, Report
),
3719 USAGE(1, HID_USAGE_GENERIC_DIAL
),
3720 USAGE(1, HID_USAGE_GENERIC_SLIDER
),
3721 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_RUDDER
),
3722 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_THROTTLE
),
3723 USAGE(1, HID_USAGE_GENERIC_RZ
),
3724 USAGE(1, HID_USAGE_GENERIC_RY
),
3725 USAGE(1, HID_USAGE_GENERIC_RX
),
3726 USAGE(1, HID_USAGE_GENERIC_Z
),
3727 USAGE(1, HID_USAGE_GENERIC_Y
),
3728 USAGE(1, HID_USAGE_GENERIC_X
),
3729 LOGICAL_MINIMUM(1, 0),
3730 LOGICAL_MAXIMUM(1, 0x7f),
3731 PHYSICAL_MINIMUM(1, 0),
3732 PHYSICAL_MAXIMUM(1, 0x7f),
3734 REPORT_COUNT(1, 10),
3735 INPUT(1, Data
|Var
|Abs
),
3737 USAGE(1, HID_USAGE_GENERIC_Z
),
3738 USAGE(1, HID_USAGE_GENERIC_Y
),
3739 USAGE(1, HID_USAGE_GENERIC_X
),
3740 LOGICAL_MINIMUM(1, 0),
3741 LOGICAL_MAXIMUM(1, 0x7f),
3742 PHYSICAL_MINIMUM(1, 0),
3743 PHYSICAL_MAXIMUM(1, 0x7f),
3744 UNIT(4, 0xf011), /* cm * s^-1 */
3747 INPUT(1, Data
|Var
|Abs
),
3749 USAGE(1, HID_USAGE_GENERIC_Z
),
3750 USAGE(1, HID_USAGE_GENERIC_Y
),
3751 USAGE(1, HID_USAGE_GENERIC_X
),
3752 LOGICAL_MINIMUM(1, 0),
3753 LOGICAL_MAXIMUM(1, 0x7f),
3754 PHYSICAL_MINIMUM(1, 0),
3755 PHYSICAL_MAXIMUM(1, 0x7f),
3756 UNIT(4, 0xe011), /* cm * s^-2 */
3759 INPUT(1, Data
|Var
|Abs
),
3761 USAGE(1, HID_USAGE_GENERIC_Z
),
3762 USAGE(1, HID_USAGE_GENERIC_Y
),
3763 USAGE(1, HID_USAGE_GENERIC_X
),
3764 LOGICAL_MINIMUM(1, 0),
3765 LOGICAL_MAXIMUM(1, 0x7f),
3766 PHYSICAL_MINIMUM(1, 0),
3767 PHYSICAL_MAXIMUM(1, 0x7f),
3768 UNIT(4, 0xe111), /* g * cm * s^-2 */
3771 INPUT(1, Data
|Var
|Abs
),
3772 UNIT(1, 0), /* None */
3776 C_ASSERT(sizeof(report_desc
) < MAX_HID_DESCRIPTOR_LEN
);
3777 #include "pop_hid_macros.h"
3779 struct hid_device_desc desc
=
3781 .use_report_id
= TRUE
,
3782 .caps
= { .InputReportByteLength
= 20 },
3783 .attributes
= default_attributes
,
3785 const DIDEVCAPS expect_caps
=
3787 .dwSize
= sizeof(DIDEVCAPS
),
3788 .dwFlags
= DIDC_ATTACHED
| DIDC_EMULATED
,
3789 .dwDevType
= DIDEVTYPE_HID
| (DI8DEVTYPE1STPERSON_LIMITED
<< 8) | DI8DEVTYPE_1STPERSON
,
3792 const DIDEVICEINSTANCEW expect_devinst
=
3794 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
3795 .guidInstance
= expect_guid_product
,
3796 .guidProduct
= expect_guid_product
,
3797 .dwDevType
= DIDEVTYPE_HID
| (DI8DEVTYPE1STPERSON_LIMITED
<< 8) | DI8DEVTYPE_1STPERSON
,
3798 .tszInstanceName
= L
"Wine Test",
3799 .tszProductName
= L
"Wine Test",
3800 .guidFFDriver
= GUID_NULL
,
3801 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3802 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3804 const DIDEVICEOBJECTINSTANCEW expect_objects
[] =
3807 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3808 .guidType
= GUID_XAxis
,
3810 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(0),
3811 .dwFlags
= DIDOI_ASPECTPOSITION
,
3812 .tszName
= L
"X Axis",
3813 .wCollectionNumber
= 1,
3814 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3815 .wUsage
= HID_USAGE_GENERIC_X
,
3819 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3820 .guidType
= GUID_YAxis
,
3822 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(1),
3823 .dwFlags
= DIDOI_ASPECTPOSITION
,
3824 .tszName
= L
"Y Axis",
3825 .wCollectionNumber
= 1,
3826 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3827 .wUsage
= HID_USAGE_GENERIC_Y
,
3831 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3832 .guidType
= GUID_ZAxis
,
3834 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(2),
3835 .dwFlags
= DIDOI_ASPECTPOSITION
,
3836 .tszName
= L
"Z Axis",
3837 .wCollectionNumber
= 1,
3838 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3839 .wUsage
= HID_USAGE_GENERIC_Z
,
3843 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3844 .guidType
= GUID_RxAxis
,
3846 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(3),
3847 .dwFlags
= DIDOI_ASPECTPOSITION
,
3848 .tszName
= L
"X Rotation",
3849 .wCollectionNumber
= 1,
3850 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3851 .wUsage
= HID_USAGE_GENERIC_RX
,
3855 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3856 .guidType
= GUID_RyAxis
,
3858 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(4),
3859 .dwFlags
= DIDOI_ASPECTPOSITION
,
3860 .tszName
= L
"Y Rotation",
3861 .wCollectionNumber
= 1,
3862 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3863 .wUsage
= HID_USAGE_GENERIC_RY
,
3867 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3868 .guidType
= GUID_RzAxis
,
3870 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(5),
3871 .dwFlags
= DIDOI_ASPECTPOSITION
,
3872 .tszName
= L
"Z Rotation",
3873 .wCollectionNumber
= 1,
3874 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3875 .wUsage
= HID_USAGE_GENERIC_RZ
,
3879 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3880 .guidType
= GUID_Slider
,
3882 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(6),
3883 .dwFlags
= DIDOI_ASPECTPOSITION
,
3884 .tszName
= L
"Throttle",
3885 .wCollectionNumber
= 1,
3886 .wUsagePage
= HID_USAGE_PAGE_SIMULATION
,
3887 .wUsage
= HID_USAGE_SIMULATION_THROTTLE
,
3891 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3892 .guidType
= GUID_RzAxis
,
3894 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(7),
3895 .dwFlags
= DIDOI_ASPECTPOSITION
,
3896 .tszName
= L
"Rudder",
3897 .wCollectionNumber
= 1,
3898 .wUsagePage
= HID_USAGE_PAGE_SIMULATION
,
3899 .wUsage
= HID_USAGE_SIMULATION_RUDDER
,
3903 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3904 .guidType
= GUID_Slider
,
3906 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(8),
3907 .dwFlags
= DIDOI_ASPECTPOSITION
,
3908 .tszName
= L
"Slider",
3909 .wCollectionNumber
= 1,
3910 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3911 .wUsage
= HID_USAGE_GENERIC_SLIDER
,
3915 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3916 .guidType
= GUID_Slider
,
3918 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(9),
3919 .dwFlags
= DIDOI_ASPECTPOSITION
,
3921 .wCollectionNumber
= 1,
3922 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3923 .wUsage
= HID_USAGE_GENERIC_DIAL
,
3927 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3928 .guidType
= GUID_XAxis
,
3930 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(10),
3931 .dwFlags
= DIDOI_ASPECTVELOCITY
,
3932 .tszName
= L
"X Axis",
3933 .wCollectionNumber
= 1,
3934 .dwDimension
= 0xf011,
3935 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3936 .wUsage
= HID_USAGE_GENERIC_X
,
3940 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3941 .guidType
= GUID_YAxis
,
3943 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(11),
3944 .dwFlags
= DIDOI_ASPECTVELOCITY
,
3945 .tszName
= L
"Y Axis",
3946 .wCollectionNumber
= 1,
3947 .dwDimension
= 0xf011,
3948 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3949 .wUsage
= HID_USAGE_GENERIC_Y
,
3953 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3954 .guidType
= GUID_ZAxis
,
3956 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(12),
3957 .dwFlags
= DIDOI_ASPECTVELOCITY
,
3958 .tszName
= L
"Z Axis",
3959 .wCollectionNumber
= 1,
3960 .dwDimension
= 0xf011,
3961 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3962 .wUsage
= HID_USAGE_GENERIC_Z
,
3966 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3967 .guidType
= GUID_XAxis
,
3969 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(13),
3970 .dwFlags
= DIDOI_ASPECTACCEL
,
3971 .tszName
= L
"X Axis",
3972 .wCollectionNumber
= 1,
3973 .dwDimension
= 0xe011,
3974 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3975 .wUsage
= HID_USAGE_GENERIC_X
,
3979 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3980 .guidType
= GUID_YAxis
,
3982 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(14),
3983 .dwFlags
= DIDOI_ASPECTACCEL
,
3984 .tszName
= L
"Y Axis",
3985 .wCollectionNumber
= 1,
3986 .dwDimension
= 0xe011,
3987 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3988 .wUsage
= HID_USAGE_GENERIC_Y
,
3992 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3993 .guidType
= GUID_ZAxis
,
3995 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(15),
3996 .dwFlags
= DIDOI_ASPECTACCEL
,
3997 .tszName
= L
"Z Axis",
3998 .wCollectionNumber
= 1,
3999 .dwDimension
= 0xe011,
4000 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
4001 .wUsage
= HID_USAGE_GENERIC_Z
,
4005 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
4006 .guidType
= GUID_XAxis
,
4008 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(16),
4009 .dwFlags
= DIDOI_ASPECTFORCE
,
4010 .tszName
= L
"X Axis",
4011 .wCollectionNumber
= 1,
4012 .dwDimension
= 0xe111,
4013 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
4014 .wUsage
= HID_USAGE_GENERIC_X
,
4018 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
4019 .guidType
= GUID_YAxis
,
4021 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(17),
4022 .dwFlags
= DIDOI_ASPECTFORCE
,
4023 .tszName
= L
"Y Axis",
4024 .wCollectionNumber
= 1,
4025 .dwDimension
= 0xe111,
4026 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
4027 .wUsage
= HID_USAGE_GENERIC_Y
,
4031 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
4032 .guidType
= GUID_ZAxis
,
4034 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(18),
4035 .dwFlags
= DIDOI_ASPECTFORCE
,
4036 .tszName
= L
"Z Axis",
4037 .wCollectionNumber
= 1,
4038 .dwDimension
= 0xe111,
4039 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
4040 .wUsage
= HID_USAGE_GENERIC_Z
,
4044 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
4045 .guidType
= GUID_Unknown
,
4046 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(0),
4047 .tszName
= L
"Collection 0 - Joystick",
4048 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
4049 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
4052 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
4053 .guidType
= GUID_Unknown
,
4054 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(1),
4055 .tszName
= L
"Collection 1 - Joystick",
4056 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
4057 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
4060 struct check_object_todo todo_objects
[ARRAY_SIZE(expect_objects
)] =
4082 struct check_objects_params check_objects_params
=
4084 .version
= DIRECTINPUT_VERSION
,
4085 .expect_count
= ARRAY_SIZE(expect_objects
),
4086 .expect_objs
= expect_objects
,
4087 .todo_objs
= todo_objects
,
4090 DIDEVICEOBJECTINSTANCEW objinst
= {.dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
)};
4091 struct check_object_todo todo_flags
= {.flags
= TRUE
};
4092 DIDEVICEINSTANCEW devinst
= {0};
4093 IDirectInputDevice8W
*device
;
4094 DIDEVCAPS caps
= {0};
4098 cleanup_registry_keys();
4100 desc
.report_descriptor_len
= sizeof(report_desc
);
4101 memcpy( desc
.report_descriptor_buf
, report_desc
, sizeof(report_desc
) );
4102 fill_context( desc
.context
, ARRAY_SIZE(desc
.context
) );
4104 if (!hid_device_start( &desc
, 1 )) goto done
;
4105 if (FAILED(hr
= dinput_test_create_device( DIRECTINPUT_VERSION
, &devinst
, &device
))) goto done
;
4107 check_dinput_devices( DIRECTINPUT_VERSION
, &devinst
);
4109 memset( &devinst
, 0, sizeof(devinst
) );
4110 devinst
.dwSize
= sizeof(DIDEVICEINSTANCEW
);
4111 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
4112 ok( hr
== DI_OK
, "GetDeviceInfo returned %#lx\n", hr
);
4113 check_member( devinst
, expect_devinst
, "%lu", dwSize
);
4115 check_member_guid( devinst
, expect_devinst
, guidInstance
);
4116 check_member_guid( devinst
, expect_devinst
, guidProduct
);
4118 check_member( devinst
, expect_devinst
, "%#lx", dwDevType
);
4119 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
4120 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
4121 check_member_guid( devinst
, expect_devinst
, guidFFDriver
);
4122 check_member( devinst
, expect_devinst
, "%04x", wUsagePage
);
4123 check_member( devinst
, expect_devinst
, "%04x", wUsage
);
4125 hr
= IDirectInputDevice8_GetCapabilities( device
, NULL
);
4126 ok( hr
== E_POINTER
, "GetCapabilities returned %#lx\n", hr
);
4127 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
4128 ok( hr
== DIERR_INVALIDPARAM
, "GetCapabilities returned %#lx\n", hr
);
4129 caps
.dwSize
= sizeof(DIDEVCAPS
);
4130 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
4131 ok( hr
== DI_OK
, "GetCapabilities returned %#lx\n", hr
);
4132 check_member( caps
, expect_caps
, "%lu", dwSize
);
4133 check_member( caps
, expect_caps
, "%#lx", dwFlags
);
4135 check_member( caps
, expect_caps
, "%#lx", dwDevType
);
4136 check_member( caps
, expect_caps
, "%lu", dwAxes
);
4137 check_member( caps
, expect_caps
, "%lu", dwButtons
);
4138 check_member( caps
, expect_caps
, "%lu", dwPOVs
);
4139 check_member( caps
, expect_caps
, "%lu", dwFFSamplePeriod
);
4140 check_member( caps
, expect_caps
, "%lu", dwFFMinTimeResolution
);
4141 check_member( caps
, expect_caps
, "%lu", dwFirmwareRevision
);
4142 check_member( caps
, expect_caps
, "%lu", dwHardwareRevision
);
4143 check_member( caps
, expect_caps
, "%lu", dwFFDriverVersion
);
4145 hr
= IDirectInputDevice8_EnumObjects( device
, check_objects
, &check_objects_params
, DIDFT_ALL
);
4146 ok( hr
== DI_OK
, "EnumObjects returned %#lx\n", hr
);
4147 ok( check_objects_params
.index
>= check_objects_params
.expect_count
, "missing %u objects\n",
4148 check_objects_params
.expect_count
- check_objects_params
.index
);
4150 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
4151 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
4153 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, DIJOFS_RZ
, DIPH_BYOFFSET
);
4154 ok( hr
== DI_OK
, "GetObjectInfo returned: %#lx\n", hr
);
4155 check_object( &objinst
, &expect_objects
[5], NULL
);
4157 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, offsetof(DIJOYSTATE2
, rglSlider
[0]), DIPH_BYOFFSET
);
4158 ok( hr
== DI_OK
, "GetObjectInfo returned: %#lx\n", hr
);
4159 check_object( &objinst
, &expect_objects
[6], NULL
);
4161 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, offsetof(DIJOYSTATE2
, rglSlider
[1]), DIPH_BYOFFSET
);
4162 ok( hr
== DI_OK
, "GetObjectInfo returned: %#lx\n", hr
);
4163 check_object( &objinst
, &expect_objects
[8], NULL
);
4165 /* c_dfDIJoystick2 is broken when it comes to more than two sliders */
4166 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, offsetof(DIJOYSTATE2
, rglVSlider
[0]), DIPH_BYOFFSET
);
4167 ok( hr
== DIERR_NOTFOUND
, "GetObjectInfo returned: %#lx\n", hr
);
4169 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, offsetof(DIJOYSTATE2
, lVX
), DIPH_BYOFFSET
);
4170 ok( hr
== DI_OK
, "GetObjectInfo returned: %#lx\n", hr
);
4171 check_object( &objinst
, &expect_objects
[10], &todo_flags
);
4173 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, offsetof(DIJOYSTATE2
, lAX
), DIPH_BYOFFSET
);
4174 ok( hr
== DI_OK
, "GetObjectInfo returned: %#lx\n", hr
);
4175 check_object( &objinst
, &expect_objects
[13], &todo_flags
);
4177 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, offsetof(DIJOYSTATE2
, lFX
), DIPH_BYOFFSET
);
4178 ok( hr
== DI_OK
, "GetObjectInfo returned: %#lx\n", hr
);
4179 check_object( &objinst
, &expect_objects
[16], &todo_flags
);
4181 /* make sure that we handle three sliders correctly when the format allows */
4182 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_df_three_sliders
);
4183 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
4185 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, offsetof(struct three_sliders_state
, slider
[0]), DIPH_BYOFFSET
);
4186 ok( hr
== DI_OK
, "GetObjectInfo returned: %#lx\n", hr
);
4187 check_object( &objinst
, &expect_objects
[6], NULL
);
4189 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, offsetof(struct three_sliders_state
, slider
[1]), DIPH_BYOFFSET
);
4190 ok( hr
== DI_OK
, "GetObjectInfo returned: %#lx\n", hr
);
4191 check_object( &objinst
, &expect_objects
[8], NULL
);
4193 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, offsetof(struct three_sliders_state
, slider
[2]), DIPH_BYOFFSET
);
4194 ok( hr
== DI_OK
, "GetObjectInfo returned: %#lx\n", hr
);
4195 check_object( &objinst
, &expect_objects
[9], NULL
);
4197 ref
= IDirectInputDevice8_Release( device
);
4198 ok( ref
== 0, "Release returned %ld\n", ref
);
4201 hid_device_stop( &desc
, 1 );
4202 cleanup_registry_keys();
4205 static void test_driving_wheel_axes(void)
4207 #include "psh_hid_macros.h"
4208 static const unsigned char report_desc
[] =
4210 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
4211 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
4212 COLLECTION(1, Application
),
4213 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
4214 COLLECTION(1, Report
),
4217 USAGE_PAGE(1, HID_USAGE_PAGE_SIMULATION
),
4218 USAGE(1, HID_USAGE_SIMULATION_RUDDER
),
4219 USAGE(1, HID_USAGE_SIMULATION_THROTTLE
),
4220 USAGE(1, HID_USAGE_SIMULATION_ACCELERATOR
),
4221 USAGE(1, HID_USAGE_SIMULATION_BRAKE
),
4222 USAGE(1, HID_USAGE_SIMULATION_CLUTCH
),
4223 USAGE(1, HID_USAGE_SIMULATION_STEERING
),
4224 LOGICAL_MINIMUM(1, 0),
4225 LOGICAL_MAXIMUM(1, 0x7f),
4226 PHYSICAL_MINIMUM(1, 0),
4227 PHYSICAL_MAXIMUM(1, 0x7f),
4230 INPUT(1, Data
|Var
|Abs
),
4234 C_ASSERT(sizeof(report_desc
) < MAX_HID_DESCRIPTOR_LEN
);
4235 #include "pop_hid_macros.h"
4237 struct hid_device_desc desc
=
4239 .use_report_id
= TRUE
,
4240 .caps
= { .InputReportByteLength
= 7 },
4241 .attributes
= default_attributes
,
4243 const DIDEVCAPS expect_caps
=
4245 .dwSize
= sizeof(DIDEVCAPS
),
4246 .dwFlags
= DIDC_ATTACHED
| DIDC_EMULATED
,
4247 .dwDevType
= DIDEVTYPE_HID
| (DI8DEVTYPEDRIVING_LIMITED
<< 8) | DI8DEVTYPE_DRIVING
,
4250 const DIDEVICEINSTANCEW expect_devinst
=
4252 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
4253 .guidInstance
= expect_guid_product
,
4254 .guidProduct
= expect_guid_product
,
4255 .dwDevType
= DIDEVTYPE_HID
| (DI8DEVTYPEDRIVING_LIMITED
<< 8) | DI8DEVTYPE_DRIVING
,
4256 .tszInstanceName
= L
"Wine Test",
4257 .tszProductName
= L
"Wine Test",
4258 .guidFFDriver
= GUID_NULL
,
4259 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
4260 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
4262 const DIDEVICEOBJECTINSTANCEW expect_objects
[] =
4265 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
4266 .guidType
= GUID_XAxis
,
4268 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(0),
4269 .dwFlags
= DIDOI_ASPECTPOSITION
,
4270 .tszName
= L
"Steering",
4271 .wCollectionNumber
= 1,
4272 .wUsagePage
= HID_USAGE_PAGE_SIMULATION
,
4273 .wUsage
= HID_USAGE_SIMULATION_STEERING
,
4277 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
4278 .guidType
= GUID_Unknown
,
4280 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(6),
4282 .tszName
= L
"Clutch",
4283 .wCollectionNumber
= 1,
4284 .wUsagePage
= HID_USAGE_PAGE_SIMULATION
,
4285 .wUsage
= HID_USAGE_SIMULATION_CLUTCH
,
4289 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
4290 .guidType
= GUID_RzAxis
,
4292 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(5),
4293 .dwFlags
= DIDOI_ASPECTPOSITION
,
4294 .tszName
= L
"Brake",
4295 .wCollectionNumber
= 1,
4296 .wUsagePage
= HID_USAGE_PAGE_SIMULATION
,
4297 .wUsage
= HID_USAGE_SIMULATION_BRAKE
,
4301 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
4302 .guidType
= GUID_YAxis
,
4304 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(1),
4305 .dwFlags
= DIDOI_ASPECTPOSITION
,
4306 .tszName
= L
"Accelerator",
4307 .wCollectionNumber
= 1,
4308 .wUsagePage
= HID_USAGE_PAGE_SIMULATION
,
4309 .wUsage
= HID_USAGE_SIMULATION_ACCELERATOR
,
4313 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
4314 .guidType
= GUID_Slider
,
4316 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(2),
4317 .dwFlags
= DIDOI_ASPECTPOSITION
,
4318 .tszName
= L
"Throttle",
4319 .wCollectionNumber
= 1,
4320 .wUsagePage
= HID_USAGE_PAGE_SIMULATION
,
4321 .wUsage
= HID_USAGE_SIMULATION_THROTTLE
,
4325 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
4326 .guidType
= GUID_RzAxis
,
4328 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(7),
4329 .dwFlags
= DIDOI_ASPECTPOSITION
,
4330 .tszName
= L
"Rudder",
4331 .wCollectionNumber
= 1,
4332 .wUsagePage
= HID_USAGE_PAGE_SIMULATION
,
4333 .wUsage
= HID_USAGE_SIMULATION_RUDDER
,
4337 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
4338 .guidType
= GUID_Unknown
,
4339 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(0),
4340 .tszName
= L
"Collection 0 - Joystick",
4341 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
4342 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
4345 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
4346 .guidType
= GUID_Unknown
,
4347 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(1),
4348 .tszName
= L
"Collection 1 - Joystick",
4349 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
4350 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
4353 struct check_objects_params check_objects_params
=
4355 .version
= DIRECTINPUT_VERSION
,
4356 .expect_count
= ARRAY_SIZE(expect_objects
),
4357 .expect_objs
= expect_objects
,
4360 DIDEVICEINSTANCEW devinst
= {0};
4361 IDirectInputDevice8W
*device
;
4362 DIDEVCAPS caps
= {0};
4366 cleanup_registry_keys();
4368 desc
.report_descriptor_len
= sizeof(report_desc
);
4369 memcpy( desc
.report_descriptor_buf
, report_desc
, sizeof(report_desc
) );
4370 fill_context( desc
.context
, ARRAY_SIZE(desc
.context
) );
4372 if (!hid_device_start( &desc
, 1 )) goto done
;
4373 if (FAILED(hr
= dinput_test_create_device( DIRECTINPUT_VERSION
, &devinst
, &device
))) goto done
;
4375 check_dinput_devices( DIRECTINPUT_VERSION
, &devinst
);
4377 memset( &devinst
, 0, sizeof(devinst
) );
4378 devinst
.dwSize
= sizeof(DIDEVICEINSTANCEW
);
4379 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
4380 ok( hr
== DI_OK
, "GetDeviceInfo returned %#lx\n", hr
);
4381 check_member( devinst
, expect_devinst
, "%lu", dwSize
);
4383 check_member_guid( devinst
, expect_devinst
, guidInstance
);
4384 check_member_guid( devinst
, expect_devinst
, guidProduct
);
4385 check_member( devinst
, expect_devinst
, "%#lx", dwDevType
);
4386 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
4387 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
4388 check_member_guid( devinst
, expect_devinst
, guidFFDriver
);
4389 check_member( devinst
, expect_devinst
, "%04x", wUsagePage
);
4390 check_member( devinst
, expect_devinst
, "%04x", wUsage
);
4392 hr
= IDirectInputDevice8_GetCapabilities( device
, NULL
);
4393 ok( hr
== E_POINTER
, "GetCapabilities returned %#lx\n", hr
);
4394 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
4395 ok( hr
== DIERR_INVALIDPARAM
, "GetCapabilities returned %#lx\n", hr
);
4396 caps
.dwSize
= sizeof(DIDEVCAPS
);
4397 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
4398 ok( hr
== DI_OK
, "GetCapabilities returned %#lx\n", hr
);
4399 check_member( caps
, expect_caps
, "%lu", dwSize
);
4400 check_member( caps
, expect_caps
, "%#lx", dwFlags
);
4401 check_member( caps
, expect_caps
, "%#lx", dwDevType
);
4402 check_member( caps
, expect_caps
, "%lu", dwAxes
);
4403 check_member( caps
, expect_caps
, "%lu", dwButtons
);
4404 check_member( caps
, expect_caps
, "%lu", dwPOVs
);
4405 check_member( caps
, expect_caps
, "%lu", dwFFSamplePeriod
);
4406 check_member( caps
, expect_caps
, "%lu", dwFFMinTimeResolution
);
4407 check_member( caps
, expect_caps
, "%lu", dwFirmwareRevision
);
4408 check_member( caps
, expect_caps
, "%lu", dwHardwareRevision
);
4409 check_member( caps
, expect_caps
, "%lu", dwFFDriverVersion
);
4411 hr
= IDirectInputDevice8_EnumObjects( device
, check_objects
, &check_objects_params
, DIDFT_ALL
);
4412 ok( hr
== DI_OK
, "EnumObjects returned %#lx\n", hr
);
4413 ok( check_objects_params
.index
>= check_objects_params
.expect_count
, "missing %u objects\n",
4414 check_objects_params
.expect_count
- check_objects_params
.index
);
4416 ref
= IDirectInputDevice8_Release( device
);
4417 ok( ref
== 0, "Release returned %ld\n", ref
);
4420 hid_device_stop( &desc
, 1 );
4421 cleanup_registry_keys();
4424 static BOOL
test_winmm_joystick(void)
4426 #include "psh_hid_macros.h"
4427 const unsigned char report_desc
[] =
4429 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
4430 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
4431 COLLECTION(1, Application
),
4432 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
4433 COLLECTION(1, Report
),
4436 USAGE(1, HID_USAGE_GENERIC_X
),
4437 USAGE(1, HID_USAGE_GENERIC_Y
),
4438 USAGE(1, HID_USAGE_GENERIC_Z
),
4439 USAGE(1, HID_USAGE_GENERIC_WHEEL
),
4440 USAGE(1, HID_USAGE_GENERIC_SLIDER
),
4441 USAGE(1, HID_USAGE_GENERIC_RX
),
4442 USAGE(1, HID_USAGE_GENERIC_RY
),
4443 USAGE(1, HID_USAGE_GENERIC_RZ
),
4444 LOGICAL_MINIMUM(1, 1),
4445 LOGICAL_MAXIMUM(4, 0xffff),
4446 PHYSICAL_MINIMUM(1, 1),
4447 PHYSICAL_MAXIMUM(4, 0xffff),
4450 INPUT(1, Data
|Var
|Abs
),
4452 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
4453 LOGICAL_MINIMUM(1, 1),
4454 LOGICAL_MAXIMUM(1, 8),
4455 PHYSICAL_MINIMUM(1, 0),
4456 PHYSICAL_MAXIMUM(1, 8),
4459 INPUT(1, Data
|Var
|Abs
|Null
),
4461 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
4462 USAGE_MINIMUM(1, 1),
4463 USAGE_MAXIMUM(1, 4),
4464 LOGICAL_MINIMUM(1, 0),
4465 LOGICAL_MAXIMUM(1, 1),
4466 PHYSICAL_MINIMUM(1, 0),
4467 PHYSICAL_MAXIMUM(1, 1),
4470 INPUT(1, Data
|Var
|Abs
),
4474 C_ASSERT(sizeof(report_desc
) < MAX_HID_DESCRIPTOR_LEN
);
4475 #include "pop_hid_macros.h"
4477 struct hid_device_desc desc
=
4479 .use_report_id
= TRUE
,
4480 .caps
= { .InputReportByteLength
= 18 },
4481 .attributes
= default_attributes
,
4483 static const JOYCAPS2W expect_regcaps
=
4485 .szRegKey
= L
"DINPUT.DLL",
4487 static const JOYCAPS2W expect_caps
=
4491 .szPname
= L
"Microsoft PC-joystick driver",
4501 .wCaps
= JOYCAPS_HASZ
| JOYCAPS_HASR
| JOYCAPS_HASU
| JOYCAPS_HASV
| JOYCAPS_HASPOV
| JOYCAPS_POV4DIR
,
4505 .szRegKey
= L
"DINPUT.DLL",
4507 struct hid_expect injected_input
[] =
4510 .code
= IOCTL_HID_READ_REPORT
,
4511 .report_buf
= {1,0x00,0x00,0x00,0x08,0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x38,0xf1},
4514 .code
= IOCTL_HID_READ_REPORT
,
4515 .report_buf
= {1,0x00,0x38,0x00,0x30,0x00,0x28,0x00,0x20,0x00,0x18,0x00,0x10,0x00,0x08,0x00,0x00,0x63},
4518 static const JOYINFOEX expect_infoex
[] =
4521 .dwSize
= sizeof(JOYINFOEX
), .dwFlags
= 0xff,
4522 .dwXpos
= 0x7fff, .dwYpos
= 0x7fff, .dwZpos
= 0x7fff, .dwRpos
= 0x7fff, .dwUpos
= 0x7fff, .dwVpos
= 0x7fff,
4523 .dwButtons
= 0, .dwButtonNumber
= 0, .dwPOV
= 0xffff,
4524 .dwReserved1
= 0xcdcdcdcd, .dwReserved2
= 0xcdcdcdcd,
4527 .dwSize
= sizeof(JOYINFOEX
), .dwFlags
= 0xff,
4528 .dwXpos
= 0, .dwYpos
= 0x07ff, .dwZpos
= 0x17ff, .dwRpos
= 0x37ff, .dwUpos
= 0x1fff, .dwVpos
= 0x27ff,
4529 .dwButtons
= 0xf, .dwButtonNumber
= 0x4, .dwPOV
= 0,
4530 .dwReserved1
= 0xcdcdcdcd, .dwReserved2
= 0xcdcdcdcd,
4533 .dwSize
= sizeof(JOYINFOEX
), .dwFlags
= 0xff,
4534 .dwXpos
= 0x37ff, .dwYpos
= 0x2fff, .dwZpos
= 0x1fff, .dwRpos
= 0, .dwUpos
= 0x17ff, .dwVpos
= 0x0fff,
4535 .dwButtons
= 0x6, .dwButtonNumber
= 0x2, .dwPOV
= 0x2328,
4536 .dwReserved1
= 0xcdcdcdcd, .dwReserved2
= 0xcdcdcdcd,
4539 static const JOYINFO expect_info
=
4546 JOYINFOEX infoex
= {.dwSize
= sizeof(JOYINFOEX
)};
4547 DIPROPGUIDANDPATH prop_guid_path
=
4551 .dwSize
= sizeof(DIPROPGUIDANDPATH
),
4552 .dwHeaderSize
= sizeof(DIPROPHEADER
),
4553 .dwHow
= DIPH_DEVICE
,
4556 IDirectInputDevice8W
*device
= NULL
;
4557 DIDEVICEINSTANCEW devinst
= {0};
4558 JOYCAPS2W caps
= {0};
4564 cleanup_registry_keys();
4566 ret
= joyGetNumDevs();
4567 ok( ret
== 16, "joyGetNumDevs returned %u\n", ret
);
4569 ret
= joyGetDevCapsW( 0, (JOYCAPSW
*)&caps
, sizeof(JOYCAPSW
) );
4570 ok( ret
== JOYERR_PARMS
, "joyGetDevCapsW returned %u\n", ret
);
4572 memset( &caps
, 0xcd, sizeof(caps
) );
4573 ret
= joyGetDevCapsW( -1, (JOYCAPSW
*)&caps
, sizeof(caps
) );
4574 ok( ret
== 0, "joyGetDevCapsW returned %u\n", ret
);
4575 check_member( caps
, expect_regcaps
, "%#x", wMid
);
4576 check_member( caps
, expect_regcaps
, "%#x", wPid
);
4577 check_member_wstr( caps
, expect_regcaps
, szPname
);
4578 check_member( caps
, expect_regcaps
, "%#x", wXmin
);
4579 check_member( caps
, expect_regcaps
, "%#x", wXmax
);
4580 check_member( caps
, expect_regcaps
, "%#x", wYmin
);
4581 check_member( caps
, expect_regcaps
, "%#x", wYmax
);
4582 check_member( caps
, expect_regcaps
, "%#x", wZmin
);
4583 check_member( caps
, expect_regcaps
, "%#x", wZmax
);
4584 check_member( caps
, expect_regcaps
, "%#x", wNumButtons
);
4585 check_member( caps
, expect_regcaps
, "%#x", wPeriodMin
);
4586 check_member( caps
, expect_regcaps
, "%#x", wPeriodMax
);
4587 check_member( caps
, expect_regcaps
, "%#x", wRmin
);
4588 check_member( caps
, expect_regcaps
, "%#x", wRmax
);
4589 check_member( caps
, expect_regcaps
, "%#x", wUmin
);
4590 check_member( caps
, expect_regcaps
, "%#x", wUmax
);
4591 check_member( caps
, expect_regcaps
, "%#x", wVmin
);
4592 check_member( caps
, expect_regcaps
, "%#x", wVmax
);
4593 check_member( caps
, expect_regcaps
, "%#x", wCaps
);
4594 check_member( caps
, expect_regcaps
, "%#x", wMaxAxes
);
4595 check_member( caps
, expect_regcaps
, "%#x", wNumAxes
);
4596 check_member( caps
, expect_regcaps
, "%#x", wMaxButtons
);
4597 check_member_wstr( caps
, expect_regcaps
, szRegKey
);
4598 check_member_wstr( caps
, expect_regcaps
, szOEMVxD
);
4599 check_member_guid( caps
, expect_regcaps
, ManufacturerGuid
);
4600 check_member_guid( caps
, expect_regcaps
, ProductGuid
);
4601 check_member_guid( caps
, expect_regcaps
, NameGuid
);
4603 desc
.report_descriptor_len
= sizeof(report_desc
);
4604 memcpy( desc
.report_descriptor_buf
, report_desc
, sizeof(report_desc
) );
4605 fill_context( desc
.context
, ARRAY_SIZE(desc
.context
) );
4607 if (!hid_device_start( &desc
, 1 )) goto done
;
4609 ret
= joyGetNumDevs();
4610 ok( ret
== 16, "joyGetNumDevs returned %u\n", ret
);
4612 ret
= joyGetPosEx( 1, &infoex
);
4613 ok( ret
== JOYERR_PARMS
, "joyGetPosEx returned %u\n", ret
);
4614 ret
= joyGetPosEx( 0, &infoex
);
4615 /* first call for an index sometimes fail */
4616 if (ret
== JOYERR_PARMS
) ret
= joyGetPosEx( 0, &infoex
);
4617 ok( ret
== 0, "joyGetPosEx returned %u\n", ret
);
4619 ret
= joyGetDevCapsW( 1, (JOYCAPSW
*)&caps
, sizeof(JOYCAPSW
) );
4620 ok( ret
== JOYERR_PARMS
, "joyGetDevCapsW returned %u\n", ret
);
4622 memset( &caps
, 0xcd, sizeof(caps
) );
4623 ret
= joyGetDevCapsW( 0, (JOYCAPSW
*)&caps
, sizeof(caps
) );
4624 ok( ret
== 0, "joyGetDevCapsW returned %u\n", ret
);
4625 check_member( caps
, expect_caps
, "%#x", wMid
);
4626 check_member( caps
, expect_caps
, "%#x", wPid
);
4628 check_member_wstr( caps
, expect_caps
, szPname
);
4629 check_member( caps
, expect_caps
, "%#x", wXmin
);
4630 check_member( caps
, expect_caps
, "%#x", wXmax
);
4631 check_member( caps
, expect_caps
, "%#x", wYmin
);
4632 check_member( caps
, expect_caps
, "%#x", wYmax
);
4633 check_member( caps
, expect_caps
, "%#x", wZmin
);
4634 check_member( caps
, expect_caps
, "%#x", wZmax
);
4635 check_member( caps
, expect_caps
, "%#x", wNumButtons
);
4636 check_member( caps
, expect_caps
, "%#x", wPeriodMin
);
4637 check_member( caps
, expect_caps
, "%#x", wPeriodMax
);
4638 check_member( caps
, expect_caps
, "%#x", wRmin
);
4639 check_member( caps
, expect_caps
, "%#x", wRmax
);
4640 check_member( caps
, expect_caps
, "%#x", wUmin
);
4641 check_member( caps
, expect_caps
, "%#x", wUmax
);
4642 check_member( caps
, expect_caps
, "%#x", wVmin
);
4643 check_member( caps
, expect_caps
, "%#x", wVmax
);
4644 check_member( caps
, expect_caps
, "%#x", wCaps
);
4645 check_member( caps
, expect_caps
, "%#x", wMaxAxes
);
4646 check_member( caps
, expect_caps
, "%#x", wNumAxes
);
4647 check_member( caps
, expect_caps
, "%#x", wMaxButtons
);
4648 check_member_wstr( caps
, expect_caps
, szRegKey
);
4649 check_member_wstr( caps
, expect_caps
, szOEMVxD
);
4650 check_member_guid( caps
, expect_caps
, ManufacturerGuid
);
4651 check_member_guid( caps
, expect_caps
, ProductGuid
);
4652 check_member_guid( caps
, expect_caps
, NameGuid
);
4654 ret
= joyGetDevCapsW( 0, (JOYCAPSW
*)&caps
, sizeof(JOYCAPSW
) );
4655 ok( ret
== 0, "joyGetDevCapsW returned %u\n", ret
);
4656 ret
= joyGetDevCapsW( 0, NULL
, sizeof(JOYCAPSW
) );
4657 ok( ret
== MMSYSERR_INVALPARAM
, "joyGetDevCapsW returned %u\n", ret
);
4658 ret
= joyGetDevCapsW( 0, (JOYCAPSW
*)&caps
, sizeof(JOYCAPSW
) + 4 );
4659 ok( ret
== JOYERR_PARMS
, "joyGetDevCapsW returned %u\n", ret
);
4660 ret
= joyGetDevCapsW( 0, (JOYCAPSW
*)&caps
, sizeof(JOYCAPSW
) - 4 );
4661 ok( ret
== JOYERR_PARMS
, "joyGetDevCapsW returned %u\n", ret
);
4663 infoex
.dwSize
= sizeof(JOYINFOEX
);
4664 infoex
.dwFlags
= JOY_RETURNALL
;
4665 ret
= joyGetPosEx( -1, &infoex
);
4666 ok( ret
== JOYERR_PARMS
, "joyGetPosEx returned %u\n", ret
);
4667 ret
= joyGetPosEx( 1, &infoex
);
4668 ok( ret
== JOYERR_PARMS
, "joyGetPosEx returned %u\n", ret
);
4669 ret
= joyGetPosEx( 16, &infoex
);
4670 ok( ret
== JOYERR_PARMS
, "joyGetPosEx returned %u\n", ret
);
4672 memset( &infoex
, 0xcd, sizeof(infoex
) );
4673 infoex
.dwSize
= sizeof(JOYINFOEX
);
4674 infoex
.dwFlags
= JOY_RETURNALL
;
4675 ret
= joyGetPosEx( 0, &infoex
);
4676 ok( ret
== 0, "joyGetPosEx returned %u\n", ret
);
4677 check_member( infoex
, expect_infoex
[0], "%#lx", dwSize
);
4678 check_member( infoex
, expect_infoex
[0], "%#lx", dwFlags
);
4679 check_member( infoex
, expect_infoex
[0], "%#lx", dwXpos
);
4680 check_member( infoex
, expect_infoex
[0], "%#lx", dwYpos
);
4681 check_member( infoex
, expect_infoex
[0], "%#lx", dwZpos
);
4682 check_member( infoex
, expect_infoex
[0], "%#lx", dwRpos
);
4683 check_member( infoex
, expect_infoex
[0], "%#lx", dwUpos
);
4684 check_member( infoex
, expect_infoex
[0], "%#lx", dwVpos
);
4685 check_member( infoex
, expect_infoex
[0], "%#lx", dwButtons
);
4686 check_member( infoex
, expect_infoex
[0], "%#lx", dwButtonNumber
);
4687 check_member( infoex
, expect_infoex
[0], "%#lx", dwPOV
);
4688 check_member( infoex
, expect_infoex
[0], "%#lx", dwReserved1
);
4689 check_member( infoex
, expect_infoex
[0], "%#lx", dwReserved2
);
4691 infoex
.dwSize
= sizeof(JOYINFOEX
) - 4;
4692 ret
= joyGetPosEx( 0, &infoex
);
4693 ok( ret
== JOYERR_PARMS
, "joyGetPosEx returned %u\n", ret
);
4695 ret
= joyGetPos( -1, &info
);
4696 ok( ret
== JOYERR_PARMS
, "joyGetPos returned %u\n", ret
);
4697 ret
= joyGetPos( 1, &info
);
4698 ok( ret
== JOYERR_PARMS
, "joyGetPos returned %u\n", ret
);
4699 memset( &info
, 0xcd, sizeof(info
) );
4700 ret
= joyGetPos( 0, &info
);
4701 ok( ret
== 0, "joyGetPos returned %u\n", ret
);
4702 check_member( info
, expect_info
, "%#x", wXpos
);
4703 check_member( info
, expect_info
, "%#x", wYpos
);
4704 check_member( info
, expect_info
, "%#x", wZpos
);
4705 check_member( info
, expect_info
, "%#x", wButtons
);
4707 if (FAILED(hr
= dinput_test_create_device( DIRECTINPUT_VERSION
, &devinst
, &device
))) goto done
;
4709 event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
4710 ok( event
!= NULL
, "CreateEventW failed, last error %lu\n", GetLastError() );
4711 hr
= IDirectInputDevice8_SetEventNotification( device
, event
);
4712 ok( hr
== DI_OK
, "SetEventNotification returned: %#lx\n", hr
);
4714 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
4715 ok( hr
== DI_OK
, "GetProperty DIPROP_GUIDANDPATH returned %#lx\n", hr
);
4716 file
= CreateFileW( prop_guid_path
.wszPath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
4717 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
4718 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
4719 ok( file
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError() );
4721 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
4722 ok( hr
== DI_OK
, "SetDataFormat returned: %#lx\n", hr
);
4723 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
| DISCL_NONEXCLUSIVE
);
4724 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#lx\n", hr
);
4725 hr
= IDirectInputDevice8_Acquire( device
);
4726 ok( hr
== DI_OK
, "Acquire returned: %#lx\n", hr
);
4728 send_hid_input( file
, &injected_input
[0], sizeof(struct hid_expect
) );
4729 ret
= WaitForSingleObject( event
, 5000 );
4730 ok( ret
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#x\n", ret
);
4731 Sleep( 50 ); /* leave some time for winmm to keep up */
4733 memset( &infoex
, 0xcd, sizeof(infoex
) );
4734 infoex
.dwSize
= sizeof(JOYINFOEX
);
4735 infoex
.dwFlags
= JOY_RETURNALL
;
4736 ret
= joyGetPosEx( 0, &infoex
);
4737 ok( ret
== 0, "joyGetPosEx returned %u\n", ret
);
4738 check_member( infoex
, expect_infoex
[1], "%#lx", dwSize
);
4739 check_member( infoex
, expect_infoex
[1], "%#lx", dwFlags
);
4740 check_member( infoex
, expect_infoex
[1], "%#lx", dwXpos
);
4741 check_member( infoex
, expect_infoex
[1], "%#lx", dwYpos
);
4742 check_member( infoex
, expect_infoex
[1], "%#lx", dwZpos
);
4743 check_member( infoex
, expect_infoex
[1], "%#lx", dwRpos
);
4744 check_member( infoex
, expect_infoex
[1], "%#lx", dwUpos
);
4745 check_member( infoex
, expect_infoex
[1], "%#lx", dwVpos
);
4746 check_member( infoex
, expect_infoex
[1], "%#lx", dwButtons
);
4747 check_member( infoex
, expect_infoex
[1], "%#lx", dwButtonNumber
);
4748 check_member( infoex
, expect_infoex
[1], "%#lx", dwPOV
);
4750 send_hid_input( file
, &injected_input
[1], sizeof(struct hid_expect
) );
4751 ret
= WaitForSingleObject( event
, 5000 );
4752 ok( ret
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#x\n", ret
);
4753 Sleep( 50 ); /* leave some time for winmm to keep up */
4755 memset( &infoex
, 0xcd, sizeof(infoex
) );
4756 infoex
.dwSize
= sizeof(JOYINFOEX
);
4757 infoex
.dwFlags
= JOY_RETURNALL
;
4758 ret
= joyGetPosEx( 0, &infoex
);
4759 ok( ret
== 0, "joyGetPosEx returned %u\n", ret
);
4760 check_member( infoex
, expect_infoex
[2], "%#lx", dwSize
);
4761 check_member( infoex
, expect_infoex
[2], "%#lx", dwFlags
);
4762 check_member( infoex
, expect_infoex
[2], "%#lx", dwXpos
);
4763 check_member( infoex
, expect_infoex
[2], "%#lx", dwYpos
);
4764 check_member( infoex
, expect_infoex
[2], "%#lx", dwZpos
);
4765 check_member( infoex
, expect_infoex
[2], "%#lx", dwRpos
);
4766 check_member( infoex
, expect_infoex
[2], "%#lx", dwUpos
);
4767 check_member( infoex
, expect_infoex
[2], "%#lx", dwVpos
);
4768 check_member( infoex
, expect_infoex
[2], "%#lx", dwButtons
);
4769 check_member( infoex
, expect_infoex
[2], "%#lx", dwButtonNumber
);
4770 check_member( infoex
, expect_infoex
[2], "%#lx", dwPOV
);
4772 ret
= IDirectInputDevice8_Release( device
);
4773 ok( ret
== 0, "Release returned %d\n", ret
);
4775 CloseHandle( event
);
4776 CloseHandle( file
);
4779 hid_device_stop( &desc
, 1 );
4780 cleanup_registry_keys();
4782 return device
!= NULL
;
4785 #define check_interface( a, b, c ) check_interface_( __LINE__, a, b, c )
4786 static void check_interface_( unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
4788 IUnknown
*iface
= iface_ptr
;
4789 HRESULT hr
, expected
;
4792 expected
= supported
? S_OK
: E_NOINTERFACE
;
4793 hr
= IUnknown_QueryInterface( iface
, iid
, (void **)&unk
);
4794 ok_ (__FILE__
, line
)( hr
== expected
, "got hr %#lx, expected %#lx.\n", hr
, expected
);
4795 if (SUCCEEDED(hr
)) IUnknown_Release( unk
);
4798 #define check_runtimeclass( a, b ) check_runtimeclass_( __LINE__, (IInspectable *)a, b )
4799 static void check_runtimeclass_( int line
, IInspectable
*inspectable
, const WCHAR
*class_name
)
4801 const WCHAR
*buffer
;
4806 hr
= IInspectable_GetRuntimeClassName( inspectable
, &str
);
4807 ok_ (__FILE__
, line
)( hr
== S_OK
, "GetRuntimeClassName returned %#lx\n", hr
);
4808 buffer
= pWindowsGetStringRawBuffer( str
, &length
);
4809 ok_ (__FILE__
, line
)( !wcscmp( buffer
, class_name
), "got class name %s\n", debugstr_w(buffer
) );
4810 pWindowsDeleteString( str
);
4813 struct controller_handler
4815 IEventHandler_RawGameController IEventHandler_RawGameController_iface
;
4820 static inline struct controller_handler
*impl_from_IEventHandler_RawGameController( IEventHandler_RawGameController
*iface
)
4822 return CONTAINING_RECORD( iface
, struct controller_handler
, IEventHandler_RawGameController_iface
);
4825 static HRESULT WINAPI
controller_handler_QueryInterface( IEventHandler_RawGameController
*iface
, REFIID iid
, void **out
)
4827 if (IsEqualGUID( iid
, &IID_IUnknown
) ||
4828 IsEqualGUID( iid
, &IID_IAgileObject
) ||
4829 IsEqualGUID( iid
, &IID_IEventHandler_RawGameController
))
4831 IUnknown_AddRef( iface
);
4836 if (winetest_debug
> 1) trace( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid
) );
4838 return E_NOINTERFACE
;
4841 static ULONG WINAPI
controller_handler_AddRef( IEventHandler_RawGameController
*iface
)
4846 static ULONG WINAPI
controller_handler_Release( IEventHandler_RawGameController
*iface
)
4851 static HRESULT WINAPI
controller_handler_Invoke( IEventHandler_RawGameController
*iface
,
4852 IInspectable
*sender
, IRawGameController
*controller
)
4854 struct controller_handler
*impl
= impl_from_IEventHandler_RawGameController( iface
);
4856 if (winetest_debug
> 1) trace( "iface %p, sender %p, controller %p\n", iface
, sender
, controller
);
4858 ok( sender
== NULL
, "got sender %p\n", sender
);
4859 impl
->invoked
= TRUE
;
4860 SetEvent( impl
->event
);
4865 static const IEventHandler_RawGameControllerVtbl controller_handler_vtbl
=
4867 controller_handler_QueryInterface
,
4868 controller_handler_AddRef
,
4869 controller_handler_Release
,
4870 controller_handler_Invoke
,
4873 static struct controller_handler controller_added
= {{&controller_handler_vtbl
}};
4875 static void test_windows_gaming_input(void)
4877 #include "psh_hid_macros.h"
4878 const unsigned char report_desc
[] =
4880 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
4881 USAGE(1, HID_USAGE_GENERIC_GAMEPAD
),
4882 COLLECTION(1, Application
),
4883 USAGE(1, HID_USAGE_GENERIC_GAMEPAD
),
4884 COLLECTION(1, Physical
),
4885 USAGE(1, HID_USAGE_GENERIC_X
),
4886 USAGE(1, HID_USAGE_GENERIC_Y
),
4887 USAGE(1, HID_USAGE_GENERIC_RX
),
4888 USAGE(1, HID_USAGE_GENERIC_RY
),
4889 USAGE(1, HID_USAGE_GENERIC_Z
),
4890 USAGE(1, HID_USAGE_GENERIC_RZ
),
4891 LOGICAL_MINIMUM(1, 0),
4892 LOGICAL_MAXIMUM(1, 127),
4893 PHYSICAL_MINIMUM(1, 0),
4894 PHYSICAL_MAXIMUM(1, 127),
4897 INPUT(1, Data
|Var
|Abs
),
4899 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
4900 LOGICAL_MINIMUM(1, 1),
4901 LOGICAL_MAXIMUM(1, 8),
4902 PHYSICAL_MINIMUM(1, 0),
4903 PHYSICAL_MAXIMUM(1, 8),
4906 INPUT(1, Data
|Var
|Abs
|Null
),
4908 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
4909 USAGE_MINIMUM(1, 1),
4910 USAGE_MAXIMUM(1, 12),
4911 LOGICAL_MINIMUM(1, 0),
4912 LOGICAL_MAXIMUM(1, 1),
4913 PHYSICAL_MINIMUM(1, 0),
4914 PHYSICAL_MAXIMUM(1, 1),
4916 REPORT_COUNT(1, 12),
4917 INPUT(1, Data
|Var
|Abs
),
4921 C_ASSERT(sizeof(report_desc
) < MAX_HID_DESCRIPTOR_LEN
);
4922 static const unsigned char wheel_threepedals_desc
[] =
4924 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
4925 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
4926 COLLECTION(1, Application
),
4927 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
4928 COLLECTION(1, Physical
),
4929 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_STEERING
),
4930 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_ACCELERATOR
),
4931 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_BRAKE
),
4932 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_CLUTCH
),
4933 USAGE(1, HID_USAGE_GENERIC_Y
),
4934 LOGICAL_MINIMUM(1, 0),
4935 LOGICAL_MAXIMUM(1, 127),
4936 PHYSICAL_MINIMUM(1, 0),
4937 PHYSICAL_MAXIMUM(1, 127),
4940 INPUT(1, Data
|Var
|Abs
),
4942 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
4943 LOGICAL_MINIMUM(1, 1),
4944 LOGICAL_MAXIMUM(1, 8),
4945 PHYSICAL_MINIMUM(1, 0),
4946 PHYSICAL_MAXIMUM(1, 8),
4949 INPUT(1, Data
|Var
|Abs
|Null
),
4951 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
4952 USAGE_MINIMUM(1, 1),
4953 USAGE_MAXIMUM(1, 5),
4954 LOGICAL_MINIMUM(1, 0),
4955 LOGICAL_MAXIMUM(1, 1),
4956 PHYSICAL_MINIMUM(1, 0),
4957 PHYSICAL_MAXIMUM(1, 1),
4959 REPORT_COUNT(1, 16),
4960 INPUT(1, Data
|Var
|Abs
),
4964 C_ASSERT(sizeof(wheel_threepedals_desc
) < MAX_HID_DESCRIPTOR_LEN
);
4965 #include "pop_hid_macros.h"
4967 struct hid_device_desc desc
=
4969 .use_report_id
= TRUE
,
4970 .caps
= { .InputReportByteLength
= 8 },
4971 .attributes
= default_attributes
,
4973 static const WCHAR
*controller_class_name
= RuntimeClass_Windows_Gaming_Input_RawGameController
;
4974 static const WCHAR
*racing_wheel_class_name
= RuntimeClass_Windows_Gaming_Input_RacingWheel
;
4975 static const WCHAR
*gamepad_class_name
= RuntimeClass_Windows_Gaming_Input_Gamepad
;
4977 IRawGameController
*raw_controller
, *tmp_raw_controller
;
4978 IVectorView_RawGameController
*controllers_view
;
4979 IRawGameControllerStatics
*controller_statics
;
4980 EventRegistrationToken controller_added_token
;
4981 IVectorView_RacingWheel
*racing_wheels_view
;
4982 IRacingWheelStatics2
*racing_wheel_statics2
;
4983 IRacingWheelStatics
*racing_wheel_statics
;
4984 IVectorView_Gamepad
*gamepads_view
;
4985 IGamepadStatics
*gamepad_statics
;
4986 IGameController
*game_controller
;
4987 IRacingWheel
*racing_wheel
;
4993 if (!load_combase_functions()) return;
4995 cleanup_registry_keys();
4997 hr
= pRoInitialize( RO_INIT_MULTITHREADED
);
4998 ok( hr
== RPC_E_CHANGED_MODE
, "RoInitialize returned %#lx\n", hr
);
5000 hr
= pWindowsCreateString( controller_class_name
, wcslen( controller_class_name
), &str
);
5001 ok( hr
== S_OK
, "WindowsCreateString returned %#lx\n", hr
);
5002 hr
= pRoGetActivationFactory( str
, &IID_IRawGameControllerStatics
, (void **)&controller_statics
);
5003 ok( hr
== S_OK
|| broken( hr
== REGDB_E_CLASSNOTREG
), "RoGetActivationFactory returned %#lx\n", hr
);
5004 pWindowsDeleteString( str
);
5006 if (hr
== REGDB_E_CLASSNOTREG
)
5008 win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( controller_class_name
) );
5012 hr
= IRawGameControllerStatics_get_RawGameControllers( controller_statics
, &controllers_view
);
5013 ok( hr
== S_OK
, "get_RawGameControllers returned %#lx\n", hr
);
5014 hr
= IVectorView_RawGameController_get_Size( controllers_view
, &size
);
5015 ok( hr
== S_OK
, "get_Size returned %#lx\n", hr
);
5016 ok( size
== 0, "got size %u\n", size
);
5018 controller_added
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
5019 ok( !!controller_added
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
5021 hr
= IRawGameControllerStatics_add_RawGameControllerAdded( controller_statics
, &controller_added
.IEventHandler_RawGameController_iface
,
5022 &controller_added_token
);
5023 ok( hr
== S_OK
, "add_RawGameControllerAdded returned %#lx\n", hr
);
5024 ok( controller_added_token
.value
, "got token %I64u\n", controller_added_token
.value
);
5026 desc
.report_descriptor_len
= sizeof(report_desc
);
5027 memcpy( desc
.report_descriptor_buf
, report_desc
, sizeof(report_desc
) );
5028 fill_context( desc
.context
, ARRAY_SIZE(desc
.context
) );
5030 if (!hid_device_start( &desc
, 1 )) goto done
;
5031 res
= WaitForSingleObject( controller_added
.event
, 5000 );
5032 ok( !res
, "WaitForSingleObject returned %#lx\n", res
);
5033 CloseHandle( controller_added
.event
);
5035 hr
= IVectorView_RawGameController_get_Size( controllers_view
, &size
);
5036 ok( hr
== S_OK
, "get_Size returned %#lx\n", hr
);
5037 ok( size
== 0, "got size %u\n", size
);
5038 IVectorView_RawGameController_Release( controllers_view
);
5040 hr
= IRawGameControllerStatics_get_RawGameControllers( controller_statics
, &controllers_view
);
5041 ok( hr
== S_OK
, "get_RawGameControllers returned %#lx\n", hr
);
5042 hr
= IVectorView_RawGameController_get_Size( controllers_view
, &size
);
5043 ok( hr
== S_OK
, "get_Size returned %#lx\n", hr
);
5044 ok( size
== 1, "got size %u\n", size
);
5045 hr
= IVectorView_RawGameController_GetAt( controllers_view
, 0, &raw_controller
);
5046 ok( hr
== S_OK
, "GetAt returned %#lx\n", hr
);
5047 IVectorView_RawGameController_Release( controllers_view
);
5049 /* HID gamepads aren't exposed as WGI gamepads on Windows */
5051 hr
= pWindowsCreateString( gamepad_class_name
, wcslen( gamepad_class_name
), &str
);
5052 ok( hr
== S_OK
, "WindowsCreateString returned %#lx\n", hr
);
5053 hr
= pRoGetActivationFactory( str
, &IID_IGamepadStatics
, (void **)&gamepad_statics
);
5054 ok( hr
== S_OK
, "RoGetActivationFactory returned %#lx\n", hr
);
5055 pWindowsDeleteString( str
);
5056 hr
= IGamepadStatics_get_Gamepads( gamepad_statics
, &gamepads_view
);
5057 ok( hr
== S_OK
, "get_Gamepads returned %#lx\n", hr
);
5058 hr
= IVectorView_Gamepad_get_Size( gamepads_view
, &size
);
5059 ok( hr
== S_OK
, "get_Size returned %#lx\n", hr
);
5060 todo_wine
/* but Wine currently intentionally does */
5061 ok( size
== 0, "got size %u\n", size
);
5062 IVectorView_Gamepad_Release( gamepads_view
);
5063 IGamepadStatics_Release( gamepad_statics
);
5065 check_runtimeclass( raw_controller
, RuntimeClass_Windows_Gaming_Input_RawGameController
);
5066 check_interface( raw_controller
, &IID_IUnknown
, TRUE
);
5067 check_interface( raw_controller
, &IID_IInspectable
, TRUE
);
5068 check_interface( raw_controller
, &IID_IAgileObject
, TRUE
);
5069 check_interface( raw_controller
, &IID_IRawGameController
, TRUE
);
5071 check_interface( raw_controller
, &IID_IRawGameController2
, TRUE
);
5072 check_interface( raw_controller
, &IID_IGameController
, TRUE
);
5073 check_interface( raw_controller
, &IID_IGamepad
, FALSE
);
5075 hr
= IRawGameController_QueryInterface( raw_controller
, &IID_IGameController
, (void **)&game_controller
);
5076 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
5078 check_runtimeclass( game_controller
, RuntimeClass_Windows_Gaming_Input_RawGameController
);
5079 check_interface( game_controller
, &IID_IUnknown
, TRUE
);
5080 check_interface( game_controller
, &IID_IInspectable
, TRUE
);
5081 check_interface( game_controller
, &IID_IAgileObject
, TRUE
);
5082 check_interface( game_controller
, &IID_IRawGameController
, TRUE
);
5084 check_interface( game_controller
, &IID_IRawGameController2
, TRUE
);
5085 check_interface( game_controller
, &IID_IGameController
, TRUE
);
5086 check_interface( game_controller
, &IID_IGamepad
, FALSE
);
5088 hr
= IRawGameControllerStatics_FromGameController( controller_statics
, game_controller
, &tmp_raw_controller
);
5089 ok( hr
== S_OK
, "FromGameController returned %#lx\n", hr
);
5090 ok( tmp_raw_controller
== raw_controller
, "got unexpected IGameController interface\n" );
5091 IRawGameController_Release( tmp_raw_controller
);
5093 IGameController_Release( game_controller
);
5094 IRawGameController_Release( raw_controller
);
5096 hr
= IRawGameControllerStatics_remove_RawGameControllerAdded( controller_statics
, controller_added_token
);
5097 ok( hr
== S_OK
, "remove_RawGameControllerAdded returned %#lx\n", hr
);
5099 hid_device_stop( &desc
, 1 );
5102 desc
.report_descriptor_len
= sizeof(wheel_threepedals_desc
);
5103 memcpy( desc
.report_descriptor_buf
, wheel_threepedals_desc
, sizeof(wheel_threepedals_desc
) );
5104 fill_context( desc
.context
, ARRAY_SIZE(desc
.context
) );
5106 controller_added
.event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
5107 ok( !!controller_added
.event
, "CreateEventW failed, error %lu\n", GetLastError() );
5109 hr
= IRawGameControllerStatics_add_RawGameControllerAdded( controller_statics
, &controller_added
.IEventHandler_RawGameController_iface
,
5110 &controller_added_token
);
5111 ok( hr
== S_OK
, "add_RawGameControllerAdded returned %#lx\n", hr
);
5112 ok( controller_added_token
.value
, "got token %I64u\n", controller_added_token
.value
);
5114 if (!hid_device_start( &desc
, 1 )) goto done
;
5115 res
= WaitForSingleObject( controller_added
.event
, 5000 );
5116 ok( !res
, "WaitForSingleObject returned %#lx\n", res
);
5117 CloseHandle( controller_added
.event
);
5119 hr
= IRawGameControllerStatics_get_RawGameControllers( controller_statics
, &controllers_view
);
5120 ok( hr
== S_OK
, "get_RawGameControllers returned %#lx\n", hr
);
5121 hr
= IVectorView_RawGameController_get_Size( controllers_view
, &size
);
5122 ok( hr
== S_OK
, "get_Size returned %#lx\n", hr
);
5123 ok( size
== 1, "got size %u\n", size
);
5124 hr
= IVectorView_RawGameController_GetAt( controllers_view
, 0, &raw_controller
);
5125 ok( hr
== S_OK
, "GetAt returned %#lx\n", hr
);
5126 IVectorView_RawGameController_Release( controllers_view
);
5128 hr
= IRawGameControllerStatics_remove_RawGameControllerAdded( controller_statics
, controller_added_token
);
5129 ok( hr
== S_OK
, "remove_RawGameControllerAdded returned %#lx\n", hr
);
5131 hr
= pWindowsCreateString( racing_wheel_class_name
, wcslen( racing_wheel_class_name
), &str
);
5132 ok( hr
== S_OK
, "WindowsCreateString returned %#lx\n", hr
);
5133 hr
= pRoGetActivationFactory( str
, &IID_IRacingWheelStatics
, (void **)&racing_wheel_statics
);
5134 ok( hr
== S_OK
, "RoGetActivationFactory returned %#lx\n", hr
);
5135 hr
= pRoGetActivationFactory( str
, &IID_IRacingWheelStatics2
, (void **)&racing_wheel_statics2
);
5136 ok( hr
== S_OK
, "RoGetActivationFactory returned %#lx\n", hr
);
5137 pWindowsDeleteString( str
);
5139 /* HID driving wheels aren't exposed as WGI RacingWheel on Windows */
5141 hr
= IRacingWheelStatics_get_RacingWheels( racing_wheel_statics
, &racing_wheels_view
);
5142 ok( hr
== S_OK
, "get_RacingWheels returned %#lx\n", hr
);
5143 hr
= IVectorView_RacingWheel_get_Size( racing_wheels_view
, &size
);
5144 ok( hr
== S_OK
, "get_Size returned %#lx\n", hr
);
5145 todo_wine
/* but Wine currently intentionally does */
5146 ok( size
== 0, "got size %u\n", size
);
5147 IVectorView_RacingWheel_Release( racing_wheels_view
);
5148 IRacingWheelStatics_Release( racing_wheel_statics
);
5150 hr
= IRawGameController_QueryInterface( raw_controller
, &IID_IGameController
, (void **)&game_controller
);
5151 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
5152 hr
= IRacingWheelStatics2_FromGameController( racing_wheel_statics2
, game_controller
, &racing_wheel
);
5153 ok( hr
== S_OK
, "FromGameController returned %#lx\n", hr
);
5155 ok( racing_wheel
== NULL
, "got racing_wheel %p\n", racing_wheel
);
5156 if (racing_wheel
) IRacingWheel_Release( racing_wheel
);
5157 IGameController_Release( game_controller
);
5158 IRacingWheelStatics2_Release( racing_wheel_statics2
);
5160 IRawGameController_Release( raw_controller
);
5161 IRawGameControllerStatics_Release( controller_statics
);
5164 hid_device_stop( &desc
, 1 );
5165 cleanup_registry_keys();
5168 static HANDLE rawinput_device_added
, rawinput_device_removed
, rawinput_event
;
5169 static char wm_input_buf
[1024];
5170 static UINT wm_input_len
;
5172 static LRESULT CALLBACK
rawinput_wndproc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
5174 UINT size
= sizeof(wm_input_buf
);
5176 if (msg
== WM_INPUT_DEVICE_CHANGE
)
5178 if (wparam
== GIDC_ARRIVAL
) ReleaseSemaphore( rawinput_device_added
, 1, NULL
);
5179 else ReleaseSemaphore( rawinput_device_removed
, 1, NULL
);
5181 if (msg
== WM_INPUT
)
5183 wm_input_len
= GetRawInputData( (HRAWINPUT
)lparam
, RID_INPUT
, (RAWINPUT
*)wm_input_buf
,
5184 &size
, sizeof(RAWINPUTHEADER
) );
5185 ReleaseSemaphore( rawinput_event
, 1, NULL
);
5188 return DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
5191 static void test_rawinput(void)
5193 #include "psh_hid_macros.h"
5194 static const unsigned char report_desc
[] =
5196 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
5197 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5198 COLLECTION(1, Application
),
5199 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5200 COLLECTION(1, Report
),
5203 USAGE(1, HID_USAGE_GENERIC_WHEEL
),
5204 USAGE(4, (0xff01u
<<16)|(0x1234)),
5205 USAGE(1, HID_USAGE_GENERIC_X
),
5206 USAGE(1, HID_USAGE_GENERIC_Y
),
5207 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_RUDDER
),
5208 USAGE(4, (HID_USAGE_PAGE_DIGITIZER
<<16)|HID_USAGE_DIGITIZER_TIP_PRESSURE
),
5209 USAGE(4, (HID_USAGE_PAGE_CONSUMER
<<16)|HID_USAGE_CONSUMER_VOLUME
),
5210 LOGICAL_MINIMUM(1, 0xe7),
5211 LOGICAL_MAXIMUM(1, 0x38),
5212 PHYSICAL_MINIMUM(1, 0xe7),
5213 PHYSICAL_MAXIMUM(1, 0x38),
5216 INPUT(1, Data
|Var
|Abs
),
5218 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
5219 LOGICAL_MINIMUM(1, 1),
5220 LOGICAL_MAXIMUM(1, 8),
5221 PHYSICAL_MINIMUM(1, 0),
5222 PHYSICAL_MAXIMUM(1, 8),
5225 INPUT(1, Data
|Var
|Abs
|Null
),
5227 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
5228 USAGE_MINIMUM(1, 1),
5229 USAGE_MAXIMUM(1, 2),
5230 LOGICAL_MINIMUM(1, 0),
5231 LOGICAL_MAXIMUM(1, 1),
5232 PHYSICAL_MINIMUM(1, 0),
5233 PHYSICAL_MAXIMUM(1, 1),
5236 INPUT(1, Data
|Var
|Abs
),
5240 C_ASSERT(sizeof(report_desc
) < MAX_HID_DESCRIPTOR_LEN
);
5241 #include "pop_hid_macros.h"
5243 struct hid_device_desc desc
=
5245 .use_report_id
= TRUE
,
5246 .caps
= { .InputReportByteLength
= 9 },
5247 .attributes
= default_attributes
,
5249 struct hid_expect injected_input
[] =
5252 .code
= IOCTL_HID_READ_REPORT
,
5253 .report_buf
= {1,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0},
5256 .code
= IOCTL_HID_READ_REPORT
,
5257 .report_buf
= {1,0x10,0x10,0x38,0x38,0x10,0x10,0x10,0xf8},
5260 .code
= IOCTL_HID_READ_REPORT
,
5261 .report_buf
= {1,0x10,0x10,0x01,0x01,0x10,0x10,0x10,0x00},
5264 .code
= IOCTL_HID_READ_REPORT
,
5265 .report_buf
= {1,0x10,0x10,0x01,0x01,0x10,0x10,0x10,0x00},
5268 .code
= IOCTL_HID_READ_REPORT
,
5269 .report_buf
= {1,0x10,0x10,0x80,0x80,0x10,0x10,0x10,0xff},
5272 .code
= IOCTL_HID_READ_REPORT
,
5273 .report_buf
= {1,0x10,0x10,0x10,0xee,0x10,0x10,0x10,0x54},
5278 .cbSize
= sizeof(WNDCLASSEXW
),
5279 .hInstance
= GetModuleHandleW( NULL
),
5280 .lpszClassName
= L
"rawinput",
5281 .lpfnWndProc
= rawinput_wndproc
,
5283 RAWINPUT
*rawinput
= (RAWINPUT
*)wm_input_buf
;
5284 RAWINPUTDEVICELIST raw_device_list
[16];
5285 RAWINPUTDEVICE raw_devices
[16];
5286 ULONG i
, res
, device_count
;
5287 WCHAR path
[MAX_PATH
] = {0};
5293 RegisterClassExW( &class );
5295 cleanup_registry_keys();
5297 desc
.report_descriptor_len
= sizeof(report_desc
);
5298 memcpy( desc
.report_descriptor_buf
, report_desc
, sizeof(report_desc
) );
5299 fill_context( desc
.context
, ARRAY_SIZE(desc
.context
) );
5301 rawinput_device_added
= CreateSemaphoreW( NULL
, 0, LONG_MAX
, NULL
);
5302 ok( !!rawinput_device_added
, "CreateSemaphoreW failed, error %lu\n", GetLastError() );
5303 rawinput_device_removed
= CreateSemaphoreW( NULL
, 0, LONG_MAX
, NULL
);
5304 ok( !!rawinput_device_removed
, "CreateSemaphoreW failed, error %lu\n", GetLastError() );
5305 rawinput_event
= CreateSemaphoreW( NULL
, 0, LONG_MAX
, NULL
);
5306 ok( !!rawinput_event
, "CreateSemaphoreW failed, error %lu\n", GetLastError() );
5308 hwnd
= CreateWindowW( class.lpszClassName
, L
"dinput", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 10, 10, 200, 200,
5309 NULL
, NULL
, NULL
, NULL
);
5310 ok( !!hwnd
, "CreateWindowW failed, error %lu\n", GetLastError() );
5312 count
= ARRAY_SIZE(raw_devices
);
5313 res
= GetRegisteredRawInputDevices( raw_devices
, &count
, sizeof(RAWINPUTDEVICE
) );
5314 ok( res
== 0, "GetRegisteredRawInputDevices returned %lu\n", res
);
5316 ok( count
== ARRAY_SIZE(raw_devices
), "got count %u\n", count
);
5318 count
= ARRAY_SIZE(raw_device_list
);
5319 res
= GetRawInputDeviceList( raw_device_list
, &count
, sizeof(RAWINPUTDEVICELIST
) );
5320 ok( res
>= 2, "GetRawInputDeviceList returned %lu\n", res
);
5321 ok( count
== ARRAY_SIZE(raw_device_list
), "got count %u\n", count
);
5324 if (!hid_device_start( &desc
, 1 )) goto done
;
5326 count
= ARRAY_SIZE(raw_devices
);
5327 res
= GetRegisteredRawInputDevices( raw_devices
, &count
, sizeof(RAWINPUTDEVICE
) );
5328 ok( res
== 0, "GetRegisteredRawInputDevices returned %lu\n", res
);
5330 ok( count
== ARRAY_SIZE(raw_devices
), "got count %u\n", count
);
5332 res
= msg_wait_for_events( 1, &rawinput_device_added
, 10 );
5333 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5334 res
= msg_wait_for_events( 1, &rawinput_device_removed
, 10 );
5335 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5336 res
= msg_wait_for_events( 1, &rawinput_event
, 10 );
5337 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5339 raw_devices
[0].usUsagePage
= HID_USAGE_PAGE_GENERIC
;
5340 raw_devices
[0].usUsage
= HID_USAGE_GENERIC_GAMEPAD
;
5341 raw_devices
[0].dwFlags
= RIDEV_DEVNOTIFY
;
5342 raw_devices
[0].hwndTarget
= hwnd
;
5343 count
= ARRAY_SIZE(raw_devices
);
5344 ret
= RegisterRawInputDevices( raw_devices
, 1, sizeof(RAWINPUTDEVICE
) );
5345 ok( ret
, "RegisterRawInputDevices failed, error %lu\n", GetLastError() );
5347 hid_device_stop( &desc
, 1 );
5349 res
= msg_wait_for_events( 1, &rawinput_device_added
, 10 );
5350 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5351 res
= msg_wait_for_events( 1, &rawinput_device_removed
, 10 );
5352 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5353 res
= msg_wait_for_events( 1, &rawinput_event
, 10 );
5354 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5356 raw_devices
[0].usUsagePage
= HID_USAGE_PAGE_GENERIC
;
5357 raw_devices
[0].usUsage
= HID_USAGE_GENERIC_JOYSTICK
;
5358 raw_devices
[0].dwFlags
= RIDEV_DEVNOTIFY
;
5359 raw_devices
[0].hwndTarget
= hwnd
;
5360 count
= ARRAY_SIZE(raw_devices
);
5361 ret
= RegisterRawInputDevices( raw_devices
, 1, sizeof(RAWINPUTDEVICE
) );
5362 ok( ret
, "RegisterRawInputDevices failed, error %lu\n", GetLastError() );
5364 hid_device_start( &desc
, 1 );
5366 res
= msg_wait_for_events( 1, &rawinput_device_added
, 1000 );
5367 ok( !res
, "WaitForSingleObject returned %#lx\n", res
);
5369 res
= msg_wait_for_events( 1, &rawinput_device_added
, 10 );
5370 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5371 res
= msg_wait_for_events( 1, &rawinput_device_removed
, 10 );
5372 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5373 res
= msg_wait_for_events( 1, &rawinput_event
, 10 );
5374 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5376 raw_devices
[0].usUsagePage
= HID_USAGE_PAGE_GENERIC
;
5377 raw_devices
[0].usUsage
= HID_USAGE_GENERIC_JOYSTICK
;
5378 raw_devices
[0].dwFlags
= RIDEV_INPUTSINK
;
5379 raw_devices
[0].hwndTarget
= hwnd
;
5380 count
= ARRAY_SIZE(raw_devices
);
5381 ret
= RegisterRawInputDevices( raw_devices
, 1, sizeof(RAWINPUTDEVICE
) );
5382 ok( ret
, "RegisterRawInputDevices failed, error %lu\n", GetLastError() );
5384 hid_device_stop( &desc
, 1 );
5385 hid_device_start( &desc
, 1 );
5387 res
= msg_wait_for_events( 1, &rawinput_device_added
, 10 );
5388 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5389 res
= msg_wait_for_events( 1, &rawinput_device_removed
, 10 );
5390 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5391 res
= msg_wait_for_events( 1, &rawinput_event
, 10 );
5392 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5395 count
= ARRAY_SIZE(raw_device_list
);
5396 res
= GetRawInputDeviceList( raw_device_list
, &count
, sizeof(RAWINPUTDEVICELIST
) );
5397 if (!strcmp( winetest_platform
, "wine" ) && res
== device_count
)
5399 /* Wine refreshes its device list every 2s, but GetRawInputDeviceInfoW with an unknown handle will force it */
5400 GetRawInputDeviceInfoW( (HANDLE
)0xdeadbeef, RIDI_DEVICEINFO
, NULL
, &count
);
5401 res
= GetRawInputDeviceList( raw_device_list
, &count
, sizeof(RAWINPUTDEVICELIST
) );
5403 ok( res
== device_count
+ 1, "GetRawInputDeviceList returned %lu\n", res
);
5404 ok( count
== ARRAY_SIZE(raw_device_list
), "got count %u\n", count
);
5407 while (device_count
--)
5409 if (raw_device_list
[device_count
].dwType
!= RIM_TYPEHID
) continue;
5411 count
= ARRAY_SIZE(path
);
5412 res
= GetRawInputDeviceInfoW( raw_device_list
[device_count
].hDevice
, RIDI_DEVICENAME
, path
, &count
);
5413 ok( res
== wcslen( path
) + 1, "GetRawInputDeviceInfoW returned %lu\n", res
);
5415 ok( count
== ARRAY_SIZE(path
), "got count %u\n", count
);
5417 if (wcsstr( path
, expect_vidpid_str
)) break;
5420 ok( !!wcsstr( path
, expect_vidpid_str
), "got path %s\n", debugstr_w(path
) );
5423 file
= CreateFileW( path
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
5424 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
5425 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
5426 ok( file
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError() );
5428 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
5430 winetest_push_context( "state[%ld]", i
);
5432 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
5434 res
= msg_wait_for_events( 1, &rawinput_event
, 1000 );
5435 ok( !res
, "WaitForSingleObject returned %#lx\n", res
);
5437 res
= msg_wait_for_events( 1, &rawinput_device_added
, 10 );
5438 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5439 res
= msg_wait_for_events( 1, &rawinput_device_removed
, 10 );
5440 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5441 res
= msg_wait_for_events( 1, &rawinput_event
, 10 );
5442 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#lx\n", res
);
5444 ok( wm_input_len
== offsetof(RAWINPUT
, data
.hid
.bRawData
[desc
.caps
.InputReportByteLength
]),
5445 "got wm_input_len %u\n", wm_input_len
);
5446 ok( !memcmp( rawinput
->data
.hid
.bRawData
, injected_input
[i
].report_buf
, desc
.caps
.InputReportByteLength
),
5447 "got unexpected report data\n" );
5449 winetest_pop_context();
5452 CloseHandle( rawinput_device_added
);
5453 CloseHandle( rawinput_device_removed
);
5454 CloseHandle( rawinput_event
);
5455 CloseHandle( file
);
5458 hid_device_stop( &desc
, 1 );
5459 cleanup_registry_keys();
5461 DestroyWindow( hwnd
);
5462 UnregisterClassW( class.lpszClassName
, class.hInstance
);
5465 START_TEST( joystick8
)
5468 if (!bus_device_start()) goto done
;
5470 winetest_mute_threshold
= 3;
5472 if (test_device_types( 0x800 ))
5474 /* This needs to be done before doing anything involving dinput.dll
5475 * on Windows, or the tests will fail, dinput8.dll is fine though. */
5476 test_winmm_joystick();
5478 test_device_types( 0x500 );
5479 test_device_types( 0x700 );
5481 test_simple_joystick( 0x500 );
5482 test_simple_joystick( 0x700 );
5483 test_simple_joystick( 0x800 );
5485 test_many_axes_joystick();
5486 test_driving_wheel_axes();
5488 test_windows_gaming_input();