dinput: Fix EnumObjects callback return value handling.
[wine.git] / dlls / dinput / tests / device8.c
bloba649fe53b4141915555f0bee207f03c6866fff9b
1 /*
2 * Copyright (c) 2011 Lucas Fialho Zawacki
3 * Copyright (c) 2006 Vitaliy Margolen
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define DIRECTINPUT_VERSION 0x0800
22 #include <stdarg.h>
23 #include <stddef.h>
24 #include <limits.h>
26 #include "ntstatus.h"
27 #define WIN32_NO_STATUS
28 #include "windef.h"
29 #include "winbase.h"
31 #define COBJMACROS
32 #include "dinput.h"
33 #include "hidusage.h"
35 #include "dinput_test.h"
37 struct enum_data
39 DWORD version;
40 union
42 IDirectInput8A *dinput8;
43 IDirectInputA *dinput;
47 static void flush_events(void)
49 int min_timeout = 100, diff = 200;
50 DWORD time = GetTickCount() + diff;
51 MSG msg;
53 while (diff > 0)
55 if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
56 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ))
58 TranslateMessage( &msg );
59 DispatchMessageA( &msg );
61 diff = time - GetTickCount();
65 static HRESULT create_dinput_device( DWORD version, const GUID *guid, IDirectInputDevice8W **device )
67 IDirectInputW *dinput;
68 HRESULT hr;
69 ULONG ref;
71 if (version < 0x800) hr = DirectInputCreateW( instance, version, &dinput, NULL );
72 else hr = DirectInput8Create( instance, version, &IID_IDirectInput8W, (void **)&dinput, NULL );
73 if (FAILED(hr))
75 win_skip( "Failed to instantiate a IDirectInput instance, hr %#lx\n", hr );
76 return hr;
79 hr = IDirectInput_CreateDevice( dinput, guid, (IDirectInputDeviceW **)device, NULL );
80 ok( hr == DI_OK, "CreateDevice returned %#lx\n", hr );
82 ref = IDirectInput_Release( dinput );
83 ok( ref == 0, "Release returned %ld\n", ref );
85 return DI_OK;
88 static HKL activate_keyboard_layout( LANGID langid, HKL *old_hkl )
90 WCHAR hkl_name[64];
91 HKL hkl;
93 swprintf( hkl_name, ARRAY_SIZE(hkl_name), L"%08x", langid );
94 hkl = LoadKeyboardLayoutW( hkl_name, 0 );
95 if (!hkl)
97 win_skip( "Unable to load keyboard layout %#x\n", langid );
98 *old_hkl = GetKeyboardLayout( 0 );
99 return 0;
102 *old_hkl = ActivateKeyboardLayout( hkl, 0 );
103 ok( !!*old_hkl, "ActivateKeyboardLayout failed, error %lu\n", GetLastError() );
105 hkl = GetKeyboardLayout( 0 );
106 todo_wine_if( LOWORD(*old_hkl) != langid )
107 ok( LOWORD(hkl) == langid, "GetKeyboardLayout returned %p\n", hkl );
108 return hkl;
111 static HRESULT direct_input_create( DWORD version, IDirectInputA **out )
113 HRESULT hr;
114 if (version < 0x800) hr = DirectInputCreateA( instance, version, out, NULL );
115 else hr = DirectInput8Create( instance, version, &IID_IDirectInput8A, (void **)out, NULL );
116 if (FAILED(hr)) win_skip( "Failed to instantiate a IDirectInput instance, hr %#lx\n", hr );
117 return hr;
120 #define check_interface( a, b, c ) check_interface_( __LINE__, a, b, c )
121 static void check_interface_( unsigned int line, void *iface_ptr, REFIID iid, BOOL supported )
123 IUnknown *iface = iface_ptr;
124 HRESULT hr, expected;
125 IUnknown *unk;
127 expected = supported ? S_OK : E_NOINTERFACE;
128 hr = IUnknown_QueryInterface( iface, iid, (void **)&unk );
129 ok_(__FILE__, line)( hr == expected, "got hr %#lx, expected %#lx.\n", hr, expected );
130 if (SUCCEEDED(hr)) IUnknown_Release( unk );
133 static BOOL CALLBACK check_device_query_interface( const DIDEVICEINSTANCEA *instance, void *context )
135 struct enum_data *data = context;
136 IUnknown *device;
137 HRESULT hr;
138 LONG ref;
140 if (data->version < 0x800)
142 hr = IDirectInput_GetDeviceStatus( data->dinput, &instance->guidInstance );
143 ok( hr == DI_OK, "GetDeviceStatus returned %#lx\n", hr );
144 hr = IDirectInput_GetDeviceStatus( data->dinput, &instance->guidProduct );
145 ok( hr == DI_OK, "GetDeviceStatus returned %#lx\n", hr );
147 hr = IDirectInput_CreateDevice( data->dinput, &instance->guidProduct, (IDirectInputDeviceA **)&device, NULL );
148 ok( hr == DI_OK, "CreateDevice returned %#lx\n", hr );
149 ref = IUnknown_Release( device );
150 ok( ref == 0, "Release returned %ld\n", ref );
152 hr = IDirectInput_CreateDevice( data->dinput, &instance->guidInstance, (IDirectInputDeviceA **)&device, NULL );
153 ok( hr == DI_OK, "CreateDevice returned %#lx\n", hr );
155 else
157 hr = IDirectInput8_GetDeviceStatus( data->dinput8, &instance->guidInstance );
158 ok( hr == DI_OK, "GetDeviceStatus returned %#lx\n", hr );
159 hr = IDirectInput8_GetDeviceStatus( data->dinput8, &instance->guidProduct );
160 ok( hr == DI_OK, "GetDeviceStatus returned %#lx\n", hr );
162 hr = IDirectInput8_CreateDevice( data->dinput8, &instance->guidProduct, (IDirectInputDevice8A **)&device, NULL );
163 ok( hr == DI_OK, "CreateDevice returned %#lx\n", hr );
164 ref = IUnknown_Release( device );
165 ok( ref == 0, "Release returned %ld\n", ref );
167 hr = IDirectInput8_CreateDevice( data->dinput8, &instance->guidInstance, (IDirectInputDevice8A **)&device, NULL );
168 ok( hr == DI_OK, "CreateDevice returned %#lx\n", hr );
171 todo_wine_if( data->version >= 0x800 )
172 check_interface( device, &IID_IDirectInputDeviceA, data->version < 0x800 );
173 todo_wine_if( data->version >= 0x800 )
174 check_interface( device, &IID_IDirectInputDevice2A, data->version < 0x800 );
175 todo_wine_if( data->version >= 0x800 )
176 check_interface( device, &IID_IDirectInputDevice7A, data->version < 0x800 );
177 todo_wine_if( data->version < 0x800 )
178 check_interface( device, &IID_IDirectInputDevice8A, data->version >= 0x800 );
180 todo_wine_if( data->version >= 0x800 )
181 check_interface( device, &IID_IDirectInputDeviceW, data->version < 0x800 );
182 todo_wine_if( data->version >= 0x800 )
183 check_interface( device, &IID_IDirectInputDevice2W, data->version < 0x800 );
184 todo_wine_if( data->version >= 0x800 )
185 check_interface( device, &IID_IDirectInputDevice7W, data->version < 0x800 );
186 todo_wine_if( data->version < 0x800 )
187 check_interface( device, &IID_IDirectInputDevice8W, data->version >= 0x800 );
189 ref = IUnknown_Release( device );
190 ok( ref == 0, "Release returned %ld\n", ref );
192 return DIENUM_CONTINUE;
195 static void test_QueryInterface( DWORD version )
197 struct enum_data data = {.version = version};
198 HRESULT hr;
199 ULONG ref;
201 if (FAILED(hr = direct_input_create( version, &data.dinput ))) return;
203 winetest_push_context( "%#lx", version );
205 if (version < 0x800)
207 hr = IDirectInput_EnumDevices( data.dinput, 0, check_device_query_interface, &data, DIEDFL_ALLDEVICES );
208 ok( hr == DI_OK, "EnumDevices returned %#lx\n", hr );
210 else
212 hr = IDirectInput8_EnumDevices( data.dinput8, 0, check_device_query_interface, &data, DIEDFL_ALLDEVICES );
213 ok( hr == DI_OK, "EnumDevices returned %#lx\n", hr );
216 ref = IDirectInput_Release( data.dinput );
217 ok( ref == 0, "Release returned %lu\n", ref );
219 winetest_pop_context();
222 struct overlapped_state
224 BYTE keys[4];
225 DWORD extra_element;
228 static DIOBJECTDATAFORMAT obj_overlapped_slider_format[] =
230 {&GUID_Key, 0, DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_MAKEINSTANCE( DIK_A ), 0},
231 {&GUID_Key, 1, DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_MAKEINSTANCE( DIK_S ), 0},
232 {&GUID_Key, 2, DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_MAKEINSTANCE( DIK_D ), 0},
233 {&GUID_Key, 3, DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_MAKEINSTANCE( DIK_F ), 0},
234 {&GUID_Slider, 0, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION},
237 static const DIDATAFORMAT overlapped_slider_format =
239 sizeof(DIDATAFORMAT),
240 sizeof(DIOBJECTDATAFORMAT),
241 DIDF_ABSAXIS,
242 sizeof(struct overlapped_state),
243 ARRAY_SIZE(obj_overlapped_slider_format),
244 obj_overlapped_slider_format,
247 static DIOBJECTDATAFORMAT obj_overlapped_pov_format[] =
249 {&GUID_Key, 0, DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_MAKEINSTANCE( DIK_A ), 0},
250 {&GUID_Key, 1, DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_MAKEINSTANCE( DIK_S ), 0},
251 {&GUID_Key, 2, DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_MAKEINSTANCE( DIK_D ), 0},
252 {&GUID_Key, 3, DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_MAKEINSTANCE( DIK_F ), 0},
253 {&GUID_POV, 0, DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0},
256 static const DIDATAFORMAT overlapped_pov_format =
258 sizeof(DIDATAFORMAT),
259 sizeof(DIOBJECTDATAFORMAT),
260 DIDF_ABSAXIS,
261 sizeof(struct overlapped_state),
262 ARRAY_SIZE(obj_overlapped_pov_format),
263 obj_overlapped_pov_format,
266 void test_overlapped_format( DWORD version )
268 static const DIPROPDWORD buffer_size =
270 .diph =
272 .dwSize = sizeof(DIPROPDWORD),
273 .dwHeaderSize = sizeof(DIPROPHEADER),
274 .dwHow = DIPH_DEVICE,
276 .dwData = 10,
278 SIZE_T data_size = version < 0x800 ? sizeof(DIDEVICEOBJECTDATA_DX3) : sizeof(DIDEVICEOBJECTDATA);
279 struct overlapped_state state;
280 IDirectInputDeviceA *keyboard;
281 IDirectInputA *dinput;
282 DWORD res, count;
283 HANDLE event;
284 HRESULT hr;
285 HWND hwnd;
287 if (FAILED(hr = direct_input_create( version, &dinput ))) return;
289 winetest_push_context( "%#lx", version );
291 event = CreateEventW( NULL, FALSE, FALSE, NULL );
292 ok( !!event, "CreateEventW failed, error %lu\n", GetLastError() );
293 hwnd = CreateWindowW( L"static", L"Title", WS_POPUP | WS_VISIBLE, 10, 10, 200, 200, NULL, NULL, NULL, NULL );
294 ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() );
296 hr = IDirectInput_CreateDevice( dinput, &GUID_SysKeyboard, &keyboard, NULL );
297 ok( hr == DI_OK, "CreateDevice returned %#lx\n", hr );
298 hr = IDirectInputDevice8_SetCooperativeLevel( keyboard, hwnd, DISCL_FOREGROUND|DISCL_EXCLUSIVE );
299 ok( hr == DI_OK, "SetCooperativeLevel returned %#lx\n", hr );
300 hr = IDirectInputDevice8_SetEventNotification( keyboard, event );
301 ok( hr == DI_OK, "SetEventNotification returned %#lx\n", hr );
303 /* test overlapped slider - default value 0 */
304 hr = IDirectInputDevice_SetDataFormat( keyboard, &overlapped_slider_format );
305 ok( hr == DI_OK, "SetDataFormat returned %#lx\n", hr );
306 hr = IDirectInputDevice_SetProperty( keyboard, DIPROP_BUFFERSIZE, &buffer_size.diph );
307 ok( hr == DI_OK, "SetProperty returned %#lx\n", hr );
310 hr = IDirectInputDevice_Acquire( keyboard );
311 ok( hr == DI_OK, "Acquire returned %#lx, skipping test_overlapped_format\n", hr );
312 if (hr != DI_OK) goto cleanup;
314 keybd_event( 0, DIK_F, KEYEVENTF_SCANCODE, 0 );
315 res = WaitForSingleObject( event, 100 );
316 if (res == WAIT_TIMEOUT) /* Acquire is asynchronous */
318 keybd_event( 0, DIK_F, KEYEVENTF_SCANCODE, 0 );
319 res = WaitForSingleObject( event, 5000 );
321 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
323 keybd_event( 0, DIK_F, KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, 0 );
324 res = WaitForSingleObject( event, 5000 );
325 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
327 count = 10;
328 hr = IDirectInputDevice_GetDeviceData( keyboard, data_size, NULL, &count, 0 );
329 ok( hr == DI_OK, "GetDeviceData returned %#lx\n", hr );
330 ok( count > 0, "got count %lu\n", count );
333 /* press D */
334 keybd_event( 0, DIK_D, KEYEVENTF_SCANCODE, 0 );
335 res = WaitForSingleObject( event, 5000 );
336 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
338 count = 10;
339 hr = IDirectInputDevice_GetDeviceData( keyboard, data_size, NULL, &count, 0 );
340 ok( hr == DI_OK, "GetDeviceData returned %#lx\n", hr );
341 ok( count == 1, "got count %lu\n", count );
343 memset( &state, 0xFF, sizeof(state) );
344 hr = IDirectInputDevice_GetDeviceState( keyboard, sizeof(state), &state );
345 ok( hr == DI_OK, "GetDeviceState returned %#lx\n", hr );
347 ok( state.keys[0] == 0x00, "key A should be still up\n" );
348 ok( state.keys[1] == 0x00, "key S should be still up\n" );
349 ok( state.keys[2] == 0x80, "keydown for D did not register\n" );
350 ok( state.keys[3] == 0x00, "key F should be still up\n" );
351 ok( state.extra_element == 0, "State struct was not memset to zero\n" );
353 /* release D */
354 keybd_event( 0, DIK_D, KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, 0 );
355 res = WaitForSingleObject( event, 5000 );
356 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
358 count = 10;
359 hr = IDirectInputDevice_GetDeviceData( keyboard, data_size, NULL, &count, 0 );
360 ok( hr == DI_OK, "GetDeviceData returned %#lx\n", hr );
361 ok( count == 1, "got count %lu\n", count );
364 hr = IDirectInputDevice_Unacquire( keyboard );
365 ok( hr == DI_OK, "Unacquire returned %#lx\n", hr );
367 /* test overlapped pov - default value - 0xFFFFFFFF */
368 hr = IDirectInputDevice_SetDataFormat( keyboard, &overlapped_pov_format );
369 ok( hr == DI_OK, "SetDataFormat returned %#lx\n", hr );
372 hr = IDirectInputDevice_Acquire( keyboard );
373 ok( hr == DI_OK, "Acquire returned %#lx, skipping test_overlapped_format\n", hr );
374 if (hr != DI_OK) goto cleanup;
376 keybd_event( 0, DIK_F, KEYEVENTF_SCANCODE, 0 );
377 res = WaitForSingleObject( event, 100 );
378 if (res == WAIT_TIMEOUT) /* Acquire is asynchronous */
380 keybd_event( 0, DIK_F, KEYEVENTF_SCANCODE, 0 );
381 res = WaitForSingleObject( event, 5000 );
383 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
385 keybd_event( 0, DIK_F, KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, 0 );
386 res = WaitForSingleObject( event, 5000 );
387 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
389 count = 10;
390 hr = IDirectInputDevice_GetDeviceData( keyboard, data_size, NULL, &count, 0 );
391 ok( hr == DI_OK, "GetDeviceData returned %#lx\n", hr );
392 ok( count > 0, "got count %lu\n", count );
395 /* press D */
396 keybd_event( 0, DIK_D, KEYEVENTF_SCANCODE, 0 );
397 res = WaitForSingleObject( event, 5000 );
398 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
400 count = 10;
401 hr = IDirectInputDevice_GetDeviceData( keyboard, data_size, NULL, &count, 0 );
402 ok( hr == DI_OK, "GetDeviceData returned %#lx\n", hr );
403 ok( count == 1, "got count %lu\n", count );
405 memset( &state, 0xFF, sizeof(state) );
406 hr = IDirectInputDevice_GetDeviceState( keyboard, sizeof(state), &state );
407 ok( hr == DI_OK, "GetDeviceState returned %#lx\n", hr );
409 ok( state.keys[0] == 0xFF, "key state should have been overwritten by the overlapped POV\n" );
410 ok( state.keys[1] == 0xFF, "key state should have been overwritten by the overlapped POV\n" );
411 ok( state.keys[2] == 0xFF, "key state should have been overwritten by the overlapped POV\n" );
412 ok( state.keys[3] == 0xFF, "key state should have been overwritten by the overlapped POV\n" );
413 ok( state.extra_element == 0, "State struct was not memset to zero\n" );
415 /* release D */
416 keybd_event( 0, DIK_D, KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, 0 );
417 res = WaitForSingleObject( event, 5000 );
418 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
420 count = 10;
421 hr = IDirectInputDevice_GetDeviceData( keyboard, data_size, NULL, &count, 0 );
422 ok( hr == DI_OK, "GetDeviceData returned %#lx\n", hr );
423 ok( count == 1, "got count %lu\n", count );
426 cleanup:
427 IUnknown_Release( keyboard );
429 DestroyWindow( hwnd );
430 CloseHandle( event );
432 winetest_pop_context();
435 static void test_device_input( IDirectInputDevice8A *device, DWORD type, DWORD code, UINT_PTR expected )
437 HRESULT hr;
438 DIDEVICEOBJECTDATA obj_data;
439 DWORD res, data_size = 1;
440 HANDLE event;
441 int i;
443 event = CreateEventW( NULL, FALSE, FALSE, NULL );
444 ok( event != NULL, "CreateEventW failed, error %lu\n", GetLastError() );
446 IDirectInputDevice_Unacquire( device );
448 hr = IDirectInputDevice8_SetEventNotification( device, event );
449 ok( hr == DI_OK, "SetEventNotification returned %#lx\n", hr );
451 hr = IDirectInputDevice8_Acquire( device );
452 ok( hr == DI_OK, "Acquire returned %#lx\n", hr );
454 if (type == INPUT_KEYBOARD)
456 keybd_event( 0, code, KEYEVENTF_SCANCODE, 0 );
457 res = WaitForSingleObject( event, 100 );
458 if (res == WAIT_TIMEOUT) /* Acquire is asynchronous */
460 keybd_event( 0, code, KEYEVENTF_SCANCODE, 0 );
461 res = WaitForSingleObject( event, 5000 );
463 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
465 keybd_event( 0, code, KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, 0 );
466 res = WaitForSingleObject( event, 5000 );
467 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
469 if (type == INPUT_MOUSE)
471 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
472 res = WaitForSingleObject( event, 100 );
473 if (res == WAIT_TIMEOUT) /* Acquire is asynchronous */
475 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
476 res = WaitForSingleObject( event, 5000 );
478 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
480 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
481 res = WaitForSingleObject( event, 5000 );
482 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
485 hr = IDirectInputDevice8_GetDeviceData( device, sizeof(obj_data), &obj_data, &data_size, 0 );
486 ok( hr == DI_OK, "GetDeviceData returned %#lx\n", hr );
487 ok( data_size == 1, "got data size %lu, expected 1\n", data_size );
488 ok( obj_data.uAppData == expected, "got action uAppData %p, expected %p\n",
489 (void *)obj_data.uAppData, (void *)expected );
491 /* Check for buffer overflow */
492 for (i = 0; i < 17; i++)
494 if (type == INPUT_KEYBOARD)
496 keybd_event( VK_SPACE, DIK_SPACE, 0, 0 );
497 res = WaitForSingleObject( event, 5000 );
498 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
500 keybd_event( VK_SPACE, DIK_SPACE, KEYEVENTF_KEYUP, 0 );
501 res = WaitForSingleObject( event, 5000 );
502 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
504 if (type == INPUT_MOUSE)
506 mouse_event( MOUSEEVENTF_LEFTDOWN, 1, 1, 0, 0 );
507 res = WaitForSingleObject( event, 5000 );
508 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
510 mouse_event( MOUSEEVENTF_LEFTUP, 1, 1, 0, 0 );
511 res = WaitForSingleObject( event, 5000 );
512 ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx\n", res );
516 data_size = 1;
517 hr = IDirectInputDevice8_GetDeviceData( device, sizeof(obj_data), &obj_data, &data_size, 0 );
518 ok( hr == DI_BUFFEROVERFLOW, "GetDeviceData returned %#lx\n", hr );
519 data_size = 1;
520 hr = IDirectInputDevice8_GetDeviceData( device, sizeof(obj_data), &obj_data, &data_size, 0 );
521 ok( hr == DI_OK, "GetDeviceData returned %#lx\n", hr );
522 ok( data_size == 1, "got data_size %lu, expected 1\n", data_size );
524 /* drain device's queue */
525 while (data_size == 1)
527 hr = IDirectInputDevice8_GetDeviceData( device, sizeof(obj_data), &obj_data, &data_size, 0 );
528 ok( hr == DI_OK, "GetDeviceData returned %#lx\n", hr );
529 if (hr != DI_OK) break;
532 hr = IDirectInputDevice_Unacquire( device );
533 ok( hr == DI_OK, "Unacquire returned %#lx\n", hr );
535 hr = IDirectInputDevice8_SetEventNotification( device, NULL );
536 ok( hr == DI_OK, "SetEventNotification returned %#lx\n", hr );
538 CloseHandle( event );
541 static void test_mouse_keyboard(void)
543 HRESULT hr;
544 HWND hwnd, di_hwnd = INVALID_HANDLE_VALUE;
545 IDirectInput8A *di = NULL;
546 IDirectInputDevice8A *di_mouse, *di_keyboard;
547 UINT raw_devices_count;
548 RAWINPUTDEVICE raw_devices[3];
550 hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput", WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL);
551 ok(hwnd != NULL, "CreateWindowExA failed\n");
552 flush_events();
554 hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&di);
555 if (hr == DIERR_OLDDIRECTINPUTVERSION ||
556 hr == DIERR_BETADIRECTINPUTVERSION ||
557 hr == REGDB_E_CLASSNOTREG)
559 win_skip("test_mouse_keyboard requires dinput8\n");
560 return;
562 ok(SUCCEEDED(hr), "DirectInput8Create failed: %#lx\n", hr);
564 hr = IDirectInput8_Initialize(di, GetModuleHandleA(NULL), DIRECTINPUT_VERSION);
565 if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION)
567 win_skip("test_mouse_keyboard requires dinput8\n");
568 return;
570 ok(SUCCEEDED(hr), "IDirectInput8_Initialize failed: %#lx\n", hr);
572 hr = IDirectInput8_CreateDevice(di, &GUID_SysMouse, &di_mouse, NULL);
573 ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %#lx\n", hr);
574 hr = IDirectInputDevice8_SetDataFormat(di_mouse, &c_dfDIMouse);
575 ok(SUCCEEDED(hr), "IDirectInputDevice8_SetDataFormat failed: %#lx\n", hr);
577 hr = IDirectInput8_CreateDevice(di, &GUID_SysKeyboard, &di_keyboard, NULL);
578 ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %#lx\n", hr);
579 hr = IDirectInputDevice8_SetDataFormat(di_keyboard, &c_dfDIKeyboard);
580 ok(SUCCEEDED(hr), "IDirectInputDevice8_SetDataFormat failed: %#lx\n", hr);
582 raw_devices_count = ARRAY_SIZE(raw_devices);
583 GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
584 ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
586 hr = IDirectInputDevice8_Acquire(di_keyboard);
587 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %#lx\n", hr);
588 raw_devices_count = ARRAY_SIZE(raw_devices);
589 memset(raw_devices, 0, sizeof(raw_devices));
590 hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
591 ok(hr == 1, "GetRegisteredRawInputDevices returned %ld, raw_devices_count: %d\n", hr, raw_devices_count);
592 ok(raw_devices[0].usUsagePage == HID_USAGE_PAGE_GENERIC, "got usUsagePage: %x\n", raw_devices[0].usUsagePage);
593 ok(raw_devices[0].usUsage == HID_USAGE_GENERIC_KEYBOARD, "got usUsage: %x\n", raw_devices[0].usUsage);
594 todo_wine
595 ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %#lx\n", raw_devices[0].dwFlags);
596 ok(raw_devices[0].hwndTarget != NULL, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
597 hr = IDirectInputDevice8_Unacquire(di_keyboard);
598 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %#lx\n", hr);
599 raw_devices_count = ARRAY_SIZE(raw_devices);
600 GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
601 ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
603 if (raw_devices[0].hwndTarget != NULL)
605 WCHAR str[16];
606 int i;
608 di_hwnd = raw_devices[0].hwndTarget;
609 i = GetClassNameW(di_hwnd, str, ARRAY_SIZE(str));
610 ok(i == lstrlenW(L"DIEmWin"), "GetClassName returned incorrect length\n");
611 ok(!lstrcmpW(L"DIEmWin", str), "GetClassName returned incorrect name for this window's class\n");
613 i = GetWindowTextW(di_hwnd, str, ARRAY_SIZE(str));
614 ok(i == lstrlenW(L"DIEmWin"), "GetClassName returned incorrect length\n");
615 ok(!lstrcmpW(L"DIEmWin", str), "GetClassName returned incorrect name for this window's class\n");
618 hr = IDirectInputDevice8_Acquire(di_mouse);
619 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %#lx\n", hr);
620 raw_devices_count = ARRAY_SIZE(raw_devices);
621 memset(raw_devices, 0, sizeof(raw_devices));
622 hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
623 ok(hr == 1, "GetRegisteredRawInputDevices returned %ld, raw_devices_count: %d\n", hr, raw_devices_count);
624 ok(raw_devices[0].usUsagePage == HID_USAGE_PAGE_GENERIC, "got usUsagePage: %x\n", raw_devices[0].usUsagePage);
625 ok(raw_devices[0].usUsage == HID_USAGE_GENERIC_MOUSE, "got usUsage: %x\n", raw_devices[0].usUsage);
626 ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %#lx\n", raw_devices[0].dwFlags);
627 ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
628 hr = IDirectInputDevice8_Unacquire(di_mouse);
629 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %#lx\n", hr);
630 raw_devices_count = ARRAY_SIZE(raw_devices);
631 GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
632 ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
634 if (raw_devices[0].hwndTarget != NULL)
635 di_hwnd = raw_devices[0].hwndTarget;
637 /* expect dinput8 to take over any activated raw input devices */
638 raw_devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
639 raw_devices[0].usUsage = HID_USAGE_GENERIC_GAMEPAD;
640 raw_devices[0].dwFlags = 0;
641 raw_devices[0].hwndTarget = hwnd;
642 raw_devices[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
643 raw_devices[1].usUsage = HID_USAGE_GENERIC_KEYBOARD;
644 raw_devices[1].dwFlags = 0;
645 raw_devices[1].hwndTarget = hwnd;
646 raw_devices[2].usUsagePage = HID_USAGE_PAGE_GENERIC;
647 raw_devices[2].usUsage = HID_USAGE_GENERIC_MOUSE;
648 raw_devices[2].dwFlags = 0;
649 raw_devices[2].hwndTarget = hwnd;
650 raw_devices_count = ARRAY_SIZE(raw_devices);
651 hr = RegisterRawInputDevices(raw_devices, raw_devices_count, sizeof(RAWINPUTDEVICE));
652 ok(hr == TRUE, "RegisterRawInputDevices failed\n");
654 hr = IDirectInputDevice8_Acquire(di_keyboard);
655 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %#lx\n", hr);
656 hr = IDirectInputDevice8_Acquire(di_mouse);
657 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %#lx\n", hr);
658 raw_devices_count = ARRAY_SIZE(raw_devices);
659 memset(raw_devices, 0, sizeof(raw_devices));
660 hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
661 ok(hr == 3, "GetRegisteredRawInputDevices returned %ld, raw_devices_count: %d\n", hr, raw_devices_count);
662 ok(raw_devices[0].usUsagePage == HID_USAGE_PAGE_GENERIC, "got usUsagePage: %x\n", raw_devices[0].usUsagePage);
663 ok(raw_devices[0].usUsage == HID_USAGE_GENERIC_MOUSE, "got usUsage: %x\n", raw_devices[0].usUsage);
664 ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %#lx\n", raw_devices[0].dwFlags);
665 ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
666 ok(raw_devices[1].usUsagePage == HID_USAGE_PAGE_GENERIC, "got usUsagePage: %x\n", raw_devices[1].usUsagePage);
667 ok(raw_devices[1].usUsage == HID_USAGE_GENERIC_GAMEPAD, "got usUsage: %x\n", raw_devices[1].usUsage);
668 ok(raw_devices[1].dwFlags == 0, "Unexpected raw device flags: %#lx\n", raw_devices[1].dwFlags);
669 ok(raw_devices[1].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget);
670 ok(raw_devices[2].usUsagePage == HID_USAGE_PAGE_GENERIC, "got usUsagePage: %x\n", raw_devices[1].usUsagePage);
671 ok(raw_devices[2].usUsage == HID_USAGE_GENERIC_KEYBOARD, "got usUsage: %x\n", raw_devices[1].usUsage);
672 ok(raw_devices[2].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget);
673 hr = IDirectInputDevice8_Unacquire(di_keyboard);
674 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %#lx\n", hr);
675 hr = IDirectInputDevice8_Unacquire(di_mouse);
676 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %#lx\n", hr);
677 raw_devices_count = ARRAY_SIZE(raw_devices);
678 GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
679 ok(raw_devices_count == 1, "Unexpected raw devices registered: %d\n", raw_devices_count);
681 IDirectInputDevice8_SetCooperativeLevel(di_mouse, hwnd, DISCL_FOREGROUND|DISCL_EXCLUSIVE);
682 IDirectInputDevice8_SetCooperativeLevel(di_keyboard, hwnd, DISCL_FOREGROUND|DISCL_EXCLUSIVE);
684 hr = IDirectInputDevice8_Acquire(di_keyboard);
685 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %#lx\n", hr);
686 hr = IDirectInputDevice8_Acquire(di_mouse);
687 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %#lx\n", hr);
688 raw_devices_count = ARRAY_SIZE(raw_devices);
689 memset(raw_devices, 0, sizeof(raw_devices));
690 hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
691 ok(hr == 3, "GetRegisteredRawInputDevices returned %ld, raw_devices_count: %d\n", hr, raw_devices_count);
692 ok(raw_devices[0].dwFlags == (RIDEV_CAPTUREMOUSE|RIDEV_NOLEGACY), "Unexpected raw device flags: %#lx\n", raw_devices[0].dwFlags);
693 ok(raw_devices[2].dwFlags == (RIDEV_NOHOTKEYS|RIDEV_NOLEGACY), "Unexpected raw device flags: %#lx\n", raw_devices[1].dwFlags);
694 hr = IDirectInputDevice8_Unacquire(di_keyboard);
695 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %#lx\n", hr);
696 hr = IDirectInputDevice8_Unacquire(di_mouse);
697 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %#lx\n", hr);
699 raw_devices_count = ARRAY_SIZE(raw_devices);
700 hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
701 ok(hr == 1, "GetRegisteredRawInputDevices returned %ld, raw_devices_count: %d\n", hr, raw_devices_count);
702 ok(raw_devices[0].usUsagePage == HID_USAGE_PAGE_GENERIC, "got usUsagePage: %x\n", raw_devices[0].usUsagePage);
703 ok(raw_devices[0].usUsage == HID_USAGE_GENERIC_GAMEPAD, "got usUsage: %x\n", raw_devices[0].usUsage);
704 ok(raw_devices[0].dwFlags == 0, "Unexpected raw device flags: %#lx\n", raw_devices[0].dwFlags);
705 ok(raw_devices[0].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
707 raw_devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
708 raw_devices[0].usUsage = HID_USAGE_GENERIC_GAMEPAD;
709 raw_devices[0].dwFlags = RIDEV_REMOVE;
710 raw_devices[0].hwndTarget = 0;
711 raw_devices[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
712 raw_devices[1].usUsage = HID_USAGE_GENERIC_KEYBOARD;
713 raw_devices[1].dwFlags = RIDEV_REMOVE;
714 raw_devices[1].hwndTarget = 0;
715 raw_devices[2].usUsagePage = HID_USAGE_PAGE_GENERIC;
716 raw_devices[2].usUsage = HID_USAGE_GENERIC_MOUSE;
717 raw_devices[2].dwFlags = RIDEV_REMOVE;
718 raw_devices[2].hwndTarget = 0;
719 raw_devices_count = ARRAY_SIZE(raw_devices);
720 hr = RegisterRawInputDevices(raw_devices, raw_devices_count, sizeof(RAWINPUTDEVICE));
721 ok(hr == TRUE, "RegisterRawInputDevices failed\n");
723 IDirectInputDevice8_Release(di_mouse);
724 IDirectInputDevice8_Release(di_keyboard);
725 IDirectInput8_Release(di);
727 DestroyWindow(hwnd);
730 static void test_keyboard_events(void)
732 HRESULT hr;
733 HWND hwnd = INVALID_HANDLE_VALUE;
734 IDirectInput8A *di;
735 IDirectInputDevice8A *di_keyboard;
736 DIPROPDWORD dp;
737 DIDEVICEOBJECTDATA obj_data[10];
738 DWORD data_size;
739 BYTE kbdata[256];
741 hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&di);
742 if (hr == DIERR_OLDDIRECTINPUTVERSION ||
743 hr == DIERR_BETADIRECTINPUTVERSION ||
744 hr == REGDB_E_CLASSNOTREG)
746 win_skip("test_keyboard_events requires dinput8\n");
747 return;
749 ok(SUCCEEDED(hr), "DirectInput8Create failed: %#lx\n", hr);
751 hr = IDirectInput8_Initialize(di, GetModuleHandleA(NULL), DIRECTINPUT_VERSION);
752 if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION)
754 win_skip("test_keyboard_events requires dinput8\n");
755 IDirectInput8_Release(di);
756 return;
758 ok(SUCCEEDED(hr), "IDirectInput8_Initialize failed: %#lx\n", hr);
760 hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput", WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL);
761 ok(hwnd != NULL, "CreateWindowExA failed\n");
763 hr = IDirectInput8_CreateDevice(di, &GUID_SysKeyboard, &di_keyboard, NULL);
764 ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %#lx\n", hr);
765 hr = IDirectInputDevice8_SetCooperativeLevel(di_keyboard, hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
766 ok(SUCCEEDED(hr), "IDirectInput8_SetCooperativeLevel failed: %#lx\n", hr);
767 hr = IDirectInputDevice8_SetDataFormat(di_keyboard, &c_dfDIKeyboard);
768 ok(SUCCEEDED(hr), "IDirectInputDevice8_SetDataFormat failed: %#lx\n", hr);
769 dp.diph.dwSize = sizeof(DIPROPDWORD);
770 dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
771 dp.diph.dwObj = 0;
772 dp.diph.dwHow = DIPH_DEVICE;
773 dp.dwData = ARRAY_SIZE(obj_data);
774 IDirectInputDevice8_SetProperty(di_keyboard, DIPROP_BUFFERSIZE, &(dp.diph));
776 hr = IDirectInputDevice8_Acquire(di_keyboard);
777 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %#lx\n", hr);
779 /* Test injecting keyboard events with both VK and scancode given. */
780 keybd_event(VK_SPACE, DIK_SPACE, 0, 0);
781 flush_events();
782 IDirectInputDevice8_Poll(di_keyboard);
783 data_size = ARRAY_SIZE(obj_data);
784 hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0);
785 ok(SUCCEEDED(hr), "Failed to get data hr=%#lx\n", hr);
786 ok(data_size == 1, "Expected 1 element, received %ld\n", data_size);
788 hr = IDirectInputDevice8_GetDeviceState(di_keyboard, sizeof(kbdata), kbdata);
789 ok(SUCCEEDED(hr), "IDirectInputDevice8_GetDeviceState failed: %#lx\n", hr);
790 ok(kbdata[DIK_SPACE], "Expected DIK_SPACE key state down\n");
792 keybd_event(VK_SPACE, DIK_SPACE, KEYEVENTF_KEYUP, 0);
793 flush_events();
794 IDirectInputDevice8_Poll(di_keyboard);
795 data_size = ARRAY_SIZE(obj_data);
796 hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0);
797 ok(SUCCEEDED(hr), "Failed to get data hr=%#lx\n", hr);
798 ok(data_size == 1, "Expected 1 element, received %ld\n", data_size);
800 /* Test injecting keyboard events with scancode=0.
801 * Windows DInput ignores the VK, sets scancode 0 to be pressed, and GetDeviceData returns no elements. */
802 keybd_event(VK_SPACE, 0, 0, 0);
803 flush_events();
804 IDirectInputDevice8_Poll(di_keyboard);
805 data_size = ARRAY_SIZE(obj_data);
806 hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0);
807 ok(SUCCEEDED(hr), "Failed to get data hr=%#lx\n", hr);
808 ok(data_size == 0, "Expected 0 elements, received %ld\n", data_size);
810 hr = IDirectInputDevice8_GetDeviceState(di_keyboard, sizeof(kbdata), kbdata);
811 ok(SUCCEEDED(hr), "IDirectInputDevice8_GetDeviceState failed: %#lx\n", hr);
812 todo_wine
813 ok(kbdata[0], "Expected key 0 state down\n");
815 keybd_event(VK_SPACE, 0, KEYEVENTF_KEYUP, 0);
816 flush_events();
817 IDirectInputDevice8_Poll(di_keyboard);
818 data_size = ARRAY_SIZE(obj_data);
819 hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0);
820 ok(SUCCEEDED(hr), "Failed to get data hr=%#lx\n", hr);
821 ok(data_size == 0, "Expected 0 elements, received %ld\n", data_size);
823 hr = IDirectInputDevice8_Unacquire(di_keyboard);
824 ok(SUCCEEDED(hr), "IDirectInputDevice8_Unacquire failed: %#lx\n", hr);
826 IDirectInputDevice8_Release(di_keyboard);
827 IDirectInput8_Release(di);
829 DestroyWindow(hwnd);
832 static void test_appdata_property(void)
834 HRESULT hr;
835 IDirectInputDevice8A *di_keyboard;
836 IDirectInput8A *pDI = NULL;
837 HWND hwnd;
838 DIPROPDWORD dw;
839 DIPROPPOINTER dp;
841 hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&pDI);
842 if (hr == DIERR_OLDDIRECTINPUTVERSION ||
843 hr == DIERR_BETADIRECTINPUTVERSION ||
844 hr == REGDB_E_CLASSNOTREG)
846 win_skip("DIPROP_APPDATA requires dinput8\n");
847 return;
849 ok(SUCCEEDED(hr), "DirectInput8 Create failed: hr=%#lx\n", hr);
850 if (FAILED(hr)) return;
852 hr = IDirectInput8_Initialize(pDI, instance, DIRECTINPUT_VERSION);
853 if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION)
855 win_skip("DIPROP_APPDATA requires dinput8\n");
856 return;
858 ok(SUCCEEDED(hr), "DirectInput8 Initialize failed: hr=%#lx\n", hr);
859 if (FAILED(hr)) return;
861 hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput",
862 WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL);
863 ok(hwnd != NULL, "failed to create window\n");
865 hr = IDirectInput8_CreateDevice(pDI, &GUID_SysKeyboard, &di_keyboard, NULL);
866 ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %#lx\n", hr);
868 hr = IDirectInputDevice8_SetDataFormat(di_keyboard, &c_dfDIKeyboard);
869 ok(SUCCEEDED(hr), "IDirectInputDevice8_SetDataFormat failed: %#lx\n", hr);
871 dw.diph.dwSize = sizeof(DIPROPDWORD);
872 dw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
873 dw.diph.dwObj = 0;
874 dw.diph.dwHow = DIPH_DEVICE;
875 dw.dwData = 32;
876 hr = IDirectInputDevice8_SetProperty(di_keyboard, DIPROP_BUFFERSIZE, &(dw.diph));
877 ok(SUCCEEDED(hr), "IDirectInputDevice8_SetProperty failed hr=%#lx\n", hr);
879 /* the default value */
880 test_device_input(di_keyboard, INPUT_KEYBOARD, DIK_A, -1);
882 dp.diph.dwHow = DIPH_DEVICE;
883 dp.diph.dwObj = 0;
884 dp.uData = 1;
885 hr = IDirectInputDevice8_SetProperty(di_keyboard, DIPROP_APPDATA, &(dp.diph));
886 ok(hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty APPDATA for the device should be invalid hr=%#lx\n", hr);
888 dp.diph.dwSize = sizeof(dp);
889 dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
890 dp.diph.dwHow = DIPH_BYUSAGE;
891 dp.diph.dwObj = 2;
892 dp.uData = 2;
893 hr = IDirectInputDevice8_SetProperty(di_keyboard, DIPROP_APPDATA, &(dp.diph));
894 ok(hr == DIERR_UNSUPPORTED, "IDirectInputDevice8_SetProperty APPDATA by usage should be unsupported hr=%#lx\n", hr);
896 dp.diph.dwHow = DIPH_BYID;
897 dp.diph.dwObj = DIDFT_MAKEINSTANCE(DIK_SPACE) | DIDFT_PSHBUTTON;
898 dp.uData = 3;
899 hr = IDirectInputDevice8_SetProperty(di_keyboard, DIPROP_APPDATA, &(dp.diph));
900 ok(SUCCEEDED(hr), "IDirectInputDevice8_SetProperty failed hr=%#lx\n", hr);
902 dp.diph.dwHow = DIPH_BYOFFSET;
903 dp.diph.dwObj = DIK_A;
904 dp.uData = 4;
905 hr = IDirectInputDevice8_SetProperty(di_keyboard, DIPROP_APPDATA, &(dp.diph));
906 ok(SUCCEEDED(hr), "IDirectInputDevice8_SetProperty failed hr=%#lx\n", hr);
908 dp.diph.dwHow = DIPH_BYOFFSET;
909 dp.diph.dwObj = DIK_B;
910 dp.uData = 5;
911 hr = IDirectInputDevice8_SetProperty(di_keyboard, DIPROP_APPDATA, &(dp.diph));
912 ok(SUCCEEDED(hr), "IDirectInputDevice8_SetProperty failed hr=%#lx\n", hr);
914 test_device_input(di_keyboard, INPUT_KEYBOARD, DIK_SPACE, 3);
915 test_device_input(di_keyboard, INPUT_KEYBOARD, DIK_A, 4);
916 test_device_input(di_keyboard, INPUT_KEYBOARD, DIK_B, 5);
917 test_device_input(di_keyboard, INPUT_KEYBOARD, DIK_C, -1);
919 /* setting data format resets APPDATA */
920 hr = IDirectInputDevice8_SetDataFormat(di_keyboard, &c_dfDIKeyboard);
921 ok(SUCCEEDED(hr), "IDirectInputDevice8_SetDataFormat failed: %#lx\n", hr);
923 test_device_input(di_keyboard, INPUT_KEYBOARD, VK_SPACE, -1);
924 test_device_input(di_keyboard, INPUT_KEYBOARD, DIK_A, -1);
925 test_device_input(di_keyboard, INPUT_KEYBOARD, DIK_B, -1);
926 test_device_input(di_keyboard, INPUT_KEYBOARD, DIK_C, -1);
928 DestroyWindow(hwnd);
929 IDirectInputDevice_Release(di_keyboard);
930 IDirectInput_Release(pDI);
933 struct check_objects_todos
935 BOOL offset;
936 BOOL type;
937 BOOL name;
940 struct check_objects_params
942 UINT index;
943 UINT stop_count;
944 UINT expect_count;
945 const DIDEVICEOBJECTINSTANCEW *expect_objs;
946 const struct check_objects_todos *todo_objs;
947 BOOL todo_extra;
950 static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *args )
952 struct check_objects_params *params = args;
953 const DIDEVICEOBJECTINSTANCEW *exp = params->expect_objs + params->index;
954 const struct check_objects_todos *todo = params->todo_objs + params->index;
956 todo_wine_if( params->todo_extra && params->index >= params->expect_count )
957 ok( params->index < params->expect_count, "unexpected extra object\n" );
958 if (params->index >= params->expect_count) return DIENUM_CONTINUE;
960 winetest_push_context( "obj[%d]", params->index );
962 check_member( *obj, *exp, "%lu", dwSize );
963 check_member_guid( *obj, *exp, guidType );
964 todo_wine_if( todo->offset )
965 check_member( *obj, *exp, "%#lx", dwOfs );
966 todo_wine_if( todo->type )
967 check_member( *obj, *exp, "%#lx", dwType );
968 check_member( *obj, *exp, "%#lx", dwFlags );
969 if (!localized) todo_wine_if( todo->name ) check_member_wstr( *obj, *exp, tszName );
970 check_member( *obj, *exp, "%lu", dwFFMaxForce );
971 check_member( *obj, *exp, "%lu", dwFFForceResolution );
972 check_member( *obj, *exp, "%u", wCollectionNumber );
973 check_member( *obj, *exp, "%u", wDesignatorIndex );
974 check_member( *obj, *exp, "%#04x", wUsagePage );
975 check_member( *obj, *exp, "%#04x", wUsage );
976 check_member( *obj, *exp, "%#lx", dwDimension );
977 check_member( *obj, *exp, "%#04x", wExponent );
978 check_member( *obj, *exp, "%u", wReportId );
980 winetest_pop_context();
982 params->index++;
983 if (params->stop_count && params->index == params->stop_count) return DIENUM_STOP;
984 return DIENUM_CONTINUE;
987 static BOOL CALLBACK check_object_count( const DIDEVICEOBJECTINSTANCEW *obj, void *args )
989 DWORD *count = args;
990 *count = *count + 1;
991 return DIENUM_CONTINUE;
994 static BOOL CALLBACK check_object_count_bad_retval( const DIDEVICEOBJECTINSTANCEW *obj, void *args )
996 DWORD *count = args;
997 *count = *count + 1;
998 return -1; /* Invalid, but should CONTINUE. Only explicit DIENUM_STOP will stop enumeration. */
1001 static void test_sys_mouse( DWORD version )
1003 const DIDEVCAPS expect_caps =
1005 .dwSize = sizeof(DIDEVCAPS),
1006 .dwFlags = DIDC_ATTACHED | DIDC_EMULATED,
1007 .dwDevType = version < 0x800 ? (DIDEVTYPEMOUSE_UNKNOWN << 8) | DIDEVTYPE_MOUSE
1008 : (DI8DEVTYPEMOUSE_UNKNOWN << 8) | DI8DEVTYPE_MOUSE,
1009 .dwAxes = 3,
1010 .dwButtons = 5,
1012 const DIDEVICEINSTANCEW expect_devinst =
1014 .dwSize = sizeof(DIDEVICEINSTANCEW),
1015 .guidInstance = GUID_SysMouse,
1016 .guidProduct = GUID_SysMouse,
1017 .dwDevType = version < 0x800 ? (DIDEVTYPEMOUSE_UNKNOWN << 8) | DIDEVTYPE_MOUSE
1018 : (DI8DEVTYPEMOUSE_UNKNOWN << 8) | DI8DEVTYPE_MOUSE,
1019 .tszInstanceName = L"Mouse",
1020 .tszProductName = L"Mouse",
1021 .guidFFDriver = GUID_NULL,
1023 const DIDEVICEOBJECTINSTANCEW expect_objects[] =
1026 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
1027 .guidType = GUID_XAxis,
1028 .dwOfs = 0x0,
1029 .dwType = DIDFT_RELAXIS|DIDFT_MAKEINSTANCE(0),
1030 .dwFlags = DIDOI_ASPECTPOSITION,
1031 .tszName = L"X-axis",
1034 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
1035 .guidType = GUID_YAxis,
1036 .dwOfs = 0x4,
1037 .dwType = DIDFT_RELAXIS|DIDFT_MAKEINSTANCE(1),
1038 .dwFlags = DIDOI_ASPECTPOSITION,
1039 .tszName = L"Y-axis",
1042 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
1043 .guidType = GUID_ZAxis,
1044 .dwOfs = 0x8,
1045 .dwType = DIDFT_RELAXIS|DIDFT_MAKEINSTANCE(2),
1046 .dwFlags = DIDOI_ASPECTPOSITION,
1047 .tszName = L"Wheel",
1050 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
1051 .guidType = GUID_Button,
1052 .dwOfs = 0xc,
1053 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(3),
1054 .tszName = L"Button 0",
1057 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
1058 .guidType = GUID_Button,
1059 .dwOfs = 0xd,
1060 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(4),
1061 .tszName = L"Button 1",
1064 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
1065 .guidType = GUID_Button,
1066 .dwOfs = 0xe,
1067 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(5),
1068 .tszName = L"Button 2",
1071 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
1072 .guidType = GUID_Button,
1073 .dwOfs = 0xf,
1074 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(6),
1075 .tszName = L"Button 3",
1078 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
1079 .guidType = GUID_Button,
1080 .dwOfs = 0x10,
1081 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(7),
1082 .tszName = L"Button 4",
1085 struct check_objects_todos todo_objects[ARRAY_SIZE(expect_objects)] = {{0}};
1086 struct check_objects_params check_objects_params =
1088 .expect_count = ARRAY_SIZE(expect_objects),
1089 .expect_objs = expect_objects,
1090 .todo_objs = todo_objects,
1091 .todo_extra = TRUE,
1093 DIPROPGUIDANDPATH prop_guid_path =
1095 .diph =
1097 .dwSize = sizeof(DIPROPGUIDANDPATH),
1098 .dwHeaderSize = sizeof(DIPROPHEADER),
1099 .dwHow = DIPH_DEVICE,
1102 DIPROPSTRING prop_string =
1104 .diph =
1106 .dwSize = sizeof(DIPROPSTRING),
1107 .dwHeaderSize = sizeof(DIPROPHEADER),
1108 .dwHow = DIPH_DEVICE,
1111 DIPROPDWORD prop_dword =
1113 .diph =
1115 .dwSize = sizeof(DIPROPDWORD),
1116 .dwHeaderSize = sizeof(DIPROPHEADER),
1117 .dwHow = DIPH_DEVICE,
1120 DIPROPRANGE prop_range =
1122 .diph =
1124 .dwSize = sizeof(DIPROPRANGE),
1125 .dwHeaderSize = sizeof(DIPROPHEADER),
1126 .dwHow = DIPH_DEVICE,
1129 DIDEVICEOBJECTINSTANCEW objinst = {0};
1130 DIDEVICEOBJECTDATA objdata = {0};
1131 DIDEVICEINSTANCEW devinst = {0};
1132 BOOL old_localized = localized;
1133 IDirectInputDevice8W *device;
1134 HWND hwnd, tmp_hwnd, child;
1135 DIDEVCAPS caps = {0};
1136 DIMOUSESTATE state;
1137 ULONG res, ref;
1138 HANDLE event;
1139 DWORD count;
1140 HRESULT hr;
1141 GUID guid;
1142 int i;
1144 if (FAILED(create_dinput_device( version, &GUID_SysMouse, &device ))) return;
1146 localized = LOWORD( GetKeyboardLayout( 0 ) ) != 0x0409;
1147 winetest_push_context( "%#lx", version );
1149 hr = IDirectInputDevice8_Initialize( device, instance, version, &GUID_SysMouseEm );
1150 ok( hr == DI_OK, "Initialize returned %#lx\n", hr );
1151 guid = GUID_SysMouseEm;
1152 memset( &devinst, 0, sizeof(devinst) );
1153 devinst.dwSize = sizeof(DIDEVICEINSTANCEW);
1154 hr = IDirectInputDevice8_GetDeviceInfo( device, &devinst );
1155 ok( hr == DI_OK, "GetDeviceInfo returned %#lx\n", hr );
1156 ok( IsEqualGUID( &guid, &GUID_SysMouseEm ), "got %s expected %s\n", debugstr_guid( &guid ),
1157 debugstr_guid( &GUID_SysMouseEm ) );
1159 hr = IDirectInputDevice8_Initialize( device, instance, version, &GUID_SysMouse );
1160 ok( hr == DI_OK, "Initialize returned %#lx\n", hr );
1162 memset( &devinst, 0, sizeof(devinst) );
1163 devinst.dwSize = sizeof(DIDEVICEINSTANCEW);
1164 hr = IDirectInputDevice8_GetDeviceInfo( device, &devinst );
1165 ok( hr == DI_OK, "GetDeviceInfo returned %#lx\n", hr );
1166 check_member( devinst, expect_devinst, "%lu", dwSize );
1167 check_member_guid( devinst, expect_devinst, guidInstance );
1168 check_member_guid( devinst, expect_devinst, guidProduct );
1169 todo_wine
1170 check_member( devinst, expect_devinst, "%#lx", dwDevType );
1171 if (!localized) check_member_wstr( devinst, expect_devinst, tszInstanceName );
1172 if (!localized) todo_wine check_member_wstr( devinst, expect_devinst, tszProductName );
1173 check_member_guid( devinst, expect_devinst, guidFFDriver );
1174 check_member( devinst, expect_devinst, "%04x", wUsagePage );
1175 check_member( devinst, expect_devinst, "%04x", wUsage );
1177 devinst.dwSize = sizeof(DIDEVICEINSTANCE_DX3W);
1178 hr = IDirectInputDevice8_GetDeviceInfo( device, &devinst );
1179 ok( hr == DI_OK, "GetDeviceInfo returned %#lx\n", hr );
1180 check_member_guid( devinst, expect_devinst, guidInstance );
1181 check_member_guid( devinst, expect_devinst, guidProduct );
1182 todo_wine
1183 check_member( devinst, expect_devinst, "%#lx", dwDevType );
1184 if (!localized) check_member_wstr( devinst, expect_devinst, tszInstanceName );
1185 if (!localized) todo_wine check_member_wstr( devinst, expect_devinst, tszProductName );
1187 caps.dwSize = sizeof(DIDEVCAPS);
1188 hr = IDirectInputDevice8_GetCapabilities( device, &caps );
1189 ok( hr == DI_OK, "GetCapabilities returned %#lx\n", hr );
1190 check_member( caps, expect_caps, "%lu", dwSize );
1191 check_member( caps, expect_caps, "%#lx", dwFlags );
1192 todo_wine
1193 check_member( caps, expect_caps, "%#lx", dwDevType );
1194 check_member( caps, expect_caps, "%lu", dwAxes );
1195 ok( caps.dwButtons == 3 || caps.dwButtons == 5, "got dwButtons %ld, expected 3 or 5\n", caps.dwButtons );
1196 check_member( caps, expect_caps, "%lu", dwPOVs );
1197 check_member( caps, expect_caps, "%lu", dwFFSamplePeriod );
1198 check_member( caps, expect_caps, "%lu", dwFFMinTimeResolution );
1199 todo_wine
1200 check_member( caps, expect_caps, "%lu", dwFirmwareRevision );
1201 todo_wine
1202 check_member( caps, expect_caps, "%lu", dwHardwareRevision );
1203 check_member( caps, expect_caps, "%lu", dwFFDriverVersion );
1205 prop_dword.diph.dwHow = DIPH_BYOFFSET;
1206 prop_dword.diph.dwObj = DIMOFS_X;
1207 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph );
1208 ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_GRANULARITY returned %#lx\n", hr );
1209 hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph );
1210 ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_DEADZONE returned %#lx\n", hr );
1211 hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph );
1212 ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_SATURATION returned %#lx\n", hr );
1213 hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph );
1214 ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_CALIBRATIONMODE returned %#lx\n", hr );
1215 prop_range.diph.dwHow = DIPH_BYOFFSET;
1216 prop_range.diph.dwObj = DIMOFS_X;
1217 hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph );
1218 ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_RANGE returned %#lx\n", hr );
1220 prop_dword.diph.dwHow = DIPH_DEVICE;
1221 prop_dword.diph.dwObj = 0;
1222 prop_dword.dwData = 0xdeadbeef;
1223 hr = IDirectInputDevice8_GetProperty( device, DIPROP_AXISMODE, &prop_dword.diph );
1224 todo_wine
1225 ok( hr == DI_OK, "GetProperty DIPROP_AXISMODE returned %#lx\n", hr );
1226 todo_wine
1227 ok( prop_dword.dwData == DIPROPAXISMODE_ABS, "got %lu expected %u\n", prop_dword.dwData, DIPROPAXISMODE_ABS );
1228 prop_dword.dwData = 0xdeadbeef;
1229 hr = IDirectInputDevice8_GetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph );
1230 ok( hr == DI_OK, "GetProperty DIPROP_BUFFERSIZE returned %#lx\n", hr );
1231 ok( prop_dword.dwData == 0, "got %#lx expected %#x\n", prop_dword.dwData, 0 );
1232 prop_dword.dwData = 0xdeadbeef;
1233 hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFGAIN, &prop_dword.diph );
1234 ok( hr == DI_OK, "GetProperty DIPROP_FFGAIN returned %#lx\n", hr );
1235 ok( prop_dword.dwData == 10000, "got %lu expected %u\n", prop_dword.dwData, 10000 );
1237 hr = IDirectInputDevice8_SetDataFormat( device, &c_dfDIMouse2 );
1238 ok( hr == DI_OK, "SetDataFormat returned %#lx\n", hr );
1240 prop_dword.diph.dwHow = DIPH_DEVICE;
1241 prop_dword.diph.dwObj = 0;
1242 prop_dword.dwData = 0xdeadbeef;
1243 hr = IDirectInputDevice8_GetProperty( device, DIPROP_AXISMODE, &prop_dword.diph );
1244 todo_wine
1245 ok( hr == DI_OK, "GetProperty DIPROP_AXISMODE returned %#lx\n", hr );
1246 todo_wine
1247 ok( prop_dword.dwData == DIPROPAXISMODE_REL, "got %lu expected %u\n", prop_dword.dwData, DIPROPAXISMODE_ABS );
1249 prop_dword.dwData = 0xdeadbeef;
1250 hr = IDirectInputDevice8_GetProperty( device, DIPROP_VIDPID, &prop_dword.diph );
1251 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_VIDPID returned %#lx\n", hr );
1252 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GUIDANDPATH, &prop_guid_path.diph );
1253 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GUIDANDPATH returned %#lx\n", hr );
1254 hr = IDirectInputDevice8_GetProperty( device, DIPROP_INSTANCENAME, &prop_string.diph );
1255 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_INSTANCENAME returned %#lx\n", hr );
1256 hr = IDirectInputDevice8_GetProperty( device, DIPROP_PRODUCTNAME, &prop_string.diph );
1257 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_PRODUCTNAME returned %#lx\n", hr );
1258 hr = IDirectInputDevice8_GetProperty( device, DIPROP_TYPENAME, &prop_string.diph );
1259 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_TYPENAME returned %#lx\n", hr );
1260 hr = IDirectInputDevice8_GetProperty( device, DIPROP_USERNAME, &prop_string.diph );
1261 if (version < 0x0800)
1262 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_USERNAME returned %#lx\n", hr );
1263 else
1265 ok( hr == DI_NOEFFECT, "GetProperty DIPROP_USERNAME returned %#lx\n", hr );
1266 ok( !wcscmp( prop_string.wsz, L"" ), "got user %s\n", debugstr_w(prop_string.wsz) );
1269 hr = IDirectInputDevice8_GetProperty( device, DIPROP_JOYSTICKID, &prop_dword.diph );
1270 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_VIDPID returned %#lx\n", hr );
1272 hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATION, &prop_dword.diph );
1273 ok( hr == DIERR_INVALIDPARAM, "GetProperty DIPROP_CALIBRATION returned %#lx\n", hr );
1274 hr = IDirectInputDevice8_GetProperty( device, DIPROP_AUTOCENTER, &prop_dword.diph );
1275 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_AUTOCENTER returned %#lx\n", hr );
1276 hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph );
1277 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_DEADZONE returned %#lx\n", hr );
1278 hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFLOAD, &prop_dword.diph );
1279 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr );
1280 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph );
1281 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GRANULARITY returned %#lx\n", hr );
1283 prop_dword.diph.dwHow = DIPH_BYUSAGE;
1284 prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC );
1285 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph );
1286 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GRANULARITY returned %#lx\n", hr );
1288 prop_dword.diph.dwHow = DIPH_BYID;
1289 prop_dword.diph.dwObj = DIDFT_MAKEINSTANCE(1) | DIDFT_RELAXIS;
1290 prop_dword.dwData = 0xdeadbeef;
1291 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph );
1292 ok( hr == DI_OK, "GetProperty DIPROP_GRANULARITY returned %#lx\n", hr );
1293 ok( prop_dword.dwData == 1, "got %ld expected 1\n", prop_dword.dwData );
1294 prop_dword.diph.dwHow = DIPH_BYOFFSET;
1295 prop_dword.diph.dwObj = DIMOFS_X;
1296 prop_dword.dwData = 0xdeadbeef;
1297 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph );
1298 ok( hr == DI_OK, "GetProperty DIPROP_GRANULARITY returned %#lx\n", hr );
1299 ok( prop_dword.dwData == 1, "got %ld expected 1\n", prop_dword.dwData );
1300 hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph );
1301 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_DEADZONE returned %#lx\n", hr );
1302 hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph );
1303 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_SATURATION returned %#lx\n", hr );
1304 hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph );
1305 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_CALIBRATIONMODE returned %#lx\n", hr );
1306 prop_dword.diph.dwObj = DIMOFS_Z;
1307 prop_dword.dwData = 0xdeadbeef;
1308 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph );
1309 ok( hr == DI_OK, "GetProperty DIPROP_GRANULARITY returned %#lx\n", hr );
1310 ok( prop_dword.dwData == WHEEL_DELTA, "got %ld expected %ld\n", prop_dword.dwData, (DWORD)WHEEL_DELTA );
1311 prop_range.lMin = 0xdeadbeef;
1312 prop_range.lMax = 0xdeadbeef;
1313 hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph );
1314 ok( hr == DI_OK, "GetProperty DIPROP_RANGE returned %#lx\n", hr );
1315 ok( prop_range.lMin == DIPROPRANGE_NOMIN, "got %ld expected %ld\n", prop_range.lMin, DIPROPRANGE_NOMIN );
1316 ok( prop_range.lMax == DIPROPRANGE_NOMAX, "got %ld expected %ld\n", prop_range.lMax, DIPROPRANGE_NOMAX );
1317 hr = IDirectInputDevice8_GetProperty( device, DIPROP_LOGICALRANGE, &prop_range.diph );
1318 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_LOGICALRANGE returned %#lx\n", hr );
1319 hr = IDirectInputDevice8_GetProperty( device, DIPROP_PHYSICALRANGE, &prop_range.diph );
1320 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_PHYSICALRANGE returned %#lx\n", hr );
1322 prop_string.diph.dwHow = DIPH_BYOFFSET;
1323 prop_string.diph.dwObj = DIMOFS_X;
1324 hr = IDirectInputDevice8_GetProperty( device, DIPROP_KEYNAME, &prop_string.diph );
1325 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_KEYNAME returned %#lx\n", hr );
1327 prop_dword.diph.dwHow = DIPH_DEVICE;
1328 prop_dword.diph.dwObj = 0;
1329 prop_dword.dwData = 0xdeadbeef;
1330 hr = IDirectInputDevice8_SetProperty( device, DIPROP_FFGAIN, &prop_dword.diph );
1331 ok( hr == DIERR_INVALIDPARAM, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr );
1332 prop_dword.dwData = 1000;
1333 hr = IDirectInputDevice8_SetProperty( device, DIPROP_FFGAIN, &prop_dword.diph );
1334 ok( hr == DI_OK, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr );
1336 res = 0;
1337 hr = IDirectInputDevice8_EnumObjects( device, check_object_count, &res, DIDFT_AXIS | DIDFT_PSHBUTTON );
1338 ok( hr == DI_OK, "EnumObjects returned %#lx\n", hr );
1339 ok( res == 3 + caps.dwButtons, "got %lu expected %lu\n", res, 3 + caps.dwButtons );
1340 check_objects_params.expect_count = 3 + caps.dwButtons;
1341 hr = IDirectInputDevice8_EnumObjects( device, check_objects, &check_objects_params, DIDFT_ALL );
1342 ok( hr == DI_OK, "EnumObjects returned %#lx\n", hr );
1343 ok( check_objects_params.index >= check_objects_params.expect_count, "missing %u objects\n",
1344 check_objects_params.expect_count - check_objects_params.index );
1346 res = 0;
1347 hr = IDirectInputDevice8_EnumObjects( device, check_object_count_bad_retval, &res, DIDFT_AXIS );
1348 ok( hr == DI_OK, "EnumObjects returned %#lx\n", hr );
1349 ok( res == 3, "got %lu expected 3\n", res );
1351 objinst.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW);
1352 res = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC );
1353 hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYUSAGE );
1354 ok( hr == DIERR_UNSUPPORTED, "GetObjectInfo returned: %#lx\n", hr );
1356 hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, DIMOFS_Y, DIPH_BYOFFSET );
1357 ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr );
1359 check_member( objinst, expect_objects[1], "%lu", dwSize );
1360 check_member_guid( objinst, expect_objects[1], guidType );
1361 check_member( objinst, expect_objects[1], "%#lx", dwOfs );
1362 check_member( objinst, expect_objects[1], "%#lx", dwType );
1363 check_member( objinst, expect_objects[1], "%#lx", dwFlags );
1364 if (!localized) check_member_wstr( objinst, expect_objects[1], tszName );
1365 check_member( objinst, expect_objects[1], "%lu", dwFFMaxForce );
1366 check_member( objinst, expect_objects[1], "%lu", dwFFForceResolution );
1367 check_member( objinst, expect_objects[1], "%u", wCollectionNumber );
1368 check_member( objinst, expect_objects[1], "%u", wDesignatorIndex );
1369 check_member( objinst, expect_objects[1], "%#04x", wUsagePage );
1370 check_member( objinst, expect_objects[1], "%#04x", wUsage );
1371 check_member( objinst, expect_objects[1], "%#lx", dwDimension );
1372 check_member( objinst, expect_objects[1], "%#04x", wExponent );
1373 check_member( objinst, expect_objects[1], "%u", wReportId );
1375 hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, 7, DIPH_BYOFFSET );
1376 ok( hr == DIERR_NOTFOUND, "GetObjectInfo returned: %#lx\n", hr );
1377 res = DIDFT_TGLBUTTON | DIDFT_MAKEINSTANCE( 3 );
1378 hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYID );
1379 ok( hr == DIERR_NOTFOUND, "GetObjectInfo returned: %#lx\n", hr );
1380 res = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 3 );
1381 hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYID );
1382 ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr );
1384 check_member( objinst, expect_objects[3], "%lu", dwSize );
1385 check_member_guid( objinst, expect_objects[3], guidType );
1386 check_member( objinst, expect_objects[3], "%#lx", dwOfs );
1387 check_member( objinst, expect_objects[3], "%#lx", dwType );
1388 check_member( objinst, expect_objects[3], "%#lx", dwFlags );
1389 if (!localized) check_member_wstr( objinst, expect_objects[3], tszName );
1390 check_member( objinst, expect_objects[3], "%lu", dwFFMaxForce );
1391 check_member( objinst, expect_objects[3], "%lu", dwFFForceResolution );
1392 check_member( objinst, expect_objects[3], "%u", wCollectionNumber );
1393 check_member( objinst, expect_objects[3], "%u", wDesignatorIndex );
1394 check_member( objinst, expect_objects[3], "%#04x", wUsagePage );
1395 check_member( objinst, expect_objects[3], "%#04x", wUsage );
1396 check_member( objinst, expect_objects[3], "%#lx", dwDimension );
1397 check_member( objinst, expect_objects[3], "%#04x", wExponent );
1398 check_member( objinst, expect_objects[3], "%u", wReportId );
1401 SetCursorPos( 60, 60 );
1403 hwnd = CreateWindowW( L"static", L"static", WS_POPUP | WS_VISIBLE,
1404 50, 50, 200, 200, NULL, NULL, NULL, NULL );
1405 ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() );
1407 hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_FOREGROUND );
1408 ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr );
1409 hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_FOREGROUND|DISCL_EXCLUSIVE );
1410 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
1411 hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_FOREGROUND|DISCL_NONEXCLUSIVE );
1412 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
1414 hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_BACKGROUND );
1415 ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr );
1416 hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_BACKGROUND|DISCL_EXCLUSIVE );
1417 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
1418 hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_BACKGROUND|DISCL_NONEXCLUSIVE );
1419 ok( hr == DI_OK, "SetCooperativeLevel returned %#lx\n", hr );
1421 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_FOREGROUND );
1422 ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr );
1423 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_FOREGROUND|DISCL_EXCLUSIVE );
1424 ok( hr == DI_OK, "SetCooperativeLevel returned %#lx\n", hr );
1425 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_FOREGROUND|DISCL_NONEXCLUSIVE );
1426 ok( hr == DI_OK, "SetCooperativeLevel returned %#lx\n", hr );
1428 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND );
1429 ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr );
1430 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND|DISCL_EXCLUSIVE );
1431 ok( hr == DIERR_UNSUPPORTED, "SetCooperativeLevel returned %#lx\n", hr );
1432 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND|DISCL_NONEXCLUSIVE );
1433 ok( hr == DI_OK, "SetCooperativeLevel returned %#lx\n", hr );
1435 child = CreateWindowW( L"static", L"static", WS_CHILD | WS_VISIBLE,
1436 10, 10, 50, 50, hwnd, NULL, NULL, NULL );
1437 ok( !!child, "CreateWindowW failed, error %lu\n", GetLastError() );
1439 hr = IDirectInputDevice8_SetCooperativeLevel( device, child, DISCL_FOREGROUND );
1440 ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr );
1441 hr = IDirectInputDevice8_SetCooperativeLevel( device, child, DISCL_FOREGROUND|DISCL_EXCLUSIVE );
1442 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
1443 hr = IDirectInputDevice8_SetCooperativeLevel( device, child, DISCL_FOREGROUND|DISCL_NONEXCLUSIVE );
1444 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
1446 hr = IDirectInputDevice8_SetCooperativeLevel( device, child, DISCL_BACKGROUND );
1447 ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr );
1448 hr = IDirectInputDevice8_SetCooperativeLevel( device, child, DISCL_BACKGROUND|DISCL_EXCLUSIVE );
1449 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
1450 hr = IDirectInputDevice8_SetCooperativeLevel( device, child, DISCL_BACKGROUND|DISCL_NONEXCLUSIVE );
1451 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
1453 DestroyWindow( child );
1456 event = CreateEventW( NULL, FALSE, FALSE, NULL );
1457 ok( !!event, "CreateEventW failed, error %lu\n", GetLastError() );
1458 hr = IDirectInputDevice8_SetEventNotification( device, event );
1459 ok( hr == DI_OK, "SetEventNotification returned %#lx\n", hr );
1460 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND );
1461 ok( hr == DI_OK, "SetCooperativeLevel returned %#lx\n", hr );
1463 prop_dword.dwData = 5;
1464 prop_dword.diph.dwHow = DIPH_DEVICE;
1465 prop_dword.diph.dwObj = 0;
1466 hr = IDirectInputDevice8_SetProperty( device, DIPROP_BUFFERSIZE, (LPCDIPROPHEADER)&prop_dword );
1467 ok( hr == DI_OK, "SetProperty returned %#lx\n", hr );
1468 hr = IDirectInputDevice8_SetDataFormat( device, &c_dfDIMouse );
1469 ok( hr == DI_OK, "SetDataFormat returned %#lx\n", hr );
1470 hr = IDirectInputDevice8_Unacquire( device );
1471 ok( hr == DI_NOEFFECT, "Unacquire returned %#lx\n", hr );
1472 hr = IDirectInputDevice8_Acquire( device );
1473 ok( hr == DI_OK, "Acquire returned %#lx, skipping test_sys_mouse\n", hr );
1474 if (hr != DI_OK) goto cleanup;
1475 hr = IDirectInputDevice8_Acquire( device );
1476 ok( hr == DI_NOEFFECT, "Acquire returned %#lx\n", hr );
1478 mouse_event( MOUSEEVENTF_MOVE, 10, 10, 0, 0 );
1479 res = WaitForSingleObject( event, 100 );
1480 if (res == WAIT_TIMEOUT) /* Acquire is asynchronous */
1482 mouse_event( MOUSEEVENTF_MOVE, 10, 10, 0, 0 );
1483 res = WaitForSingleObject( event, 5000 );
1485 ok( !res, "WaitForSingleObject returned %#lx\n", res );
1487 count = 1;
1488 hr = IDirectInputDevice8_GetDeviceData( device, sizeof(objdata), &objdata, &count, 0 );
1489 ok( hr == DI_OK, "GetDeviceData returned %#lx\n", hr );
1490 ok( count == 1, "got count %lu\n", count );
1492 mouse_event( MOUSEEVENTF_MOVE, 10, 10, 0, 0 );
1493 res = WaitForSingleObject( event, 5000 );
1494 ok( !res, "WaitForSingleObject returned %#lx\n", res );
1496 hr = IDirectInputDevice8_Unacquire( device );
1497 ok( hr == DI_OK, "Unacquire returned %#lx\n", hr );
1498 count = 1;
1499 hr = IDirectInputDevice8_GetDeviceData( device, sizeof(objdata), &objdata, &count, 0 );
1500 ok( hr == (version < 0x800 ? DI_OK : DIERR_NOTACQUIRED), "GetDeviceData returned %#lx\n", hr );
1501 ok( count == 1, "got count %lu\n", count );
1503 hr = IDirectInputDevice8_Acquire( device );
1504 ok( hr == DI_OK, "Acquire returned %#lx, skipping test_sys_mouse\n", hr );
1505 if (hr != DI_OK) goto cleanup;
1507 mouse_event( MOUSEEVENTF_MOVE, 10, 10, 0, 0 );
1508 res = WaitForSingleObject( event, 100 );
1509 if (res == WAIT_TIMEOUT) /* Acquire is asynchronous */
1511 mouse_event( MOUSEEVENTF_MOVE, 10, 10, 0, 0 );
1512 res = WaitForSingleObject( event, 5000 );
1514 ok( !res, "WaitForSingleObject returned %#lx\n", res );
1516 hr = IDirectInputDevice8_Unacquire( device );
1517 ok( hr == DI_OK, "Unacquire returned %#lx\n", hr );
1519 hr = IDirectInputDevice8_Acquire( device );
1520 ok( hr == DI_OK, "Acquire returned %#lx, skipping test_sys_mouse\n", hr );
1521 if (hr != DI_OK) goto cleanup;
1523 count = 1;
1524 hr = IDirectInputDevice8_GetDeviceData( device, sizeof(objdata), &objdata, &count, 0 );
1525 ok( hr == (version < 0x800 ? DI_OK : DI_BUFFEROVERFLOW), "GetDeviceData returned %#lx\n", hr );
1526 ok( count == 1, "got count %lu\n", count );
1528 mouse_event( MOUSEEVENTF_MOVE, 10, 10, 0, 0 );
1529 res = WaitForSingleObject( event, 100 );
1530 if (res == WAIT_TIMEOUT) /* Acquire is asynchronous */
1532 mouse_event( MOUSEEVENTF_MOVE, 10, 10, 0, 0 );
1533 res = WaitForSingleObject( event, 5000 );
1535 ok( !res, "WaitForSingleObject returned %#lx\n", res );
1537 for (i = 0; i < 2; i++)
1539 mouse_event( MOUSEEVENTF_MOVE, 10 + i, 10 + i, 0, 0 );
1540 res = WaitForSingleObject( event, 5000 );
1541 ok( !res, "WaitForSingleObject returned %#lx\n", res );
1544 count = 1;
1545 hr = IDirectInputDevice8_GetDeviceData( device, sizeof(objdata), &objdata, &count, 0 );
1546 ok( hr == (version < 0x800 ? DI_OK : DI_BUFFEROVERFLOW), "GetDeviceData returned %#lx\n", hr );
1547 count = 1;
1548 hr = IDirectInputDevice8_GetDeviceData( device, sizeof(objdata), &objdata, &count, 0 );
1550 flaky_wine_if (hr == DIERR_NOTACQUIRED)
1551 ok( hr == DI_OK, "GetDeviceData returned %#lx\n", hr );
1552 ok( count == 1, "got count %lu\n", count );
1554 if (hr != DIERR_NOTACQUIRED)
1556 hr = IDirectInputDevice8_Unacquire( device );
1557 ok( hr == DI_OK, "Unacquire returned %#lx\n", hr );
1560 tmp_hwnd = CreateWindowW( L"static", L"static", WS_POPUP | WS_VISIBLE,
1561 50, 250, 200, 200, NULL, NULL, NULL, NULL );
1562 ok( !!tmp_hwnd, "CreateWindowW failed, error %lu\n", GetLastError() );
1564 hr = IDirectInputDevice8_GetDeviceState( device, sizeof(state), &state );
1565 ok( hr == DIERR_NOTACQUIRED, "GetDeviceState returned %#lx\n", hr );
1567 hr = IDirectInputDevice8_Acquire( device );
1568 ok( hr == DIERR_OTHERAPPHASPRIO, "Acquire returned %#lx\n", hr );
1570 DestroyWindow( tmp_hwnd );
1573 cleanup:
1574 CloseHandle( event );
1575 DestroyWindow( hwnd );
1577 ref = IDirectInputDevice8_Release( device );
1578 ok( ref == 0, "Release returned %ld\n", ref );
1580 winetest_pop_context();
1581 localized = old_localized;
1584 static void test_dik_codes( IDirectInputDevice8W *device, HANDLE event, HWND hwnd )
1586 static const struct key2dik
1588 BYTE key, dik, todo;
1590 key2dik_en[] =
1592 {'Q',DIK_Q}, {'W',DIK_W}, {'E',DIK_E}, {'R',DIK_R}, {'T',DIK_T}, {'Y',DIK_Y},
1593 {'[',DIK_LBRACKET}, {']',DIK_RBRACKET}, {'.',DIK_PERIOD}
1595 key2dik_fr[] =
1597 {'A',DIK_Q}, {'Z',DIK_W}, {'E',DIK_E}, {'R',DIK_R}, {'T',DIK_T}, {'Y',DIK_Y},
1598 {'^',DIK_LBRACKET}, {'$',DIK_RBRACKET}, {':',DIK_PERIOD}
1600 key2dik_de[] =
1602 {'Q',DIK_Q}, {'W',DIK_W}, {'E',DIK_E}, {'R',DIK_R}, {'T',DIK_T}, {'Z',DIK_Y},
1603 {'\xfc',DIK_LBRACKET,1}, {'+',DIK_RBRACKET}, {'.',DIK_PERIOD}
1605 key2dik_ja[] =
1607 {'Q',DIK_Q}, {'W',DIK_W}, {'E',DIK_E}, {'R',DIK_R}, {'T',DIK_T}, {'Y',DIK_Y},
1608 {'@',DIK_AT}, {']',DIK_RBRACKET}, {'.',DIK_PERIOD}
1610 static const struct
1612 LANGID langid;
1613 const struct key2dik *map;
1614 DWORD type;
1615 } tests[] =
1617 { MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), key2dik_en, DIDEVTYPEKEYBOARD_PCENH },
1618 { MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH), key2dik_fr, DIDEVTYPEKEYBOARD_PCENH },
1619 { MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), key2dik_de, DIDEVTYPEKEYBOARD_PCENH },
1620 { MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), key2dik_ja, DIDEVTYPEKEYBOARD_JAPAN106 }
1622 DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)};
1623 const struct key2dik *map;
1624 BYTE key_state[256];
1625 HKL hkl, old_hkl;
1626 WORD vkey, scan;
1627 HRESULT hr;
1628 ULONG res;
1629 UINT i, j;
1631 hr = IDirectInputDevice_SetDataFormat( device, &c_dfDIKeyboard );
1632 ok( hr == DI_OK, "SetDataFormat returned %#lx\n", hr );
1633 hr = IDirectInputDevice_Acquire( device );
1634 ok( hr == DI_OK, "Acquire returned %#lx\n", hr );
1635 hr = IDirectInputDevice_GetCapabilities( device, &caps );
1636 ok( hr == DI_OK, "GetDeviceInstance returned %#lx\n", hr );
1638 for (i = 0; i < ARRAY_SIZE(tests); ++i)
1640 if (tests[i].type != GET_DIDEVICE_SUBTYPE( caps.dwDevType ))
1642 skip( "keyboard type %#x doesn't match for lang %#x\n",
1643 GET_DIDEVICE_SUBTYPE( caps.dwDevType ), tests[i].langid );
1644 continue;
1647 winetest_push_context( "lang %#x", tests[i].langid );
1649 hkl = activate_keyboard_layout( tests[i].langid, &old_hkl );
1650 if (LOWORD(old_hkl) != MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT) ||
1651 LOWORD(hkl) != tests[i].langid) goto skip_key_tests;
1653 map = tests[i].map;
1654 for (j = 0; j < ARRAY_SIZE(key2dik_en); j++)
1656 winetest_push_context( "key %#x, dik %#x", map[j].key, map[j].dik );
1658 vkey = VkKeyScanExW( map[j].key, hkl );
1659 todo_wine_if( map[j].todo )
1660 ok( vkey != 0xffff, "VkKeyScanExW failed\n" );
1662 vkey = LOBYTE(vkey);
1663 res = MapVirtualKeyExA( vkey, MAPVK_VK_TO_CHAR, hkl ) & 0xff;
1664 todo_wine_if( map[j].todo )
1665 ok( res == map[j].key, "MapVirtualKeyExA failed\n" );
1667 scan = MapVirtualKeyExA( vkey, MAPVK_VK_TO_VSC, hkl );
1668 todo_wine_if( map[j].todo )
1669 ok( scan, "MapVirtualKeyExA failed\n" );
1671 keybd_event( vkey, scan, 0, 0 );
1672 res = WaitForSingleObject( event, 100 );
1673 if (i == 0 && j == 0 && res == WAIT_TIMEOUT) /* Acquire is asynchronous */
1675 keybd_event( vkey, scan, 0, 0 );
1676 res = WaitForSingleObject( event, 5000 );
1678 ok( !res, "WaitForSingleObject returned %#lx\n", res );
1680 hr = IDirectInputDevice_GetDeviceState( device, sizeof(key_state), key_state );
1681 ok( hr == DI_OK, "GetDeviceState returned %#lx\n", hr );
1683 todo_wine_if( map[j].todo )
1684 ok( key_state[map[j].dik] == 0x80, "got state %#x\n", key_state[map[j].dik] );
1686 keybd_event( vkey, scan, KEYEVENTF_KEYUP, 0 );
1687 res = WaitForSingleObject( event, 5000 );
1688 ok( !res, "WaitForSingleObject returned %#lx\n", res );
1690 winetest_pop_context();
1693 skip_key_tests:
1694 ActivateKeyboardLayout( old_hkl, 0 );
1695 UnloadKeyboardLayout( hkl );
1697 winetest_pop_context();
1700 hr = IDirectInputDevice8_Unacquire( device );
1701 ok( hr == DI_OK, "Unacquire returned %#lx\n", hr );
1704 static void test_sys_keyboard( DWORD version )
1706 const DIDEVCAPS expect_caps =
1708 .dwSize = sizeof(DIDEVCAPS),
1709 .dwFlags = DIDC_ATTACHED | DIDC_EMULATED,
1710 .dwDevType = version < 0x800 ? (DIDEVTYPEKEYBOARD_PCENH << 8) | DIDEVTYPE_KEYBOARD
1711 : (DI8DEVTYPEKEYBOARD_PCENH << 8) | DI8DEVTYPE_KEYBOARD,
1712 .dwButtons = 128,
1714 const DIDEVICEINSTANCEW expect_devinst =
1716 .dwSize = sizeof(DIDEVICEINSTANCEW),
1717 .guidInstance = GUID_SysKeyboard,
1718 .guidProduct = GUID_SysKeyboard,
1719 .dwDevType = version < 0x800 ? (DIDEVTYPEKEYBOARD_PCENH << 8) | DIDEVTYPE_KEYBOARD
1720 : (DI8DEVTYPEKEYBOARD_PCENH << 8) | DI8DEVTYPE_KEYBOARD,
1721 .tszInstanceName = L"Keyboard",
1722 .tszProductName = L"Keyboard",
1723 .guidFFDriver = GUID_NULL,
1726 DIDEVICEOBJECTINSTANCEW expect_objects[] =
1729 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
1730 .guidType = GUID_Key,
1731 .dwOfs = DIK_ESCAPE,
1732 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(DIK_ESCAPE),
1733 .tszName = L"Esc",
1736 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
1737 .guidType = GUID_Key,
1738 .dwOfs = DIK_1,
1739 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(DIK_1),
1740 .tszName = L"1",
1743 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
1744 .guidType = GUID_Key,
1745 .dwOfs = DIK_2,
1746 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(DIK_2),
1747 .tszName = L"2",
1750 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
1751 .guidType = GUID_Key,
1752 .dwOfs = DIK_3,
1753 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(DIK_3),
1754 .tszName = L"3",
1757 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
1758 .guidType = GUID_Key,
1759 .dwOfs = DIK_4,
1760 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(DIK_4),
1761 .tszName = L"4",
1764 struct check_objects_todos todo_objects[ARRAY_SIZE(expect_objects)] = {{0}};
1765 struct check_objects_params check_objects_params =
1767 .stop_count = ARRAY_SIZE(expect_objects),
1768 .expect_count = ARRAY_SIZE(expect_objects),
1769 .expect_objs = expect_objects,
1770 .todo_objs = todo_objects,
1772 DIPROPGUIDANDPATH prop_guid_path =
1774 .diph =
1776 .dwSize = sizeof(DIPROPGUIDANDPATH),
1777 .dwHeaderSize = sizeof(DIPROPHEADER),
1778 .dwHow = DIPH_DEVICE,
1781 DIPROPSTRING prop_string =
1783 .diph =
1785 .dwSize = sizeof(DIPROPSTRING),
1786 .dwHeaderSize = sizeof(DIPROPHEADER),
1787 .dwHow = DIPH_DEVICE,
1790 DIPROPDWORD prop_dword =
1792 .diph =
1794 .dwSize = sizeof(DIPROPDWORD),
1795 .dwHeaderSize = sizeof(DIPROPHEADER),
1796 .dwHow = DIPH_DEVICE,
1799 DIPROPRANGE prop_range =
1801 .diph =
1803 .dwSize = sizeof(DIPROPRANGE),
1804 .dwHeaderSize = sizeof(DIPROPHEADER),
1805 .dwHow = DIPH_DEVICE,
1809 LONG key_state[6], zero_state[6] = {0};
1810 DIOBJECTDATAFORMAT obj_data_format[] =
1812 {&GUID_Key, sizeof(LONG) * 0, DIDFT_MAKEINSTANCE( DIK_Q ) | DIDFT_BUTTON, 0},
1813 {&GUID_Key, sizeof(LONG) * 1, DIDFT_MAKEINSTANCE( DIK_W ) | DIDFT_BUTTON, 0},
1814 {&GUID_Key, sizeof(LONG) * 2, DIDFT_MAKEINSTANCE( DIK_E ) | DIDFT_BUTTON, 0},
1815 {&GUID_Key, sizeof(LONG) * 4, DIDFT_MAKEINSTANCE( DIK_R ) | DIDFT_BUTTON, 0},
1817 DIDATAFORMAT data_format =
1819 sizeof(DIDATAFORMAT), sizeof(DIOBJECTDATAFORMAT), DIDF_RELAXIS,
1820 sizeof(key_state), ARRAY_SIZE(obj_data_format), obj_data_format,
1823 DIDEVICEOBJECTINSTANCEW objinst = {0};
1824 DIDEVICEINSTANCEW devinst = {0};
1825 BOOL old_localized = localized;
1826 IDirectInputDevice8W *device;
1827 DIDEVCAPS caps = {0};
1828 BYTE full_state[256];
1829 HKL hkl, old_hkl;
1830 HWND hwnd, child;
1831 ULONG res, ref;
1832 HANDLE event;
1833 HRESULT hr;
1834 GUID guid;
1836 if (FAILED(create_dinput_device( version, &GUID_SysKeyboard, &device ))) return;
1838 localized = TRUE; /* Skip name tests, Wine sometimes succeeds depending on the host key names */
1839 winetest_push_context( "%#lx", version );
1841 hr = IDirectInputDevice8_Initialize( device, instance, version, &GUID_SysKeyboardEm );
1842 ok( hr == DI_OK, "Initialize returned %#lx\n", hr );
1843 guid = GUID_SysKeyboardEm;
1844 memset( &devinst, 0, sizeof(devinst) );
1845 devinst.dwSize = sizeof(DIDEVICEINSTANCEW);
1846 hr = IDirectInputDevice8_GetDeviceInfo( device, &devinst );
1847 ok( hr == DI_OK, "GetDeviceInfo returned %#lx\n", hr );
1848 ok( IsEqualGUID( &guid, &GUID_SysKeyboardEm ), "got %s expected %s\n", debugstr_guid( &guid ),
1849 debugstr_guid( &GUID_SysKeyboardEm ) );
1851 hr = IDirectInputDevice8_Initialize( device, instance, version, &GUID_SysKeyboard );
1852 ok( hr == DI_OK, "Initialize returned %#lx\n", hr );
1854 memset( &devinst, 0, sizeof(devinst) );
1855 devinst.dwSize = sizeof(DIDEVICEINSTANCEW);
1856 hr = IDirectInputDevice8_GetDeviceInfo( device, &devinst );
1857 ok( hr == DI_OK, "GetDeviceInfo returned %#lx\n", hr );
1858 check_member( devinst, expect_devinst, "%lu", dwSize );
1859 check_member_guid( devinst, expect_devinst, guidInstance );
1860 check_member_guid( devinst, expect_devinst, guidProduct );
1861 check_member( devinst, expect_devinst, "%#lx", dwDevType );
1862 if (!localized) check_member_wstr( devinst, expect_devinst, tszInstanceName );
1863 if (!localized) todo_wine check_member_wstr( devinst, expect_devinst, tszProductName );
1864 check_member_guid( devinst, expect_devinst, guidFFDriver );
1865 check_member( devinst, expect_devinst, "%04x", wUsagePage );
1866 check_member( devinst, expect_devinst, "%04x", wUsage );
1868 devinst.dwSize = sizeof(DIDEVICEINSTANCE_DX3W);
1869 hr = IDirectInputDevice8_GetDeviceInfo( device, &devinst );
1870 ok( hr == DI_OK, "GetDeviceInfo returned %#lx\n", hr );
1871 check_member_guid( devinst, expect_devinst, guidInstance );
1872 check_member_guid( devinst, expect_devinst, guidProduct );
1873 check_member( devinst, expect_devinst, "%#lx", dwDevType );
1874 if (!localized) check_member_wstr( devinst, expect_devinst, tszInstanceName );
1875 if (!localized) todo_wine check_member_wstr( devinst, expect_devinst, tszProductName );
1877 caps.dwSize = sizeof(DIDEVCAPS);
1878 hr = IDirectInputDevice8_GetCapabilities( device, &caps );
1879 ok( hr == DI_OK, "GetCapabilities returned %#lx\n", hr );
1880 check_member( caps, expect_caps, "%lu", dwSize );
1881 check_member( caps, expect_caps, "%#lx", dwFlags );
1882 check_member( caps, expect_caps, "%#lx", dwDevType );
1883 check_member( caps, expect_caps, "%lu", dwAxes );
1884 todo_wine
1885 check_member( caps, expect_caps, "%lu", dwButtons );
1886 check_member( caps, expect_caps, "%lu", dwPOVs );
1887 check_member( caps, expect_caps, "%lu", dwFFSamplePeriod );
1888 check_member( caps, expect_caps, "%lu", dwFFMinTimeResolution );
1889 todo_wine
1890 check_member( caps, expect_caps, "%lu", dwFirmwareRevision );
1891 todo_wine
1892 check_member( caps, expect_caps, "%lu", dwHardwareRevision );
1893 check_member( caps, expect_caps, "%lu", dwFFDriverVersion );
1895 prop_dword.diph.dwHow = DIPH_BYOFFSET;
1896 prop_dword.diph.dwObj = 1;
1897 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph );
1898 ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_GRANULARITY returned %#lx\n", hr );
1899 hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph );
1900 ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_DEADZONE returned %#lx\n", hr );
1901 hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph );
1902 ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_SATURATION returned %#lx\n", hr );
1903 hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph );
1904 ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_CALIBRATIONMODE returned %#lx\n", hr );
1905 prop_range.diph.dwHow = DIPH_BYOFFSET;
1906 prop_range.diph.dwObj = 1;
1907 hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph );
1908 ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_RANGE returned %#lx\n", hr );
1909 hr = IDirectInputDevice8_GetProperty( device, DIPROP_LOGICALRANGE, &prop_range.diph );
1910 ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_LOGICALRANGE returned %#lx\n", hr );
1911 hr = IDirectInputDevice8_GetProperty( device, DIPROP_PHYSICALRANGE, &prop_range.diph );
1912 ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_PHYSICALRANGE returned %#lx\n", hr );
1914 prop_dword.diph.dwHow = DIPH_DEVICE;
1915 prop_dword.diph.dwObj = 0;
1916 prop_dword.dwData = 0xdeadbeef;
1917 hr = IDirectInputDevice8_GetProperty( device, DIPROP_AXISMODE, &prop_dword.diph );
1918 todo_wine
1919 ok( hr == DI_OK, "GetProperty DIPROP_AXISMODE returned %#lx\n", hr );
1920 todo_wine
1921 ok( prop_dword.dwData == DIPROPAXISMODE_ABS, "got %lu expected %u\n", prop_dword.dwData, DIPROPAXISMODE_ABS );
1922 prop_dword.dwData = 0xdeadbeef;
1923 hr = IDirectInputDevice8_GetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph );
1924 ok( hr == DI_OK, "GetProperty DIPROP_BUFFERSIZE returned %#lx\n", hr );
1925 ok( prop_dword.dwData == 0, "got %#lx expected %#x\n", prop_dword.dwData, 0 );
1926 prop_dword.dwData = 0xdeadbeef;
1927 hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFGAIN, &prop_dword.diph );
1928 ok( hr == DI_OK, "GetProperty DIPROP_FFGAIN returned %#lx\n", hr );
1929 ok( prop_dword.dwData == 10000, "got %lu expected %u\n", prop_dword.dwData, 10000 );
1931 hr = IDirectInputDevice8_SetDataFormat( device, &c_dfDIKeyboard );
1932 ok( hr == DI_OK, "SetDataFormat returned %#lx\n", hr );
1934 prop_dword.diph.dwHow = DIPH_DEVICE;
1935 prop_dword.diph.dwObj = 0;
1936 prop_dword.dwData = 0xdeadbeef;
1937 hr = IDirectInputDevice8_GetProperty( device, DIPROP_AXISMODE, &prop_dword.diph );
1938 todo_wine
1939 ok( hr == DI_OK, "GetProperty DIPROP_AXISMODE returned %#lx\n", hr );
1940 todo_wine
1941 ok( prop_dword.dwData == DIPROPAXISMODE_REL, "got %lu expected %u\n", prop_dword.dwData, DIPROPAXISMODE_ABS );
1943 prop_dword.dwData = 0xdeadbeef;
1944 hr = IDirectInputDevice8_GetProperty( device, DIPROP_VIDPID, &prop_dword.diph );
1945 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_VIDPID returned %#lx\n", hr );
1946 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GUIDANDPATH, &prop_guid_path.diph );
1947 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GUIDANDPATH returned %#lx\n", hr );
1948 hr = IDirectInputDevice8_GetProperty( device, DIPROP_INSTANCENAME, &prop_string.diph );
1949 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_INSTANCENAME returned %#lx\n", hr );
1950 hr = IDirectInputDevice8_GetProperty( device, DIPROP_PRODUCTNAME, &prop_string.diph );
1951 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_PRODUCTNAME returned %#lx\n", hr );
1952 hr = IDirectInputDevice8_GetProperty( device, DIPROP_TYPENAME, &prop_string.diph );
1953 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_TYPENAME returned %#lx\n", hr );
1954 hr = IDirectInputDevice8_GetProperty( device, DIPROP_USERNAME, &prop_string.diph );
1955 if (version < 0x0800)
1956 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_USERNAME returned %#lx\n", hr );
1957 else
1959 ok( hr == DI_NOEFFECT, "GetProperty DIPROP_USERNAME returned %#lx\n", hr );
1960 ok( !wcscmp( prop_string.wsz, L"" ), "got user %s\n", debugstr_w(prop_string.wsz) );
1963 hr = IDirectInputDevice8_GetProperty( device, DIPROP_JOYSTICKID, &prop_dword.diph );
1964 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_VIDPID returned %#lx\n", hr );
1966 hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATION, &prop_dword.diph );
1967 ok( hr == DIERR_INVALIDPARAM, "GetProperty DIPROP_CALIBRATION returned %#lx\n", hr );
1968 hr = IDirectInputDevice8_GetProperty( device, DIPROP_AUTOCENTER, &prop_dword.diph );
1969 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_AUTOCENTER returned %#lx\n", hr );
1970 hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph );
1971 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_DEADZONE returned %#lx\n", hr );
1972 hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFLOAD, &prop_dword.diph );
1973 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_FFLOAD returned %#lx\n", hr );
1974 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph );
1975 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GRANULARITY returned %#lx\n", hr );
1977 prop_dword.diph.dwHow = DIPH_BYUSAGE;
1978 prop_dword.diph.dwObj = MAKELONG( HID_USAGE_KEYBOARD_LCTRL, HID_USAGE_PAGE_KEYBOARD );
1979 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph );
1980 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GRANULARITY returned %#lx\n", hr );
1982 prop_dword.diph.dwHow = DIPH_BYOFFSET;
1983 prop_dword.diph.dwObj = 1;
1984 hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph );
1985 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GRANULARITY returned %#lx\n", hr );
1986 hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph );
1987 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_DEADZONE returned %#lx\n", hr );
1988 hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph );
1989 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_SATURATION returned %#lx\n", hr );
1990 hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph );
1991 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_CALIBRATIONMODE returned %#lx\n", hr );
1992 prop_range.diph.dwHow = DIPH_BYOFFSET;
1993 prop_range.diph.dwObj = 1;
1994 hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph );
1995 ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_RANGE returned %#lx\n", hr );
1997 prop_dword.diph.dwHow = DIPH_DEVICE;
1998 prop_dword.diph.dwObj = 0;
1999 prop_dword.dwData = 0xdeadbeef;
2000 hr = IDirectInputDevice8_SetProperty( device, DIPROP_FFGAIN, &prop_dword.diph );
2001 ok( hr == DIERR_INVALIDPARAM, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr );
2002 prop_dword.dwData = 1000;
2003 hr = IDirectInputDevice8_SetProperty( device, DIPROP_FFGAIN, &prop_dword.diph );
2004 ok( hr == DI_OK, "SetProperty DIPROP_FFGAIN returned %#lx\n", hr );
2006 res = 0;
2007 hr = IDirectInputDevice8_EnumObjects( device, check_object_count, &res, DIDFT_AXIS | DIDFT_PSHBUTTON );
2008 ok( hr == DI_OK, "EnumObjects returned %#lx\n", hr );
2009 if (!localized) todo_wine ok( res == 127, "got %lu expected %u\n", res, 127 );
2010 hr = IDirectInputDevice8_EnumObjects( device, check_objects, &check_objects_params, DIDFT_ALL );
2011 ok( hr == DI_OK, "EnumObjects returned %#lx\n", hr );
2012 ok( check_objects_params.index >= check_objects_params.expect_count, "missing %u objects\n",
2013 check_objects_params.expect_count - check_objects_params.index );
2015 objinst.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW);
2016 res = MAKELONG( HID_USAGE_KEYBOARD_LCTRL, HID_USAGE_PAGE_KEYBOARD );
2017 hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYUSAGE );
2018 ok( hr == DIERR_UNSUPPORTED, "GetObjectInfo returned: %#lx\n", hr );
2020 hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, 2, DIPH_BYOFFSET );
2021 ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr );
2023 check_member( objinst, expect_objects[1], "%lu", dwSize );
2024 check_member_guid( objinst, expect_objects[1], guidType );
2025 check_member( objinst, expect_objects[1], "%#lx", dwOfs );
2026 check_member( objinst, expect_objects[1], "%#lx", dwType );
2027 check_member( objinst, expect_objects[1], "%#lx", dwFlags );
2028 if (!localized) check_member_wstr( objinst, expect_objects[1], tszName );
2029 check_member( objinst, expect_objects[1], "%lu", dwFFMaxForce );
2030 check_member( objinst, expect_objects[1], "%lu", dwFFForceResolution );
2031 check_member( objinst, expect_objects[1], "%u", wCollectionNumber );
2032 check_member( objinst, expect_objects[1], "%u", wDesignatorIndex );
2033 check_member( objinst, expect_objects[1], "%#04x", wUsagePage );
2034 check_member( objinst, expect_objects[1], "%#04x", wUsage );
2035 check_member( objinst, expect_objects[1], "%#lx", dwDimension );
2036 check_member( objinst, expect_objects[1], "%#04x", wExponent );
2037 check_member( objinst, expect_objects[1], "%u", wReportId );
2039 hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, 423, DIPH_BYOFFSET );
2040 ok( hr == DIERR_NOTFOUND, "GetObjectInfo returned: %#lx\n", hr );
2041 res = DIDFT_TGLBUTTON | DIDFT_MAKEINSTANCE( 3 );
2042 hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYID );
2043 ok( hr == DIERR_NOTFOUND, "GetObjectInfo returned: %#lx\n", hr );
2044 res = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 3 );
2045 hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYID );
2046 ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr );
2048 check_member( objinst, expect_objects[2], "%lu", dwSize );
2049 check_member_guid( objinst, expect_objects[2], guidType );
2050 check_member( objinst, expect_objects[2], "%#lx", dwOfs );
2051 check_member( objinst, expect_objects[2], "%#lx", dwType );
2052 check_member( objinst, expect_objects[2], "%#lx", dwFlags );
2053 if (!localized) check_member_wstr( objinst, expect_objects[2], tszName );
2054 check_member( objinst, expect_objects[2], "%lu", dwFFMaxForce );
2055 check_member( objinst, expect_objects[2], "%lu", dwFFForceResolution );
2056 check_member( objinst, expect_objects[2], "%u", wCollectionNumber );
2057 check_member( objinst, expect_objects[2], "%u", wDesignatorIndex );
2058 check_member( objinst, expect_objects[2], "%#04x", wUsagePage );
2059 check_member( objinst, expect_objects[2], "%#04x", wUsage );
2060 check_member( objinst, expect_objects[2], "%#lx", dwDimension );
2061 check_member( objinst, expect_objects[2], "%#04x", wExponent );
2062 check_member( objinst, expect_objects[2], "%u", wReportId );
2065 hwnd = CreateWindowW( L"static", L"static", WS_POPUP | WS_VISIBLE,
2066 50, 50, 200, 200, NULL, NULL, NULL, NULL );
2067 ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() );
2069 hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_FOREGROUND );
2070 ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr );
2071 hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_FOREGROUND|DISCL_EXCLUSIVE );
2072 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
2073 hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_FOREGROUND|DISCL_NONEXCLUSIVE );
2074 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
2076 hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_BACKGROUND );
2077 ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr );
2078 hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_BACKGROUND|DISCL_EXCLUSIVE );
2079 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
2080 hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_BACKGROUND|DISCL_NONEXCLUSIVE );
2081 ok( hr == DI_OK, "SetCooperativeLevel returned %#lx\n", hr );
2083 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_FOREGROUND );
2084 ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr );
2085 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_FOREGROUND|DISCL_EXCLUSIVE );
2086 todo_wine_if( version == 0x500 )
2087 ok( hr == (version == 0x500 ? DIERR_INVALIDPARAM : DI_OK), "SetCooperativeLevel returned %#lx\n", hr );
2088 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_FOREGROUND|DISCL_NONEXCLUSIVE );
2089 ok( hr == DI_OK, "SetCooperativeLevel returned %#lx\n", hr );
2091 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND );
2092 ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr );
2093 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND|DISCL_EXCLUSIVE );
2094 todo_wine_if( version == 0x500 )
2095 ok( hr == (version == 0x500 ? DIERR_INVALIDPARAM : DIERR_UNSUPPORTED), "SetCooperativeLevel returned %#lx\n", hr );
2096 hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND|DISCL_NONEXCLUSIVE );
2097 ok( hr == DI_OK, "SetCooperativeLevel returned %#lx\n", hr );
2099 child = CreateWindowW( L"static", L"static", WS_CHILD | WS_VISIBLE,
2100 10, 10, 50, 50, hwnd, NULL, NULL, NULL );
2101 ok( !!child, "CreateWindowW failed, error %lu\n", GetLastError() );
2103 hr = IDirectInputDevice8_SetCooperativeLevel( device, child, DISCL_FOREGROUND );
2104 ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr );
2105 hr = IDirectInputDevice8_SetCooperativeLevel( device, child, DISCL_FOREGROUND|DISCL_EXCLUSIVE );
2106 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
2107 hr = IDirectInputDevice8_SetCooperativeLevel( device, child, DISCL_FOREGROUND|DISCL_NONEXCLUSIVE );
2108 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
2110 hr = IDirectInputDevice8_SetCooperativeLevel( device, child, DISCL_BACKGROUND );
2111 ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr );
2112 hr = IDirectInputDevice8_SetCooperativeLevel( device, child, DISCL_BACKGROUND|DISCL_EXCLUSIVE );
2113 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
2114 hr = IDirectInputDevice8_SetCooperativeLevel( device, child, DISCL_BACKGROUND|DISCL_NONEXCLUSIVE );
2115 ok( hr == E_HANDLE, "SetCooperativeLevel returned %#lx\n", hr );
2117 DestroyWindow( child );
2119 event = CreateEventW( NULL, FALSE, FALSE, NULL );
2120 ok( !!event, "CreateEventW failed, error %lu\n", GetLastError() );
2122 hkl = activate_keyboard_layout( MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), &old_hkl );
2123 if (LOWORD(hkl) != MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT)) goto skip_key_tests;
2125 hr = IDirectInputDevice8_SetEventNotification( device, event );
2126 ok( hr == DI_OK, "SetEventNotification returned %#lx\n", hr );
2127 hr = IDirectInputDevice8_SetDataFormat( device, &c_dfDIKeyboard );
2128 ok( hr == DI_OK, "SetDataFormat returned %#lx\n", hr );
2129 hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND );
2130 ok( hr == DI_OK, "SetCooperativeLevel returned %#lx\n", hr );
2131 hr = IDirectInputDevice8_GetDeviceState( device, 10, full_state );
2132 ok( hr == DIERR_NOTACQUIRED, "GetDeviceState returned %#lx\n", hr );
2133 hr = IDirectInputDevice8_GetDeviceState( device, sizeof(full_state), full_state );
2134 ok( hr == DIERR_NOTACQUIRED, "GetDeviceState returned %#lx\n", hr );
2135 hr = IDirectInputDevice8_Unacquire( device );
2136 ok( hr == DI_NOEFFECT, "Unacquire returned %#lx\n", hr );
2137 hr = IDirectInputDevice8_Acquire( device );
2138 ok( hr == DI_OK, "Acquire returned %#lx\n", hr );
2139 hr = IDirectInputDevice8_Acquire( device );
2140 ok( hr == DI_NOEFFECT, "Acquire returned %#lx\n", hr );
2141 hr = IDirectInputDevice8_GetDeviceState( device, 10, full_state );
2142 ok( hr == DIERR_INVALIDPARAM, "GetDeviceState returned %#lx\n", hr );
2143 hr = IDirectInputDevice8_GetDeviceState( device, sizeof(full_state), full_state );
2144 ok( hr == DI_OK, "GetDeviceState returned %#lx\n", hr );
2145 hr = IDirectInputDevice8_Unacquire( device );
2146 ok( hr == DI_OK, "Uncquire returned %#lx\n", hr );
2147 hr = IDirectInputDevice8_SetDataFormat( device, &data_format );
2148 ok( hr == DI_OK, "SetDataFormat returned %#lx\n", hr );
2149 hr = IDirectInputDevice8_Acquire( device );
2150 ok( hr == DI_OK, "Acquire returned %#lx\n", hr );
2151 hr = IDirectInputDevice8_GetDeviceState( device, sizeof(key_state), key_state );
2152 ok( hr == DI_OK, "GetDeviceState returned %#lx\n", hr );
2153 hr = IDirectInputDevice8_GetDeviceState( device, sizeof(full_state), full_state );
2154 ok( hr == DIERR_INVALIDPARAM, "GetDeviceState returned %#lx\n", hr );
2156 memset( key_state, 0x56, sizeof(key_state) );
2157 hr = IDirectInputDevice8_GetDeviceState( device, sizeof(key_state), key_state );
2158 ok( hr == DI_OK, "GetDeviceState returned %#lx\n", hr );
2159 ok( !memcmp( key_state, zero_state, sizeof(key_state) ), "got non zero state\n" );
2161 keybd_event( 'Q', 0, 0, 0 );
2162 res = WaitForSingleObject( event, 100 );
2163 if (res == WAIT_TIMEOUT) /* Acquire is asynchronous */
2165 keybd_event( 'Q', 0, 0, 0 );
2166 res = WaitForSingleObject( event, 5000 );
2168 ok( !res, "WaitForSingleObject returned %#lx\n", res );
2170 memset( key_state, 0xcd, sizeof(key_state) );
2171 hr = IDirectInputDevice8_GetDeviceState( device, sizeof(key_state), key_state );
2172 ok( hr == DI_OK, "GetDeviceState returned %#lx\n", hr );
2173 ok( key_state[0] == (version < 0x800 ? 0x80 : 0), "got key_state[0] %lu\n", key_state[0] );
2175 /* unacquiring should reset the device state */
2176 hr = IDirectInputDevice8_Unacquire( device );
2177 ok( hr == DI_OK, "Unacquire returned %#lx\n", hr );
2178 hr = IDirectInputDevice8_Acquire( device );
2179 ok( hr == DI_OK, "Acquire returned %#lx\n", hr );
2180 hr = IDirectInputDevice8_GetDeviceState( device, sizeof(key_state), key_state );
2181 ok( hr == DI_OK, "GetDeviceState returned %#lx\n", hr );
2182 ok( !memcmp( key_state, zero_state, sizeof(key_state) ), "got non zero state\n" );
2184 keybd_event( 'Q', 0, KEYEVENTF_KEYUP, 0 );
2186 hr = IDirectInputDevice8_Unacquire( device );
2187 ok( hr == DI_OK, "Unacquire returned %#lx\n", hr );
2189 skip_key_tests:
2190 ActivateKeyboardLayout( old_hkl, 0 );
2191 UnloadKeyboardLayout( hkl );
2193 test_dik_codes( device, event, hwnd );
2195 CloseHandle( event );
2196 DestroyWindow( hwnd );
2198 ref = IDirectInputDevice8_Release( device );
2199 ok( ref == 0, "Release returned %ld\n", ref );
2201 winetest_pop_context();
2202 localized = old_localized;
2205 START_TEST(device8)
2207 dinput_test_init();
2209 test_QueryInterface( 0x300 );
2210 test_QueryInterface( 0x500 );
2211 test_QueryInterface( 0x700 );
2212 test_QueryInterface( 0x800 );
2214 test_overlapped_format( 0x700 );
2215 test_overlapped_format( 0x800 );
2217 test_sys_mouse( 0x500 );
2218 test_sys_mouse( 0x700 );
2219 test_sys_mouse( 0x800 );
2221 test_sys_keyboard( 0x500 );
2222 test_sys_keyboard( 0x700 );
2223 test_sys_keyboard( 0x800 );
2225 test_mouse_keyboard();
2226 test_keyboard_events();
2227 test_appdata_property();
2229 dinput_test_exit();