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
25 #include "wine/test.h"
31 DIACTIONFORMATA
*lpdiaf
;
32 IDirectInputDevice8A
*keyboard
;
33 IDirectInputDevice8A
*mouse
;
39 static const GUID ACTION_MAPPING_GUID
= { 0x1, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
49 static DIACTIONA actionMapping
[]=
52 { 0, 0x01008A01 /* DIAXIS_DRIVINGR_STEER */, 0, { "Steer.\0" } },
54 { 1, 0x01000C01 /* DIBUTTON_DRIVINGR_SHIFTUP */, 0, { "Upshift.\0" } },
56 { 2, DIKEYBOARD_SPACE
, 0, { "Missile.\0" } },
58 { 3, DIMOUSE_BUTTON0
, 0, { "Select\0" } },
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)
71 int min_timeout
= 100;
72 DWORD time
= GetTickCount() + diff
;
76 if (MsgWaitForMultipleObjects(0, NULL
, FALSE
, min_timeout
, QS_ALLINPUT
) == WAIT_TIMEOUT
)
78 diff
= time
- GetTickCount();
83 static void test_device_input(IDirectInputDevice8A
*lpdid
, DWORD event_type
, DWORD event
, UINT_PTR expected
)
86 DIDEVICEOBJECTDATA obj_data
;
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);
100 IDirectInputDevice8_Poll(lpdid
);
101 hr
= IDirectInputDevice8_GetDeviceData(lpdid
, sizeof(obj_data
), &obj_data
, &data_size
, 0);
105 win_skip("We're not able to inject input into Windows dinput8 with events\n");
106 IDirectInputDevice_Unacquire(lpdid
);
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);
126 IDirectInputDevice8_Poll(lpdid
);
129 hr
= IDirectInputDevice8_GetDeviceData(lpdid
, sizeof(obj_data
), &obj_data
, &data_size
, 0);
130 ok(hr
== DI_BUFFEROVERFLOW
, "GetDeviceData() failed: %08x\n", hr
);
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
)
151 DWORD instance
, type
, how
;
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
)
180 WCHAR usernameW
[MAX_PATH
];
181 DWORD username_size
= MAX_PATH
;
182 struct enum_data
*data
= pvRef
;
184 DIDEVICEOBJECTDATA buffer
[5];
185 IDirectInputDevice8A
*lpdid2
;
187 if (!data
) return DIENUM_CONTINUE
;
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
);
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
);
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
);
240 dps
.diph
.dwHow
= DIPH_DEVICE
;
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
));
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
);
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 */
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
);
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_appdata_property_vs_map(struct enum_data
*data
)
302 dp
.diph
.dwSize
= sizeof(dp
);
303 dp
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
);
304 dp
.diph
.dwHow
= DIPH_BYID
;
305 dp
.diph
.dwObj
= DIDFT_MAKEINSTANCE(DIK_SPACE
) | DIDFT_PSHBUTTON
;
307 hr
= IDirectInputDevice8_SetProperty(data
->keyboard
, DIPROP_APPDATA
, &(dp
.diph
));
308 ok(SUCCEEDED(hr
), "IDirectInputDevice8_SetProperty failed hr=%08x\n", hr
);
310 test_device_input(data
->keyboard
, INPUT_KEYBOARD
, VK_SPACE
, 10);
312 dp
.diph
.dwHow
= DIPH_BYID
;
313 dp
.diph
.dwObj
= DIDFT_MAKEINSTANCE(DIK_V
) | DIDFT_PSHBUTTON
;
315 hr
= IDirectInputDevice8_SetProperty(data
->keyboard
, DIPROP_APPDATA
, &(dp
.diph
));
316 ok(hr
== DIERR_OBJECTNOTFOUND
, "IDirectInputDevice8_SetProperty should not find key that's not in the action map hr=%08x\n", hr
);
318 /* setting format should reset action map */
319 hr
= IDirectInputDevice8_SetDataFormat(data
->keyboard
, &c_dfDIKeyboard
);
320 ok(SUCCEEDED(hr
), "SetDataFormat failed: %08x\n", hr
);
322 test_device_input(data
->keyboard
, INPUT_KEYBOARD
, VK_SPACE
, -1);
324 dp
.diph
.dwHow
= DIPH_BYID
;
325 dp
.diph
.dwObj
= DIDFT_MAKEINSTANCE(DIK_V
) | DIDFT_PSHBUTTON
;
327 hr
= IDirectInputDevice8_SetProperty(data
->keyboard
, DIPROP_APPDATA
, &(dp
.diph
));
328 ok(SUCCEEDED(hr
), "IDirectInputDevice8_SetProperty failed hr=%08x\n", hr
);
330 test_device_input(data
->keyboard
, INPUT_KEYBOARD
, 'V', 11);
332 /* back to action map */
333 hr
= IDirectInputDevice8_SetActionMap(data
->keyboard
, data
->lpdiaf
, NULL
, 0);
334 ok(SUCCEEDED(hr
), "SetActionMap failed hr=%08x\n", hr
);
336 test_device_input(data
->keyboard
, INPUT_KEYBOARD
, VK_SPACE
, 2);
339 static void test_action_mapping(void)
342 HINSTANCE hinst
= GetModuleHandleA(NULL
);
343 IDirectInput8A
*pDI
= NULL
;
346 struct enum_data data
= {pDI
, &af
, NULL
, NULL
, NULL
, 0};
349 hr
= CoCreateInstance(&CLSID_DirectInput8
, 0, CLSCTX_INPROC_SERVER
, &IID_IDirectInput8A
, (LPVOID
*)&pDI
);
350 if (hr
== DIERR_OLDDIRECTINPUTVERSION
||
351 hr
== DIERR_BETADIRECTINPUTVERSION
||
352 hr
== REGDB_E_CLASSNOTREG
)
354 win_skip("ActionMapping requires dinput8\n");
357 ok(SUCCEEDED(hr
), "DirectInput8 Create failed: hr=%08x\n", hr
);
358 if (FAILED(hr
)) return;
360 hr
= IDirectInput8_Initialize(pDI
,hinst
, DIRECTINPUT_VERSION
);
361 if (hr
== DIERR_OLDDIRECTINPUTVERSION
|| hr
== DIERR_BETADIRECTINPUTVERSION
)
363 win_skip("ActionMapping requires dinput8\n");
366 ok(SUCCEEDED(hr
), "DirectInput8 Initialize failed: hr=%08x\n", hr
);
367 if (FAILED(hr
)) return;
369 memset (&af
, 0, sizeof(af
));
370 af
.dwSize
= sizeof(af
);
371 af
.dwActionSize
= sizeof(DIACTIONA
);
372 af
.dwDataSize
= 4 * ARRAY_SIZE(actionMapping
);
373 af
.dwNumActions
= ARRAY_SIZE(actionMapping
);
374 af
.rgoAction
= actionMapping
;
375 af
.guidActionMap
= ACTION_MAPPING_GUID
;
376 af
.dwGenre
= 0x01000000; /* DIVIRTUAL_DRIVING_RACE */
377 af
.dwBufferSize
= 32;
379 /* This enumeration builds and sets the action map for all devices */
381 hr
= IDirectInput8_EnumDevicesBySemantics(pDI
, 0, &af
, enumeration_callback
, &data
, DIEDBSFL_ATTACHEDONLY
);
382 ok (SUCCEEDED(hr
), "EnumDevicesBySemantics failed: hr=%08x\n", hr
);
385 IDirectInputDevice_Release(data
.keyboard
);
388 IDirectInputDevice_Release(data
.mouse
);
390 /* Repeat tests with a non NULL user */
391 data
.username
= "Ninja Brian";
392 hr
= IDirectInput8_EnumDevicesBySemantics(pDI
, NULL
, &af
, enumeration_callback
, &data
, DIEDBSFL_ATTACHEDONLY
);
393 ok (SUCCEEDED(hr
), "EnumDevicesBySemantics failed: hr=%08x\n", hr
);
395 hwnd
= CreateWindowExA(WS_EX_TOPMOST
, "static", "dinput",
396 WS_POPUP
| WS_VISIBLE
, 0, 0, 100, 100, NULL
, NULL
, NULL
, NULL
);
397 ok(hwnd
!= NULL
, "failed to create window\n");
398 SetCursorPos(50, 50);
400 if (data
.keyboard
!= NULL
)
402 /* Test keyboard BuildActionMap */
403 test_build_action_map(data
.keyboard
, data
.lpdiaf
, DITEST_KEYBOARDSPACE
, DIDFT_PSHBUTTON
, DIK_SPACE
);
404 /* Test keyboard input */
405 test_device_input(data
.keyboard
, INPUT_KEYBOARD
, VK_SPACE
, 2);
407 /* setting format should reset action map */
408 hr
= IDirectInputDevice8_SetDataFormat(data
.keyboard
, &c_dfDIKeyboard
);
409 ok (SUCCEEDED(hr
), "IDirectInputDevice8_SetDataFormat failed: %08x\n", hr
);
411 test_device_input(data
.keyboard
, INPUT_KEYBOARD
, VK_SPACE
, -1);
413 /* back to action map */
414 hr
= IDirectInputDevice8_SetActionMap(data
.keyboard
, data
.lpdiaf
, NULL
, 0);
415 ok (SUCCEEDED(hr
), "SetActionMap should succeed hr=%08x\n", hr
);
417 test_device_input(data
.keyboard
, INPUT_KEYBOARD
, VK_SPACE
, 2);
419 test_appdata_property_vs_map(&data
);
421 /* Test BuildActionMap with no suitable actions for a device */
422 IDirectInputDevice_Unacquire(data
.keyboard
);
423 af
.dwDataSize
= 4 * DITEST_KEYBOARDSPACE
;
424 af
.dwNumActions
= DITEST_KEYBOARDSPACE
;
426 hr
= IDirectInputDevice8_BuildActionMap(data
.keyboard
, data
.lpdiaf
, NULL
, DIDBAM_HWDEFAULTS
);
427 ok (hr
== DI_NOEFFECT
, "BuildActionMap should have no effect with no actions hr=%08x\n", hr
);
429 hr
= IDirectInputDevice8_SetActionMap(data
.keyboard
, data
.lpdiaf
, NULL
, 0);
430 ok (hr
== DI_NOEFFECT
, "SetActionMap should have no effect with no actions to map hr=%08x\n", hr
);
432 af
.dwDataSize
= 4 * ARRAY_SIZE(actionMapping
);
433 af
.dwNumActions
= ARRAY_SIZE(actionMapping
);
435 /* test DIDSAM_NOUSER */
436 dps
.diph
.dwSize
= sizeof(dps
);
437 dps
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
);
439 dps
.diph
.dwHow
= DIPH_DEVICE
;
442 hr
= IDirectInputDevice_GetProperty(data
.keyboard
, DIPROP_USERNAME
, &dps
.diph
);
443 ok (SUCCEEDED(hr
), "GetProperty failed hr=%08x\n", hr
);
444 ok (dps
.wsz
[0] != 0, "Expected any username, got=%s\n", wine_dbgstr_w(dps
.wsz
));
446 hr
= IDirectInputDevice8_SetActionMap(data
.keyboard
, data
.lpdiaf
, NULL
, DIDSAM_NOUSER
);
447 ok (SUCCEEDED(hr
), "SetActionMap failed hr=%08x\n", hr
);
449 dps
.diph
.dwSize
= sizeof(dps
);
450 dps
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
);
452 dps
.diph
.dwHow
= DIPH_DEVICE
;
455 hr
= IDirectInputDevice_GetProperty(data
.keyboard
, DIPROP_USERNAME
, &dps
.diph
);
456 ok (SUCCEEDED(hr
), "GetProperty failed hr=%08x\n", hr
);
457 ok (dps
.wsz
[0] == 0, "Expected empty username, got=%s\n", wine_dbgstr_w(dps
.wsz
));
459 IDirectInputDevice_Release(data
.keyboard
);
462 if (data
.mouse
!= NULL
)
464 /* Test mouse BuildActionMap */
465 test_build_action_map(data
.mouse
, data
.lpdiaf
, DITEST_MOUSEBUTTON0
, DIDFT_PSHBUTTON
, 0x03);
466 test_build_action_map(data
.mouse
, data
.lpdiaf
, DITEST_YAXIS
, DIDFT_RELAXIS
, 0x01);
468 test_device_input(data
.mouse
, INPUT_MOUSE
, MOUSEEVENTF_LEFTDOWN
, 3);
470 IDirectInputDevice_Release(data
.mouse
);
474 IDirectInput_Release(pDI
);
477 static void test_save_settings(void)
480 HINSTANCE hinst
= GetModuleHandleA(NULL
);
481 IDirectInput8A
*pDI
= NULL
;
483 IDirectInputDevice8A
*pKey
;
485 static const GUID mapping_guid
= { 0xcafecafe, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
486 static const GUID other_guid
= { 0xcafe, 0xcafe, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
488 static DIACTIONA actions
[] = {
489 { 0, DIKEYBOARD_A
, 0, { "Blam" } },
490 { 1, DIKEYBOARD_B
, 0, { "Kapow"} }
492 static const DWORD results
[] = {
493 DIDFT_MAKEINSTANCE(DIK_A
) | DIDFT_PSHBUTTON
,
494 DIDFT_MAKEINSTANCE(DIK_B
) | DIDFT_PSHBUTTON
496 static const DWORD other_results
[] = {
497 DIDFT_MAKEINSTANCE(DIK_C
) | DIDFT_PSHBUTTON
,
498 DIDFT_MAKEINSTANCE(DIK_D
) | DIDFT_PSHBUTTON
501 hr
= CoCreateInstance(&CLSID_DirectInput8
, 0, CLSCTX_INPROC_SERVER
, &IID_IDirectInput8A
, (LPVOID
*)&pDI
);
502 if (hr
== DIERR_OLDDIRECTINPUTVERSION
||
503 hr
== DIERR_BETADIRECTINPUTVERSION
||
504 hr
== REGDB_E_CLASSNOTREG
)
506 win_skip("ActionMapping requires dinput8\n");
509 ok (SUCCEEDED(hr
), "DirectInput8 Create failed: hr=%08x\n", hr
);
510 if (FAILED(hr
)) return;
512 hr
= IDirectInput8_Initialize(pDI
,hinst
, DIRECTINPUT_VERSION
);
513 if (hr
== DIERR_OLDDIRECTINPUTVERSION
|| hr
== DIERR_BETADIRECTINPUTVERSION
)
515 win_skip("ActionMapping requires dinput8\n");
518 ok (SUCCEEDED(hr
), "DirectInput8 Initialize failed: hr=%08x\n", hr
);
519 if (FAILED(hr
)) return;
521 hr
= IDirectInput_CreateDevice(pDI
, &GUID_SysKeyboard
, &pKey
, NULL
);
522 ok (SUCCEEDED(hr
), "IDirectInput_Create device failed hr: 0x%08x\n", hr
);
523 if (FAILED(hr
)) return;
525 memset (&af
, 0, sizeof(af
));
526 af
.dwSize
= sizeof(af
);
527 af
.dwActionSize
= sizeof(DIACTIONA
);
528 af
.dwDataSize
= 4 * ARRAY_SIZE(actions
);
529 af
.dwNumActions
= ARRAY_SIZE(actions
);
530 af
.rgoAction
= actions
;
531 af
.guidActionMap
= mapping_guid
;
532 af
.dwGenre
= 0x01000000; /* DIVIRTUAL_DRIVING_RACE */
533 af
.dwBufferSize
= 32;
535 /* Easy case. Ask for default mapping, save, ask for previous map and read it back */
536 hr
= IDirectInputDevice8_BuildActionMap(pKey
, &af
, NULL
, DIDBAM_HWDEFAULTS
);
537 ok (SUCCEEDED(hr
), "BuildActionMap failed hr=%08x\n", hr
);
538 ok (results
[0] == af
.rgoAction
[0].dwObjID
,
539 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results
[0], af
.rgoAction
[0].dwObjID
);
541 ok (results
[1] == af
.rgoAction
[1].dwObjID
,
542 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results
[1], af
.rgoAction
[1].dwObjID
);
544 hr
= IDirectInputDevice8_SetActionMap(pKey
, &af
, NULL
, DIDSAM_FORCESAVE
);
545 ok (SUCCEEDED(hr
), "SetActionMap failed hr=%08x\n", hr
);
547 if (hr
== DI_SETTINGSNOTSAVED
)
549 skip ("Can't test saving settings if SetActionMap returns DI_SETTINGSNOTSAVED\n");
553 af
.rgoAction
[0].dwObjID
= 0;
554 af
.rgoAction
[1].dwObjID
= 0;
555 memset(&af
.rgoAction
[0].guidInstance
, 0, sizeof(GUID
));
556 memset(&af
.rgoAction
[1].guidInstance
, 0, sizeof(GUID
));
558 hr
= IDirectInputDevice8_BuildActionMap(pKey
, &af
, NULL
, 0);
559 ok (SUCCEEDED(hr
), "BuildActionMap failed hr=%08x\n", hr
);
561 ok (results
[0] == af
.rgoAction
[0].dwObjID
,
562 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results
[0], af
.rgoAction
[0].dwObjID
);
563 ok (IsEqualGUID(&GUID_SysKeyboard
, &af
.rgoAction
[0].guidInstance
), "Action should be mapped to keyboard\n");
565 ok (results
[1] == af
.rgoAction
[1].dwObjID
,
566 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results
[1], af
.rgoAction
[1].dwObjID
);
567 ok (IsEqualGUID(&GUID_SysKeyboard
, &af
.rgoAction
[1].guidInstance
), "Action should be mapped to keyboard\n");
569 /* Test that a different action map with no pre-stored settings, in spite of the flags,
570 does not try to load mappings and instead applies the default mapping */
571 af
.guidActionMap
= other_guid
;
573 af
.rgoAction
[0].dwObjID
= 0;
574 af
.rgoAction
[1].dwObjID
= 0;
575 memset(&af
.rgoAction
[0].guidInstance
, 0, sizeof(GUID
));
576 memset(&af
.rgoAction
[1].guidInstance
, 0, sizeof(GUID
));
578 hr
= IDirectInputDevice8_BuildActionMap(pKey
, &af
, NULL
, 0);
579 ok (SUCCEEDED(hr
), "BuildActionMap failed hr=%08x\n", hr
);
581 ok (results
[0] == af
.rgoAction
[0].dwObjID
,
582 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results
[0], af
.rgoAction
[0].dwObjID
);
583 ok (IsEqualGUID(&GUID_SysKeyboard
, &af
.rgoAction
[0].guidInstance
), "Action should be mapped to keyboard\n");
585 ok (results
[1] == af
.rgoAction
[1].dwObjID
,
586 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results
[1], af
.rgoAction
[1].dwObjID
);
587 ok (IsEqualGUID(&GUID_SysKeyboard
, &af
.rgoAction
[1].guidInstance
), "Action should be mapped to keyboard\n");
589 af
.guidActionMap
= mapping_guid
;
590 /* Hard case. Customized mapping, save, ask for previous map and read it back */
591 af
.rgoAction
[0].dwObjID
= other_results
[0];
592 af
.rgoAction
[0].dwHow
= DIAH_USERCONFIG
;
593 af
.rgoAction
[0].guidInstance
= GUID_SysKeyboard
;
594 af
.rgoAction
[1].dwObjID
= other_results
[1];
595 af
.rgoAction
[1].dwHow
= DIAH_USERCONFIG
;
596 af
.rgoAction
[1].guidInstance
= GUID_SysKeyboard
;
598 hr
= IDirectInputDevice8_SetActionMap(pKey
, &af
, NULL
, DIDSAM_FORCESAVE
);
599 ok (SUCCEEDED(hr
), "SetActionMap failed hr=%08x\n", hr
);
601 if (hr
== DI_SETTINGSNOTSAVED
)
603 skip ("Can't test saving settings if SetActionMap returns DI_SETTINGSNOTSAVED\n");
607 af
.rgoAction
[0].dwObjID
= 0;
608 af
.rgoAction
[1].dwObjID
= 0;
609 memset(&af
.rgoAction
[0].guidInstance
, 0, sizeof(GUID
));
610 memset(&af
.rgoAction
[1].guidInstance
, 0, sizeof(GUID
));
612 hr
= IDirectInputDevice8_BuildActionMap(pKey
, &af
, NULL
, 0);
613 ok (SUCCEEDED(hr
), "BuildActionMap failed hr=%08x\n", hr
);
615 ok (other_results
[0] == af
.rgoAction
[0].dwObjID
,
616 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", other_results
[0], af
.rgoAction
[0].dwObjID
);
617 ok (IsEqualGUID(&GUID_SysKeyboard
, &af
.rgoAction
[0].guidInstance
), "Action should be mapped to keyboard\n");
619 ok (other_results
[1] == af
.rgoAction
[1].dwObjID
,
620 "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", other_results
[1], af
.rgoAction
[1].dwObjID
);
621 ok (IsEqualGUID(&GUID_SysKeyboard
, &af
.rgoAction
[1].guidInstance
), "Action should be mapped to keyboard\n");
623 IDirectInputDevice_Release(pKey
);
624 IDirectInput_Release(pDI
);
627 static void test_mouse_keyboard(void)
630 HWND hwnd
, di_hwnd
= INVALID_HANDLE_VALUE
;
631 IDirectInput8A
*di
= NULL
;
632 IDirectInputDevice8A
*di_mouse
, *di_keyboard
;
633 UINT raw_devices_count
;
634 RAWINPUTDEVICE raw_devices
[3];
636 hwnd
= CreateWindowExA(WS_EX_TOPMOST
, "static", "dinput", WS_POPUP
| WS_VISIBLE
, 0, 0, 100, 100, NULL
, NULL
, NULL
, NULL
);
637 ok(hwnd
!= NULL
, "CreateWindowExA failed\n");
639 hr
= CoCreateInstance(&CLSID_DirectInput8
, 0, CLSCTX_INPROC_SERVER
, &IID_IDirectInput8A
, (LPVOID
*)&di
);
640 if (hr
== DIERR_OLDDIRECTINPUTVERSION
||
641 hr
== DIERR_BETADIRECTINPUTVERSION
||
642 hr
== REGDB_E_CLASSNOTREG
)
644 win_skip("test_mouse_keyboard requires dinput8\n");
647 ok(SUCCEEDED(hr
), "DirectInput8Create failed: %08x\n", hr
);
649 hr
= IDirectInput8_Initialize(di
, GetModuleHandleA(NULL
), DIRECTINPUT_VERSION
);
650 if (hr
== DIERR_OLDDIRECTINPUTVERSION
|| hr
== DIERR_BETADIRECTINPUTVERSION
)
652 win_skip("test_mouse_keyboard requires dinput8\n");
655 ok(SUCCEEDED(hr
), "IDirectInput8_Initialize failed: %08x\n", hr
);
657 hr
= IDirectInput8_CreateDevice(di
, &GUID_SysMouse
, &di_mouse
, NULL
);
658 ok(SUCCEEDED(hr
), "IDirectInput8_CreateDevice failed: %08x\n", hr
);
659 hr
= IDirectInputDevice8_SetDataFormat(di_mouse
, &c_dfDIMouse
);
660 ok(SUCCEEDED(hr
), "IDirectInputDevice8_SetDataFormat failed: %08x\n", hr
);
662 hr
= IDirectInput8_CreateDevice(di
, &GUID_SysKeyboard
, &di_keyboard
, NULL
);
663 ok(SUCCEEDED(hr
), "IDirectInput8_CreateDevice failed: %08x\n", hr
);
664 hr
= IDirectInputDevice8_SetDataFormat(di_keyboard
, &c_dfDIKeyboard
);
665 ok(SUCCEEDED(hr
), "IDirectInputDevice8_SetDataFormat failed: %08x\n", hr
);
667 raw_devices_count
= ARRAY_SIZE(raw_devices
);
668 GetRegisteredRawInputDevices(NULL
, &raw_devices_count
, sizeof(RAWINPUTDEVICE
));
669 ok(raw_devices_count
== 0, "Unexpected raw devices registered: %d\n", raw_devices_count
);
671 hr
= IDirectInputDevice8_Acquire(di_keyboard
);
672 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Acquire failed: %08x\n", hr
);
673 raw_devices_count
= ARRAY_SIZE(raw_devices
);
674 memset(raw_devices
, 0, sizeof(raw_devices
));
675 hr
= GetRegisteredRawInputDevices(raw_devices
, &raw_devices_count
, sizeof(RAWINPUTDEVICE
));
677 ok(hr
== 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr
, raw_devices_count
);
679 ok(raw_devices
[0].usUsagePage
== 1, "Unexpected raw device usage page: %x\n", raw_devices
[0].usUsagePage
);
681 ok(raw_devices
[0].usUsage
== 6, "Unexpected raw device usage: %x\n", raw_devices
[0].usUsage
);
683 ok(raw_devices
[0].dwFlags
== RIDEV_INPUTSINK
, "Unexpected raw device flags: %x\n", raw_devices
[0].dwFlags
);
685 ok(raw_devices
[0].hwndTarget
!= NULL
, "Unexpected raw device target: %p\n", raw_devices
[0].hwndTarget
);
686 hr
= IDirectInputDevice8_Unacquire(di_keyboard
);
687 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Acquire failed: %08x\n", hr
);
688 raw_devices_count
= ARRAY_SIZE(raw_devices
);
689 GetRegisteredRawInputDevices(NULL
, &raw_devices_count
, sizeof(RAWINPUTDEVICE
));
690 ok(raw_devices_count
== 0, "Unexpected raw devices registered: %d\n", raw_devices_count
);
692 if (raw_devices
[0].hwndTarget
!= NULL
)
697 di_hwnd
= raw_devices
[0].hwndTarget
;
698 i
= GetClassNameW(di_hwnd
, str
, ARRAY_SIZE(str
));
699 ok(i
== lstrlenW(L
"DIEmWin"), "GetClassName returned incorrect length\n");
700 ok(!lstrcmpW(L
"DIEmWin", str
), "GetClassName returned incorrect name for this window's class\n");
702 i
= GetWindowTextW(di_hwnd
, str
, ARRAY_SIZE(str
));
703 ok(i
== lstrlenW(L
"DIEmWin"), "GetClassName returned incorrect length\n");
704 ok(!lstrcmpW(L
"DIEmWin", str
), "GetClassName returned incorrect name for this window's class\n");
707 hr
= IDirectInputDevice8_Acquire(di_mouse
);
708 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Acquire failed: %08x\n", hr
);
709 raw_devices_count
= ARRAY_SIZE(raw_devices
);
710 memset(raw_devices
, 0, sizeof(raw_devices
));
711 hr
= GetRegisteredRawInputDevices(raw_devices
, &raw_devices_count
, sizeof(RAWINPUTDEVICE
));
712 ok(hr
== 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr
, raw_devices_count
);
713 ok(raw_devices
[0].usUsagePage
== 1, "Unexpected raw device usage page: %x\n", raw_devices
[0].usUsagePage
);
714 ok(raw_devices
[0].usUsage
== 2, "Unexpected raw device usage: %x\n", raw_devices
[0].usUsage
);
715 ok(raw_devices
[0].dwFlags
== RIDEV_INPUTSINK
, "Unexpected raw device flags: %x\n", raw_devices
[0].dwFlags
);
717 ok(raw_devices
[0].hwndTarget
== di_hwnd
, "Unexpected raw device target: %p\n", raw_devices
[0].hwndTarget
);
718 hr
= IDirectInputDevice8_Unacquire(di_mouse
);
719 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Acquire failed: %08x\n", hr
);
720 raw_devices_count
= ARRAY_SIZE(raw_devices
);
721 GetRegisteredRawInputDevices(NULL
, &raw_devices_count
, sizeof(RAWINPUTDEVICE
));
722 ok(raw_devices_count
== 0, "Unexpected raw devices registered: %d\n", raw_devices_count
);
724 if (raw_devices
[0].hwndTarget
!= NULL
)
725 di_hwnd
= raw_devices
[0].hwndTarget
;
727 /* expect dinput8 to take over any activated raw input devices */
728 raw_devices
[0].usUsagePage
= 0x01;
729 raw_devices
[0].usUsage
= 0x05;
730 raw_devices
[0].dwFlags
= 0;
731 raw_devices
[0].hwndTarget
= hwnd
;
732 raw_devices
[1].usUsagePage
= 0x01;
733 raw_devices
[1].usUsage
= 0x06;
734 raw_devices
[1].dwFlags
= 0;
735 raw_devices
[1].hwndTarget
= hwnd
;
736 raw_devices
[2].usUsagePage
= 0x01;
737 raw_devices
[2].usUsage
= 0x02;
738 raw_devices
[2].dwFlags
= 0;
739 raw_devices
[2].hwndTarget
= hwnd
;
740 raw_devices_count
= ARRAY_SIZE(raw_devices
);
741 hr
= RegisterRawInputDevices(raw_devices
, raw_devices_count
, sizeof(RAWINPUTDEVICE
));
742 ok(hr
== TRUE
, "RegisterRawInputDevices failed\n");
744 hr
= IDirectInputDevice8_Acquire(di_keyboard
);
745 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Acquire failed: %08x\n", hr
);
746 hr
= IDirectInputDevice8_Acquire(di_mouse
);
747 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Acquire failed: %08x\n", hr
);
748 raw_devices_count
= ARRAY_SIZE(raw_devices
);
749 memset(raw_devices
, 0, sizeof(raw_devices
));
750 hr
= GetRegisteredRawInputDevices(raw_devices
, &raw_devices_count
, sizeof(RAWINPUTDEVICE
));
751 ok(hr
== 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr
, raw_devices_count
);
752 ok(raw_devices
[0].usUsagePage
== 1, "Unexpected raw device usage page: %x\n", raw_devices
[0].usUsagePage
);
753 ok(raw_devices
[0].usUsage
== 2, "Unexpected raw device usage: %x\n", raw_devices
[0].usUsage
);
754 ok(raw_devices
[0].dwFlags
== RIDEV_INPUTSINK
, "Unexpected raw device flags: %x\n", raw_devices
[0].dwFlags
);
755 ok(raw_devices
[0].hwndTarget
== di_hwnd
, "Unexpected raw device target: %p\n", raw_devices
[0].hwndTarget
);
756 ok(raw_devices
[1].usUsagePage
== 1, "Unexpected raw device usage page: %x\n", raw_devices
[1].usUsagePage
);
757 ok(raw_devices
[1].usUsage
== 5, "Unexpected raw device usage: %x\n", raw_devices
[1].usUsage
);
758 ok(raw_devices
[1].dwFlags
== 0, "Unexpected raw device flags: %x\n", raw_devices
[1].dwFlags
);
759 ok(raw_devices
[1].hwndTarget
== hwnd
, "Unexpected raw device target: %p\n", raw_devices
[1].hwndTarget
);
760 ok(raw_devices
[2].usUsagePage
== 1, "Unexpected raw device usage page: %x\n", raw_devices
[1].usUsagePage
);
761 ok(raw_devices
[2].usUsage
== 6, "Unexpected raw device usage: %x\n", raw_devices
[1].usUsage
);
763 ok(raw_devices
[2].dwFlags
== RIDEV_INPUTSINK
, "Unexpected raw device flags: %x\n", raw_devices
[1].dwFlags
);
765 ok(raw_devices
[2].hwndTarget
== di_hwnd
, "Unexpected raw device target: %p\n", raw_devices
[1].hwndTarget
);
766 hr
= IDirectInputDevice8_Unacquire(di_keyboard
);
767 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Acquire failed: %08x\n", hr
);
768 hr
= IDirectInputDevice8_Unacquire(di_mouse
);
769 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Acquire failed: %08x\n", hr
);
770 raw_devices_count
= ARRAY_SIZE(raw_devices
);
771 GetRegisteredRawInputDevices(NULL
, &raw_devices_count
, sizeof(RAWINPUTDEVICE
));
773 ok(raw_devices_count
== 1, "Unexpected raw devices registered: %d\n", raw_devices_count
);
775 IDirectInputDevice8_SetCooperativeLevel(di_mouse
, hwnd
, DISCL_FOREGROUND
|DISCL_EXCLUSIVE
);
776 IDirectInputDevice8_SetCooperativeLevel(di_keyboard
, hwnd
, DISCL_FOREGROUND
|DISCL_EXCLUSIVE
);
778 hr
= IDirectInputDevice8_Acquire(di_keyboard
);
779 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Acquire failed: %08x\n", hr
);
780 hr
= IDirectInputDevice8_Acquire(di_mouse
);
781 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Acquire failed: %08x\n", hr
);
782 raw_devices_count
= ARRAY_SIZE(raw_devices
);
783 memset(raw_devices
, 0, sizeof(raw_devices
));
784 hr
= GetRegisteredRawInputDevices(raw_devices
, &raw_devices_count
, sizeof(RAWINPUTDEVICE
));
785 ok(hr
== 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr
, raw_devices_count
);
786 ok(raw_devices
[0].dwFlags
== (RIDEV_CAPTUREMOUSE
|RIDEV_NOLEGACY
), "Unexpected raw device flags: %x\n", raw_devices
[0].dwFlags
);
788 ok(raw_devices
[2].dwFlags
== (RIDEV_NOHOTKEYS
|RIDEV_NOLEGACY
), "Unexpected raw device flags: %x\n", raw_devices
[1].dwFlags
);
789 hr
= IDirectInputDevice8_Unacquire(di_keyboard
);
790 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Acquire failed: %08x\n", hr
);
791 hr
= IDirectInputDevice8_Unacquire(di_mouse
);
792 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Acquire failed: %08x\n", hr
);
794 raw_devices_count
= ARRAY_SIZE(raw_devices
);
795 hr
= GetRegisteredRawInputDevices(raw_devices
, &raw_devices_count
, sizeof(RAWINPUTDEVICE
));
797 ok(hr
== 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr
, raw_devices_count
);
798 ok(raw_devices
[0].usUsagePage
== 1, "Unexpected raw device usage page: %x\n", raw_devices
[0].usUsagePage
);
799 ok(raw_devices
[0].usUsage
== 5, "Unexpected raw device usage: %x\n", raw_devices
[0].usUsage
);
800 ok(raw_devices
[0].dwFlags
== 0, "Unexpected raw device flags: %x\n", raw_devices
[0].dwFlags
);
801 ok(raw_devices
[0].hwndTarget
== hwnd
, "Unexpected raw device target: %p\n", raw_devices
[0].hwndTarget
);
803 IDirectInputDevice8_Release(di_mouse
);
804 IDirectInputDevice8_Release(di_keyboard
);
805 IDirectInput8_Release(di
);
810 static void test_keyboard_events(void)
813 HWND hwnd
= INVALID_HANDLE_VALUE
;
815 IDirectInputDevice8A
*di_keyboard
;
817 DIDEVICEOBJECTDATA obj_data
[10];
821 hr
= CoCreateInstance(&CLSID_DirectInput8
, 0, CLSCTX_INPROC_SERVER
, &IID_IDirectInput8A
, (LPVOID
*)&di
);
822 if (hr
== DIERR_OLDDIRECTINPUTVERSION
||
823 hr
== DIERR_BETADIRECTINPUTVERSION
||
824 hr
== REGDB_E_CLASSNOTREG
)
826 win_skip("test_keyboard_events requires dinput8\n");
829 ok(SUCCEEDED(hr
), "DirectInput8Create failed: %08x\n", hr
);
831 hr
= IDirectInput8_Initialize(di
, GetModuleHandleA(NULL
), DIRECTINPUT_VERSION
);
832 if (hr
== DIERR_OLDDIRECTINPUTVERSION
|| hr
== DIERR_BETADIRECTINPUTVERSION
)
834 win_skip("test_keyboard_events requires dinput8\n");
835 IDirectInput8_Release(di
);
838 ok(SUCCEEDED(hr
), "IDirectInput8_Initialize failed: %08x\n", hr
);
840 hwnd
= CreateWindowExA(WS_EX_TOPMOST
, "static", "dinput", WS_POPUP
| WS_VISIBLE
, 0, 0, 100, 100, NULL
, NULL
, NULL
, NULL
);
841 ok(hwnd
!= NULL
, "CreateWindowExA failed\n");
843 hr
= IDirectInput8_CreateDevice(di
, &GUID_SysKeyboard
, &di_keyboard
, NULL
);
844 ok(SUCCEEDED(hr
), "IDirectInput8_CreateDevice failed: %08x\n", hr
);
845 hr
= IDirectInputDevice8_SetCooperativeLevel(di_keyboard
, hwnd
, DISCL_BACKGROUND
| DISCL_NONEXCLUSIVE
);
846 ok(SUCCEEDED(hr
), "IDirectInput8_SetCooperativeLevel failed: %08x\n", hr
);
847 hr
= IDirectInputDevice8_SetDataFormat(di_keyboard
, &c_dfDIKeyboard
);
848 ok(SUCCEEDED(hr
), "IDirectInputDevice8_SetDataFormat failed: %08x\n", hr
);
849 dp
.diph
.dwSize
= sizeof(DIPROPDWORD
);
850 dp
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
);
852 dp
.diph
.dwHow
= DIPH_DEVICE
;
853 dp
.dwData
= ARRAY_SIZE(obj_data
);
854 IDirectInputDevice8_SetProperty(di_keyboard
, DIPROP_BUFFERSIZE
, &(dp
.diph
));
856 hr
= IDirectInputDevice8_Acquire(di_keyboard
);
857 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Acquire failed: %08x\n", hr
);
859 /* Test injecting keyboard events with both VK and scancode given. */
860 keybd_event(VK_SPACE
, DIK_SPACE
, 0, 0);
862 IDirectInputDevice8_Poll(di_keyboard
);
863 data_size
= ARRAY_SIZE(obj_data
);
864 hr
= IDirectInputDevice8_GetDeviceData(di_keyboard
, sizeof(DIDEVICEOBJECTDATA
), obj_data
, &data_size
, 0);
865 ok(SUCCEEDED(hr
), "Failed to get data hr=%08x\n", hr
);
866 ok(data_size
== 1, "Expected 1 element, received %d\n", data_size
);
868 hr
= IDirectInputDevice8_GetDeviceState(di_keyboard
, sizeof(kbdata
), kbdata
);
869 ok(SUCCEEDED(hr
), "IDirectInputDevice8_GetDeviceState failed: %08x\n", hr
);
870 ok(kbdata
[DIK_SPACE
], "Expected DIK_SPACE key state down\n");
872 keybd_event(VK_SPACE
, DIK_SPACE
, KEYEVENTF_KEYUP
, 0);
874 IDirectInputDevice8_Poll(di_keyboard
);
875 data_size
= ARRAY_SIZE(obj_data
);
876 hr
= IDirectInputDevice8_GetDeviceData(di_keyboard
, sizeof(DIDEVICEOBJECTDATA
), obj_data
, &data_size
, 0);
877 ok(SUCCEEDED(hr
), "Failed to get data hr=%08x\n", hr
);
878 ok(data_size
== 1, "Expected 1 element, received %d\n", data_size
);
880 /* Test injecting keyboard events with scancode=0.
881 * Windows DInput ignores the VK, sets scancode 0 to be pressed, and GetDeviceData returns no elements. */
882 keybd_event(VK_SPACE
, 0, 0, 0);
884 IDirectInputDevice8_Poll(di_keyboard
);
885 data_size
= ARRAY_SIZE(obj_data
);
886 hr
= IDirectInputDevice8_GetDeviceData(di_keyboard
, sizeof(DIDEVICEOBJECTDATA
), obj_data
, &data_size
, 0);
887 ok(SUCCEEDED(hr
), "Failed to get data hr=%08x\n", hr
);
888 ok(data_size
== 0, "Expected 0 elements, received %d\n", data_size
);
890 hr
= IDirectInputDevice8_GetDeviceState(di_keyboard
, sizeof(kbdata
), kbdata
);
891 ok(SUCCEEDED(hr
), "IDirectInputDevice8_GetDeviceState failed: %08x\n", hr
);
893 ok(kbdata
[0], "Expected key 0 state down\n");
895 keybd_event(VK_SPACE
, 0, KEYEVENTF_KEYUP
, 0);
897 IDirectInputDevice8_Poll(di_keyboard
);
898 data_size
= ARRAY_SIZE(obj_data
);
899 hr
= IDirectInputDevice8_GetDeviceData(di_keyboard
, sizeof(DIDEVICEOBJECTDATA
), obj_data
, &data_size
, 0);
900 ok(SUCCEEDED(hr
), "Failed to get data hr=%08x\n", hr
);
901 ok(data_size
== 0, "Expected 0 elements, received %d\n", data_size
);
903 hr
= IDirectInputDevice8_Unacquire(di_keyboard
);
904 ok(SUCCEEDED(hr
), "IDirectInputDevice8_Unacquire failed: %08x\n", hr
);
906 IDirectInputDevice8_Release(di_keyboard
);
907 IDirectInput8_Release(di
);
912 static void test_appdata_property(void)
915 HINSTANCE hinst
= GetModuleHandleA(NULL
);
916 IDirectInputDevice8A
*di_keyboard
;
917 IDirectInput8A
*pDI
= NULL
;
922 hr
= CoCreateInstance(&CLSID_DirectInput8
, 0, CLSCTX_INPROC_SERVER
, &IID_IDirectInput8A
, (LPVOID
*)&pDI
);
923 if (hr
== DIERR_OLDDIRECTINPUTVERSION
||
924 hr
== DIERR_BETADIRECTINPUTVERSION
||
925 hr
== REGDB_E_CLASSNOTREG
)
927 win_skip("DIPROP_APPDATA requires dinput8\n");
930 ok(SUCCEEDED(hr
), "DirectInput8 Create failed: hr=%08x\n", hr
);
931 if (FAILED(hr
)) return;
933 hr
= IDirectInput8_Initialize(pDI
,hinst
, DIRECTINPUT_VERSION
);
934 if (hr
== DIERR_OLDDIRECTINPUTVERSION
|| hr
== DIERR_BETADIRECTINPUTVERSION
)
936 win_skip("DIPROP_APPDATA requires dinput8\n");
939 ok(SUCCEEDED(hr
), "DirectInput8 Initialize failed: hr=%08x\n", hr
);
940 if (FAILED(hr
)) return;
942 hwnd
= CreateWindowExA(WS_EX_TOPMOST
, "static", "dinput",
943 WS_POPUP
| WS_VISIBLE
, 0, 0, 100, 100, NULL
, NULL
, NULL
, NULL
);
944 ok(hwnd
!= NULL
, "failed to create window\n");
946 hr
= IDirectInput8_CreateDevice(pDI
, &GUID_SysKeyboard
, &di_keyboard
, NULL
);
947 ok(SUCCEEDED(hr
), "IDirectInput8_CreateDevice failed: %08x\n", hr
);
949 hr
= IDirectInputDevice8_SetDataFormat(di_keyboard
, &c_dfDIKeyboard
);
950 ok(SUCCEEDED(hr
), "IDirectInputDevice8_SetDataFormat failed: %08x\n", hr
);
952 dw
.diph
.dwSize
= sizeof(DIPROPDWORD
);
953 dw
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
);
955 dw
.diph
.dwHow
= DIPH_DEVICE
;
957 hr
= IDirectInputDevice8_SetProperty(di_keyboard
, DIPROP_BUFFERSIZE
, &(dw
.diph
));
958 ok(SUCCEEDED(hr
), "IDirectInputDevice8_SetProperty failed hr=%08x\n", hr
);
960 /* the default value */
961 test_device_input(di_keyboard
, INPUT_KEYBOARD
, 'A', -1);
963 dp
.diph
.dwHow
= DIPH_DEVICE
;
966 hr
= IDirectInputDevice8_SetProperty(di_keyboard
, DIPROP_APPDATA
, &(dp
.diph
));
967 ok(hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty APPDATA for the device should be invalid hr=%08x\n", hr
);
969 dp
.diph
.dwSize
= sizeof(dp
);
970 dp
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
);
971 dp
.diph
.dwHow
= DIPH_BYUSAGE
;
974 hr
= IDirectInputDevice8_SetProperty(di_keyboard
, DIPROP_APPDATA
, &(dp
.diph
));
975 ok(hr
== DIERR_UNSUPPORTED
, "IDirectInputDevice8_SetProperty APPDATA by usage should be unsupported hr=%08x\n", hr
);
977 dp
.diph
.dwHow
= DIPH_BYID
;
978 dp
.diph
.dwObj
= DIDFT_MAKEINSTANCE(DIK_SPACE
) | DIDFT_PSHBUTTON
;
980 hr
= IDirectInputDevice8_SetProperty(di_keyboard
, DIPROP_APPDATA
, &(dp
.diph
));
981 ok(SUCCEEDED(hr
), "IDirectInputDevice8_SetProperty failed hr=%08x\n", hr
);
983 dp
.diph
.dwHow
= DIPH_BYOFFSET
;
984 dp
.diph
.dwObj
= DIK_A
;
986 hr
= IDirectInputDevice8_SetProperty(di_keyboard
, DIPROP_APPDATA
, &(dp
.diph
));
987 ok(SUCCEEDED(hr
), "IDirectInputDevice8_SetProperty failed hr=%08x\n", hr
);
989 dp
.diph
.dwHow
= DIPH_BYOFFSET
;
990 dp
.diph
.dwObj
= DIK_B
;
992 hr
= IDirectInputDevice8_SetProperty(di_keyboard
, DIPROP_APPDATA
, &(dp
.diph
));
993 ok(SUCCEEDED(hr
), "IDirectInputDevice8_SetProperty failed hr=%08x\n", hr
);
995 test_device_input(di_keyboard
, INPUT_KEYBOARD
, VK_SPACE
, 3);
996 test_device_input(di_keyboard
, INPUT_KEYBOARD
, 'A', 4);
997 test_device_input(di_keyboard
, INPUT_KEYBOARD
, 'B', 5);
998 test_device_input(di_keyboard
, INPUT_KEYBOARD
, 'C', -1);
1000 /* setting data format resets APPDATA */
1001 hr
= IDirectInputDevice8_SetDataFormat(di_keyboard
, &c_dfDIKeyboard
);
1002 ok(SUCCEEDED(hr
), "IDirectInputDevice8_SetDataFormat failed: %08x\n", hr
);
1004 test_device_input(di_keyboard
, INPUT_KEYBOARD
, VK_SPACE
, -1);
1005 test_device_input(di_keyboard
, INPUT_KEYBOARD
, 'A', -1);
1006 test_device_input(di_keyboard
, INPUT_KEYBOARD
, 'B', -1);
1007 test_device_input(di_keyboard
, INPUT_KEYBOARD
, 'C', -1);
1009 DestroyWindow(hwnd
);
1010 IDirectInputDevice_Release(di_keyboard
);
1011 IDirectInput_Release(pDI
);
1018 test_action_mapping();
1019 test_save_settings();
1020 test_mouse_keyboard();
1021 test_keyboard_events();
1022 test_appdata_property();