dinput8/tests: Make input helper function more versatile.
[wine.git] / dlls / dinput8 / tests / device.c
blob02574961ec15c801638a3ecbd254569381b5fd4c
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 #define COBJMACROS
23 #include <windows.h>
25 #include "wine/test.h"
26 #include "windef.h"
27 #include "dinput.h"
29 struct enum_data {
30 IDirectInput8A *pDI;
31 DIACTIONFORMATA *lpdiaf;
32 IDirectInputDevice8A *keyboard;
33 IDirectInputDevice8A *mouse;
34 const char* username;
35 int ndevices;
38 /* Dummy GUID */
39 static const GUID ACTION_MAPPING_GUID = { 0x1, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
41 enum {
42 DITEST_AXIS,
43 DITEST_BUTTON,
44 DITEST_KEYBOARDSPACE,
45 DITEST_MOUSEBUTTON0,
46 DITEST_YAXIS
49 static DIACTIONA actionMapping[]=
51 /* axis */
52 { 0, 0x01008A01 /* DIAXIS_DRIVINGR_STEER */, 0, { "Steer.\0" } },
53 /* button */
54 { 1, 0x01000C01 /* DIBUTTON_DRIVINGR_SHIFTUP */, 0, { "Upshift.\0" } },
55 /* keyboard key */
56 { 2, DIKEYBOARD_SPACE, 0, { "Missile.\0" } },
57 /* mouse button */
58 { 3, DIMOUSE_BUTTON0, 0, { "Select\0" } },
59 /* mouse axis */
60 { 4, DIMOUSE_YAXIS, 0, { "Y Axis\0" } }
62 /* By placing the memory pointed to by lptszActionName right before memory with PAGE_NOACCESS
63 * one can find out that the regular ansi string termination is not respected by EnumDevicesBySemantics.
64 * Adding a double termination, making it a valid wide string termination, made the test succeed.
65 * Therefore it looks like ansi version of EnumDevicesBySemantics forwards the string to
66 * the wide variant without conversation. */
68 static void flush_events(void)
70 int diff = 200;
71 int min_timeout = 100;
72 DWORD time = GetTickCount() + diff;
74 while (diff > 0)
76 if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT)
77 break;
78 diff = time - GetTickCount();
79 min_timeout = 50;
83 static void test_device_input(IDirectInputDevice8A *lpdid, DWORD event_type, DWORD event, UINT_PTR expected)
85 HRESULT hr;
86 DIDEVICEOBJECTDATA obj_data;
87 DWORD data_size = 1;
88 int i;
90 hr = IDirectInputDevice8_Acquire(lpdid);
91 ok (SUCCEEDED(hr), "Failed to acquire device hr=%08x\n", hr);
93 if (event_type == INPUT_KEYBOARD)
94 keybd_event(event, MapVirtualKeyA(event, MAPVK_VK_TO_VSC), 0, 0);
96 if (event_type == INPUT_MOUSE)
97 mouse_event( event, 0, 0, 0, 0);
99 flush_events();
100 IDirectInputDevice8_Poll(lpdid);
101 hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0);
103 if (data_size != 1)
105 win_skip("We're not able to inject input into Windows dinput8 with events\n");
106 IDirectInputDevice_Unacquire(lpdid);
107 return;
110 ok (obj_data.uAppData == expected, "Retrieval of action failed uAppData=%lu expected=%lu\n", obj_data.uAppData, expected);
112 /* Check for buffer overflow */
113 for (i = 0; i < 17; i++)
114 if (event_type == INPUT_KEYBOARD)
116 keybd_event( VK_SPACE, DIK_SPACE, 0, 0);
117 keybd_event( VK_SPACE, DIK_SPACE, KEYEVENTF_KEYUP, 0);
119 else if (event_type == INPUT_MOUSE)
121 mouse_event(MOUSEEVENTF_LEFTDOWN, 1, 1, 0, 0);
122 mouse_event(MOUSEEVENTF_LEFTUP, 1, 1, 0, 0);
125 flush_events();
126 IDirectInputDevice8_Poll(lpdid);
128 data_size = 1;
129 hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0);
130 ok(hr == DI_BUFFEROVERFLOW, "GetDeviceData() failed: %08x\n", hr);
131 data_size = 1;
132 hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0);
133 ok(hr == DI_OK && data_size == 1, "GetDeviceData() failed: %08x cnt:%d\n", hr, data_size);
135 /* drain device's queue */
136 while (data_size == 1)
138 hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0);
139 ok(hr == DI_OK, "GetDeviceData() failed: %08x cnt:%d\n", hr, data_size);
140 if (hr != DI_OK) break;
143 IDirectInputDevice_Unacquire(lpdid);
146 static void test_build_action_map(IDirectInputDevice8A *lpdid, DIACTIONFORMATA *lpdiaf,
147 int action_index, DWORD expected_type, DWORD expected_inst)
149 HRESULT hr;
150 DIACTIONA *actions;
151 DWORD instance, type, how;
152 GUID assigned_to;
153 DIDEVICEINSTANCEA ddi;
155 ddi.dwSize = sizeof(ddi);
156 IDirectInputDevice_GetDeviceInfo(lpdid, &ddi);
158 hr = IDirectInputDevice8_BuildActionMap(lpdid, lpdiaf, NULL, DIDBAM_HWDEFAULTS);
159 ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);
161 actions = lpdiaf->rgoAction;
162 instance = DIDFT_GETINSTANCE(actions[action_index].dwObjID);
163 type = DIDFT_GETTYPE(actions[action_index].dwObjID);
164 how = actions[action_index].dwHow;
165 assigned_to = actions[action_index].guidInstance;
167 ok (how == DIAH_USERCONFIG || how == DIAH_DEFAULT, "Action was not set dwHow=%08x\n", how);
168 ok (instance == expected_inst, "Action not mapped correctly instance=%08x expected=%08x\n", instance, expected_inst);
169 ok (type == expected_type, "Action type not mapped correctly type=%08x expected=%08x\n", type, expected_type);
170 ok (IsEqualGUID(&assigned_to, &ddi.guidInstance), "Action and device GUID do not match action=%d\n", action_index);
173 static BOOL CALLBACK enumeration_callback(const DIDEVICEINSTANCEA *lpddi, IDirectInputDevice8A *lpdid,
174 DWORD dwFlags, DWORD dwRemaining, LPVOID pvRef)
176 HRESULT hr;
177 DIPROPDWORD dp;
178 DIPROPRANGE dpr;
179 DIPROPSTRING dps;
180 WCHAR usernameW[MAX_PATH];
181 DWORD username_size = MAX_PATH;
182 struct enum_data *data = pvRef;
183 DWORD cnt;
184 DIDEVICEOBJECTDATA buffer[5];
185 IDirectInputDevice8A *lpdid2;
187 if (!data) return DIENUM_CONTINUE;
189 data->ndevices++;
191 /* Convert username to WCHAR */
192 if (data->username != NULL)
194 username_size = MultiByteToWideChar(CP_ACP, 0, data->username, -1, usernameW, 0);
195 MultiByteToWideChar(CP_ACP, 0, data->username, -1, usernameW, username_size);
197 else
198 GetUserNameW(usernameW, &username_size);
200 /* collect the mouse and keyboard */
201 if (IsEqualGUID(&lpddi->guidInstance, &GUID_SysKeyboard))
203 IDirectInputDevice_AddRef(lpdid);
204 data->keyboard = lpdid;
206 ok (dwFlags & DIEDBS_MAPPEDPRI1, "Keyboard should be mapped as pri1 dwFlags=%08x\n", dwFlags);
209 if (IsEqualGUID(&lpddi->guidInstance, &GUID_SysMouse))
211 IDirectInputDevice_AddRef(lpdid);
212 data->mouse = lpdid;
214 ok (dwFlags & DIEDBS_MAPPEDPRI1, "Mouse should be mapped as pri1 dwFlags=%08x\n", dwFlags);
217 /* Creating second device object to check if it has the same username */
218 hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidInstance, &lpdid2, NULL);
219 ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
221 /* Building and setting an action map */
222 /* It should not use any pre-stored mappings so we use DIDBAM_HWDEFAULTS */
223 hr = IDirectInputDevice8_BuildActionMap(lpdid, data->lpdiaf, NULL, DIDBAM_HWDEFAULTS);
224 ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);
226 /* Device has no data format and thus can't be acquired */
227 hr = IDirectInputDevice8_Acquire(lpdid);
228 ok (hr == DIERR_INVALIDPARAM, "Device was acquired before SetActionMap hr=%08x\n", hr);
230 hr = IDirectInputDevice8_SetActionMap(lpdid, data->lpdiaf, data->username, 0);
231 ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr);
233 /* Some joysticks may have no suitable actions and thus should not be tested */
234 if (hr == DI_NOEFFECT) return DIENUM_CONTINUE;
236 /* Test username after SetActionMap */
237 dps.diph.dwSize = sizeof(dps);
238 dps.diph.dwHeaderSize = sizeof(DIPROPHEADER);
239 dps.diph.dwObj = 0;
240 dps.diph.dwHow = DIPH_DEVICE;
241 dps.wsz[0] = '\0';
243 hr = IDirectInputDevice_GetProperty(lpdid, DIPROP_USERNAME, &dps.diph);
244 ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr);
245 ok (!lstrcmpW(usernameW, dps.wsz), "Username not set correctly expected=%s, got=%s\n", wine_dbgstr_w(usernameW), wine_dbgstr_w(dps.wsz));
247 dps.wsz[0] = '\0';
248 hr = IDirectInputDevice_GetProperty(lpdid2, DIPROP_USERNAME, &dps.diph);
249 ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr);
250 ok (!lstrcmpW(usernameW, dps.wsz), "Username not set correctly expected=%s, got=%s\n", wine_dbgstr_w(usernameW), wine_dbgstr_w(dps.wsz));
252 /* Test buffer size */
253 memset(&dp, 0, sizeof(dp));
254 dp.diph.dwSize = sizeof(dp);
255 dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
256 dp.diph.dwHow = DIPH_DEVICE;
258 hr = IDirectInputDevice_GetProperty(lpdid, DIPROP_BUFFERSIZE, &dp.diph);
259 ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr);
260 ok (dp.dwData == data->lpdiaf->dwBufferSize, "SetActionMap must set the buffer, buffersize=%d\n", dp.dwData);
262 cnt = 1;
263 hr = IDirectInputDevice_GetDeviceData(lpdid, sizeof(buffer[0]), buffer, &cnt, 0);
264 ok(hr == DIERR_NOTACQUIRED, "GetDeviceData() failed hr=%08x\n", hr);
266 /* Test axis range */
267 memset(&dpr, 0, sizeof(dpr));
268 dpr.diph.dwSize = sizeof(dpr);
269 dpr.diph.dwHeaderSize = sizeof(DIPROPHEADER);
270 dpr.diph.dwHow = DIPH_DEVICE;
272 hr = IDirectInputDevice_GetProperty(lpdid, DIPROP_RANGE, &dpr.diph);
273 /* Only test if device supports the range property */
274 if (SUCCEEDED(hr))
276 ok (dpr.lMin == data->lpdiaf->lAxisMin, "SetActionMap must set the min axis range expected=%d got=%d\n", data->lpdiaf->lAxisMin, dpr.lMin);
277 ok (dpr.lMax == data->lpdiaf->lAxisMax, "SetActionMap must set the max axis range expected=%d got=%d\n", data->lpdiaf->lAxisMax, dpr.lMax);
280 /* SetActionMap has set the data format so now it should work */
281 hr = IDirectInputDevice8_Acquire(lpdid);
282 ok (SUCCEEDED(hr), "Acquire failed hr=%08x\n", hr);
284 cnt = 1;
285 hr = IDirectInputDevice_GetDeviceData(lpdid, sizeof(buffer[0]), buffer, &cnt, 0);
286 ok(hr == DI_OK, "GetDeviceData() failed hr=%08x\n", hr);
288 /* SetActionMap should not work on an acquired device */
289 hr = IDirectInputDevice8_SetActionMap(lpdid, data->lpdiaf, NULL, 0);
290 ok (hr == DIERR_ACQUIRED, "SetActionMap succeeded with an acquired device hr=%08x\n", hr);
292 IDirectInputDevice_Release(lpdid2);
294 return DIENUM_CONTINUE;
297 static void test_action_mapping(void)
299 HRESULT hr;
300 HINSTANCE hinst = GetModuleHandleA(NULL);
301 IDirectInput8A *pDI = NULL;
302 DIACTIONFORMATA af;
303 DIPROPSTRING dps;
304 struct enum_data data = {pDI, &af, NULL, NULL, NULL, 0};
305 HWND hwnd;
307 hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&pDI);
308 if (hr == DIERR_OLDDIRECTINPUTVERSION ||
309 hr == DIERR_BETADIRECTINPUTVERSION ||
310 hr == REGDB_E_CLASSNOTREG)
312 win_skip("ActionMapping requires dinput8\n");
313 return;
315 ok(SUCCEEDED(hr), "DirectInput8 Create failed: hr=%08x\n", hr);
316 if (FAILED(hr)) return;
318 hr = IDirectInput8_Initialize(pDI,hinst, DIRECTINPUT_VERSION);
319 if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION)
321 win_skip("ActionMapping requires dinput8\n");
322 return;
324 ok(SUCCEEDED(hr), "DirectInput8 Initialize failed: hr=%08x\n", hr);
325 if (FAILED(hr)) return;
327 memset (&af, 0, sizeof(af));
328 af.dwSize = sizeof(af);
329 af.dwActionSize = sizeof(DIACTIONA);
330 af.dwDataSize = 4 * ARRAY_SIZE(actionMapping);
331 af.dwNumActions = ARRAY_SIZE(actionMapping);
332 af.rgoAction = actionMapping;
333 af.guidActionMap = ACTION_MAPPING_GUID;
334 af.dwGenre = 0x01000000; /* DIVIRTUAL_DRIVING_RACE */
335 af.dwBufferSize = 32;
337 /* This enumeration builds and sets the action map for all devices */
338 data.pDI = pDI;
339 hr = IDirectInput8_EnumDevicesBySemantics(pDI, 0, &af, enumeration_callback, &data, DIEDBSFL_ATTACHEDONLY);
340 ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);
342 if (data.keyboard)
343 IDirectInputDevice_Release(data.keyboard);
345 if (data.mouse)
346 IDirectInputDevice_Release(data.mouse);
348 /* Repeat tests with a non NULL user */
349 data.username = "Ninja Brian";
350 hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &af, enumeration_callback, &data, DIEDBSFL_ATTACHEDONLY);
351 ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);
353 hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput",
354 WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL);
355 ok(hwnd != NULL, "failed to create window\n");
356 SetCursorPos(50, 50);
358 if (data.keyboard != NULL)
360 /* Test keyboard BuildActionMap */
361 test_build_action_map(data.keyboard, data.lpdiaf, DITEST_KEYBOARDSPACE, DIDFT_PSHBUTTON, DIK_SPACE);
362 /* Test keyboard input */
363 test_device_input(data.keyboard, INPUT_KEYBOARD, VK_SPACE, 2);
365 /* Test BuildActionMap with no suitable actions for a device */
366 IDirectInputDevice_Unacquire(data.keyboard);
367 af.dwDataSize = 4 * DITEST_KEYBOARDSPACE;
368 af.dwNumActions = DITEST_KEYBOARDSPACE;
370 hr = IDirectInputDevice8_BuildActionMap(data.keyboard, data.lpdiaf, NULL, DIDBAM_HWDEFAULTS);
371 ok (hr == DI_NOEFFECT, "BuildActionMap should have no effect with no actions hr=%08x\n", hr);
373 hr = IDirectInputDevice8_SetActionMap(data.keyboard, data.lpdiaf, NULL, 0);
374 ok (hr == DI_NOEFFECT, "SetActionMap should have no effect with no actions to map hr=%08x\n", hr);
376 af.dwDataSize = 4 * ARRAY_SIZE(actionMapping);
377 af.dwNumActions = ARRAY_SIZE(actionMapping);
379 /* test DIDSAM_NOUSER */
380 dps.diph.dwSize = sizeof(dps);
381 dps.diph.dwHeaderSize = sizeof(DIPROPHEADER);
382 dps.diph.dwObj = 0;
383 dps.diph.dwHow = DIPH_DEVICE;
384 dps.wsz[0] = '\0';
386 hr = IDirectInputDevice_GetProperty(data.keyboard, DIPROP_USERNAME, &dps.diph);
387 ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr);
388 ok (dps.wsz[0] != 0, "Expected any username, got=%s\n", wine_dbgstr_w(dps.wsz));
390 hr = IDirectInputDevice8_SetActionMap(data.keyboard, data.lpdiaf, NULL, DIDSAM_NOUSER);
391 ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr);
393 dps.diph.dwSize = sizeof(dps);
394 dps.diph.dwHeaderSize = sizeof(DIPROPHEADER);
395 dps.diph.dwObj = 0;
396 dps.diph.dwHow = DIPH_DEVICE;
397 dps.wsz[0] = '\0';
399 hr = IDirectInputDevice_GetProperty(data.keyboard, DIPROP_USERNAME, &dps.diph);
400 ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr);
401 ok (dps.wsz[0] == 0, "Expected empty username, got=%s\n", wine_dbgstr_w(dps.wsz));
403 IDirectInputDevice_Release(data.keyboard);
406 if (data.mouse != NULL)
408 /* Test mouse BuildActionMap */
409 test_build_action_map(data.mouse, data.lpdiaf, DITEST_MOUSEBUTTON0, DIDFT_PSHBUTTON, 0x03);
410 test_build_action_map(data.mouse, data.lpdiaf, DITEST_YAXIS, DIDFT_RELAXIS, 0x01);
412 test_device_input(data.mouse, INPUT_MOUSE, MOUSEEVENTF_LEFTDOWN, 3);
414 IDirectInputDevice_Release(data.mouse);
417 DestroyWindow(hwnd);
418 IDirectInput_Release(pDI);
421 static void test_save_settings(void)
423 HRESULT hr;
424 HINSTANCE hinst = GetModuleHandleA(NULL);
425 IDirectInput8A *pDI = NULL;
426 DIACTIONFORMATA af;
427 IDirectInputDevice8A *pKey;
429 static const GUID mapping_guid = { 0xcafecafe, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
430 static const GUID other_guid = { 0xcafe, 0xcafe, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
432 static DIACTIONA actions[] = {
433 { 0, DIKEYBOARD_A , 0, { "Blam" } },
434 { 1, DIKEYBOARD_B , 0, { "Kapow"} }
436 static const DWORD results[] = {
437 DIDFT_MAKEINSTANCE(DIK_A) | DIDFT_PSHBUTTON,
438 DIDFT_MAKEINSTANCE(DIK_B) | DIDFT_PSHBUTTON
440 static const DWORD other_results[] = {
441 DIDFT_MAKEINSTANCE(DIK_C) | DIDFT_PSHBUTTON,
442 DIDFT_MAKEINSTANCE(DIK_D) | DIDFT_PSHBUTTON
445 hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&pDI);
446 if (hr == DIERR_OLDDIRECTINPUTVERSION ||
447 hr == DIERR_BETADIRECTINPUTVERSION ||
448 hr == REGDB_E_CLASSNOTREG)
450 win_skip("ActionMapping requires dinput8\n");
451 return;
453 ok (SUCCEEDED(hr), "DirectInput8 Create failed: hr=%08x\n", hr);
454 if (FAILED(hr)) return;
456 hr = IDirectInput8_Initialize(pDI,hinst, DIRECTINPUT_VERSION);
457 if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION)
459 win_skip("ActionMapping requires dinput8\n");
460 return;
462 ok (SUCCEEDED(hr), "DirectInput8 Initialize failed: hr=%08x\n", hr);
463 if (FAILED(hr)) return;
465 hr = IDirectInput_CreateDevice(pDI, &GUID_SysKeyboard, &pKey, NULL);
466 ok (SUCCEEDED(hr), "IDirectInput_Create device failed hr: 0x%08x\n", hr);
467 if (FAILED(hr)) return;
469 memset (&af, 0, sizeof(af));
470 af.dwSize = sizeof(af);
471 af.dwActionSize = sizeof(DIACTIONA);
472 af.dwDataSize = 4 * ARRAY_SIZE(actions);
473 af.dwNumActions = ARRAY_SIZE(actions);
474 af.rgoAction = actions;
475 af.guidActionMap = mapping_guid;
476 af.dwGenre = 0x01000000; /* DIVIRTUAL_DRIVING_RACE */
477 af.dwBufferSize = 32;
479 /* Easy case. Ask for default mapping, save, ask for previous map and read it back */
480 hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, DIDBAM_HWDEFAULTS);
481 ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);
482 ok (results[0] == af.rgoAction[0].dwObjID,
483 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[0], af.rgoAction[0].dwObjID);
485 ok (results[1] == af.rgoAction[1].dwObjID,
486 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[1], af.rgoAction[1].dwObjID);
488 hr = IDirectInputDevice8_SetActionMap(pKey, &af, NULL, DIDSAM_FORCESAVE);
489 ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr);
491 if (hr == DI_SETTINGSNOTSAVED)
493 skip ("Can't test saving settings if SetActionMap returns DI_SETTINGSNOTSAVED\n");
494 return;
497 af.rgoAction[0].dwObjID = 0;
498 af.rgoAction[1].dwObjID = 0;
499 memset(&af.rgoAction[0].guidInstance, 0, sizeof(GUID));
500 memset(&af.rgoAction[1].guidInstance, 0, sizeof(GUID));
502 hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, 0);
503 ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);
505 ok (results[0] == af.rgoAction[0].dwObjID,
506 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[0], af.rgoAction[0].dwObjID);
507 ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[0].guidInstance), "Action should be mapped to keyboard\n");
509 ok (results[1] == af.rgoAction[1].dwObjID,
510 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[1], af.rgoAction[1].dwObjID);
511 ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[1].guidInstance), "Action should be mapped to keyboard\n");
513 /* Test that a different action map with no pre-stored settings, in spite of the flags,
514 does not try to load mappings and instead applies the default mapping */
515 af.guidActionMap = other_guid;
517 af.rgoAction[0].dwObjID = 0;
518 af.rgoAction[1].dwObjID = 0;
519 memset(&af.rgoAction[0].guidInstance, 0, sizeof(GUID));
520 memset(&af.rgoAction[1].guidInstance, 0, sizeof(GUID));
522 hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, 0);
523 ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);
525 ok (results[0] == af.rgoAction[0].dwObjID,
526 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[0], af.rgoAction[0].dwObjID);
527 ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[0].guidInstance), "Action should be mapped to keyboard\n");
529 ok (results[1] == af.rgoAction[1].dwObjID,
530 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[1], af.rgoAction[1].dwObjID);
531 ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[1].guidInstance), "Action should be mapped to keyboard\n");
533 af.guidActionMap = mapping_guid;
534 /* Hard case. Customized mapping, save, ask for previous map and read it back */
535 af.rgoAction[0].dwObjID = other_results[0];
536 af.rgoAction[0].dwHow = DIAH_USERCONFIG;
537 af.rgoAction[0].guidInstance = GUID_SysKeyboard;
538 af.rgoAction[1].dwObjID = other_results[1];
539 af.rgoAction[1].dwHow = DIAH_USERCONFIG;
540 af.rgoAction[1].guidInstance = GUID_SysKeyboard;
542 hr = IDirectInputDevice8_SetActionMap(pKey, &af, NULL, DIDSAM_FORCESAVE);
543 ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr);
545 if (hr == DI_SETTINGSNOTSAVED)
547 skip ("Can't test saving settings if SetActionMap returns DI_SETTINGSNOTSAVED\n");
548 return;
551 af.rgoAction[0].dwObjID = 0;
552 af.rgoAction[1].dwObjID = 0;
553 memset(&af.rgoAction[0].guidInstance, 0, sizeof(GUID));
554 memset(&af.rgoAction[1].guidInstance, 0, sizeof(GUID));
556 hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, 0);
557 ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);
559 ok (other_results[0] == af.rgoAction[0].dwObjID,
560 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", other_results[0], af.rgoAction[0].dwObjID);
561 ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[0].guidInstance), "Action should be mapped to keyboard\n");
563 ok (other_results[1] == af.rgoAction[1].dwObjID,
564 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", other_results[1], af.rgoAction[1].dwObjID);
565 ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[1].guidInstance), "Action should be mapped to keyboard\n");
567 IDirectInputDevice_Release(pKey);
568 IDirectInput_Release(pDI);
571 static void test_mouse_keyboard(void)
573 HRESULT hr;
574 HWND hwnd, di_hwnd = INVALID_HANDLE_VALUE;
575 IDirectInput8A *di = NULL;
576 IDirectInputDevice8A *di_mouse, *di_keyboard;
577 UINT raw_devices_count;
578 RAWINPUTDEVICE raw_devices[3];
580 hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput", WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL);
581 ok(hwnd != NULL, "CreateWindowExA failed\n");
583 hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&di);
584 if (hr == DIERR_OLDDIRECTINPUTVERSION ||
585 hr == DIERR_BETADIRECTINPUTVERSION ||
586 hr == REGDB_E_CLASSNOTREG)
588 win_skip("test_mouse_keyboard requires dinput8\n");
589 return;
591 ok(SUCCEEDED(hr), "DirectInput8Create failed: %08x\n", hr);
593 hr = IDirectInput8_Initialize(di, GetModuleHandleA(NULL), DIRECTINPUT_VERSION);
594 if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION)
596 win_skip("test_mouse_keyboard requires dinput8\n");
597 return;
599 ok(SUCCEEDED(hr), "IDirectInput8_Initialize failed: %08x\n", hr);
601 hr = IDirectInput8_CreateDevice(di, &GUID_SysMouse, &di_mouse, NULL);
602 ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %08x\n", hr);
603 hr = IDirectInputDevice8_SetDataFormat(di_mouse, &c_dfDIMouse);
604 ok(SUCCEEDED(hr), "IDirectInputDevice8_SetDataFormat failed: %08x\n", hr);
606 hr = IDirectInput8_CreateDevice(di, &GUID_SysKeyboard, &di_keyboard, NULL);
607 ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %08x\n", hr);
608 hr = IDirectInputDevice8_SetDataFormat(di_keyboard, &c_dfDIKeyboard);
609 ok(SUCCEEDED(hr), "IDirectInputDevice8_SetDataFormat failed: %08x\n", hr);
611 raw_devices_count = ARRAY_SIZE(raw_devices);
612 GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
613 ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
615 hr = IDirectInputDevice8_Acquire(di_keyboard);
616 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
617 raw_devices_count = ARRAY_SIZE(raw_devices);
618 memset(raw_devices, 0, sizeof(raw_devices));
619 hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
620 todo_wine
621 ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
622 todo_wine
623 ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
624 todo_wine
625 ok(raw_devices[0].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
626 todo_wine
627 ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
628 todo_wine
629 ok(raw_devices[0].hwndTarget != NULL, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
630 hr = IDirectInputDevice8_Unacquire(di_keyboard);
631 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
632 raw_devices_count = ARRAY_SIZE(raw_devices);
633 GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
634 ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
636 if (raw_devices[0].hwndTarget != NULL)
638 WCHAR str[16];
639 int i;
641 di_hwnd = raw_devices[0].hwndTarget;
642 i = GetClassNameW(di_hwnd, str, ARRAY_SIZE(str));
643 ok(i == lstrlenW(L"DIEmWin"), "GetClassName returned incorrect length\n");
644 ok(!lstrcmpW(L"DIEmWin", str), "GetClassName returned incorrect name for this window's class\n");
646 i = GetWindowTextW(di_hwnd, str, ARRAY_SIZE(str));
647 ok(i == lstrlenW(L"DIEmWin"), "GetClassName returned incorrect length\n");
648 ok(!lstrcmpW(L"DIEmWin", str), "GetClassName returned incorrect name for this window's class\n");
651 hr = IDirectInputDevice8_Acquire(di_mouse);
652 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
653 raw_devices_count = ARRAY_SIZE(raw_devices);
654 memset(raw_devices, 0, sizeof(raw_devices));
655 hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
656 ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
657 ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
658 ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
659 ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
660 todo_wine
661 ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
662 hr = IDirectInputDevice8_Unacquire(di_mouse);
663 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
664 raw_devices_count = ARRAY_SIZE(raw_devices);
665 GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
666 ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
668 if (raw_devices[0].hwndTarget != NULL)
669 di_hwnd = raw_devices[0].hwndTarget;
671 /* expect dinput8 to take over any activated raw input devices */
672 raw_devices[0].usUsagePage = 0x01;
673 raw_devices[0].usUsage = 0x05;
674 raw_devices[0].dwFlags = 0;
675 raw_devices[0].hwndTarget = hwnd;
676 raw_devices[1].usUsagePage = 0x01;
677 raw_devices[1].usUsage = 0x06;
678 raw_devices[1].dwFlags = 0;
679 raw_devices[1].hwndTarget = hwnd;
680 raw_devices[2].usUsagePage = 0x01;
681 raw_devices[2].usUsage = 0x02;
682 raw_devices[2].dwFlags = 0;
683 raw_devices[2].hwndTarget = hwnd;
684 raw_devices_count = ARRAY_SIZE(raw_devices);
685 hr = RegisterRawInputDevices(raw_devices, raw_devices_count, sizeof(RAWINPUTDEVICE));
686 ok(hr == TRUE, "RegisterRawInputDevices failed\n");
688 hr = IDirectInputDevice8_Acquire(di_keyboard);
689 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
690 hr = IDirectInputDevice8_Acquire(di_mouse);
691 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
692 raw_devices_count = ARRAY_SIZE(raw_devices);
693 memset(raw_devices, 0, sizeof(raw_devices));
694 hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
695 ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
696 ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
697 ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
698 ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
699 ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
700 ok(raw_devices[1].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage);
701 ok(raw_devices[1].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage);
702 ok(raw_devices[1].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags);
703 ok(raw_devices[1].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget);
704 ok(raw_devices[2].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage);
705 ok(raw_devices[2].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage);
706 todo_wine
707 ok(raw_devices[2].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags);
708 todo_wine
709 ok(raw_devices[2].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget);
710 hr = IDirectInputDevice8_Unacquire(di_keyboard);
711 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
712 hr = IDirectInputDevice8_Unacquire(di_mouse);
713 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
714 raw_devices_count = ARRAY_SIZE(raw_devices);
715 GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
716 todo_wine
717 ok(raw_devices_count == 1, "Unexpected raw devices registered: %d\n", raw_devices_count);
719 IDirectInputDevice8_SetCooperativeLevel(di_mouse, hwnd, DISCL_FOREGROUND|DISCL_EXCLUSIVE);
720 IDirectInputDevice8_SetCooperativeLevel(di_keyboard, hwnd, DISCL_FOREGROUND|DISCL_EXCLUSIVE);
722 hr = IDirectInputDevice8_Acquire(di_keyboard);
723 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
724 hr = IDirectInputDevice8_Acquire(di_mouse);
725 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
726 raw_devices_count = ARRAY_SIZE(raw_devices);
727 memset(raw_devices, 0, sizeof(raw_devices));
728 hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
729 ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
730 ok(raw_devices[0].dwFlags == (RIDEV_CAPTUREMOUSE|RIDEV_NOLEGACY), "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
731 todo_wine
732 ok(raw_devices[2].dwFlags == (RIDEV_NOHOTKEYS|RIDEV_NOLEGACY), "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags);
733 hr = IDirectInputDevice8_Unacquire(di_keyboard);
734 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
735 hr = IDirectInputDevice8_Unacquire(di_mouse);
736 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
738 raw_devices_count = ARRAY_SIZE(raw_devices);
739 hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
740 todo_wine
741 ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
742 ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
743 ok(raw_devices[0].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
744 ok(raw_devices[0].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
745 ok(raw_devices[0].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
747 IDirectInputDevice8_Release(di_mouse);
748 IDirectInputDevice8_Release(di_keyboard);
749 IDirectInput8_Release(di);
751 DestroyWindow(hwnd);
754 static void test_keyboard_events(void)
756 HRESULT hr;
757 HWND hwnd = INVALID_HANDLE_VALUE;
758 IDirectInput8A *di;
759 IDirectInputDevice8A *di_keyboard;
760 DIPROPDWORD dp;
761 DIDEVICEOBJECTDATA obj_data[10];
762 DWORD data_size;
763 BYTE kbdata[256];
765 hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&di);
766 if (hr == DIERR_OLDDIRECTINPUTVERSION ||
767 hr == DIERR_BETADIRECTINPUTVERSION ||
768 hr == REGDB_E_CLASSNOTREG)
770 win_skip("test_keyboard_events requires dinput8\n");
771 return;
773 ok(SUCCEEDED(hr), "DirectInput8Create failed: %08x\n", hr);
775 hr = IDirectInput8_Initialize(di, GetModuleHandleA(NULL), DIRECTINPUT_VERSION);
776 if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION)
778 win_skip("test_keyboard_events requires dinput8\n");
779 IDirectInput8_Release(di);
780 return;
782 ok(SUCCEEDED(hr), "IDirectInput8_Initialize failed: %08x\n", hr);
784 hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput", WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL);
785 ok(hwnd != NULL, "CreateWindowExA failed\n");
787 hr = IDirectInput8_CreateDevice(di, &GUID_SysKeyboard, &di_keyboard, NULL);
788 ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %08x\n", hr);
789 hr = IDirectInputDevice8_SetCooperativeLevel(di_keyboard, hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
790 ok(SUCCEEDED(hr), "IDirectInput8_SetCooperativeLevel failed: %08x\n", hr);
791 hr = IDirectInputDevice8_SetDataFormat(di_keyboard, &c_dfDIKeyboard);
792 ok(SUCCEEDED(hr), "IDirectInputDevice8_SetDataFormat failed: %08x\n", hr);
793 dp.diph.dwSize = sizeof(DIPROPDWORD);
794 dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
795 dp.diph.dwObj = 0;
796 dp.diph.dwHow = DIPH_DEVICE;
797 dp.dwData = ARRAY_SIZE(obj_data);
798 IDirectInputDevice8_SetProperty(di_keyboard, DIPROP_BUFFERSIZE, &(dp.diph));
800 hr = IDirectInputDevice8_Acquire(di_keyboard);
801 ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
803 /* Test injecting keyboard events with both VK and scancode given. */
804 keybd_event(VK_SPACE, DIK_SPACE, 0, 0);
805 flush_events();
806 IDirectInputDevice8_Poll(di_keyboard);
807 data_size = ARRAY_SIZE(obj_data);
808 hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0);
809 ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr);
810 ok(data_size == 1, "Expected 1 element, received %d\n", data_size);
812 hr = IDirectInputDevice8_GetDeviceState(di_keyboard, sizeof(kbdata), kbdata);
813 ok(SUCCEEDED(hr), "IDirectInputDevice8_GetDeviceState failed: %08x\n", hr);
814 ok(kbdata[DIK_SPACE], "Expected DIK_SPACE key state down\n");
816 keybd_event(VK_SPACE, DIK_SPACE, KEYEVENTF_KEYUP, 0);
817 flush_events();
818 IDirectInputDevice8_Poll(di_keyboard);
819 data_size = ARRAY_SIZE(obj_data);
820 hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0);
821 ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr);
822 ok(data_size == 1, "Expected 1 element, received %d\n", data_size);
824 /* Test injecting keyboard events with scancode=0.
825 * Windows DInput ignores the VK, sets scancode 0 to be pressed, and GetDeviceData returns no elements. */
826 keybd_event(VK_SPACE, 0, 0, 0);
827 flush_events();
828 IDirectInputDevice8_Poll(di_keyboard);
829 data_size = ARRAY_SIZE(obj_data);
830 hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0);
831 ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr);
832 ok(data_size == 0, "Expected 0 elements, received %d\n", data_size);
834 hr = IDirectInputDevice8_GetDeviceState(di_keyboard, sizeof(kbdata), kbdata);
835 ok(SUCCEEDED(hr), "IDirectInputDevice8_GetDeviceState failed: %08x\n", hr);
836 todo_wine
837 ok(kbdata[0], "Expected key 0 state down\n");
839 keybd_event(VK_SPACE, 0, KEYEVENTF_KEYUP, 0);
840 flush_events();
841 IDirectInputDevice8_Poll(di_keyboard);
842 data_size = ARRAY_SIZE(obj_data);
843 hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0);
844 ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr);
845 ok(data_size == 0, "Expected 0 elements, received %d\n", data_size);
847 hr = IDirectInputDevice8_Unacquire(di_keyboard);
848 ok(SUCCEEDED(hr), "IDirectInputDevice8_Unacquire failed: %08x\n", hr);
850 IDirectInputDevice8_Release(di_keyboard);
851 IDirectInput8_Release(di);
853 DestroyWindow(hwnd);
856 START_TEST(device)
858 CoInitialize(NULL);
860 test_action_mapping();
861 test_save_settings();
862 test_mouse_keyboard();
863 test_keyboard_events();
865 CoUninitialize();