ReactOS 0.4.15-dev-5672-gf73ac17
joystick.c
Go to the documentation of this file.
1/*
2 * Unit tests for joystick APIs
3 *
4 * Copyright 2014 Bruno Jesus
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <stdarg.h>
22
23#include "windef.h"
24#include "winbase.h"
25#include "winuser.h"
26#include "mmsystem.h"
27#include "wine/test.h"
28
29static HWND window;
30
32{
34}
35
36static void create_window(void)
37{
38 const char name[] = "Joystick Test";
39 WNDCLASSA wc;
40
41 memset(&wc, 0, sizeof(wc));
43 wc.hInstance = 0;
45 RegisterClassA(&wc);
48 NULL, NULL, NULL, NULL);
49 ok(window != NULL, "Expected CreateWindowEx to work, error %d\n", GetLastError());
50}
51
52static void destroy_window(void)
53{
55 window = NULL;
56}
57
58static void test_api(void)
59{
61 JOYCAPSA jc;
62 JOYCAPSW jcw;
64 union _infoex
65 {
67 char buffer[sizeof(JOYINFOEX) * 2];
68 } infoex;
69 UINT i, par, devices, joyid, win98 = 0, win8 = 0;
70 UINT period[] = {0, 1, 9, 10, 100, 1000, 1001, 10000, 65535, 65536, 0xFFFFFFFF};
71 UINT threshold_error = 0x600, period_win8_error = 0x7CE;
75
77 joyid = -1;
78 /* joyGetNumDevs does NOT return the number of joysticks connected, only slots in the OS */
79 for (i = 0; i < devices; i++)
80 {
81 memset(&jc, 0, sizeof(jc));
82 ret = joyGetDevCapsA(JOYSTICKID1 + i, &jc, sizeof(jc));
83 if (ret == JOYERR_NOERROR)
84 {
85 if (joyid == -1) /* Cache the first found joystick to run advanced tests below */
86 joyid = JOYSTICKID1 + i;
87
88 trace("Joystick[%d] - name: '%s', axes: %d, buttons: %d, period range: %d - %d\n",
90 ret = joyGetDevCapsW(JOYSTICKID1 + i, &jcw, sizeof(jcw));
91 if (ret != MMSYSERR_NOTSUPPORTED) /* Win 98 */
92 {
93 ok(ret == JOYERR_NOERROR, "Expected %d, got %d\n", JOYERR_NOERROR, ret);
94 ok(jc.wNumAxes == jcw.wNumAxes, "Expected %d == %d\n", jc.wNumAxes, jcw.wNumAxes);
95 ok(jc.wNumButtons == jcw.wNumButtons, "Expected %d == %d\n", jc.wNumButtons, jcw.wNumButtons);
96 }
97 else win98++;
98 }
99 else
100 {
101 ok(ret == JOYERR_PARMS, "Expected %d, got %d\n", JOYERR_PARMS, ret);
102 ret = joyGetDevCapsW(JOYSTICKID1 + i, &jcw, sizeof(jcw));
103 ok(ret == JOYERR_PARMS || (ret == MMSYSERR_NOTSUPPORTED) /* Win 98 */,
104 "Expected %d, got %d\n", JOYERR_PARMS, ret);
105 }
106 }
107 /* Test invalid joystick - If no joystick is present the driver is not initialized,
108 * so a NODRIVER error is returned, if at least one joystick is present the error is
109 * about invalid parameters. */
110 ret = joyGetDevCapsA(joyid + devices, &jc, sizeof(jc));
112 "Expected %d or %d, got %d\n", MMSYSERR_NODRIVER, JOYERR_PARMS, ret);
113
114 if (joyid == -1)
115 {
116 skip("This test requires a real joystick.\n");
117 return;
118 }
119
120 /* Capture tests */
121 ret = joySetCapture(NULL, joyid, 100, FALSE);
122 ok(ret == JOYERR_PARMS || broken(win98 && ret == MMSYSERR_INVALPARAM) /* Win 98 */,
123 "Expected %d, got %d\n", JOYERR_PARMS, ret);
124 ret = joySetCapture(window, joyid, 100, FALSE);
125 ok(ret == JOYERR_NOERROR, "Expected %d, got %d\n", JOYERR_NOERROR, ret);
126 ret = joySetCapture(window, joyid, 100, FALSE); /* double capture */
127 if (ret == JOYERR_NOCANDO)
128 {
130 ok(broken(1), "Expected double capture using joySetCapture to work\n");
131 if (!win98 && broken(1)) win8++; /* Windows 98 or 8 cannot cope with that */
132 }
133 else ok(ret == JOYERR_NOERROR, "Expected %d, got %d\n", JOYERR_NOERROR, ret);
134 ret = joyReleaseCapture(joyid);
135 ok(ret == JOYERR_NOERROR, "Expected %d, got %d\n", JOYERR_NOERROR, ret);
136 ret = joyReleaseCapture(joyid);
137 ok(ret == JOYERR_NOERROR, "Expected %d, got %d\n", JOYERR_NOERROR, ret); /* double release */
138
139 /* Try some unusual period values for joySetCapture and unusual threshold values for joySetThreshold.
140 * Windows XP allows almost all test values, Windows 8 will return error on most test values, Windows
141 * 98 allows anything but cuts the values to their maximum supported values internally. */
142 for (i = 0; i < ARRAY_SIZE(period); i++)
143 {
144 ret = joySetCapture(window, joyid, period[i], FALSE);
145 if (win8 && ((1 << i) & period_win8_error))
146 ok(ret == JOYERR_NOCANDO, "Test [%d]: Expected %d, got %d\n", i, JOYERR_NOCANDO, ret);
147 else
148 ok(ret == JOYERR_NOERROR, "Test [%d]: Expected %d, got %d\n", i, JOYERR_NOERROR, ret);
149 ret = joyReleaseCapture(joyid);
150 ok(ret == JOYERR_NOERROR, "Test [%d]: Expected %d, got %d\n", i, JOYERR_NOERROR, ret);
151 /* Reuse the periods to test the threshold */
152 ret = joySetThreshold(joyid, period[i]);
153 if (!win98 && (1 << i) & threshold_error)
154 ok(ret == MMSYSERR_INVALPARAM, "Test [%d]: Expected %d, got %d\n", i, MMSYSERR_INVALPARAM, ret);
155 else
156 ok(ret == JOYERR_NOERROR, "Test [%d]: Expected %d, got %d\n", i, JOYERR_NOERROR, ret);
157 par = 0xdead;
158 ret = joyGetThreshold(joyid, &par);
159 ok(ret == JOYERR_NOERROR, "Test [%d]: Expected %d, got %d\n", i, JOYERR_NOERROR, ret);
160 if (!win98 || i < 8)
161 {
162 if ((1 << i) & threshold_error)
163 ok(par == period[8], "Test [%d]: Expected %d, got %d\n", i, period[8], par);
164 else
165 ok(par == period[i], "Test [%d]: Expected %d, got %d\n", i, period[i], par);
166 }
167 }
168
169 /* Position tests */
170 ret = joyGetPos(joyid, NULL);
171 ok(ret == MMSYSERR_INVALPARAM, "Expected %d, got %d\n", MMSYSERR_INVALPARAM, ret);
172 ret = joyGetPos(joyid, &info);
173 ok(ret == JOYERR_NOERROR, "Expected %d, got %d\n", JOYERR_NOERROR, ret);
174 ret = joyGetPosEx(joyid, NULL);
175 ok(ret == MMSYSERR_INVALPARAM || broken(win8 && ret == JOYERR_PARMS) /* Win 8 */,
176 "Expected %d, got %d\n", MMSYSERR_INVALPARAM, ret);
177 memset(&infoex, 0, sizeof(infoex));
178 ret = joyGetPosEx(joyid, &infoex.ex);
179 ok(ret == JOYERR_PARMS || broken(win98 && ret == MMSYSERR_INVALPARAM),
180 "Expected %d, got %d\n", JOYERR_PARMS, ret);
181 infoex.ex.dwSize = sizeof(infoex.ex);
182 ret = joyGetPosEx(joyid, &infoex.ex);
183 ok(ret == JOYERR_NOERROR, "Expected %d, got %d\n", JOYERR_NOERROR, ret);
184 infoex.ex.dwSize = sizeof(infoex.ex) - 1;
185 ret = joyGetPosEx(joyid, &infoex.ex);
186 ok(ret == JOYERR_PARMS || broken(win98 && ret == MMSYSERR_INVALPARAM),
187 "Expected %d, got %d\n", JOYERR_PARMS, ret);
188 infoex.ex.dwSize = sizeof(infoex);
189 ret = joyGetPosEx(joyid, &infoex.ex);
190 ok(ret == JOYERR_NOERROR, "Expected %d, got %d\n", JOYERR_NOERROR, ret);
191
192 infoex.ex.dwSize = sizeof(infoex.ex);
193 for (i = 0; i < ARRAY_SIZE(flags); i++)
194 {
195 infoex.ex.dwFlags = flags[i];
196 ret = joyGetPosEx(joyid, &infoex.ex);
197 ok(ret == JOYERR_NOERROR, "Expected %d, got %d\n", JOYERR_NOERROR, ret);
198 }
199
200 /* the interactive tests spans for 15 seconds, a 500ms polling is used to get
201 * changes in the joystick. */
203 {
204#define MAX_TIME 15000
205 DWORD tick = GetTickCount(), spent;
206 infoex.ex.dwSize = sizeof(infoex.ex);
207 infoex.ex.dwFlags = JOY_RETURNALL;
208 do
209 {
210 spent = GetTickCount() - tick;
211 ret = joyGetPosEx(joyid, &infoex.ex);
212 if (ret == JOYERR_NOERROR)
213 {
214 trace("X: %5d, Y: %5d, Z: %5d, POV: %5d\n",
215 infoex.ex.dwXpos, infoex.ex.dwYpos, infoex.ex.dwZpos, infoex.ex.dwPOV);
216 trace("R: %5d, U: %5d, V: %5d\n",
217 infoex.ex.dwRpos, infoex.ex.dwUpos, infoex.ex.dwVpos);
218 trace("BUTTONS: 0x%04X, BUTTON_COUNT: %2d, REMAINING: %d ms\n\n",
219 infoex.ex.dwButtons, infoex.ex.dwButtonNumber, MAX_TIME - spent);
220 }
221 Sleep(500);
222 }
223 while (spent < MAX_TIME);
224#undef MAX_TIME
225 }
226 else
227 skip("Skipping interactive tests for the joystick\n");
228}
229
230START_TEST(joystick)
231{
233 test_api();
235}
#define broken(x)
Definition: _sntprintf.h:21
#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 msg(x)
Definition: auth_time.c:54
#define ARRAY_SIZE(a)
Definition: main.h:24
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define CALLBACK
Definition: compat.h:35
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
MMRESULT WINAPI joyGetThreshold(UINT wID, LPUINT lpThreshold)
Definition: joystick.c:259
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx(UINT wID, LPJOYINFOEX lpInfo)
Definition: joystick.c:216
MMRESULT WINAPI joyGetPos(UINT wID, LPJOYINFO lpInfo)
Definition: joystick.c:241
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsA(UINT_PTR wID, LPJOYCAPSA lpCaps, UINT wSize)
Definition: joystick.c:167
MMRESULT WINAPI joySetCapture(HWND hWnd, UINT wID, UINT wPeriod, BOOL bChanged)
Definition: joystick.c:290
UINT WINAPI DECLSPEC_HOTPATCH joyGetNumDevs(void)
Definition: joystick.c:137
MMRESULT WINAPI joySetThreshold(UINT wID, UINT wThreshold)
Definition: joystick.c:316
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW(UINT_PTR wID, LPJOYCAPSW lpCaps, UINT wSize)
Definition: joystick.c:153
MMRESULT WINAPI joyReleaseCapture(UINT wID)
Definition: joystick.c:272
static struct all_devices * devices
Definition: dsm_ctrl.c:48
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint buffer
Definition: glext.h:5915
GLbitfield flags
Definition: glext.h:7161
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 JOY_RETURNRAWDATA
Definition: mmsystem.h:482
#define JOY_RETURNX
Definition: mmsystem.h:474
#define JOY_RETURNU
Definition: mmsystem.h:478
#define JOY_RETURNR
Definition: mmsystem.h:477
UINT MMRESULT
Definition: mmsystem.h:962
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define JOY_RETURNV
Definition: mmsystem.h:479
#define MMSYSERR_NODRIVER
Definition: mmsystem.h:102
#define JOYERR_NOCANDO
Definition: mmsystem.h:431
#define JOY_RETURNALL
Definition: mmsystem.h:486
struct joyinfoex_tag JOYINFOEX
#define JOY_RETURNY
Definition: mmsystem.h:475
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define JOY_RETURNBUTTONS
Definition: mmsystem.h:481
#define JOY_RETURNZ
Definition: mmsystem.h:476
#define JOYERR_NOERROR
Definition: mmsystem.h:429
#define JOY_RETURNPOV
Definition: mmsystem.h:480
#define JOY_RETURNCENTERED
Definition: mmsystem.h:484
#define JOYERR_PARMS
Definition: mmsystem.h:430
#define JOYSTICKID1
Definition: mmsystem.h:499
#define JOY_RETURNPOVCTS
Definition: mmsystem.h:483
static UINT WPARAM wparam
Definition: combo.c:716
static UINT WPARAM LPARAM lparam
Definition: combo.c:716
#define todo_wine
Definition: custom.c:79
static void destroy_window(void)
Definition: joystick.c:52
#define MAX_TIME
static HWND window
Definition: joystick.c:29
static void test_api(void)
Definition: joystick.c:58
static LRESULT CALLBACK proc_window(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: joystick.c:31
static void create_window(void)
Definition: joystick.c:36
unsigned int UINT
Definition: ndis.h:50
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
int winetest_interactive
#define memset(x, y, z)
Definition: compat.h:39
HINSTANCE hInstance
Definition: winuser.h:3157
LPCSTR lpszClassName
Definition: winuser.h:3162
WNDPROC lpfnWndProc
Definition: winuser.h:3154
Definition: comerr.c:44
Definition: name.c:39
UINT wNumAxes
Definition: mmsystem.h:1419
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1401
UINT wNumButtons
Definition: mmsystem.h:1408
UINT wPeriodMin
Definition: mmsystem.h:1409
UINT wPeriodMax
Definition: mmsystem.h:1410
UINT wNumAxes
Definition: mmsystem.h:1446
UINT wNumButtons
Definition: mmsystem.h:1435
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1040
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define CW_USEDEFAULT
Definition: winuser.h:225
BOOL WINAPI DestroyWindow(_In_ HWND)