Assorted spelling fixes.
[wine.git] / dlls / dinput8 / tests / device.c
blob6495559bce8fc127a9044888304e322181d253fb
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" } },
53 /* button */
54 { 1, 0x01000C01 /* DIBUTTON_DRIVINGR_SHIFTUP */ , 0, { "Upshift" } },
55 /* keyboard key */
56 { 2, DIKEYBOARD_SPACE , 0, { "Missile" } },
57 /* mouse button */
58 { 3, DIMOUSE_BUTTON0, 0, { "Select" } },
59 /* mouse axis */
60 { 4, DIMOUSE_YAXIS, 0, { "Y Axis" } }
63 static void flush_events(void)
65 int diff = 200;
66 int min_timeout = 100;
67 DWORD time = GetTickCount() + diff;
69 while (diff > 0)
71 if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT)
72 break;
73 diff = time - GetTickCount();
74 min_timeout = 50;
78 static void test_device_input(IDirectInputDevice8A *lpdid, DWORD event_type, DWORD event, DWORD expected)
80 HRESULT hr;
81 DIDEVICEOBJECTDATA obj_data;
82 DWORD data_size = 1;
83 int i;
85 hr = IDirectInputDevice8_Acquire(lpdid);
86 ok (SUCCEEDED(hr), "Failed to acquire device hr=%08x\n", hr);
88 if (event_type == INPUT_KEYBOARD)
89 keybd_event( event, DIK_SPACE, 0, 0);
91 if (event_type == INPUT_MOUSE)
92 mouse_event( event, 0, 0, 0, 0);
94 flush_events();
95 IDirectInputDevice8_Poll(lpdid);
96 hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0);
98 if (data_size != 1)
100 win_skip("We're not able to inject input into Windows dinput8 with events\n");
101 IDirectInputDevice_Unacquire(lpdid);
102 return;
105 ok (obj_data.uAppData == expected, "Retrieval of action failed uAppData=%lu expected=%d\n", obj_data.uAppData, expected);
107 /* Check for buffer owerflow */
108 for (i = 0; i < 17; i++)
109 if (event_type == INPUT_KEYBOARD)
111 keybd_event( VK_SPACE, DIK_SPACE, 0, 0);
112 keybd_event( VK_SPACE, DIK_SPACE, KEYEVENTF_KEYUP, 0);
114 else if (event_type == INPUT_MOUSE)
116 mouse_event(MOUSEEVENTF_LEFTDOWN, 1, 1, 0, 0);
117 mouse_event(MOUSEEVENTF_LEFTUP, 1, 1, 0, 0);
120 flush_events();
121 IDirectInputDevice8_Poll(lpdid);
123 data_size = 1;
124 hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0);
125 ok(hr == DI_BUFFEROVERFLOW, "GetDeviceData() failed: %08x\n", hr);
126 data_size = 1;
127 hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0);
128 ok(hr == DI_OK && data_size == 1, "GetDeviceData() failed: %08x cnt:%d\n", hr, data_size);
130 IDirectInputDevice_Unacquire(lpdid);
133 static void test_build_action_map(IDirectInputDevice8A *lpdid, DIACTIONFORMATA *lpdiaf,
134 int action_index, DWORD expected_type, DWORD expected_inst)
136 HRESULT hr;
137 DIACTIONA *actions;
138 DWORD instance, type, how;
139 GUID assigned_to;
140 DIDEVICEINSTANCEA ddi;
142 ddi.dwSize = sizeof(ddi);
143 IDirectInputDevice_GetDeviceInfo(lpdid, &ddi);
145 hr = IDirectInputDevice8_BuildActionMap(lpdid, lpdiaf, NULL, DIDBAM_HWDEFAULTS);
146 ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);
148 actions = lpdiaf->rgoAction;
149 instance = DIDFT_GETINSTANCE(actions[action_index].dwObjID);
150 type = DIDFT_GETTYPE(actions[action_index].dwObjID);
151 how = actions[action_index].dwHow;
152 assigned_to = actions[action_index].guidInstance;
154 ok (how == DIAH_USERCONFIG || how == DIAH_DEFAULT, "Action was not set dwHow=%08x\n", how);
155 ok (instance == expected_inst, "Action not mapped correctly instance=%08x expected=%08x\n", instance, expected_inst);
156 ok (type == expected_type, "Action type not mapped correctly type=%08x expected=%08x\n", type, expected_type);
157 ok (IsEqualGUID(&assigned_to, &ddi.guidInstance), "Action and device GUID do not match action=%d\n", action_index);
160 static BOOL CALLBACK enumeration_callback(const DIDEVICEINSTANCEA *lpddi, IDirectInputDevice8A *lpdid,
161 DWORD dwFlags, DWORD dwRemaining, LPVOID pvRef)
163 HRESULT hr;
164 DIPROPDWORD dp;
165 DIPROPRANGE dpr;
166 DIPROPSTRING dps;
167 WCHAR usernameW[MAX_PATH];
168 DWORD username_size = MAX_PATH;
169 struct enum_data *data = pvRef;
170 DWORD cnt;
171 DIDEVICEOBJECTDATA buffer[5];
173 if (!data) return DIENUM_CONTINUE;
175 data->ndevices++;
177 /* Convert username to WCHAR */
178 if (data->username != NULL)
180 username_size = MultiByteToWideChar(CP_ACP, 0, data->username, -1, usernameW, 0);
181 MultiByteToWideChar(CP_ACP, 0, data->username, -1, usernameW, username_size);
183 else
184 GetUserNameW(usernameW, &username_size);
186 /* collect the mouse and keyboard */
187 if (IsEqualGUID(&lpddi->guidInstance, &GUID_SysKeyboard))
189 IDirectInputDevice_AddRef(lpdid);
190 data->keyboard = lpdid;
192 ok (dwFlags & DIEDBS_MAPPEDPRI1, "Keyboard should be mapped as pri1 dwFlags=%08x\n", dwFlags);
195 if (IsEqualGUID(&lpddi->guidInstance, &GUID_SysMouse))
197 IDirectInputDevice_AddRef(lpdid);
198 data->mouse = lpdid;
200 ok (dwFlags & DIEDBS_MAPPEDPRI1, "Mouse should be mapped as pri1 dwFlags=%08x\n", dwFlags);
203 /* Building and setting an action map */
204 /* It should not use any pre-stored mappings so we use DIDBAM_HWDEFAULTS */
205 hr = IDirectInputDevice8_BuildActionMap(lpdid, data->lpdiaf, NULL, DIDBAM_HWDEFAULTS);
206 ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);
208 /* Device has no data format and thus can't be acquired */
209 hr = IDirectInputDevice8_Acquire(lpdid);
210 ok (hr == DIERR_INVALIDPARAM, "Device was acquired before SetActionMap hr=%08x\n", hr);
212 hr = IDirectInputDevice8_SetActionMap(lpdid, data->lpdiaf, data->username, 0);
213 ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr);
215 /* Some joysticks may have no suitable actions and thus should not be tested */
216 if (hr == DI_NOEFFECT) return DIENUM_CONTINUE;
218 /* Test username after SetActionMap */
219 dps.diph.dwSize = sizeof(dps);
220 dps.diph.dwHeaderSize = sizeof(DIPROPHEADER);
221 dps.diph.dwObj = 0;
222 dps.diph.dwHow = DIPH_DEVICE;
223 dps.wsz[0] = '\0';
225 hr = IDirectInputDevice_GetProperty(lpdid, DIPROP_USERNAME, &dps.diph);
226 todo_wine ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr);
227 todo_wine ok (!lstrcmpW(usernameW, dps.wsz), "Username not set correctly expected=%s, got=%s\n", wine_dbgstr_wn(usernameW, -1), wine_dbgstr_wn(dps.wsz, -1));
229 /* Test buffer size */
230 memset(&dp, 0, sizeof(dp));
231 dp.diph.dwSize = sizeof(dp);
232 dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
233 dp.diph.dwHow = DIPH_DEVICE;
235 hr = IDirectInputDevice_GetProperty(lpdid, DIPROP_BUFFERSIZE, &dp.diph);
236 ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr);
237 ok (dp.dwData == data->lpdiaf->dwBufferSize, "SetActionMap must set the buffer, buffersize=%d\n", dp.dwData);
239 cnt = 1;
240 hr = IDirectInputDevice_GetDeviceData(lpdid, sizeof(buffer[0]), buffer, &cnt, 0);
241 ok(hr == DIERR_NOTACQUIRED, "GetDeviceData() failed hr=%08x\n", hr);
243 /* Test axis range */
244 memset(&dpr, 0, sizeof(dpr));
245 dpr.diph.dwSize = sizeof(dpr);
246 dpr.diph.dwHeaderSize = sizeof(DIPROPHEADER);
247 dpr.diph.dwHow = DIPH_DEVICE;
249 hr = IDirectInputDevice_GetProperty(lpdid, DIPROP_RANGE, &dpr.diph);
250 /* Only test if device supports the range property */
251 if (SUCCEEDED(hr))
253 ok (dpr.lMin == data->lpdiaf->lAxisMin, "SetActionMap must set the min axis range expected=%d got=%d\n", data->lpdiaf->lAxisMin, dpr.lMin);
254 ok (dpr.lMax == data->lpdiaf->lAxisMax, "SetActionMap must set the max axis range expected=%d got=%d\n", data->lpdiaf->lAxisMax, dpr.lMax);
257 /* SetActionMap has set the data format so now it should work */
258 hr = IDirectInputDevice8_Acquire(lpdid);
259 ok (SUCCEEDED(hr), "Acquire failed hr=%08x\n", hr);
261 cnt = 1;
262 hr = IDirectInputDevice_GetDeviceData(lpdid, sizeof(buffer[0]), buffer, &cnt, 0);
263 ok(hr == DI_OK, "GetDeviceData() failed hr=%08x\n", hr);
265 /* SetActionMap should not work on an acquired device */
266 hr = IDirectInputDevice8_SetActionMap(lpdid, data->lpdiaf, NULL, 0);
267 ok (hr == DIERR_ACQUIRED, "SetActionMap succeeded with an acquired device hr=%08x\n", hr);
269 return DIENUM_CONTINUE;
272 static void test_action_mapping(void)
274 HRESULT hr;
275 HINSTANCE hinst = GetModuleHandleA(NULL);
276 IDirectInput8A *pDI = NULL;
277 DIACTIONFORMATA af;
278 struct enum_data data = {pDI, &af, NULL, NULL, NULL, 0};
279 HWND hwnd;
281 hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&pDI);
282 if (hr == DIERR_OLDDIRECTINPUTVERSION ||
283 hr == DIERR_BETADIRECTINPUTVERSION ||
284 hr == REGDB_E_CLASSNOTREG)
286 win_skip("ActionMapping requires dinput8\n");
287 return;
289 ok(SUCCEEDED(hr), "DirectInput8 Create failed: hr=%08x\n", hr);
290 if (FAILED(hr)) return;
292 hr = IDirectInput8_Initialize(pDI,hinst, DIRECTINPUT_VERSION);
293 if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION)
295 win_skip("ActionMapping requires dinput8\n");
296 return;
298 ok(SUCCEEDED(hr), "DirectInput8 Initialize failed: hr=%08x\n", hr);
299 if (FAILED(hr)) return;
301 memset (&af, 0, sizeof(af));
302 af.dwSize = sizeof(af);
303 af.dwActionSize = sizeof(DIACTIONA);
304 af.dwDataSize = 4 * sizeof(actionMapping) / sizeof(actionMapping[0]);
305 af.dwNumActions = sizeof(actionMapping) / sizeof(actionMapping[0]);
306 af.rgoAction = actionMapping;
307 af.guidActionMap = ACTION_MAPPING_GUID;
308 af.dwGenre = 0x01000000; /* DIVIRTUAL_DRIVING_RACE */
309 af.dwBufferSize = 32;
311 /* This enumeration builds and sets the action map for all devices */
312 hr = IDirectInput8_EnumDevicesBySemantics(pDI, 0, &af, enumeration_callback, &data, DIEDBSFL_ATTACHEDONLY);
313 ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);
315 /* Repeat tests with a non NULL user */
316 data.username = "Ninja Brian";
317 hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &af, enumeration_callback, &data, DIEDBSFL_ATTACHEDONLY);
318 ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);
320 hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput",
321 WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL);
322 ok(hwnd != NULL, "failed to create window\n");
323 SetCursorPos(50, 50);
325 if (data.keyboard != NULL)
327 /* Test keyboard BuildActionMap */
328 test_build_action_map(data.keyboard, data.lpdiaf, DITEST_KEYBOARDSPACE, DIDFT_PSHBUTTON, DIK_SPACE);
329 /* Test keyboard input */
330 test_device_input(data.keyboard, INPUT_KEYBOARD, VK_SPACE, 2);
332 /* Test BuildActionMap with no suitable actions for a device */
333 IDirectInputDevice_Unacquire(data.keyboard);
334 af.dwDataSize = 4 * DITEST_KEYBOARDSPACE;
335 af.dwNumActions = DITEST_KEYBOARDSPACE;
337 hr = IDirectInputDevice8_BuildActionMap(data.keyboard, data.lpdiaf, NULL, DIDBAM_HWDEFAULTS);
338 ok (hr == DI_NOEFFECT, "BuildActionMap should have no effect with no actions hr=%08x\n", hr);
340 hr = IDirectInputDevice8_SetActionMap(data.keyboard, data.lpdiaf, NULL, 0);
341 ok (hr == DI_NOEFFECT, "SetActionMap should have no effect with no actions to map hr=%08x\n", hr);
343 af.dwDataSize = 4 * sizeof(actionMapping) / sizeof(actionMapping[0]);
344 af.dwNumActions = sizeof(actionMapping) / sizeof(actionMapping[0]);
347 if (data.mouse != NULL)
349 /* Test mouse BuildActionMap */
350 test_build_action_map(data.mouse, data.lpdiaf, DITEST_MOUSEBUTTON0, DIDFT_PSHBUTTON, 0x03);
351 test_build_action_map(data.mouse, data.lpdiaf, DITEST_YAXIS, DIDFT_RELAXIS, 0x01);
353 test_device_input(data.mouse, INPUT_MOUSE, MOUSEEVENTF_LEFTDOWN, 3);
356 DestroyWindow(hwnd);
359 static void test_save_settings(void)
361 HRESULT hr;
362 HINSTANCE hinst = GetModuleHandleA(NULL);
363 IDirectInput8A *pDI = NULL;
364 DIACTIONFORMATA af;
365 IDirectInputDevice8A *pKey;
367 static const GUID mapping_guid = { 0xcafecafe, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
368 static const GUID other_guid = { 0xcafe, 0xcafe, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
370 static DIACTIONA actions[] = {
371 { 0, DIKEYBOARD_A , 0, { "Blam" } },
372 { 1, DIKEYBOARD_B , 0, { "Kapow"} }
374 static const DWORD results[] = {
375 DIDFT_MAKEINSTANCE(DIK_A) | DIDFT_PSHBUTTON,
376 DIDFT_MAKEINSTANCE(DIK_B) | DIDFT_PSHBUTTON
378 static const DWORD other_results[] = {
379 DIDFT_MAKEINSTANCE(DIK_C) | DIDFT_PSHBUTTON,
380 DIDFT_MAKEINSTANCE(DIK_D) | DIDFT_PSHBUTTON
383 hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&pDI);
384 if (hr == DIERR_OLDDIRECTINPUTVERSION ||
385 hr == DIERR_BETADIRECTINPUTVERSION ||
386 hr == REGDB_E_CLASSNOTREG)
388 win_skip("ActionMapping requires dinput8\n");
389 return;
391 ok (SUCCEEDED(hr), "DirectInput8 Create failed: hr=%08x\n", hr);
392 if (FAILED(hr)) return;
394 hr = IDirectInput8_Initialize(pDI,hinst, DIRECTINPUT_VERSION);
395 if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION)
397 win_skip("ActionMapping requires dinput8\n");
398 return;
400 ok (SUCCEEDED(hr), "DirectInput8 Initialize failed: hr=%08x\n", hr);
401 if (FAILED(hr)) return;
403 hr = IDirectInput_CreateDevice(pDI, &GUID_SysKeyboard, &pKey, NULL);
404 ok (SUCCEEDED(hr), "IDirectInput_Create device failed hr: 0x%08x\n", hr);
405 if (FAILED(hr)) return;
407 memset (&af, 0, sizeof(af));
408 af.dwSize = sizeof(af);
409 af.dwActionSize = sizeof(DIACTIONA);
410 af.dwDataSize = 4 * sizeof(actions) / sizeof(actions[0]);
411 af.dwNumActions = sizeof(actions) / sizeof(actions[0]);
412 af.rgoAction = actions;
413 af.guidActionMap = mapping_guid;
414 af.dwGenre = 0x01000000; /* DIVIRTUAL_DRIVING_RACE */
415 af.dwBufferSize = 32;
417 /* Easy case. Ask for default mapping, save, ask for previous map and read it back */
418 hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, DIDBAM_HWDEFAULTS);
419 ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);
421 ok (results[0] == af.rgoAction[0].dwObjID,
422 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[0], af.rgoAction[0].dwObjID);
424 ok (results[1] == af.rgoAction[1].dwObjID,
425 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[1], af.rgoAction[1].dwObjID);
427 hr = IDirectInputDevice8_SetActionMap(pKey, &af, NULL, DIDSAM_FORCESAVE);
428 ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr);
430 if (hr == DI_SETTINGSNOTSAVED)
432 skip ("Can't test saving settings if SetActionMap returns DI_SETTINGSNOTSAVED\n");
433 return;
436 af.rgoAction[0].dwObjID = 0;
437 af.rgoAction[1].dwObjID = 0;
438 memset(&af.rgoAction[0].guidInstance, 0, sizeof(GUID));
439 memset(&af.rgoAction[1].guidInstance, 0, sizeof(GUID));
441 hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, 0);
442 ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);
444 ok (results[0] == af.rgoAction[0].dwObjID,
445 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[0], af.rgoAction[0].dwObjID);
446 ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[0].guidInstance), "Action should be mapped to keyboard\n");
448 ok (results[1] == af.rgoAction[1].dwObjID,
449 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[1], af.rgoAction[1].dwObjID);
450 ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[1].guidInstance), "Action should be mapped to keyboard\n");
452 /* Test that a different action map with no pre-stored settings, in spite of the flags,
453 does not try to load mappings and instead applies the default mapping */
454 af.guidActionMap = other_guid;
456 af.rgoAction[0].dwObjID = 0;
457 af.rgoAction[1].dwObjID = 0;
458 memset(&af.rgoAction[0].guidInstance, 0, sizeof(GUID));
459 memset(&af.rgoAction[1].guidInstance, 0, sizeof(GUID));
461 hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, 0);
462 ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);
464 ok (results[0] == af.rgoAction[0].dwObjID,
465 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[0], af.rgoAction[0].dwObjID);
466 ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[0].guidInstance), "Action should be mapped to keyboard\n");
468 ok (results[1] == af.rgoAction[1].dwObjID,
469 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[1], af.rgoAction[1].dwObjID);
470 ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[1].guidInstance), "Action should be mapped to keyboard\n");
472 af.guidActionMap = mapping_guid;
473 /* Hard case. Customized mapping, save, ask for previous map and read it back */
474 af.rgoAction[0].dwObjID = other_results[0];
475 af.rgoAction[0].dwHow = DIAH_USERCONFIG;
476 af.rgoAction[0].guidInstance = GUID_SysKeyboard;
477 af.rgoAction[1].dwObjID = other_results[1];
478 af.rgoAction[1].dwHow = DIAH_USERCONFIG;
479 af.rgoAction[1].guidInstance = GUID_SysKeyboard;
481 hr = IDirectInputDevice8_SetActionMap(pKey, &af, NULL, DIDSAM_FORCESAVE);
482 ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr);
484 if (hr == DI_SETTINGSNOTSAVED)
486 skip ("Can't test saving settings if SetActionMap returns DI_SETTINGSNOTSAVED\n");
487 return;
490 af.rgoAction[0].dwObjID = 0;
491 af.rgoAction[1].dwObjID = 0;
492 memset(&af.rgoAction[0].guidInstance, 0, sizeof(GUID));
493 memset(&af.rgoAction[1].guidInstance, 0, sizeof(GUID));
495 hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, 0);
496 ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);
498 ok (other_results[0] == af.rgoAction[0].dwObjID,
499 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", other_results[0], af.rgoAction[0].dwObjID);
500 ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[0].guidInstance), "Action should be mapped to keyboard\n");
502 ok (other_results[1] == af.rgoAction[1].dwObjID,
503 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", other_results[1], af.rgoAction[1].dwObjID);
504 ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[1].guidInstance), "Action should be mapped to keyboard\n");
507 START_TEST(device)
509 CoInitialize(NULL);
511 test_action_mapping();
512 test_save_settings();
514 CoUninitialize();