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
20 #define DIRECTINPUT_VERSION 0x0700
22 #define NONAMELESSSTRUCT
23 #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();
143 ok(data
->version
> 0x0300, "Joysticks not supported in version 0x%04lx\n", data
->version
);
145 hr
= IDirectInput_CreateDevice(data
->pDI
, &lpddi
->guidInstance
, NULL
, NULL
);
146 ok(hr
==E_POINTER
,"IDirectInput_CreateDevice() should have returned "
147 "E_POINTER, returned: %s\n", DXGetErrorString8(hr
));
149 hr
= IDirectInput_CreateDevice(data
->pDI
, NULL
, &pJoystick
, NULL
);
150 ok(hr
==E_POINTER
,"IDirectInput_CreateDevice() should have returned "
151 "E_POINTER, returned: %s\n", DXGetErrorString8(hr
));
153 hr
= IDirectInput_CreateDevice(data
->pDI
, NULL
, NULL
, NULL
);
154 ok(hr
==E_POINTER
,"IDirectInput_CreateDevice() should have returned "
155 "E_POINTER, returned: %s\n", DXGetErrorString8(hr
));
157 hr
= IDirectInput_CreateDevice(data
->pDI
, &lpddi
->guidInstance
,
159 ok(hr
==DI_OK
,"IDirectInput_CreateDevice() failed: %s\n",
160 DXGetErrorString8(hr
));
164 trace("---- %s ----\n", lpddi
->tszProductName
);
166 hr
= IDirectInputDevice_SetDataFormat(pJoystick
, NULL
);
167 ok(hr
==E_POINTER
,"IDirectInputDevice_SetDataFormat() should have returned "
168 "E_POINTER, returned: %s\n", DXGetErrorString8(hr
));
170 ZeroMemory(&format
, sizeof(format
));
171 hr
= IDirectInputDevice_SetDataFormat(pJoystick
, &format
);
172 ok(hr
==DIERR_INVALIDPARAM
,"IDirectInputDevice_SetDataFormat() should have "
173 "returned DIERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(hr
));
175 /* try the default formats */
176 hr
= IDirectInputDevice_SetDataFormat(pJoystick
, &c_dfDIJoystick
);
177 ok(hr
==DI_OK
,"IDirectInputDevice_SetDataFormat() failed: %s\n",
178 DXGetErrorString8(hr
));
180 hr
= IDirectInputDevice_SetDataFormat(pJoystick
, &c_dfDIJoystick2
);
181 ok(hr
==DI_OK
,"IDirectInputDevice_SetDataFormat() failed: %s\n",
182 DXGetErrorString8(hr
));
184 /* try an alternate format */
185 hr
= IDirectInputDevice_SetDataFormat(pJoystick
, &c_dfDIJoystickTest
);
186 ok(hr
==DI_OK
,"IDirectInputDevice_SetDataFormat() failed: %s\n",
187 DXGetErrorString8(hr
));
189 hr
= IDirectInputDevice_SetDataFormat(pJoystick
, &c_dfDIJoystick2
);
190 ok(hr
==DI_OK
,"IDirectInputDevice_SetDataFormat() failed: %s\n",
191 DXGetErrorString8(hr
));
195 hr
= IDirectInputDevice_SetCooperativeLevel(pJoystick
, hWnd
,
196 DISCL_NONEXCLUSIVE
| DISCL_BACKGROUND
);
197 ok(hr
==DI_OK
,"IDirectInputDevice_SetCooperativeLevel() failed: %s\n",
198 DXGetErrorString8(hr
));
200 /* get capabilities */
201 hr
= IDirectInputDevice_GetCapabilities(pJoystick
, NULL
);
202 ok(hr
==E_POINTER
,"IDirectInputDevice_GetCapabilities() "
203 "should have returned E_POINTER, returned: %s\n",
204 DXGetErrorString8(hr
));
206 ZeroMemory(&caps
, sizeof(caps
));
207 hr
= IDirectInputDevice_GetCapabilities(pJoystick
, &caps
);
208 ok(hr
==DIERR_INVALIDPARAM
,"IDirectInputDevice_GetCapabilities() "
209 "should have returned DIERR_INVALIDPARAM, returned: %s\n",
210 DXGetErrorString8(hr
));
212 caps
.dwSize
= sizeof(caps
);
213 hr
= IDirectInputDevice_GetCapabilities(pJoystick
, &caps
);
214 ok(hr
==DI_OK
,"IDirectInputDevice_GetCapabilities() failed: %s\n",
215 DXGetErrorString8(hr
));
217 ZeroMemory(&info
, sizeof(info
));
218 info
.pJoystick
= pJoystick
;
220 /* enumerate objects */
221 hr
= IDirectInputDevice_EnumObjects(pJoystick
, EnumAxes
, (VOID
*)&info
, DIDFT_ALL
);
222 ok(hr
==DI_OK
,"IDirectInputDevice_EnumObjects() failed: %s\n",
223 DXGetErrorString8(hr
));
225 ok(caps
.dwAxes
== info
.axis
, "Number of enumerated axes doesn't match capabilities\n");
226 ok(caps
.dwButtons
== info
.button
, "Number of enumerated buttons doesn't match capabilities\n");
227 ok(caps
.dwPOVs
== info
.pov
, "Number of enumerated POVs doesn't match capabilities\n");
229 hr
= IDirectInputDevice_GetDeviceInfo(pJoystick
, 0);
230 ok(hr
==E_POINTER
, "IDirectInputDevice_GetDeviceInfo() "
231 "should have returned E_POINTER, returned: %s\n",
232 DXGetErrorString8(hr
));
234 ZeroMemory(&inst
, sizeof(inst
));
235 ZeroMemory(&inst3
, sizeof(inst3
));
237 hr
= IDirectInputDevice_GetDeviceInfo(pJoystick
, &inst
);
238 ok(hr
==DIERR_INVALIDPARAM
, "IDirectInputDevice_GetDeviceInfo() "
239 "should have returned DIERR_INVALIDPARAM, returned: %s\n",
240 DXGetErrorString8(hr
));
242 inst
.dwSize
= sizeof(inst
);
243 hr
= IDirectInputDevice_GetDeviceInfo(pJoystick
, &inst
);
244 ok(hr
==DI_OK
,"IDirectInputDevice_GetDeviceInfo() failed: %s\n",
245 DXGetErrorString8(hr
));
247 inst3
.dwSize
= sizeof(inst3
);
248 hr
= IDirectInputDevice_GetDeviceInfo(pJoystick
, (LPDIDEVICEINSTANCE
)&inst3
);
249 ok(hr
==DI_OK
,"IDirectInputDevice_GetDeviceInfo() failed: %s\n",
250 DXGetErrorString8(hr
));
252 hr
= IDirectInputDevice_Acquire(pJoystick
);
253 ok(hr
==DI_OK
,"IDirectInputDevice_Acquire() failed: %s\n",
254 DXGetErrorString8(hr
));
258 if (winetest_interactive
) {
259 trace("You have 30 seconds to test all axes, sliders, POVs and buttons\n");
265 for (i
= 0; i
< count
; i
++) {
266 hr
= IDirectInputDevice_GetDeviceState(pJoystick
, sizeof(DIJOYSTATE2
), &js
);
267 ok(hr
==DI_OK
,"IDirectInputDevice_GetDeviceState() failed: %s\n",
268 DXGetErrorString8(hr
));
271 trace("X%5ld Y%5ld Z%5ld Rx%5ld Ry%5ld Rz%5ld "
272 "S0%5ld S1%5ld POV0%5ld POV1%5ld POV2%5ld POV3%5ld "
273 "B %d %d %d %d %d %d %d %d %d %d %d %d\r",
274 js
.lX
, js
.lY
, js
.lZ
, js
.lRx
, js
.lRy
, js
.lRz
,
275 js
.rglSlider
[0], js
.rglSlider
[1],
276 js
.rgdwPOV
[0], js
.rgdwPOV
[1], js
.rgdwPOV
[2], js
.rgdwPOV
[3],
277 js
.rgbButtons
[0]>>7, js
.rgbButtons
[1]>>7, js
.rgbButtons
[2]>>7,
278 js
.rgbButtons
[3]>>7, js
.rgbButtons
[4]>>7, js
.rgbButtons
[5]>>7,
279 js
.rgbButtons
[6]>>7, js
.rgbButtons
[7]>>7, js
.rgbButtons
[8]>>7,
280 js
.rgbButtons
[9]>>7, js
.rgbButtons
[10]>>7, js
.rgbButtons
[11]>>7);
285 hr
= IDirectInputDevice_Unacquire(pJoystick
);
286 ok(hr
==DI_OK
,"IDirectInputDevice_Unacquire() failed: %s\n",
287 DXGetErrorString8(hr
));
290 ref
= IDirectInputDevice_Release(pJoystick
);
291 ok(ref
==0,"IDirectInputDevice_Release() reference count = %ld\n", ref
);
294 return DIENUM_CONTINUE
;
297 static void joystick_tests(DWORD version
)
302 HINSTANCE hInstance
= GetModuleHandle(NULL
);
304 trace("-- Testing Direct Input Version 0x%04lx --\n", version
);
305 hr
= DirectInputCreate(hInstance
, version
, &pDI
, NULL
);
306 ok(hr
==DI_OK
||hr
==DIERR_OLDDIRECTINPUTVERSION
,
307 "DirectInputCreate() failed: %s\n", DXGetErrorString8(hr
));
308 if (hr
==DI_OK
&& pDI
!=0) {
311 data
.version
= version
;
312 hr
= IDirectInput_EnumDevices(pDI
, DIDEVTYPE_JOYSTICK
, EnumJoysticks
,
313 &data
, DIEDFL_ALLDEVICES
);
314 ok(hr
==DI_OK
,"IDirectInput_EnumDevices() failed: %s\n",
315 DXGetErrorString8(hr
));
316 ref
= IDirectInput_Release(pDI
);
317 ok(ref
==0,"IDirectInput_Release() reference count = %ld\n", ref
);
318 } else if (hr
==DIERR_OLDDIRECTINPUTVERSION
)
319 trace(" Version Not Supported\n");
326 trace("DLL Version: %s\n", get_file_version("dinput.dll"));
328 joystick_tests(0x0700);
329 joystick_tests(0x0500);
330 joystick_tests(0x0300);