msvcp100: Add _Concurrent_queue_base_v4 push/pop implementation.
[wine.git] / dlls / winmm / tests / joystick.c
blob5714001315ac23d72c5d584285366a9a16388b32
1 /*
2 * Unit tests for joystick APIs
4 * Copyright 2014 Bruno Jesus
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.
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.
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
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "mmsystem.h"
27 #include "wine/test.h"
29 static HWND window;
31 static LRESULT CALLBACK proc_window(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
33 return DefWindowProcA(hwnd, msg, wparam, lparam);
36 static void create_window(void)
38 const char name[] = "Joystick Test";
39 WNDCLASSA wc;
41 memset(&wc, 0, sizeof(wc));
42 wc.lpfnWndProc = proc_window;
43 wc.hInstance = 0;
44 wc.lpszClassName = name;
45 RegisterClassA(&wc);
46 window = CreateWindowExA(0, name, name, WS_OVERLAPPEDWINDOW,
47 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
48 NULL, NULL, NULL, NULL);
49 ok(window != NULL, "Expected CreateWindowEx to work, error %d\n", GetLastError());
52 static void destroy_window(void)
54 DestroyWindow(window);
55 window = NULL;
58 static void test_api(void)
60 MMRESULT ret;
61 JOYCAPSA jc;
62 JOYCAPSW jcw;
63 JOYINFO info;
64 union _infoex
66 JOYINFOEX ex;
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;
72 UINT flags[] = { JOY_RETURNALL, JOY_RETURNBUTTONS, JOY_RETURNCENTERED, JOY_RETURNPOV,
73 JOY_RETURNPOVCTS, JOY_RETURNR, JOY_RETURNRAWDATA, JOY_RETURNU,
74 JOY_RETURNV, JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ };
76 devices = joyGetNumDevs();
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++)
81 memset(&jc, 0, sizeof(jc));
82 ret = joyGetDevCapsA(JOYSTICKID1 + i, &jc, sizeof(jc));
83 if (ret == JOYERR_NOERROR)
85 if (joyid == -1) /* Cache the first found joystick to run advanced tests below */
86 joyid = JOYSTICKID1 + i;
88 trace("Joystick[%d] - name: '%s', axes: %d, buttons: %d, period range: %d - %d\n",
89 JOYSTICKID1 + i, jc.szPname, jc.wNumAxes, jc.wNumButtons, jc.wPeriodMin, jc.wPeriodMax);
90 ret = joyGetDevCapsW(JOYSTICKID1 + i, &jcw, sizeof(jcw));
91 if (ret != MMSYSERR_NOTSUPPORTED) /* Win 98 */
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);
97 else win98++;
99 else
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);
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));
111 ok(ret == MMSYSERR_NODRIVER || ret == JOYERR_PARMS,
112 "Expected %d or %d, got %d\n", MMSYSERR_NODRIVER, JOYERR_PARMS, ret);
114 if (joyid == -1)
116 skip("This test requires a real joystick.\n");
117 return;
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)
129 todo_wine
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 */
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 */
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 < sizeof(period) / sizeof(period[0]); i++)
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)
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);
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);
192 infoex.ex.dwSize = sizeof(infoex.ex);
193 for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++)
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);
200 /* the interactive tests spans for 15 seconds, a 500ms polling is used to get
201 * changes in the joystick. */
202 if (winetest_interactive)
204 #define MAX_TIME 15000
205 DWORD tick = GetTickCount(), spent;
206 infoex.ex.dwSize = sizeof(infoex.ex);
207 infoex.ex.dwFlags = JOY_RETURNALL;
210 spent = GetTickCount() - tick;
211 ret = joyGetPosEx(joyid, &infoex.ex);
212 if (ret == JOYERR_NOERROR)
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);
221 Sleep(500);
223 while (spent < MAX_TIME);
224 #undef MAX_TIME
226 else
227 skip("Skipping interactive tests for the joystick\n");
230 START_TEST(joystick)
232 create_window();
233 test_api();
234 destroy_window();