ReactOS  0.4.15-dev-3303-g1ade494
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  WARN("OpenDriverA(\"winejoystick.drv\") failed\n");
70 
71  /* The default driver is missing, don't attempt to load it again */
72  winejoystick_missing = TRUE;
73  }
74 
75  return (JOY_Sticks[dwJoyID].hDriver != 0);
76 }
77 
78 /**************************************************************************
79  * JOY_Timer [internal]
80  */
81 static void CALLBACK JOY_Timer(HWND hWnd, UINT wMsg, UINT_PTR wTimer, DWORD dwTime)
82 {
83  int i;
84  WINE_JOYSTICK* joy;
85  JOYINFO ji;
86  LONG pos;
87  unsigned buttonChange;
88 
89  for (i = 0; i < MAXJOYSTICK; i++) {
90  joy = &JOY_Sticks[i];
91 
92  if (joy->hCapture != hWnd) continue;
93 
94  joyGetPos(i, &ji);
95  pos = MAKELONG(ji.wXpos, ji.wYpos);
96 
97  if (!joy->bChanged ||
98  abs(joy->ji.wXpos - ji.wXpos) > joy->threshold ||
99  abs(joy->ji.wYpos - ji.wYpos) > joy->threshold) {
101  joy->ji.wXpos = ji.wXpos;
102  joy->ji.wYpos = ji.wYpos;
103  }
104  if (!joy->bChanged ||
105  abs(joy->ji.wZpos - ji.wZpos) > joy->threshold) {
107  joy->ji.wZpos = ji.wZpos;
108  }
109  if ((buttonChange = joy->ji.wButtons ^ ji.wButtons) != 0) {
110  if (ji.wButtons & buttonChange)
112  (buttonChange << 8) | (ji.wButtons & buttonChange), pos);
113  if (joy->ji.wButtons & buttonChange)
115  (buttonChange << 8) | (joy->ji.wButtons & buttonChange), pos);
116  joy->ji.wButtons = ji.wButtons;
117  }
118  }
119 }
120 
121 /**************************************************************************
122  * joyConfigChanged [WINMM.@]
123  */
125 {
126  FIXME("(%x) - stub\n", flags);
127 
128  if (flags)
129  return JOYERR_PARMS;
130 
131  return JOYERR_NOERROR;
132 }
133 
134 /**************************************************************************
135  * joyGetNumDevs [WINMM.@]
136  */
138 {
139  UINT ret = 0;
140  int i;
141 
142  for (i = 0; i < MAXJOYSTICK; i++) {
143  if (JOY_LoadDriver(i)) {
145  }
146  }
147  return ret;
148 }
149 
150 /**************************************************************************
151  * joyGetDevCapsW [WINMM.@]
152  */
154 {
155  if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
156  if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
157 
158  lpCaps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */
159  lpCaps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */
160 
161  return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETDEVCAPS, (LPARAM)lpCaps, wSize);
162 }
163 
164 /**************************************************************************
165  * joyGetDevCapsA [WINMM.@]
166  */
168 {
169  JOYCAPSW jcw;
170  MMRESULT ret;
171 
172  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
173 
174  ret = joyGetDevCapsW(wID, &jcw, sizeof(jcw));
175 
176  if (ret == JOYERR_NOERROR)
177  {
178  lpCaps->wMid = jcw.wMid;
179  lpCaps->wPid = jcw.wPid;
180  WideCharToMultiByte( CP_ACP, 0, jcw.szPname, -1, lpCaps->szPname,
181  sizeof(lpCaps->szPname), NULL, NULL );
182  lpCaps->wXmin = jcw.wXmin;
183  lpCaps->wXmax = jcw.wXmax;
184  lpCaps->wYmin = jcw.wYmin;
185  lpCaps->wYmax = jcw.wYmax;
186  lpCaps->wZmin = jcw.wZmin;
187  lpCaps->wZmax = jcw.wZmax;
188  lpCaps->wNumButtons = jcw.wNumButtons;
189  lpCaps->wPeriodMin = jcw.wPeriodMin;
190  lpCaps->wPeriodMax = jcw.wPeriodMax;
191 
192  if (wSize >= sizeof(JOYCAPSA)) { /* Win95 extensions ? */
193  lpCaps->wRmin = jcw.wRmin;
194  lpCaps->wRmax = jcw.wRmax;
195  lpCaps->wUmin = jcw.wUmin;
196  lpCaps->wUmax = jcw.wUmax;
197  lpCaps->wVmin = jcw.wVmin;
198  lpCaps->wVmax = jcw.wVmax;
199  lpCaps->wCaps = jcw.wCaps;
200  lpCaps->wMaxAxes = jcw.wMaxAxes;
201  lpCaps->wNumAxes = jcw.wNumAxes;
202  lpCaps->wMaxButtons = jcw.wMaxButtons;
203  WideCharToMultiByte( CP_ACP, 0, jcw.szRegKey, -1, lpCaps->szRegKey,
204  sizeof(lpCaps->szRegKey), NULL, NULL );
205  WideCharToMultiByte( CP_ACP, 0, jcw.szOEMVxD, -1, lpCaps->szOEMVxD,
206  sizeof(lpCaps->szOEMVxD), NULL, NULL );
207  }
208  }
209 
210  return ret;
211 }
212 
213 /**************************************************************************
214  * joyGetPosEx [WINMM.@]
215  */
217 {
218  TRACE("(%d, %p);\n", wID, lpInfo);
219 
220  if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
221  if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
222 
223  lpInfo->dwXpos = 0;
224  lpInfo->dwYpos = 0;
225  lpInfo->dwZpos = 0;
226  lpInfo->dwRpos = 0;
227  lpInfo->dwUpos = 0;
228  lpInfo->dwVpos = 0;
229  lpInfo->dwButtons = 0;
230  lpInfo->dwButtonNumber = 0;
231  lpInfo->dwPOV = 0;
232  lpInfo->dwReserved1 = 0;
233  lpInfo->dwReserved2 = 0;
234 
235  return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETPOSEX, (LPARAM)lpInfo, 0);
236 }
237 
238 /**************************************************************************
239  * joyGetPos [WINMM.@]
240  */
242 {
243  TRACE("(%d, %p);\n", wID, lpInfo);
244 
245  if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
246  if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
247 
248  lpInfo->wXpos = 0;
249  lpInfo->wYpos = 0;
250  lpInfo->wZpos = 0;
251  lpInfo->wButtons = 0;
252 
253  return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETPOS, (LPARAM)lpInfo, 0);
254 }
255 
256 /**************************************************************************
257  * joyGetThreshold [WINMM.@]
258  */
260 {
261  TRACE("(%04X, %p);\n", wID, lpThreshold);
262 
263  if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
264 
265  *lpThreshold = JOY_Sticks[wID].threshold;
266  return JOYERR_NOERROR;
267 }
268 
269 /**************************************************************************
270  * joyReleaseCapture [WINMM.@]
271  */
273 {
274  TRACE("(%04X);\n", wID);
275 
276  if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
277  if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
278  if (!JOY_Sticks[wID].hCapture) return JOYERR_NOCANDO;
279 
280  KillTimer(JOY_Sticks[wID].hCapture, JOY_Sticks[wID].wTimer);
281  JOY_Sticks[wID].hCapture = 0;
282  JOY_Sticks[wID].wTimer = 0;
283 
284  return JOYERR_NOERROR;
285 }
286 
287 /**************************************************************************
288  * joySetCapture [WINMM.@]
289  */
290 MMRESULT WINAPI joySetCapture(HWND hWnd, UINT wID, UINT wPeriod, BOOL bChanged)
291 {
292  TRACE("(%p, %04X, %d, %d);\n", hWnd, wID, wPeriod, bChanged);
293 
294  if (wID >= MAXJOYSTICK || hWnd == 0) return JOYERR_PARMS;
295  if (wPeriod<JOY_PERIOD_MIN || wPeriod>JOY_PERIOD_MAX) return JOYERR_PARMS;
296  if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
297 
298  if (JOY_Sticks[wID].hCapture || !IsWindow(hWnd))
299  return JOYERR_NOCANDO; /* FIXME: what should be returned ? */
300 
301  if (joyGetPos(wID, &JOY_Sticks[wID].ji) != JOYERR_NOERROR)
302  return JOYERR_UNPLUGGED;
303 
304  if ((JOY_Sticks[wID].wTimer = SetTimer(hWnd, 0, wPeriod, JOY_Timer)) == 0)
305  return JOYERR_NOCANDO;
306 
307  JOY_Sticks[wID].hCapture = hWnd;
308  JOY_Sticks[wID].bChanged = bChanged;
309 
310  return JOYERR_NOERROR;
311 }
312 
313 /**************************************************************************
314  * joySetThreshold [WINMM.@]
315  */
317 {
318  TRACE("(%04X, %d);\n", wID, wThreshold);
319 
320  if (wID >= MAXJOYSTICK) return MMSYSERR_INVALPARAM;
321 
322  JOY_Sticks[wID].threshold = wThreshold;
323 
324  return JOYERR_NOERROR;
325 }
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:259
MMRESULT WINAPI joySetThreshold(UINT wID, UINT wThreshold)
Definition: joystick.c:316
#define JOYERR_PARMS
Definition: mmsystem.h:430
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:111
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:216
UINT wVmin
Definition: mmsystem.h:1415
#define JOYERR_NOERROR
Definition: mmsystem.h:429
#define TRUE
Definition: types.h:120
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:109
DWORD dwYpos
Definition: mmsystem.h:1463
UINT wUmin
Definition: mmsystem.h:1413
#define WARN(fmt,...)
Definition: debug.h:112
#define CALLBACK
Definition: compat.h:35
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:59
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:137
MMRESULT WINAPI joyGetPos(UINT wID, LPJOYINFO lpInfo)
Definition: joystick.c:241
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
#define MMSYSERR_NODRIVER
Definition: mmsystem.h:102
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1401
#define FALSE
Definition: types.h:117
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:111
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:249
UINT wXpos
Definition: mmsystem.h:1453
UINT wYmax
Definition: mmsystem.h:1405
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:243
DWORD dwTime
Definition: solitaire.cpp:26
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:153
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsA(UINT_PTR wID, LPJOYCAPSA lpCaps, UINT wSize)
Definition: joystick.c:167
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:272
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:124
DWORD dwXpos
Definition: mmsystem.h:1462
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 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
#define NULL
Definition: types.h:112
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:290
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:81