server: Remove the socket from the polling loop if it was aborted.
[wine.git] / dlls / dinput / tests / device.c
blob6307957b6e2dba909a4193129247522e7b462728
1 /*
2 * Copyright (c) 2006 Vitaliy Margolen
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define DIRECTINPUT_VERSION 0x0700
21 #define COBJMACROS
22 #include <windows.h>
24 #include "wine/test.h"
25 #include "windef.h"
26 #include "dinput.h"
28 #include <limits.h>
30 static const DIOBJECTDATAFORMAT obj_data_format[] = {
31 { &GUID_YAxis, 16, DIDFT_OPTIONAL|DIDFT_AXIS |DIDFT_MAKEINSTANCE(1), 0},
32 { &GUID_Button,15, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(3), 0},
33 { &GUID_Key, 0, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(16),0},
34 { &GUID_Key, 1, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(17),0},
35 { &GUID_Key, 2, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(18),0},
36 { &GUID_Key, 3, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(19),0},
37 { &GUID_Key, 4, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(20),0},
38 { &GUID_Key, 5, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(21),0},
39 { &GUID_Key, 6, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(22),0},
40 { &GUID_Key, 7, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(23),0},
41 { &GUID_Key, 8, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(24),0},
42 { &GUID_Key, 9, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(25),0},
43 { &GUID_Key, 10, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(26),0},
44 { &GUID_Key, 11, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(27),0},
45 { &GUID_Key, 12, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(28),0},
46 { NULL, 13, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(5),0},
48 { &GUID_Button,14, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(32),0}
51 static const DIDATAFORMAT data_format = {
52 sizeof(DIDATAFORMAT),
53 sizeof(DIOBJECTDATAFORMAT),
54 DIDF_ABSAXIS,
55 32,
56 ARRAY_SIZE(obj_data_format),
57 (LPDIOBJECTDATAFORMAT)obj_data_format
60 static BOOL CALLBACK enum_callback(const DIDEVICEOBJECTINSTANCEA *oi, void *info)
62 if (winetest_debug > 1)
63 trace(" Type:%4x Ofs:%3d Flags:%08x Name:%s\n",
64 oi->dwType, oi->dwOfs, oi->dwFlags, oi->tszName);
65 (*(int*)info)++;
66 return DIENUM_CONTINUE;
69 static BOOL CALLBACK enum_type_callback(const DIDEVICEOBJECTINSTANCEA *oi, void *info)
71 DWORD expected = *(DWORD*)info;
72 ok (expected & DIDFT_GETTYPE(oi->dwType), "EnumObjects() enumerated wrong type for obj %s, expected: %08x got: %08x\n", oi->tszName, expected, oi->dwType);
73 return DIENUM_CONTINUE;
76 static void test_object_info(IDirectInputDeviceA *device, HWND hwnd)
78 HRESULT hr;
79 DIPROPDWORD dp;
80 DIDEVICEOBJECTINSTANCEA obj_info;
81 DWORD obj_types[] = {DIDFT_BUTTON, DIDFT_AXIS, DIDFT_POV};
82 int type_index;
83 int cnt1 = 0;
84 DWORD cnt = 0;
85 DIDEVICEOBJECTDATA buffer[5];
87 hr = IDirectInputDevice_EnumObjects(device, NULL, &cnt, DIDFT_ALL);
88 ok(hr == DIERR_INVALIDPARAM, "IDirectInputDevice_EnumObjects returned %08x, expected %08x\n", hr, DIERR_INVALIDPARAM);
90 hr = IDirectInputDevice_EnumObjects(device, enum_callback, &cnt, DIDFT_ALL);
91 ok(SUCCEEDED(hr), "EnumObjects() failed: %08x\n", hr);
93 hr = IDirectInputDevice_SetDataFormat(device, &data_format);
94 ok(SUCCEEDED(hr), "SetDataFormat() failed: %08x\n", hr);
96 hr = IDirectInputDevice_EnumObjects(device, enum_callback, &cnt1, DIDFT_ALL);
97 ok(SUCCEEDED(hr), "EnumObjects() failed: %08x\n", hr);
98 if (0) /* fails for joystick only */
99 ok(cnt == cnt1, "Enum count changed from %d to %d\n", cnt, cnt1);
101 /* Testing EnumObjects with different types of device objects */
102 for (type_index=0; type_index < ARRAY_SIZE(obj_types); type_index++)
104 hr = IDirectInputDevice_EnumObjects(device, enum_type_callback, &obj_types[type_index], obj_types[type_index]);
105 ok(SUCCEEDED(hr), "EnumObjects() failed: %08x\n", hr);
108 /* Test buffered mode */
109 memset(&dp, 0, sizeof(dp));
110 dp.diph.dwSize = sizeof(DIPROPDWORD);
111 dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
112 dp.diph.dwHow = DIPH_DEVICE;
113 dp.diph.dwObj = 0;
114 dp.dwData = UINT_MAX;
116 hr = IDirectInputDevice_GetProperty(device, DIPROP_BUFFERSIZE, &dp.diph);
117 ok(hr == DI_OK, "Failed: %08x\n", hr);
118 ok(dp.dwData == 0, "got %d\n", dp.dwData);
120 dp.dwData = UINT_MAX;
121 hr = IDirectInputDevice_SetProperty(device, DIPROP_BUFFERSIZE, (LPCDIPROPHEADER)&dp.diph);
122 ok(hr == DI_OK, "SetProperty() failed: %08x\n", hr);
124 dp.dwData = 0;
125 hr = IDirectInputDevice_GetProperty(device, DIPROP_BUFFERSIZE, &dp.diph);
126 ok(hr == DI_OK, "Failed: %08x\n", hr);
127 ok(dp.dwData == UINT_MAX, "got %d\n", dp.dwData);
129 dp.dwData = 0;
130 hr = IDirectInputDevice_SetProperty(device, DIPROP_BUFFERSIZE, (LPCDIPROPHEADER)&dp.diph);
131 ok(hr == DI_OK, "SetProperty() failed: %08x\n", hr);
132 cnt = 5;
133 hr = IDirectInputDevice_GetDeviceData(device, sizeof(buffer[0]), buffer, &cnt, 0);
134 ok(hr == DI_OK && cnt == 5, "GetDeviceData() failed: %08x cnt: %d\n", hr, cnt);
135 hr = IDirectInputDevice_GetDeviceData(device, sizeof(DIDEVICEOBJECTDATA_DX3), buffer, &cnt, 0);
136 ok(hr == DIERR_NOTBUFFERED, "GetDeviceData() should have failed: %08x\n", hr);
137 IDirectInputDevice_Acquire(device);
138 hr = IDirectInputDevice_GetDeviceData(device, sizeof(DIDEVICEOBJECTDATA_DX3), buffer, &cnt, 0);
139 ok(hr == DIERR_NOTBUFFERED, "GetDeviceData() should have failed: %08x\n", hr);
140 IDirectInputDevice_Unacquire(device);
142 dp.dwData = 20;
143 hr = IDirectInputDevice_SetProperty(device, DIPROP_BUFFERSIZE, (LPCDIPROPHEADER)&dp.diph);
144 ok(hr == DI_OK, "SetProperty() failed: %08x\n", hr);
145 cnt = 5;
146 hr = IDirectInputDevice_GetDeviceData(device, sizeof(buffer[0]), buffer, &cnt, 0);
147 ok(hr == DI_OK, "GetDeviceData() failed: %08x\n", hr);
148 hr = IDirectInputDevice_GetDeviceData(device, sizeof(DIDEVICEOBJECTDATA_DX3), buffer, &cnt, 0);
149 ok(hr == DIERR_NOTACQUIRED, "GetDeviceData() should have failed: %08x\n", hr);
150 hr = IDirectInputDevice_Acquire(device);
151 ok(hr == DI_OK, "Acquire() failed: %08x\n", hr);
152 cnt = 1;
153 hr = IDirectInputDevice_GetDeviceData(device, sizeof(buffer[0]), buffer, &cnt, 0);
154 ok(hr == DI_OK, "GetDeviceData() failed: %08x\n", hr);
155 hr = IDirectInputDevice_Unacquire(device);
156 ok(hr == DI_OK, "Unacquire() failed: %08x\n", hr);
157 cnt = 1;
158 hr = IDirectInputDevice_GetDeviceData(device, sizeof(buffer[0]), buffer, &cnt, 0);
159 ok(hr == DI_OK, "GetDeviceData() failed: %08x\n", hr);
161 hr = IDirectInputDevice_GetObjectInfo(device, NULL, 16, DIPH_BYOFFSET);
162 ok(hr == E_POINTER, "IDirectInputDevice_GetObjectInfo returned %08x, expected %08x\n", hr, E_POINTER);
164 obj_info.dwSize = 1;
165 hr = IDirectInputDevice_GetObjectInfo(device, &obj_info, 16, DIPH_BYOFFSET);
166 ok(hr == DIERR_INVALIDPARAM, "IDirectInputDevice_GetObjectInfo returned %08x, expected %08x\n", hr, DIERR_INVALIDPARAM);
167 obj_info.dwSize = 0xdeadbeef;
168 hr = IDirectInputDevice_GetObjectInfo(device, &obj_info, 16, DIPH_BYOFFSET);
169 ok(hr == DIERR_INVALIDPARAM, "IDirectInputDevice_GetObjectInfo returned %08x, expected %08x\n", hr, DIERR_INVALIDPARAM);
171 /* No need to test devices without axis */
172 obj_info.dwSize = sizeof(obj_info);
173 hr = IDirectInputDevice_GetObjectInfo(device, &obj_info, 16, DIPH_BYOFFSET);
174 if (SUCCEEDED(hr))
176 /* No device supports per axis relative/absolute mode */
177 dp.diph.dwHow = DIPH_BYOFFSET;
178 dp.diph.dwObj = 16;
179 dp.dwData = DIPROPAXISMODE_ABS;
180 hr = IDirectInputDevice_SetProperty(device, DIPROP_AXISMODE, &dp.diph);
181 ok(hr == DIERR_UNSUPPORTED, "SetProperty() returned: %08x\n", hr);
182 dp.diph.dwHow = DIPH_DEVICE;
183 hr = IDirectInputDevice_SetProperty(device, DIPROP_AXISMODE, &dp.diph);
184 ok(hr == DIERR_INVALIDPARAM, "SetProperty() returned: %08x\n", hr);
185 dp.diph.dwObj = 0;
186 hr = IDirectInputDevice_SetProperty(device, DIPROP_AXISMODE, &dp.diph);
187 ok(hr == DI_OK, "SetProperty() failed: %08x\n", hr);
189 /* Cannot change mode while acquired */
190 hr = IDirectInputDevice_Acquire(device);
191 ok(hr == DI_OK, "Acquire() failed: %08x\n", hr);
193 hr = IDirectInputDevice_SetProperty(device, DIPROP_AXISMODE, &dp.diph);
194 ok(hr == DIERR_ACQUIRED, "SetProperty() returned: %08x\n", hr);
195 hr = IDirectInputDevice_Unacquire(device);
196 ok(hr == DI_OK, "Unacquire() failed: %08x\n", hr);
199 /* Reset buffer size */
200 dp.diph.dwSize = sizeof(DIPROPDWORD);
201 dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
202 dp.diph.dwHow = DIPH_DEVICE;
203 dp.diph.dwObj = 0;
204 dp.dwData = 0;
205 hr = IDirectInputDevice_SetProperty(device, DIPROP_BUFFERSIZE, (LPCDIPROPHEADER)&dp.diph);
206 ok(hr == DI_OK, "SetProperty() failed: %08x\n", hr);
209 struct enum_data
211 IDirectInputA *pDI;
212 HWND hwnd;
213 BOOL tested_product_creation;
216 static BOOL CALLBACK enum_devices(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
218 struct enum_data *data = pvRef;
219 IDirectInputDeviceA *device, *obj = NULL;
220 DIDEVICEINSTANCEA ddi2;
221 HRESULT hr;
222 IUnknown *iface, *tmp_iface;
224 hr = IDirectInput_GetDeviceStatus(data->pDI, &lpddi->guidInstance);
225 ok(hr == DI_OK, "IDirectInput_GetDeviceStatus() failed: %08x\n", hr);
227 if (hr == DI_OK)
229 hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidInstance, &device, NULL);
230 ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
231 trace("Testing device %p \"%s\"\n", device, lpddi->tszInstanceName);
233 hr = IUnknown_QueryInterface(device, &IID_IDirectInputDevice2A, (LPVOID*)&obj);
234 ok(SUCCEEDED(hr), "IUnknown_QueryInterface(IID_IDirectInputDevice2A) failed: %08x\n", hr);
235 test_object_info(obj, data->hwnd);
236 IUnknown_Release(obj);
237 obj = NULL;
239 hr = IUnknown_QueryInterface(device, &IID_IDirectInputDevice2W, (LPVOID*)&obj);
240 ok(SUCCEEDED(hr), "IUnknown_QueryInterface(IID_IDirectInputDevice2W) failed: %08x\n", hr);
241 test_object_info(obj, data->hwnd);
242 IUnknown_Release(obj);
244 hr = IUnknown_QueryInterface( device, &IID_IDirectInputDeviceA, (void **)&iface );
245 ok( SUCCEEDED(hr), "IUnknown_QueryInterface(IID_IDirectInputDeviceA) failed: %08x\n", hr );
246 hr = IUnknown_QueryInterface( device, &IID_IDirectInputDevice2A, (void **)&tmp_iface );
247 ok( SUCCEEDED(hr), "IUnknown_QueryInterface(IID_IDirectInputDevice2A) failed: %08x\n", hr );
248 ok( tmp_iface == iface, "IDirectInputDevice2A iface differs from IDirectInputDeviceA\n" );
249 IUnknown_Release( tmp_iface );
250 hr = IUnknown_QueryInterface( device, &IID_IDirectInputDevice7A, (void **)&tmp_iface );
251 ok( SUCCEEDED(hr), "IUnknown_QueryInterface(IID_IDirectInputDevice7A) failed: %08x\n", hr );
252 ok( tmp_iface == iface, "IDirectInputDevice7A iface differs from IDirectInputDeviceA\n" );
253 IUnknown_Release( tmp_iface );
254 IUnknown_Release( iface );
256 hr = IUnknown_QueryInterface( device, &IID_IUnknown, (void **)&iface );
257 ok( SUCCEEDED(hr), "IUnknown_QueryInterface(IID_IUnknown) failed: %08x\n", hr );
258 hr = IUnknown_QueryInterface( device, &IID_IDirectInputDeviceW, (void **)&tmp_iface );
259 ok( SUCCEEDED(hr), "IUnknown_QueryInterface(IID_IDirectInputDeviceW) failed: %08x\n", hr );
260 ok( tmp_iface == iface, "IDirectInputDeviceW iface differs from IUnknown\n" );
261 IUnknown_Release( tmp_iface );
262 hr = IUnknown_QueryInterface( device, &IID_IDirectInputDevice2W, (void **)&tmp_iface );
263 ok( SUCCEEDED(hr), "IUnknown_QueryInterface(IID_IDirectInputDevice2W) failed: %08x\n", hr );
264 ok( tmp_iface == iface, "IDirectInputDevice2W iface differs from IUnknown\n" );
265 IUnknown_Release( tmp_iface );
266 hr = IUnknown_QueryInterface( device, &IID_IDirectInputDevice7W, (void **)&tmp_iface );
267 ok( SUCCEEDED(hr), "IUnknown_QueryInterface(IID_IDirectInputDevice7W) failed: %08x\n", hr );
268 ok( tmp_iface == iface, "IDirectInputDevice7W iface differs from IUnknown\n" );
269 IUnknown_Release( tmp_iface );
270 IUnknown_Release( iface );
272 IUnknown_Release(device);
274 if (!IsEqualGUID(&lpddi->guidInstance, &lpddi->guidProduct))
276 data->tested_product_creation = TRUE;
277 hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidProduct, &device, NULL);
278 ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
280 ddi2.dwSize = sizeof(ddi2);
281 hr = IDirectInputDevice_GetDeviceInfo(device, &ddi2);
282 ok(SUCCEEDED(hr), "IDirectInput_GetDeviceInfo failed: %08x\n", hr);
284 ok(IsEqualGUID(&lpddi->guidProduct, &ddi2.guidProduct), "Product GUIDs do not match. Expected %s, got %s\n", debugstr_guid(&lpddi->guidProduct), debugstr_guid(&ddi2.guidProduct));
285 ok(IsEqualGUID(&ddi2.guidProduct, &ddi2.guidInstance), "Instance GUID should equal product GUID. Expected %s, got %s\n", debugstr_guid(&ddi2.guidProduct), debugstr_guid(&ddi2.guidInstance));
286 /* we cannot compare guidInstances as we may get a different device */
288 IUnknown_Release(device);
292 return DIENUM_CONTINUE;
295 struct overlapped_state
297 BYTE keys[4];
298 DWORD extra_element;
301 static const DIOBJECTDATAFORMAT obj_overlapped_slider_format[] = {
302 { &GUID_Key, 0, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(DIK_A),0},
303 { &GUID_Key, 1, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(DIK_S),0},
304 { &GUID_Key, 2, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(DIK_D),0},
305 { &GUID_Key, 3, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(DIK_F),0},
306 { &GUID_Slider, 0, DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION},
309 static const DIDATAFORMAT overlapped_slider_format = {
310 sizeof(DIDATAFORMAT),
311 sizeof(DIOBJECTDATAFORMAT),
312 DIDF_ABSAXIS,
313 sizeof(struct overlapped_state),
314 ARRAY_SIZE(obj_overlapped_slider_format),
315 (LPDIOBJECTDATAFORMAT)obj_overlapped_slider_format
318 static const DIOBJECTDATAFORMAT obj_overlapped_pov_format[] = {
319 { &GUID_Key, 0, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(DIK_A),0},
320 { &GUID_Key, 1, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(DIK_S),0},
321 { &GUID_Key, 2, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(DIK_D),0},
322 { &GUID_Key, 3, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(DIK_F),0},
323 { &GUID_POV, 0, DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
326 static const DIDATAFORMAT overlapped_pov_format = {
327 sizeof(DIDATAFORMAT),
328 sizeof(DIOBJECTDATAFORMAT),
329 DIDF_ABSAXIS,
330 sizeof(struct overlapped_state),
331 ARRAY_SIZE(obj_overlapped_pov_format),
332 (LPDIOBJECTDATAFORMAT)obj_overlapped_pov_format
335 static void pump_messages(void)
337 MSG msg;
339 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
341 TranslateMessage(&msg);
342 DispatchMessageA(&msg);
346 void overlapped_format_tests(IDirectInputA *pDI, HWND hwnd)
348 HRESULT hr;
349 struct overlapped_state state;
350 IDirectInputDeviceA *keyboard = NULL;
352 hr = IDirectInput_CreateDevice(pDI, &GUID_SysKeyboard, &keyboard, NULL);
353 ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
355 /* test overlapped slider - default value 0 */
356 hr = IDirectInputDevice_SetDataFormat(keyboard, &overlapped_slider_format);
357 ok(SUCCEEDED(hr), "IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
358 hr = IDirectInputDevice_Acquire(keyboard);
359 ok(SUCCEEDED(hr), "IDirectInputDevice_Acquire() failed: %08x\n", hr);
361 SetFocus(hwnd);
362 pump_messages();
364 /* press D */
365 keybd_event(0, DIK_D, KEYEVENTF_SCANCODE, 0);
366 pump_messages();
368 memset(&state, 0xFF, sizeof(state));
369 hr = IDirectInputDevice_GetDeviceState(keyboard, sizeof(state), &state);
370 ok(SUCCEEDED(hr), "IDirectInputDevice_GetDeviceState() failed: %08x\n", hr);
372 ok(state.keys[0] == 0x00, "key A should be still up\n");
373 ok(state.keys[1] == 0x00, "key S should be still up\n");
374 ok(state.keys[2] == 0x80, "keydown for D did not register\n");
375 ok(state.keys[3] == 0x00, "key F should be still up\n");
376 ok(state.extra_element == 0, "State struct was not memset to zero\n");
378 /* release D */
379 keybd_event(0, DIK_D, KEYEVENTF_SCANCODE|KEYEVENTF_KEYUP, 0);
380 pump_messages();
382 hr = IDirectInputDevice_Unacquire(keyboard);
383 ok(SUCCEEDED(hr), "IDirectInputDevice_Unacquire() failed: %08x\n", hr);
385 /* test overlapped pov - default value - 0xFFFFFFFF */
386 hr = IDirectInputDevice_SetDataFormat(keyboard, &overlapped_pov_format);
387 ok(SUCCEEDED(hr), "IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
388 hr = IDirectInputDevice_Acquire(keyboard);
389 ok(SUCCEEDED(hr), "IDirectInputDevice_Acquire() failed: %08x\n", hr);
391 SetFocus(hwnd);
392 pump_messages();
394 /* press D */
395 keybd_event(0, DIK_D, KEYEVENTF_SCANCODE, 0);
396 pump_messages();
398 memset(&state, 0xFF, sizeof(state));
399 hr = IDirectInputDevice_GetDeviceState(keyboard, sizeof(state), &state);
400 ok(SUCCEEDED(hr), "IDirectInputDevice_GetDeviceState() failed: %08x\n", hr);
402 ok(state.keys[0] == 0xFF, "key state should have been overwritten by the overlapped POV\n");
403 ok(state.keys[1] == 0xFF, "key state should have been overwritten by the overlapped POV\n");
404 ok(state.keys[2] == 0xFF, "key state should have been overwritten by the overlapped POV\n");
405 ok(state.keys[3] == 0xFF, "key state should have been overwritten by the overlapped POV\n");
406 ok(state.extra_element == 0, "State struct was not memset to zero\n");
408 /* release D */
409 keybd_event(0, DIK_D, KEYEVENTF_SCANCODE|KEYEVENTF_KEYUP, 0);
410 pump_messages();
412 if (keyboard) IUnknown_Release(keyboard);
415 static void device_tests(void)
417 HRESULT hr;
418 IDirectInputA *pDI = NULL, *obj = NULL;
419 HINSTANCE hInstance = GetModuleHandleW(NULL);
420 HWND hwnd;
421 struct enum_data data;
423 hr = CoCreateInstance(&CLSID_DirectInput, 0, 1, &IID_IDirectInput2A, (LPVOID*)&pDI);
424 if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_DEVICENOTREG)
426 skip("Tests require a newer dinput version\n");
427 return;
429 ok(SUCCEEDED(hr), "DirectInputCreateA() failed: %08x\n", hr);
430 if (FAILED(hr)) return;
432 hr = IDirectInput_Initialize(pDI, hInstance, DIRECTINPUT_VERSION);
433 ok(SUCCEEDED(hr), "Initialize() failed: %08x\n", hr);
434 if (FAILED(hr)) return;
436 hr = IUnknown_QueryInterface(pDI, &IID_IDirectInput2W, (LPVOID*)&obj);
437 ok(SUCCEEDED(hr), "QueryInterface(IDirectInput7W) failed: %08x\n", hr);
439 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
440 NULL, NULL);
441 ok(hwnd != NULL, "err: %d\n", GetLastError());
442 if (hwnd)
444 ShowWindow(hwnd, SW_SHOW);
446 data.pDI = pDI;
447 data.hwnd = hwnd;
448 data.tested_product_creation = FALSE;
449 hr = IDirectInput_EnumDevices(pDI, 0, enum_devices, &data, DIEDFL_ALLDEVICES);
450 ok(SUCCEEDED(hr), "IDirectInput_EnumDevices() failed: %08x\n", hr);
452 if (!data.tested_product_creation) winetest_skip("Device creation using product GUID not tested\n");
454 /* If GetDeviceStatus returns DI_OK the device must exist */
455 hr = IDirectInput_GetDeviceStatus(pDI, &GUID_Joystick);
456 if (hr == DI_OK)
458 IDirectInputDeviceA *device = NULL;
460 hr = IDirectInput_CreateDevice(pDI, &GUID_Joystick, &device, NULL);
461 ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
462 if (device) IUnknown_Release(device);
465 overlapped_format_tests(pDI, hwnd);
467 DestroyWindow(hwnd);
469 if (obj) IUnknown_Release(obj);
470 if (pDI) IUnknown_Release(pDI);
473 START_TEST(device)
475 CoInitialize(NULL);
477 device_tests();
479 CoUninitialize();