2 * Copyright (c) 2004-2005 Robert Reif
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #define DIRECTINPUT_VERSION 0x0700
21 #define NONAMELESSSTRUCT
22 #define NONAMELESSUNION
29 #include "wine/test.h"
34 #include "dinput_test.h"
36 #define numObjects(x) (sizeof(x) / sizeof(x[0]))
38 typedef struct tagUserData
{
43 static const DIOBJECTDATAFORMAT dfDIJoystickTest
[] = {
44 { &GUID_XAxis
,DIJOFS_X
,DIDFT_OPTIONAL
|DIDFT_AXIS
|DIDFT_ANYINSTANCE
,0},
45 { &GUID_YAxis
,DIJOFS_Y
,DIDFT_OPTIONAL
|DIDFT_AXIS
|DIDFT_ANYINSTANCE
,0},
46 { &GUID_ZAxis
,DIJOFS_Z
,DIDFT_OPTIONAL
|DIDFT_AXIS
|DIDFT_ANYINSTANCE
,0},
47 { &GUID_RxAxis
,DIJOFS_RX
,DIDFT_OPTIONAL
|DIDFT_AXIS
|DIDFT_ANYINSTANCE
,0},
48 { &GUID_RyAxis
,DIJOFS_RY
,DIDFT_OPTIONAL
|DIDFT_AXIS
|DIDFT_ANYINSTANCE
,0},
49 { &GUID_RzAxis
,DIJOFS_RZ
,DIDFT_OPTIONAL
|DIDFT_AXIS
|DIDFT_ANYINSTANCE
,0},
50 { &GUID_Button
,DIJOFS_BUTTON(0),DIDFT_OPTIONAL
|DIDFT_BUTTON
|DIDFT_ANYINSTANCE
,0},
51 { &GUID_Button
,DIJOFS_BUTTON(1),DIDFT_OPTIONAL
|DIDFT_BUTTON
|DIDFT_ANYINSTANCE
,0},
52 { &GUID_Button
,DIJOFS_BUTTON(2),DIDFT_OPTIONAL
|DIDFT_BUTTON
|DIDFT_ANYINSTANCE
,0},
53 { &GUID_Button
,DIJOFS_BUTTON(3),DIDFT_OPTIONAL
|DIDFT_BUTTON
|DIDFT_ANYINSTANCE
,0},
54 { &GUID_Button
,DIJOFS_BUTTON(4),DIDFT_OPTIONAL
|DIDFT_BUTTON
|DIDFT_ANYINSTANCE
,0},
55 { &GUID_Button
,DIJOFS_BUTTON(5),DIDFT_OPTIONAL
|DIDFT_BUTTON
|DIDFT_ANYINSTANCE
,0},
56 { &GUID_Button
,DIJOFS_BUTTON(6),DIDFT_OPTIONAL
|DIDFT_BUTTON
|DIDFT_ANYINSTANCE
,0},
57 { &GUID_Button
,DIJOFS_BUTTON(7),DIDFT_OPTIONAL
|DIDFT_BUTTON
|DIDFT_ANYINSTANCE
,0},
58 { &GUID_Button
,DIJOFS_BUTTON(8),DIDFT_OPTIONAL
|DIDFT_BUTTON
|DIDFT_ANYINSTANCE
,0},
59 { &GUID_Button
,DIJOFS_BUTTON(9),DIDFT_OPTIONAL
|DIDFT_BUTTON
|DIDFT_ANYINSTANCE
,0},
60 { &GUID_Button
,DIJOFS_BUTTON(10),DIDFT_OPTIONAL
|DIDFT_BUTTON
|DIDFT_ANYINSTANCE
,0},
63 static const DIDATAFORMAT c_dfDIJoystickTest
= {
65 sizeof(DIOBJECTDATAFORMAT
),
68 numObjects(dfDIJoystickTest
),
69 (LPDIOBJECTDATAFORMAT
)dfDIJoystickTest
74 HWND hwnd
=GetForegroundWindow();
76 hwnd
=GetDesktopWindow();
80 typedef struct tagJoystickInfo
82 LPDIRECTINPUTDEVICE pJoystick
;
88 static BOOL CALLBACK
EnumAxes(
89 const DIDEVICEOBJECTINSTANCE
* pdidoi
,
93 JoystickInfo
* info
= (JoystickInfo
*)pContext
;
95 if (IsEqualIID(&pdidoi
->guidType
, &GUID_XAxis
) ||
96 IsEqualIID(&pdidoi
->guidType
, &GUID_YAxis
) ||
97 IsEqualIID(&pdidoi
->guidType
, &GUID_ZAxis
) ||
98 IsEqualIID(&pdidoi
->guidType
, &GUID_RxAxis
) ||
99 IsEqualIID(&pdidoi
->guidType
, &GUID_RyAxis
) ||
100 IsEqualIID(&pdidoi
->guidType
, &GUID_RzAxis
) ||
101 IsEqualIID(&pdidoi
->guidType
, &GUID_Slider
)) {
103 diprg
.diph
.dwSize
= sizeof(DIPROPRANGE
);
104 diprg
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
);
105 diprg
.diph
.dwHow
= DIPH_BYID
;
106 diprg
.diph
.dwObj
= pdidoi
->dwType
;
110 hr
= IDirectInputDevice_SetProperty(info
->pJoystick
, DIPROP_RANGE
, NULL
);
111 ok(hr
==E_INVALIDARG
,"IDirectInputDevice_SetProperty() should have returned "
112 "E_INVALIDARG, returned: %s\n", DXGetErrorString8(hr
));
114 hr
= IDirectInputDevice_SetProperty(info
->pJoystick
, DIPROP_RANGE
, &diprg
.diph
);
115 ok(hr
==DI_OK
,"IDirectInputDevice_SetProperty() failed: %s\n", DXGetErrorString8(hr
));
118 } else if (IsEqualIID(&pdidoi
->guidType
, &GUID_POV
))
120 else if (IsEqualIID(&pdidoi
->guidType
, &GUID_Button
))
123 return DIENUM_CONTINUE
;
126 static BOOL CALLBACK
EnumJoysticks(
127 LPCDIDEVICEINSTANCE lpddi
,
131 UserData
* data
= (UserData
*)pvRef
;
132 LPDIRECTINPUTDEVICE pJoystick
;
139 DIDEVICEINSTANCE inst
;
140 DIDEVICEINSTANCE_DX3 inst3
;
141 HWND hWnd
= get_hwnd();
142 char oldstate
[248], curstate
[248];
144 ok(data
->version
> 0x0300, "Joysticks not supported in version 0x%04lx\n", data
->version
);
146 hr
= IDirectInput_CreateDevice(data
->pDI
, &lpddi
->guidInstance
, NULL
, NULL
);
147 ok(hr
==E_POINTER
,"IDirectInput_CreateDevice() should have returned "
148 "E_POINTER, returned: %s\n", DXGetErrorString8(hr
));
150 hr
= IDirectInput_CreateDevice(data
->pDI
, NULL
, &pJoystick
, NULL
);
151 ok(hr
==E_POINTER
,"IDirectInput_CreateDevice() should have returned "
152 "E_POINTER, returned: %s\n", DXGetErrorString8(hr
));
154 hr
= IDirectInput_CreateDevice(data
->pDI
, NULL
, NULL
, NULL
);
155 ok(hr
==E_POINTER
,"IDirectInput_CreateDevice() should have returned "
156 "E_POINTER, returned: %s\n", DXGetErrorString8(hr
));
158 hr
= IDirectInput_CreateDevice(data
->pDI
, &lpddi
->guidInstance
,
160 ok(hr
==DI_OK
,"IDirectInput_CreateDevice() failed: %s\n",
161 DXGetErrorString8(hr
));
165 trace("---- %s ----\n", lpddi
->tszProductName
);
167 hr
= IDirectInputDevice_SetDataFormat(pJoystick
, NULL
);
168 ok(hr
==E_POINTER
,"IDirectInputDevice_SetDataFormat() should have returned "
169 "E_POINTER, returned: %s\n", DXGetErrorString8(hr
));
171 ZeroMemory(&format
, sizeof(format
));
172 hr
= IDirectInputDevice_SetDataFormat(pJoystick
, &format
);
173 ok(hr
==DIERR_INVALIDPARAM
,"IDirectInputDevice_SetDataFormat() should have "
174 "returned DIERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(hr
));
176 /* try the default formats */
177 hr
= IDirectInputDevice_SetDataFormat(pJoystick
, &c_dfDIJoystick
);
178 ok(hr
==DI_OK
,"IDirectInputDevice_SetDataFormat() failed: %s\n",
179 DXGetErrorString8(hr
));
181 hr
= IDirectInputDevice_SetDataFormat(pJoystick
, &c_dfDIJoystick2
);
182 ok(hr
==DI_OK
,"IDirectInputDevice_SetDataFormat() failed: %s\n",
183 DXGetErrorString8(hr
));
185 /* try an alternate format */
186 hr
= IDirectInputDevice_SetDataFormat(pJoystick
, &c_dfDIJoystickTest
);
187 ok(hr
==DI_OK
,"IDirectInputDevice_SetDataFormat() failed: %s\n",
188 DXGetErrorString8(hr
));
190 hr
= IDirectInputDevice_SetDataFormat(pJoystick
, &c_dfDIJoystick2
);
191 ok(hr
==DI_OK
,"IDirectInputDevice_SetDataFormat() failed: %s\n",
192 DXGetErrorString8(hr
));
196 hr
= IDirectInputDevice_SetCooperativeLevel(pJoystick
, hWnd
,
197 DISCL_NONEXCLUSIVE
| DISCL_BACKGROUND
);
198 ok(hr
==DI_OK
,"IDirectInputDevice_SetCooperativeLevel() failed: %s\n",
199 DXGetErrorString8(hr
));
201 /* get capabilities */
202 hr
= IDirectInputDevice_GetCapabilities(pJoystick
, NULL
);
203 ok(hr
==E_POINTER
,"IDirectInputDevice_GetCapabilities() "
204 "should have returned E_POINTER, returned: %s\n",
205 DXGetErrorString8(hr
));
207 ZeroMemory(&caps
, sizeof(caps
));
208 hr
= IDirectInputDevice_GetCapabilities(pJoystick
, &caps
);
209 ok(hr
==DIERR_INVALIDPARAM
,"IDirectInputDevice_GetCapabilities() "
210 "should have returned DIERR_INVALIDPARAM, returned: %s\n",
211 DXGetErrorString8(hr
));
213 caps
.dwSize
= sizeof(caps
);
214 hr
= IDirectInputDevice_GetCapabilities(pJoystick
, &caps
);
215 ok(hr
==DI_OK
,"IDirectInputDevice_GetCapabilities() failed: %s\n",
216 DXGetErrorString8(hr
));
218 ZeroMemory(&info
, sizeof(info
));
219 info
.pJoystick
= pJoystick
;
221 /* enumerate objects */
222 hr
= IDirectInputDevice_EnumObjects(pJoystick
, EnumAxes
, (VOID
*)&info
, DIDFT_ALL
);
223 ok(hr
==DI_OK
,"IDirectInputDevice_EnumObjects() failed: %s\n",
224 DXGetErrorString8(hr
));
226 ok(caps
.dwAxes
== info
.axis
, "Number of enumerated axes doesn't match capabilities\n");
227 ok(caps
.dwButtons
== info
.button
, "Number of enumerated buttons doesn't match capabilities\n");
228 ok(caps
.dwPOVs
== info
.pov
, "Number of enumerated POVs doesn't match capabilities\n");
230 hr
= IDirectInputDevice_GetDeviceInfo(pJoystick
, 0);
231 ok(hr
==E_POINTER
, "IDirectInputDevice_GetDeviceInfo() "
232 "should have returned E_POINTER, returned: %s\n",
233 DXGetErrorString8(hr
));
235 ZeroMemory(&inst
, sizeof(inst
));
236 ZeroMemory(&inst3
, sizeof(inst3
));
238 hr
= IDirectInputDevice_GetDeviceInfo(pJoystick
, &inst
);
239 ok(hr
==DIERR_INVALIDPARAM
, "IDirectInputDevice_GetDeviceInfo() "
240 "should have returned DIERR_INVALIDPARAM, returned: %s\n",
241 DXGetErrorString8(hr
));
243 inst
.dwSize
= sizeof(inst
);
244 hr
= IDirectInputDevice_GetDeviceInfo(pJoystick
, &inst
);
245 ok(hr
==DI_OK
,"IDirectInputDevice_GetDeviceInfo() failed: %s\n",
246 DXGetErrorString8(hr
));
248 inst3
.dwSize
= sizeof(inst3
);
249 hr
= IDirectInputDevice_GetDeviceInfo(pJoystick
, (LPDIDEVICEINSTANCE
)&inst3
);
250 ok(hr
==DI_OK
,"IDirectInputDevice_GetDeviceInfo() failed: %s\n",
251 DXGetErrorString8(hr
));
253 hr
= IDirectInputDevice_Acquire(pJoystick
);
254 ok(hr
==DI_OK
,"IDirectInputDevice_Acquire() failed: %s\n",
255 DXGetErrorString8(hr
));
259 if (winetest_interactive
) {
260 trace("You have 30 seconds to test all axes, sliders, POVs and buttons\n");
267 for (i
= 0; i
< count
; i
++) {
268 hr
= IDirectInputDevice_GetDeviceState(pJoystick
, sizeof(DIJOYSTATE2
), &js
);
269 ok(hr
==DI_OK
,"IDirectInputDevice_GetDeviceState() failed: %s\n",
270 DXGetErrorString8(hr
));
273 sprintf(curstate
, "X%5ld Y%5ld Z%5ld Rx%5ld Ry%5ld Rz%5ld "
274 "S0%5ld S1%5ld POV0%5ld POV1%5ld POV2%5ld POV3%5ld "
275 "B %d %d %d %d %d %d %d %d %d %d %d %d\n",
276 js
.lX
, js
.lY
, js
.lZ
, js
.lRx
, js
.lRy
, js
.lRz
,
277 js
.rglSlider
[0], js
.rglSlider
[1],
278 js
.rgdwPOV
[0], js
.rgdwPOV
[1], js
.rgdwPOV
[2], js
.rgdwPOV
[3],
279 js
.rgbButtons
[0]>>7, js
.rgbButtons
[1]>>7, js
.rgbButtons
[2]>>7,
280 js
.rgbButtons
[3]>>7, js
.rgbButtons
[4]>>7, js
.rgbButtons
[5]>>7,
281 js
.rgbButtons
[6]>>7, js
.rgbButtons
[7]>>7, js
.rgbButtons
[8]>>7,
282 js
.rgbButtons
[9]>>7, js
.rgbButtons
[10]>>7, js
.rgbButtons
[11]>>7);
283 if (strcmp(oldstate
, curstate
) != 0)
286 strcpy(oldstate
, curstate
);
292 hr
= IDirectInputDevice_Unacquire(pJoystick
);
293 ok(hr
==DI_OK
,"IDirectInputDevice_Unacquire() failed: %s\n",
294 DXGetErrorString8(hr
));
297 ref
= IDirectInputDevice_Release(pJoystick
);
298 ok(ref
==0,"IDirectInputDevice_Release() reference count = %ld\n", ref
);
301 return DIENUM_CONTINUE
;
304 static void joystick_tests(DWORD version
)
309 HINSTANCE hInstance
= GetModuleHandle(NULL
);
311 trace("-- Testing Direct Input Version 0x%04lx --\n", version
);
312 hr
= DirectInputCreate(hInstance
, version
, &pDI
, NULL
);
313 ok(hr
==DI_OK
||hr
==DIERR_OLDDIRECTINPUTVERSION
,
314 "DirectInputCreate() failed: %s\n", DXGetErrorString8(hr
));
315 if (hr
==DI_OK
&& pDI
!=0) {
318 data
.version
= version
;
319 hr
= IDirectInput_EnumDevices(pDI
, DIDEVTYPE_JOYSTICK
, EnumJoysticks
,
320 &data
, DIEDFL_ALLDEVICES
);
321 ok(hr
==DI_OK
,"IDirectInput_EnumDevices() failed: %s\n",
322 DXGetErrorString8(hr
));
323 ref
= IDirectInput_Release(pDI
);
324 ok(ref
==0,"IDirectInput_Release() reference count = %ld\n", ref
);
325 } else if (hr
==DIERR_OLDDIRECTINPUTVERSION
)
326 trace(" Version Not Supported\n");
333 trace("DLL Version: %s\n", get_file_version("dinput.dll"));
335 joystick_tests(0x0700);
336 joystick_tests(0x0500);
337 joystick_tests(0x0300);