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
24 #include "wine/test.h"
29 static const DIOBJECTDATAFORMAT obj_data_format[] = {
30 { &GUID_YAxis, 16, DIDFT_OPTIONAL|DIDFT_AXIS |DIDFT_MAKEINSTANCE(1), 0},
31 { &GUID_Button,15, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(3), 0},
32 { &GUID_Key, 0, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(16),0},
33 { &GUID_Key, 1, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(17),0},
34 { &GUID_Key, 2, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(18),0},
35 { &GUID_Key, 3, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(19),0},
36 { &GUID_Key, 4, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(20),0},
37 { &GUID_Key, 5, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(21),0},
38 { &GUID_Key, 6, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(22),0},
39 { &GUID_Key, 7, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(23),0},
40 { &GUID_Key, 8, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(24),0},
41 { &GUID_Key, 9, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(25),0},
42 { &GUID_Key, 10, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(26),0},
43 { &GUID_Key, 11, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(27),0},
44 { &GUID_Key, 12, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(28),0},
45 { NULL, 13, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(5),0},
47 { &GUID_Button,14, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(32),0}
50 static const DIDATAFORMAT data_format = {
52 sizeof(DIOBJECTDATAFORMAT),
55 sizeof(obj_data_format) / sizeof(obj_data_format[0]),
56 (LPDIOBJECTDATAFORMAT)obj_data_format
59 static BOOL CALLBACK enum_callback(LPCDIDEVICEOBJECTINSTANCE oi, LPVOID info)
61 if (winetest_debug > 1)
62 trace(" Type:%4x Ofs:%3d Flags:%08x Name:%s\n",
63 oi->dwType, oi->dwOfs, oi->dwFlags, oi->tszName);
65 return DIENUM_CONTINUE;
68 static void test_object_info(LPDIRECTINPUTDEVICE device, HWND hwnd)
72 DIDEVICEOBJECTINSTANCE obj_info;
73 int cnt = 0, cnt1 = 0;
75 hr = IDirectInputDevice_EnumObjects(device, enum_callback, &cnt, DIDFT_ALL);
76 ok(SUCCEEDED(hr), "EnumObjects() failed: %s\n", DXGetErrorString8(hr));
78 hr = IDirectInputDevice_SetDataFormat(device, &data_format);
79 ok(SUCCEEDED(hr), "SetDataFormat() failed: %s\n", DXGetErrorString8(hr));
81 hr = IDirectInputDevice_EnumObjects(device, enum_callback, &cnt1, DIDFT_ALL);
82 ok(SUCCEEDED(hr), "EnumObjects() failed: %s\n", DXGetErrorString8(hr));
83 if (0) /* fails for joystick only */
84 ok(cnt == cnt1, "Enum count changed from %d to %d\n", cnt, cnt1);
86 /* No need to test devices without axis */
87 obj_info.dwSize = sizeof(obj_info);
88 hr = IDirectInputDevice_GetObjectInfo(device, &obj_info, 16, DIPH_BYOFFSET);
91 /* No device supports per axis relative/absolute mode */
92 memset(&dp, 0, sizeof(dp));
93 dp.diph.dwSize = sizeof(DIPROPDWORD);
94 dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
95 dp.diph.dwHow = DIPH_BYOFFSET;
97 dp.dwData = DIPROPAXISMODE_ABS;
98 hr = IDirectInputDevice_SetProperty(device, DIPROP_AXISMODE, &dp.diph);
99 ok(hr == DIERR_UNSUPPORTED, "SetProperty() returned: %s\n", DXGetErrorString8(hr));
100 dp.diph.dwHow = DIPH_DEVICE;
101 hr = IDirectInputDevice_SetProperty(device, DIPROP_AXISMODE, &dp.diph);
102 ok(hr == DIERR_INVALIDPARAM, "SetProperty() returned: %s\n", DXGetErrorString8(hr));
104 hr = IDirectInputDevice_SetProperty(device, DIPROP_AXISMODE, &dp.diph);
105 ok(hr == DI_OK, "SetProperty() failed: %s\n", DXGetErrorString8(hr));
107 /* Cannot change mode while acquired */
108 hr = IDirectInputDevice_Acquire(device);
109 ok(hr == DI_OK, "Acquire() failed: %s\n", DXGetErrorString8(hr));
110 hr = IDirectInputDevice_SetProperty(device, DIPROP_AXISMODE, &dp.diph);
111 ok(hr == DIERR_ACQUIRED, "SetProperty() returned: %s\n", DXGetErrorString8(hr));
121 static BOOL CALLBACK enum_devices(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
123 struct enum_data *data = (struct enum_data*)pvRef;
124 LPDIRECTINPUTDEVICE device;
127 hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidInstance, &device, NULL);
128 ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %s\n", DXGetErrorString8(hr));
131 trace("Testing device \"%s\"\n", lpddi->tszInstanceName);
132 test_object_info(device, data->hwnd);
133 IUnknown_Release(device);
135 return DIENUM_CONTINUE;
138 static void device_tests(void)
141 LPDIRECTINPUT pDI = NULL;
142 HINSTANCE hInstance = GetModuleHandle(NULL);
144 struct enum_data data;
146 hr = DirectInputCreate(hInstance, DIRECTINPUT_VERSION, &pDI, NULL);
147 if (hr == DIERR_OLDDIRECTINPUTVERSION)
149 skip("Tests require a newer dinput version\n");
152 ok(SUCCEEDED(hr), "DirectInputCreate() failed: %s\n", DXGetErrorString8(hr));
153 if (FAILED(hr)) return;
155 hwnd = CreateWindow("static", "Title", WS_OVERLAPPEDWINDOW,
156 10, 10, 200, 200, NULL, NULL, NULL, NULL);
157 ok(hwnd != NULL, "err: %d\n", GetLastError());
160 ShowWindow(hwnd, SW_SHOW);
164 hr = IDirectInput_EnumDevices(pDI, 0, enum_devices, &data, DIEDFL_ALLDEVICES);
165 ok(SUCCEEDED(hr), "IDirectInput_EnumDevices() failed: %s\n", DXGetErrorString8(hr));
169 if (pDI) IUnknown_Release(pDI);