ReactOS 0.4.15-dev-8058-ga7cbb60
xinput.c
Go to the documentation of this file.
1/*
2 * The Wine project - Xinput Joystick Library
3 * Copyright 2008 Andrew Fenn
4 *
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.
9 *
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.
14 *
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
18 */
19
20#include <windows.h>
21#include <stdio.h>
22
23#include "xinput.h"
24#include "wine/test.h"
25
26static DWORD (WINAPI *pXInputGetState)(DWORD, XINPUT_STATE*);
27static DWORD (WINAPI *pXInputGetStateEx)(DWORD, XINPUT_STATE*);
28static DWORD (WINAPI *pXInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
29static DWORD (WINAPI *pXInputSetState)(DWORD, XINPUT_VIBRATION*);
30static void (WINAPI *pXInputEnable)(BOOL);
31static DWORD (WINAPI *pXInputGetKeystroke)(DWORD, DWORD, PXINPUT_KEYSTROKE);
32static DWORD (WINAPI *pXInputGetDSoundAudioDeviceGuids)(DWORD, GUID*, GUID*);
33static DWORD (WINAPI *pXInputGetBatteryInformation)(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
34
36{
37 trace("-- Gamepad Variables --\n");
38 trace("Gamepad.wButtons: %#x\n", data->wButtons);
39 trace("Gamepad.bLeftTrigger: %d\n", data->bLeftTrigger);
40 trace("Gamepad.bRightTrigger: %d\n", data->bRightTrigger);
41 trace("Gamepad.sThumbLX: %d\n", data->sThumbLX);
42 trace("Gamepad.sThumbLY: %d\n", data->sThumbLY);
43 trace("Gamepad.sThumbRX: %d\n", data->sThumbRX);
44 trace("Gamepad.sThumbRY: %d\n\n", data->sThumbRY);
45}
46
47static void test_set_state(void)
48{
49 XINPUT_VIBRATION vibrator;
50 DWORD controllerNum;
52
53 for(controllerNum = 0; controllerNum < XUSER_MAX_COUNT; controllerNum++)
54 {
55 ZeroMemory(&vibrator, sizeof(XINPUT_VIBRATION));
56
57 vibrator.wLeftMotorSpeed = 32767;
58 vibrator.wRightMotorSpeed = 32767;
59 result = pXInputSetState(controllerNum, &vibrator);
60 if (result == ERROR_DEVICE_NOT_CONNECTED) continue;
61
62 Sleep(250);
63 vibrator.wLeftMotorSpeed = 0;
64 vibrator.wRightMotorSpeed = 0;
65 result = pXInputSetState(controllerNum, &vibrator);
66 ok(result == ERROR_SUCCESS, "XInputSetState failed with (%d)\n", result);
67
68 /* Disabling XInput here, queueing a vibration and then re-enabling XInput
69 * is used to prove that vibrations are auto enabled when resuming XInput.
70 * If XInputEnable(1) is removed below the vibration will never play. */
71 if (pXInputEnable) pXInputEnable(0);
72
73 Sleep(250);
74 vibrator.wLeftMotorSpeed = 65535;
75 vibrator.wRightMotorSpeed = 65535;
76 result = pXInputSetState(controllerNum, &vibrator);
77 ok(result == ERROR_SUCCESS, "XInputSetState failed with (%d)\n", result);
78
79 if (pXInputEnable) pXInputEnable(1);
80 Sleep(250);
81
82 vibrator.wLeftMotorSpeed = 0;
83 vibrator.wRightMotorSpeed = 0;
84 result = pXInputSetState(controllerNum, &vibrator);
85 ok(result == ERROR_SUCCESS, "XInputSetState failed with (%d)\n", result);
86 }
87
88 result = pXInputSetState(XUSER_MAX_COUNT+1, &vibrator);
89 ok(result == ERROR_BAD_ARGUMENTS, "XInputSetState returned (%d)\n", result);
90}
91
92static void test_get_state(void)
93{
95 DWORD controllerNum, i, result, good = XUSER_MAX_COUNT;
96
97 for (i = 0; i < (pXInputGetStateEx ? 2 : 1); i++)
98 {
99 for (controllerNum = 0; controllerNum < XUSER_MAX_COUNT; controllerNum++)
100 {
101 ZeroMemory(&state, sizeof(state));
102
103 if (i == 0)
104 result = pXInputGetState(controllerNum, &state);
105 else
106 result = pXInputGetStateEx(controllerNum, &state);
108 "%s failed with (%d)\n", i == 0 ? "XInputGetState" : "XInputGetStateEx", result);
109
111 {
112 skip("Controller %d is not connected\n", controllerNum);
113 continue;
114 }
115
116 trace("-- Results for controller %d --\n", controllerNum);
117 if (i == 0)
118 {
119 good = controllerNum;
120 trace("XInputGetState: %d\n", result);
121 }
122 else
123 trace("XInputGetStateEx: %d\n", result);
124 trace("State->dwPacketNumber: %d\n", state.dwPacketNumber);
125 dump_gamepad(&state.Gamepad);
126 }
127 }
128
129 result = pXInputGetState(0, NULL);
130 ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result);
131
132 result = pXInputGetState(XUSER_MAX_COUNT, &state);
133 ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result);
134
135 result = pXInputGetState(XUSER_MAX_COUNT+1, &state);
136 ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result);
137 if (pXInputGetStateEx)
138 {
139 result = pXInputGetStateEx(XUSER_MAX_COUNT, &state);
140 ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result);
141
142 result = pXInputGetStateEx(XUSER_MAX_COUNT+1, &state);
143 ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result);
144 }
145
147 {
148 DWORD now = GetTickCount(), packet = 0;
149 XINPUT_GAMEPAD *game = &state.Gamepad;
150
151 trace("You have 20 seconds to test the joystick freely\n");
152 do
153 {
154 Sleep(100);
155 pXInputGetState(good, &state);
156 if (state.dwPacketNumber == packet)
157 continue;
158
159 packet = state.dwPacketNumber;
160 trace("Buttons 0x%04X Triggers %3d/%3d LT %6d/%6d RT %6d/%6d\n",
161 game->wButtons, game->bLeftTrigger, game->bRightTrigger,
162 game->sThumbLX, game->sThumbLY, game->sThumbRX, game->sThumbRY);
163 }
164 while(GetTickCount() - now < 20000);
165 trace("Test over...\n");
166 }
167}
168
169static void test_get_keystroke(void)
170{
171 XINPUT_KEYSTROKE keystroke;
172 DWORD controllerNum;
174
175 for(controllerNum = 0; controllerNum < XUSER_MAX_COUNT; controllerNum++)
176 {
177 ZeroMemory(&keystroke, sizeof(XINPUT_KEYSTROKE));
178
179 result = pXInputGetKeystroke(controllerNum, XINPUT_FLAG_GAMEPAD, &keystroke);
181 "XInputGetKeystroke failed with (%d)\n", result);
182
184 {
185 skip("Controller %d is not connected\n", controllerNum);
186 }
187 }
188
189 ZeroMemory(&keystroke, sizeof(XINPUT_KEYSTROKE));
190 result = pXInputGetKeystroke(XUSER_MAX_COUNT+1, XINPUT_FLAG_GAMEPAD, &keystroke);
191 ok(result == ERROR_BAD_ARGUMENTS, "XInputGetKeystroke returned (%d)\n", result);
192}
193
194static void test_get_capabilities(void)
195{
196 XINPUT_CAPABILITIES capabilities;
197 DWORD controllerNum;
199
200 for(controllerNum = 0; controllerNum < XUSER_MAX_COUNT; controllerNum++)
201 {
202 ZeroMemory(&capabilities, sizeof(XINPUT_CAPABILITIES));
203
204 result = pXInputGetCapabilities(controllerNum, XINPUT_FLAG_GAMEPAD, &capabilities);
205 ok(result == ERROR_SUCCESS || result == ERROR_DEVICE_NOT_CONNECTED, "XInputGetCapabilities failed with (%d)\n", result);
206
208 {
209 skip("Controller %d is not connected\n", controllerNum);
210 continue;
211 }
212
213 /* Important to show that the results changed between 1.3 and 1.4 XInput version */
214 dump_gamepad(&capabilities.Gamepad);
215 }
216
217 ZeroMemory(&capabilities, sizeof(XINPUT_CAPABILITIES));
218 result = pXInputGetCapabilities(XUSER_MAX_COUNT+1, XINPUT_FLAG_GAMEPAD, &capabilities);
219 ok(result == ERROR_BAD_ARGUMENTS, "XInputGetCapabilities returned (%d)\n", result);
220}
221
223{
224 DWORD controllerNum;
226 GUID soundRender, soundCapture;
227 GUID testGuid = {0xFFFFFFFF, 0xFFFF, 0xFFFF, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
228 GUID emptyGuid = {0x0, 0x0, 0x0, {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}};
229
230 for(controllerNum = 0; controllerNum < XUSER_MAX_COUNT; controllerNum++)
231 {
232 soundRender = soundCapture = testGuid;
233 result = pXInputGetDSoundAudioDeviceGuids(controllerNum, &soundRender, &soundCapture);
234 ok(result == ERROR_SUCCESS || result == ERROR_DEVICE_NOT_CONNECTED, "XInputGetDSoundAudioDeviceGuids failed with (%d)\n", result);
235
237 {
238 skip("Controller %d is not connected\n", controllerNum);
239 continue;
240 }
241
242 if (!IsEqualGUID(&soundRender, &emptyGuid))
243 ok(!IsEqualGUID(&soundRender, &testGuid), "Broken GUID returned for sound render device\n");
244 else
245 trace("Headset phone not attached\n");
246
247 if (!IsEqualGUID(&soundCapture, &emptyGuid))
248 ok(!IsEqualGUID(&soundCapture, &testGuid), "Broken GUID returned for sound capture device\n");
249 else
250 trace("Headset microphone not attached\n");
251 }
252
253 result = pXInputGetDSoundAudioDeviceGuids(XUSER_MAX_COUNT+1, &soundRender, &soundCapture);
254 ok(result == ERROR_BAD_ARGUMENTS, "XInputGetDSoundAudioDeviceGuids returned (%d)\n", result);
255}
256
258{
259 DWORD controllerNum;
261 XINPUT_BATTERY_INFORMATION batteryInfo;
262
263 for(controllerNum = 0; controllerNum < XUSER_MAX_COUNT; controllerNum++)
264 {
265 ZeroMemory(&batteryInfo, sizeof(XINPUT_BATTERY_INFORMATION));
266
267 result = pXInputGetBatteryInformation(controllerNum, BATTERY_DEVTYPE_GAMEPAD, &batteryInfo);
268 ok(result == ERROR_SUCCESS || result == ERROR_DEVICE_NOT_CONNECTED, "XInputGetBatteryInformation failed with (%d)\n", result);
269
271 {
272 ok(batteryInfo.BatteryLevel == BATTERY_TYPE_DISCONNECTED, "Failed to report device as being disconnected.\n");
273 skip("Controller %d is not connected\n", controllerNum);
274 }
275 }
276
277 result = pXInputGetBatteryInformation(XUSER_MAX_COUNT+1, BATTERY_DEVTYPE_GAMEPAD, &batteryInfo);
278 ok(result == ERROR_BAD_ARGUMENTS, "XInputGetBatteryInformation returned (%d)\n", result);
279}
280
282{
283 struct
284 {
285 const char *name;
286 int version;
287 } libs[] = {
288 { "xinput1_1.dll", 1 },
289 { "xinput1_2.dll", 2 },
290 { "xinput1_3.dll", 3 },
291 { "xinput1_4.dll", 4 },
292 { "xinput9_1_0.dll", 0 } /* legacy for XP/Vista */
293 };
294 HMODULE hXinput;
295 void *pXInputGetStateEx_Ordinal;
296 int i;
297
298 for (i = 0; i < ARRAY_SIZE(libs); i++)
299 {
300 hXinput = LoadLibraryA( libs[i].name );
301
302 if (!hXinput)
303 {
304 win_skip("Could not load %s\n", libs[i].name);
305 continue;
306 }
307 trace("Testing %s\n", libs[i].name);
308
309 pXInputEnable = (void*)GetProcAddress(hXinput, "XInputEnable");
310 pXInputSetState = (void*)GetProcAddress(hXinput, "XInputSetState");
311 pXInputGetState = (void*)GetProcAddress(hXinput, "XInputGetState");
312 pXInputGetStateEx = (void*)GetProcAddress(hXinput, "XInputGetStateEx"); /* Win >= 8 */
313 pXInputGetStateEx_Ordinal = (void*)GetProcAddress(hXinput, (LPCSTR) 100);
314 pXInputGetKeystroke = (void*)GetProcAddress(hXinput, "XInputGetKeystroke");
315 pXInputGetCapabilities = (void*)GetProcAddress(hXinput, "XInputGetCapabilities");
316 pXInputGetDSoundAudioDeviceGuids = (void*)GetProcAddress(hXinput, "XInputGetDSoundAudioDeviceGuids");
317 pXInputGetBatteryInformation = (void*)GetProcAddress(hXinput, "XInputGetBatteryInformation");
318
319 /* XInputGetStateEx may not be present by name, use ordinal in this case */
320 if (!pXInputGetStateEx)
321 pXInputGetStateEx = pXInputGetStateEx_Ordinal;
322
326
327 if (libs[i].version != 4)
329 else
330 ok(!pXInputGetDSoundAudioDeviceGuids, "XInputGetDSoundAudioDeviceGuids exists in %s\n", libs[i].name);
331
332 if (libs[i].version > 2)
333 {
336 ok(pXInputGetStateEx != NULL, "XInputGetStateEx not found in %s\n", libs[i].name);
337 }
338 else
339 {
340 ok(!pXInputGetKeystroke, "XInputGetKeystroke exists in %s\n", libs[i].name);
341 ok(!pXInputGetStateEx, "XInputGetStateEx exists in %s\n", libs[i].name);
342 ok(!pXInputGetBatteryInformation, "XInputGetBatteryInformation exists in %s\n", libs[i].name);
343 if (libs[i].version == 0)
344 ok(!pXInputEnable, "XInputEnable exists in %s\n", libs[i].name);
345 }
346
347 FreeLibrary(hXinput);
348 }
349}
static int state
Definition: maze.c:121
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ARRAY_SIZE(A)
Definition: main.h:33
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define GetProcAddress(x, y)
Definition: compat.h:753
#define FreeLibrary(x)
Definition: compat.h:748
static const WCHAR version[]
Definition: asmname.c:66
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
unsigned long DWORD
Definition: ntddk_ex.h:95
time_t now
Definition: finger.c:65
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define BOOL
Definition: nt_native.h:43
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define win_skip
Definition: test.h:163
int winetest_interactive
XINPUT_GAMEPAD Gamepad
Definition: xinput.h:217
BYTE bRightTrigger
Definition: xinput.h:166
BYTE bLeftTrigger
Definition: xinput.h:165
SHORT sThumbRY
Definition: xinput.h:170
WORD wButtons
Definition: xinput.h:164
SHORT sThumbLX
Definition: xinput.h:167
SHORT sThumbLY
Definition: xinput.h:168
SHORT sThumbRX
Definition: xinput.h:169
WORD wRightMotorSpeed
Definition: xinput.h:202
WORD wLeftMotorSpeed
Definition: xinput.h:201
Definition: name.c:39
Definition: dhcpd.h:135
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define ZeroMemory
Definition: winbase.h:1712
#define WINAPI
Definition: msvc.h:6
#define ERROR_DEVICE_NOT_CONNECTED
Definition: winerror.h:689
#define ERROR_EMPTY
Definition: winerror.h:1250
#define ERROR_BAD_ARGUMENTS
Definition: winerror.h:232
static GUID GUID *static BYTE
Definition: xinput.c:33
static GUID GUID *static XINPUT_BATTERY_INFORMATION *static void dump_gamepad(XINPUT_GAMEPAD *data)
Definition: xinput.c:35
static void test_set_state(void)
Definition: xinput.c:47
static void test_get_keystroke(void)
Definition: xinput.c:169
static XINPUT_STATE *static XINPUT_STATE *static DWORD
Definition: xinput.c:28
static PXINPUT_KEYSTROKE
Definition: xinput.c:31
static void test_get_state(void)
Definition: xinput.c:92
static void test_get_batteryinformation(void)
Definition: xinput.c:257
static void test_get_capabilities(void)
Definition: xinput.c:194
static void test_get_dsoundaudiodevice(void)
Definition: xinput.c:222
#define XUSER_MAX_COUNT
Definition: xinput.h:156
#define BATTERY_TYPE_DISCONNECTED
Definition: xinput.h:141
#define XINPUT_FLAG_GAMEPAD
Definition: xinput.h:129
#define BATTERY_DEVTYPE_GAMEPAD
Definition: xinput.h:139
const char * LPCSTR
Definition: xmlstorage.h:183