ReactOS  0.4.13-dev-241-g63286c6
joystick.c File Reference
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "mmsystem.h"
#include "wine/test.h"
Include dependency graph for joystick.c:

Go to the source code of this file.

Macros

#define MAX_TIME   15000
 

Functions

static LRESULT CALLBACK proc_window (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
 
static void create_window (void)
 
static void destroy_window (void)
 
static void test_api (void)
 
 START_TEST (joystick)
 

Variables

static HWND window
 

Macro Definition Documentation

◆ MAX_TIME

#define MAX_TIME   15000

Function Documentation

◆ create_window()

static void create_window ( void  )
static

Definition at line 36 of file joystick.c.

37 {
38  const char name[] = "Joystick Test";
39  WNDCLASSA wc;
40 
41  memset(&wc, 0, sizeof(wc));
43  wc.hInstance = 0;
44  wc.lpszClassName = name;
45  RegisterClassA(&wc);
48  NULL, NULL, NULL, NULL);
49  ok(window != NULL, "Expected CreateWindowEx to work, error %d\n", GetLastError());
50 }
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ok(value,...)
#define CW_USEDEFAULT
Definition: winuser.h:225
smooth NULL
Definition: ftsmooth.c:416
static LRESULT CALLBACK proc_window(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: joystick.c:31
LPCSTR lpszClassName
Definition: winuser.h:3125
HINSTANCE hInstance
Definition: winuser.h:3120
static HWND window
Definition: joystick.c:29
WNDPROC lpfnWndProc
Definition: winuser.h:3117
Definition: name.c:36
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)
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define memset(x, y, z)
Definition: compat.h:39
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
GLuint const GLchar * name
Definition: glext.h:6031

Referenced by START_TEST().

◆ destroy_window()

static void destroy_window ( void  )
static

Definition at line 52 of file joystick.c.

53 {
55  window = NULL;
56 }
BOOL WINAPI DestroyWindow(_In_ HWND)
smooth NULL
Definition: ftsmooth.c:416
static HWND window
Definition: joystick.c:29

Referenced by START_TEST().

◆ proc_window()

static LRESULT CALLBACK proc_window ( HWND  hwnd,
UINT  msg,
WPARAM  wparam,
LPARAM  lparam 
)
static

Definition at line 31 of file joystick.c.

32 {
33  return DefWindowProcA(hwnd, msg, wparam, lparam);
34 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
static UINT WPARAM LPARAM lparam
Definition: combo.c:716
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define msg(x)
Definition: auth_time.c:54
static UINT WPARAM wparam
Definition: combo.c:716

Referenced by create_window().

◆ START_TEST()

START_TEST ( joystick  )

Definition at line 230 of file joystick.c.

231 {
232  create_window();
233  test_api();
234  destroy_window();
235 }
static void test_api(void)
Definition: joystick.c:58
static void destroy_window(void)
Definition: joystick.c:52
static void create_window(void)
Definition: joystick.c:36

◆ test_api()

static void test_api ( void  )
static

Definition at line 58 of file joystick.c.

59 {
60  MMRESULT ret;
61  JOYCAPSA jc;
62  JOYCAPSW jcw;
63  JOYINFO info;
64  union _infoex
65  {
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;
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  {
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 */
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 < sizeof(period) / sizeof(period[0]); 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 < sizeof(flags) / sizeof(flags[0]); 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 }
#define trace(...)
Definition: kmt_test.h:217
MMRESULT WINAPI joyGetThreshold(UINT wID, LPUINT lpThreshold)
Definition: joystick.c:257
MMRESULT WINAPI joySetThreshold(UINT wID, UINT wThreshold)
Definition: joystick.c:314
#define JOYERR_PARMS
Definition: mmsystem.h:430
Definition: comerr.c:44
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
#define JOYERR_NOCANDO
Definition: mmsystem.h:431
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx(UINT wID, LPJOYINFOEX lpInfo)
Definition: joystick.c:214
#define JOYERR_NOERROR
Definition: mmsystem.h:429
const char * devices
Definition: diskspace.c:793
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
UINT wNumButtons
Definition: mmsystem.h:1408
#define MAX_TIME
UINT MMRESULT
Definition: mmsystem.h:962
GLuint buffer
Definition: glext.h:5915
struct joyinfoex_tag JOYINFOEX
#define JOY_RETURNCENTERED
Definition: mmsystem.h:484
int winetest_interactive
UINT WINAPI DECLSPEC_HOTPATCH joyGetNumDevs(void)
Definition: joystick.c:135
MMRESULT WINAPI joyGetPos(UINT wID, LPJOYINFO lpInfo)
Definition: joystick.c:239
struct _test_info info[]
Definition: SetCursorPos.c:19
UINT wNumAxes
Definition: mmsystem.h:1419
#define JOY_RETURNY
Definition: mmsystem.h:475
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 MMSYSERR_NODRIVER
Definition: mmsystem.h:102
#define JOY_RETURNRAWDATA
Definition: mmsystem.h:482
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1401
#define JOY_RETURNV
Definition: mmsystem.h:479
UINT wPeriodMin
Definition: mmsystem.h:1409
#define JOY_RETURNX
Definition: mmsystem.h:474
#define ok(value,...)
UINT wNumAxes
Definition: mmsystem.h:1446
smooth NULL
Definition: ftsmooth.c:416
UINT wNumButtons
Definition: mmsystem.h:1435
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW(UINT_PTR wID, LPJOYCAPSW lpCaps, UINT wSize)
Definition: joystick.c:151
unsigned long DWORD
Definition: ntddk_ex.h:95
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsA(UINT_PTR wID, LPJOYCAPSA lpCaps, UINT wSize)
Definition: joystick.c:165
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
GLbitfield flags
Definition: glext.h:7161
int ret
#define todo_wine
Definition: test.h:154
MMRESULT WINAPI joyReleaseCapture(UINT wID)
Definition: joystick.c:270
#define broken(x)
Definition: _sntprintf.h:21
#define JOY_RETURNPOVCTS
Definition: mmsystem.h:483
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
static HWND window
Definition: joystick.c:29
#define JOY_RETURNR
Definition: mmsystem.h:477
#define JOY_RETURNU
Definition: mmsystem.h:478
unsigned int UINT
Definition: ndis.h:50
#define skip(...)
#define JOY_RETURNALL
Definition: mmsystem.h:486
#define JOYSTICKID1
Definition: mmsystem.h:499
MMRESULT WINAPI joySetCapture(HWND hWnd, UINT wID, UINT wPeriod, BOOL bChanged)
Definition: joystick.c:288
#define memset(x, y, z)
Definition: compat.h:39
#define JOY_RETURNPOV
Definition: mmsystem.h:480
UINT wPeriodMax
Definition: mmsystem.h:1410
#define JOY_RETURNZ
Definition: mmsystem.h:476
#define JOY_RETURNBUTTONS
Definition: mmsystem.h:481

Referenced by START_TEST().

Variable Documentation

◆ window

HWND window
static

Definition at line 29 of file joystick.c.

Referenced by create_window(), destroy_window(), and test_api().