ReactOS  0.4.14-dev-323-g6fe6a88
joystick.c
Go to the documentation of this file.
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2 /*
3  * joystick functions
4  *
5  * Copyright 1997 Andreas Mohr
6  * 2000 Wolfgang Schwotzer
7  * Eric Pouech
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include "winemm.h"
25 
26 #ifdef HAVE_UNISTD_H
27 # include <unistd.h>
28 #endif
29 
30 #include <stdlib.h>
31 
32 #ifdef HAVE_SYS_IOCTL_H
33 #include <sys/ioctl.h>
34 #endif
35 
37 
38 #define MAXJOYSTICK (JOYSTICKID2 + 30)
39 #define JOY_PERIOD_MIN (10) /* min Capture time period */
40 #define JOY_PERIOD_MAX (1000) /* max Capture time period */
41 
42 typedef struct tagWINE_JOYSTICK {
48  HDRVR hDriver;
50 
52 
53 /**************************************************************************
54  * JOY_LoadDriver [internal]
55  */
56 static BOOL JOY_LoadDriver(DWORD dwJoyID)
57 {
58  static BOOL winejoystick_missing = FALSE;
59 
60  if (dwJoyID >= MAXJOYSTICK || winejoystick_missing)
61  return FALSE;
62  if (JOY_Sticks[dwJoyID].hDriver)
63  return TRUE;
64 
65  JOY_Sticks[dwJoyID].hDriver = OpenDriverA("winejoystick.drv", 0, dwJoyID);
66 
67  if (!JOY_Sticks[dwJoyID].hDriver)
68  {
69  /* The default driver is missing, don't attempt to load it again */
70  winejoystick_missing = TRUE;
71  }
72 
73  return (JOY_Sticks[dwJoyID].hDriver != 0);
74 }
75 
76 /**************************************************************************
77  * JOY_Timer [internal]
78  */
79 static void CALLBACK JOY_Timer(HWND hWnd, UINT wMsg, UINT_PTR wTimer, DWORD dwTime)
80 {
81  int i;
82  WINE_JOYSTICK* joy;
83  JOYINFO ji;
84  LONG pos;
85  unsigned buttonChange;
86 
87  for (i = 0; i < MAXJOYSTICK; i++) {
88  joy = &JOY_Sticks[i];
89 
90  if (joy->hCapture != hWnd) continue;
91 
92  joyGetPos(i, &ji);
93  pos = MAKELONG(ji.wXpos, ji.wYpos);
94 
95  if (!joy->bChanged ||
96  abs(joy->ji.wXpos - ji.wXpos) > joy->threshold ||
97  abs(joy->ji.wYpos - ji.wYpos) > joy->threshold) {
99  joy->ji.wXpos = ji.wXpos;
100  joy->ji.wYpos = ji.wYpos;
101  }
102  if (!joy->bChanged ||
103  abs(joy->ji.wZpos - ji.wZpos) > joy->threshold) {
105  joy->ji.wZpos = ji.wZpos;
106  }
107  if ((buttonChange = joy->ji.wButtons ^ ji.wButtons) != 0) {
108  if (ji.wButtons & buttonChange)
110  (buttonChange << 8) | (ji.wButtons & buttonChange), pos);
111  if (joy->ji.wButtons & buttonChange)
113  (buttonChange << 8) | (joy->ji.wButtons & buttonChange), pos);
114  joy->ji.wButtons = ji.wButtons;
115  }
116  }
117 }
118 
119 /**************************************************************************
120  * joyConfigChanged [WINMM.@]
121  */
123 {
124  FIXME("(%x) - stub\n", flags);
125 
126  if (flags)
127  return JOYERR_PARMS;
128 
129  return JOYERR_NOERROR;
130 }
131 
132 /**************************************************************************
133  * joyGetNumDevs [WINMM.@]
134  */
136 {
137  UINT ret = 0;
138  int i;
139 
140  for (i = 0; i < MAXJOYSTICK; i++) {
141  if (JOY_LoadDriver(i)) {
143  }
144  }
145  return ret;
146 }
147 
148 /**************************************************************************
149  * joyGetDevCapsW [WINMM.@]
150  */
152 {
153  if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
154  if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
155 
156  lpCaps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */
157  lpCaps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */
158 
159  return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETDEVCAPS, (LPARAM)lpCaps, wSize);
160 }
161 
162 /**************************************************************************
163  * joyGetDevCapsA [WINMM.@]
164  */
166 {
167  JOYCAPSW jcw;
168  MMRESULT ret;
169 
170  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
171 
172  ret = joyGetDevCapsW(wID, &jcw, sizeof(jcw));
173 
174  if (ret == JOYERR_NOERROR)
175  {
176  lpCaps->wMid = jcw.wMid;
177  lpCaps->wPid = jcw.wPid;
178  WideCharToMultiByte( CP_ACP, 0, jcw.szPname, -1, lpCaps->szPname,
179  sizeof(lpCaps->szPname), NULL, NULL );
180  lpCaps->wXmin = jcw.wXmin;
181  lpCaps->wXmax = jcw.wXmax;
182  lpCaps->wYmin = jcw.wYmin;
183  lpCaps->wYmax = jcw.wYmax;
184  lpCaps->wZmin = jcw.wZmin;
185  lpCaps->wZmax = jcw.wZmax;
186  lpCaps->wNumButtons = jcw.wNumButtons;
187  lpCaps->wPeriodMin = jcw.wPeriodMin;
188  lpCaps->wPeriodMax = jcw.wPeriodMax;
189 
190  if (wSize >= sizeof(JOYCAPSA)) { /* Win95 extensions ? */
191  lpCaps->wRmin = jcw.wRmin;
192  lpCaps->wRmax = jcw.wRmax;
193  lpCaps->wUmin = jcw.wUmin;
194  lpCaps->wUmax = jcw.wUmax;
195  lpCaps->wVmin = jcw.wVmin;
196  lpCaps->wVmax = jcw.wVmax;
197  lpCaps->wCaps = jcw.wCaps;
198  lpCaps->wMaxAxes = jcw.wMaxAxes;
199  lpCaps->wNumAxes = jcw.wNumAxes;
200  lpCaps->wMaxButtons = jcw.wMaxButtons;
201  WideCharToMultiByte( CP_ACP, 0, jcw.szRegKey, -1, lpCaps->szRegKey,
202  sizeof(lpCaps->szRegKey), NULL, NULL );
203  WideCharToMultiByte( CP_ACP, 0, jcw.szOEMVxD, -1, lpCaps->szOEMVxD,
204  sizeof(lpCaps->szOEMVxD), NULL, NULL );
205  }
206  }
207 
208  return ret;
209 }
210 
211 /**************************************************************************
212  * joyGetPosEx [WINMM.@]
213  */
215 {
216  TRACE("(%d, %p);\n", wID, lpInfo);
217 
218  if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
219  if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
220 
221  lpInfo->dwXpos = 0;
222  lpInfo->dwYpos = 0;
223  lpInfo->dwZpos = 0;
224  lpInfo->dwRpos = 0;
225  lpInfo->dwUpos = 0;
226  lpInfo->dwVpos = 0;
227  lpInfo->dwButtons = 0;
228  lpInfo->dwButtonNumber = 0;
229  lpInfo->dwPOV = 0;
230  lpInfo->dwReserved1 = 0;
231  lpInfo->dwReserved2 = 0;
232 
233  return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETPOSEX, (LPARAM)lpInfo, 0);
234 }
235 
236 /**************************************************************************
237  * joyGetPos [WINMM.@]
238  */
240 {
241  TRACE("(%d, %p);\n", wID, lpInfo);
242 
243  if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
244  if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
245 
246  lpInfo->wXpos = 0;
247  lpInfo->wYpos = 0;
248  lpInfo->wZpos = 0;
249  lpInfo->wButtons = 0;
250 
251  return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETPOS, (LPARAM)lpInfo, 0);
252 }
253 
254 /**************************************************************************
255  * joyGetThreshold [WINMM.@]
256  */
258 {
259  TRACE("(%04X, %p);\n", wID, lpThreshold);
260 
261  if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
262 
263  *lpThreshold = JOY_Sticks[wID].threshold;
264  return JOYERR_NOERROR;
265 }
266 
267 /**************************************************************************
268  * joyReleaseCapture [WINMM.@]
269  */
271 {
272  TRACE("(%04X);\n", wID);
273 
274  if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
275  if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
276  if (!JOY_Sticks[wID].hCapture) return JOYERR_NOCANDO;
277 
278  KillTimer(JOY_Sticks[wID].hCapture, JOY_Sticks[wID].wTimer);
279  JOY_Sticks[wID].hCapture = 0;
280  JOY_Sticks[wID].wTimer = 0;
281 
282  return JOYERR_NOERROR;
283 }
284 
285 /**************************************************************************
286  * joySetCapture [WINMM.@]
287  */
288 MMRESULT WINAPI joySetCapture(HWND hWnd, UINT wID, UINT wPeriod, BOOL bChanged)
289 {
290  TRACE("(%p, %04X, %d, %d);\n", hWnd, wID, wPeriod, bChanged);
291 
292  if (wID >= MAXJOYSTICK || hWnd == 0) return JOYERR_PARMS;
293  if (wPeriod<JOY_PERIOD_MIN || wPeriod>JOY_PERIOD_MAX) return JOYERR_PARMS;
294  if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
295 
296  if (JOY_Sticks[wID].hCapture || !IsWindow(hWnd))
297  return JOYERR_NOCANDO; /* FIXME: what should be returned ? */
298 
299  if (joyGetPos(wID, &JOY_Sticks[wID].ji) != JOYERR_NOERROR)
300  return JOYERR_UNPLUGGED;
301 
302  if ((JOY_Sticks[wID].wTimer = SetTimer(hWnd, 0, wPeriod, JOY_Timer)) == 0)
303  return JOYERR_NOCANDO;
304 
305  JOY_Sticks[wID].hCapture = hWnd;
306  JOY_Sticks[wID].bChanged = bChanged;
307 
308  return JOYERR_NOERROR;
309 }
310 
311 /**************************************************************************
312  * joySetThreshold [WINMM.@]
313  */
315 {
316  TRACE("(%04X, %d);\n", wID, wThreshold);
317 
318  if (wID >= MAXJOYSTICK) return MMSYSERR_INVALPARAM;
319 
320  JOY_Sticks[wID].threshold = wThreshold;
321 
322  return JOYERR_NOERROR;
323 }
DWORD dwButtonNumber
Definition: mmsystem.h:1469
#define abs(i)
Definition: fconv.c:206
LRESULT WINAPI SendDriverMessage(HDRVR hDriver, UINT msg, LPARAM lParam1, LPARAM lParam2)
Definition: driver.c:131
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
#define TRUE
Definition: types.h:120
UINT wYmin
Definition: mmsystem.h:1404
#define JDD_GETDEVCAPS
Definition: mmddk.h:332
UINT wButtons
Definition: mmsystem.h:1456
DWORD dwReserved2
Definition: mmsystem.h:1472
#define JOYERR_NOCANDO
Definition: mmsystem.h:431
#define WideCharToMultiByte
Definition: compat.h:101
UINT wMaxAxes
Definition: mmsystem.h:1418
UINT wYmin
Definition: mmsystem.h:1431
UINT wXmax
Definition: mmsystem.h:1430
BOOL WINAPI IsWindow(_In_opt_ HWND)
UINT wZpos
Definition: mmsystem.h:1455
#define JDD_GETPOS
Definition: mmddk.h:333
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx(UINT wID, LPJOYINFOEX lpInfo)
Definition: joystick.c:214
UINT wVmin
Definition: mmsystem.h:1415
#define JOYERR_NOERROR
Definition: mmsystem.h:429
UINT wCaps
Definition: mmsystem.h:1417
HDRVR WINAPI OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam)
Definition: driver.c:365
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define CP_ACP
Definition: compat.h:99
DWORD dwYpos
Definition: mmsystem.h:1463
UINT wUmin
Definition: mmsystem.h:1413
#define CALLBACK
Definition: compat.h:27
HWND hWnd
Definition: settings.c:17
UINT wNumButtons
Definition: mmsystem.h:1408
CHAR szOEMVxD[MAX_JOYSTICKOEMVXDNAME]
Definition: mmsystem.h:1422
_In_ LPWSTR _In_ ULONG _In_ ULONG _In_ ULONG _Out_ DEVINFO _In_ HDEV _In_ LPWSTR _In_ HANDLE hDriver
Definition: winddi.h:3553
UINT MMRESULT
Definition: mmsystem.h:962
#define JOYERR_UNPLUGGED
Definition: mmsystem.h:432
uint32_t * LPUINT
Definition: typedefs.h:57
UINT wMaxAxes
Definition: mmsystem.h:1445
UINT wRmin
Definition: mmsystem.h:1411
#define JDD_GETNUMDEVS
Definition: mmddk.h:331
UINT WINAPI DECLSPEC_HOTPATCH joyGetNumDevs(void)
Definition: joystick.c:135
MMRESULT WINAPI joyGetPos(UINT wID, LPJOYINFO lpInfo)
Definition: joystick.c:239
DWORD dwUpos
Definition: mmsystem.h:1466
UINT wUmin
Definition: mmsystem.h:1440
UINT wVmax
Definition: mmsystem.h:1416
UINT wNumAxes
Definition: mmsystem.h:1419
WINE_DEFAULT_DEBUG_CHANNEL(dinput)
WCHAR szOEMVxD[MAX_JOYSTICKOEMVXDNAME]
Definition: mmsystem.h:1449
UINT wVmax
Definition: mmsystem.h:1443
UINT wPeriodMin
Definition: mmsystem.h:1436
#define MM_JOY1MOVE
Definition: mmsystem.h:47
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
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1401
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
UINT wZmax
Definition: mmsystem.h:1434
UINT wPeriodMin
Definition: mmsystem.h:1409
DWORD dwReserved1
Definition: mmsystem.h:1471
#define FIXME(fmt,...)
Definition: debug.h:110
DWORD threshold
Definition: joystick.c:46
UINT wNumAxes
Definition: mmsystem.h:1446
CHAR szRegKey[MAXPNAMELEN]
Definition: mmsystem.h:1421
#define MAKELONG(a, b)
Definition: typedefs.h:248
UINT wXpos
Definition: mmsystem.h:1453
UINT wYmax
Definition: mmsystem.h:1405
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
UINT wMaxButtons
Definition: mmsystem.h:1420
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
UINT wUmax
Definition: mmsystem.h:1441
struct tagWINE_JOYSTICK WINE_JOYSTICK
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:240
DWORD dwTime
Definition: solitaire.cpp:25
UINT wNumButtons
Definition: mmsystem.h:1435
static BOOL JOY_LoadDriver(DWORD dwJoyID)
Definition: joystick.c:56
#define TRACE(s)
Definition: solgame.cpp:4
UINT wCaps
Definition: mmsystem.h:1444
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW(UINT_PTR wID, LPJOYCAPSW lpCaps, UINT wSize)
Definition: joystick.c:151
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsA(UINT_PTR wID, LPJOYCAPSA lpCaps, UINT wSize)
Definition: joystick.c:165
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
GLbitfield flags
Definition: glext.h:7161
UINT wRmax
Definition: mmsystem.h:1439
DWORD dwZpos
Definition: mmsystem.h:1464
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
int ret
DWORD dwVpos
Definition: mmsystem.h:1467
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1428
DWORD dwRpos
Definition: mmsystem.h:1465
MMRESULT WINAPI joyReleaseCapture(UINT wID)
Definition: joystick.c:270
UINT wRmax
Definition: mmsystem.h:1412
DWORD dwButtons
Definition: mmsystem.h:1468
#define JOY_PERIOD_MAX
Definition: joystick.c:40
UINT wVmin
Definition: mmsystem.h:1442
MMRESULT WINAPI joyConfigChanged(DWORD flags)
Definition: joystick.c:122
DWORD dwXpos
Definition: mmsystem.h:1462
#define MAXJOYSTICK
Definition: joystick.c:38
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
UINT wMaxButtons
Definition: mmsystem.h:1447
UINT wYpos
Definition: mmsystem.h:1454
WCHAR szRegKey[MAXPNAMELEN]
Definition: mmsystem.h:1448
UINT wXmin
Definition: mmsystem.h:1402
JOYINFO ji
Definition: joystick.c:43
unsigned int UINT
Definition: ndis.h:50
UINT wPeriodMax
Definition: mmsystem.h:1437
#define JDD_GETPOSEX
Definition: mmddk.h:336
#define JOY_PERIOD_MIN
Definition: joystick.c:39
#define MM_JOY1ZMOVE
Definition: mmsystem.h:49
UINT wUmax
Definition: mmsystem.h:1414
UINT wYmax
Definition: mmsystem.h:1432
UINT wXmax
Definition: mmsystem.h:1403
#define MM_JOY1BUTTONDOWN
Definition: mmsystem.h:51
UINT wZmax
Definition: mmsystem.h:1407
static WINE_JOYSTICK JOY_Sticks[MAXJOYSTICK]
Definition: joystick.c:51
UINT wZmin
Definition: mmsystem.h:1433
#define MM_JOY1BUTTONUP
Definition: mmsystem.h:53
MMRESULT WINAPI joySetCapture(HWND hWnd, UINT wID, UINT wPeriod, BOOL bChanged)
Definition: joystick.c:288
UINT wZmin
Definition: mmsystem.h:1406
UINT wXmin
Definition: mmsystem.h:1429
UINT wPeriodMax
Definition: mmsystem.h:1410
UINT wRmin
Definition: mmsystem.h:1438
static void CALLBACK JOY_Timer(HWND hWnd, UINT wMsg, UINT_PTR wTimer, DWORD dwTime)
Definition: joystick.c:79