added support for gcc precompiled headers
[wxWidgets.git] / src / unix / joystick.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: joystick.cpp
3 // Purpose: wxJoystick class
4 // Author: Ported to Linux by Guilhem Lavaux
5 // Modified by:
6 // Created: 05/23/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "joystick.h"
14 #endif
15
16 // for compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #include "wx/defs.h"
20
21 #if wxUSE_JOYSTICK
22
23 #include "wx/joystick.h"
24
25 #include <linux/joystick.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/time.h>
29 #include <sys/ioctl.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32
33 #include "wx/event.h"
34 #include "wx/window.h"
35
36 #define JOYSTICK_AXE_MAX 32767
37 #define JOYSTICK_AXE_MIN -32767
38
39 IMPLEMENT_DYNAMIC_CLASS(wxJoystick, wxObject)
40
41 wxJoystick::wxJoystick(int joystick)
42 {
43 wxString dev_name;
44 // Assume it's the same device name on all Linux systems ...
45 dev_name.Printf( wxT("/dev/js%d"), (joystick == wxJOYSTICK1) ? 0 : 1); // FIXME Unicode?
46
47 m_joystick = open(dev_name.fn_str(), O_RDWR);
48 m_lastposition = wxPoint(-1, -1);
49 for (int i=0;i<15;i++)
50 m_axe[i] = 0;
51 if (m_joystick != -1)
52 Create();
53 }
54
55 ////////////////////////////////////////////////////////////////////////////
56 // Background thread
57 ////////////////////////////////////////////////////////////////////////////
58 void *wxJoystick::Entry(void)
59 {
60 struct js_event j_evt;
61 wxJoystickEvent jwx_event;
62 fd_set read_fds;
63 struct timeval time_out = {0, 0};
64
65 FD_ZERO(&read_fds);
66 while (1) {
67 TestDestroy();
68
69 if (m_polling) {
70 FD_SET(m_joystick, &read_fds);
71 select(m_joystick+1, &read_fds, NULL, NULL, &time_out);
72 if (FD_ISSET(m_joystick, &read_fds))
73 read(m_joystick, &j_evt, sizeof(j_evt));
74 else
75 j_evt.type = 0;
76 } else {
77 read(m_joystick, &j_evt, sizeof(j_evt));
78 }
79
80 if ((j_evt.type & JS_EVENT_AXIS) == JS_EVENT_AXIS) {
81 switch (j_evt.number) {
82 case 1:
83 m_lastposition.x = j_evt.value;
84 jwx_event.SetEventType(wxEVT_JOY_MOVE);
85 break;
86 case 2:
87 m_lastposition.y = j_evt.value;
88 jwx_event.SetEventType(wxEVT_JOY_MOVE);
89 break;
90 case 3:
91 m_axe[3] = j_evt.value;
92 jwx_event.SetEventType(wxEVT_JOY_ZMOVE);
93 break;
94 default:
95 m_axe[j_evt.number] = j_evt.value;
96 jwx_event.SetEventType(wxEVT_JOY_MOVE);
97 break;
98 }
99 jwx_event.SetPosition(m_lastposition);
100 jwx_event.SetZPosition(m_axe[3]);
101 }
102 if ((j_evt.type & JS_EVENT_BUTTON) == JS_EVENT_BUTTON) {
103 register int mask = 1 << j_evt.number;
104 char button = m_buttons & mask;
105
106 m_buttons &= ~mask;
107 if (button) {
108 jwx_event.SetEventType(wxEVT_JOY_BUTTON_UP);
109 } else {
110 jwx_event.SetEventType(wxEVT_JOY_BUTTON_DOWN);
111 m_buttons |= mask;
112 }
113
114 jwx_event.SetButtonState(m_buttons);
115 jwx_event.SetButtonChange(j_evt.number);
116 }
117 }
118 if (m_catchwin)
119 m_catchwin->ProcessEvent(jwx_event);
120 if (m_polling)
121 usleep(m_polling*1000);
122 }
123
124 ////////////////////////////////////////////////////////////////////////////
125 // State
126 ////////////////////////////////////////////////////////////////////////////
127
128 wxPoint wxJoystick::GetPosition(void) const
129 {
130 return m_lastposition;
131 }
132
133 int wxJoystick::GetZPosition(void) const
134 {
135 return m_axe[3];
136 }
137
138 int wxJoystick::GetButtonState(void) const
139 {
140 return m_buttons;
141 }
142
143 int wxJoystick::GetPOVPosition(void) const
144 {
145 return -1;
146 }
147
148 int wxJoystick::GetPOVCTSPosition(void) const
149 {
150 return -1;
151 }
152
153 int wxJoystick::GetRudderPosition(void) const
154 {
155 return m_axe[4];
156 }
157
158 int wxJoystick::GetUPosition(void) const
159 {
160 return m_axe[5];
161 }
162
163 int wxJoystick::GetVPosition(void) const
164 {
165 return m_axe[6];
166 }
167
168 int wxJoystick::GetMovementThreshold(void) const
169 {
170 return 0;
171 }
172
173 void wxJoystick::SetMovementThreshold(int threshold)
174 {
175 }
176
177 ////////////////////////////////////////////////////////////////////////////
178 // Capabilities
179 ////////////////////////////////////////////////////////////////////////////
180
181 bool wxJoystick::IsOk(void) const
182 {
183 return (m_joystick != -1);
184 }
185
186 int wxJoystick::GetNumberJoysticks(void) const
187 {
188 wxString dev_name;
189 int fd, j;
190
191 for (j=0;j<2;j++) {
192 dev_name.Printf(wxT("/dev/js%d"), j);
193 fd = open(dev_name.fn_str(), O_RDONLY);
194 if (fd == -1)
195 return j;
196 close(fd);
197 }
198 return j;
199 }
200
201 int wxJoystick::GetManufacturerId(void) const
202 {
203 return 0;
204 }
205
206 int wxJoystick::GetProductId(void) const
207 {
208 return 0;
209 }
210
211 wxString wxJoystick::GetProductName(void) const
212 {
213 wxString dev_name;
214 // 2002-08-20 johan@linkdata.se
215 // Return the device name in lieu of a better one
216 dev_name.Printf( wxT("/dev/js%d"), (m_joystick == wxJOYSTICK1) ? 0 : 1); // FIXME Unicode?
217 return dev_name;
218 }
219
220 int wxJoystick::GetXMin(void) const
221 {
222 return JOYSTICK_AXE_MAX;
223 }
224
225 int wxJoystick::GetYMin(void) const
226 {
227 return JOYSTICK_AXE_MAX;
228 }
229
230 int wxJoystick::GetZMin(void) const
231 {
232 return JOYSTICK_AXE_MAX;
233 }
234
235 int wxJoystick::GetXMax(void) const
236 {
237 return JOYSTICK_AXE_MAX;
238 }
239
240 int wxJoystick::GetYMax(void) const
241 {
242 return JOYSTICK_AXE_MAX;
243 }
244
245 int wxJoystick::GetZMax(void) const
246 {
247 return JOYSTICK_AXE_MAX;
248 }
249
250 int wxJoystick::GetNumberButtons(void) const
251 {
252 int nb;
253
254 ioctl(m_joystick, JSIOCGBUTTONS, &nb);
255
256 return nb;
257 }
258
259 int wxJoystick::GetNumberAxes(void) const
260 {
261 int nb;
262
263 ioctl(m_joystick, JSIOCGAXES, &nb);
264
265 return nb;
266 }
267
268 int wxJoystick::GetMaxButtons(void) const
269 {
270 return 15; // internal
271 }
272
273 int wxJoystick::GetMaxAxes(void) const
274 {
275 return 15; // internal
276 }
277
278 int wxJoystick::GetPollingMin(void) const
279 {
280 return -1;
281 }
282
283 int wxJoystick::GetPollingMax(void) const
284 {
285 return -1;
286 }
287
288 int wxJoystick::GetRudderMin(void) const
289 {
290 return JOYSTICK_AXE_MIN;
291 }
292
293 int wxJoystick::GetRudderMax(void) const
294 {
295 return JOYSTICK_AXE_MAX;
296 }
297
298 int wxJoystick::GetUMin(void) const
299 {
300 return JOYSTICK_AXE_MIN;
301 }
302
303 int wxJoystick::GetUMax(void) const
304 {
305 return JOYSTICK_AXE_MAX;
306 }
307
308 int wxJoystick::GetVMin(void) const
309 {
310 return JOYSTICK_AXE_MIN;
311 }
312
313 int wxJoystick::GetVMax(void) const
314 {
315 return JOYSTICK_AXE_MAX;
316 }
317
318 bool wxJoystick::HasRudder(void) const
319 {
320 return GetNumberAxes() >= 4;
321 }
322
323 bool wxJoystick::HasZ(void) const
324 {
325 return GetNumberAxes() >= 3;
326 }
327
328 bool wxJoystick::HasU(void) const
329 {
330 return GetNumberAxes() >= 5;
331 }
332
333 bool wxJoystick::HasV(void) const
334 {
335 return GetNumberAxes() >= 6;
336 }
337
338 bool wxJoystick::HasPOV(void) const
339 {
340 return FALSE;
341 }
342
343 bool wxJoystick::HasPOV4Dir(void) const
344 {
345 return FALSE;
346 }
347
348 bool wxJoystick::HasPOVCTS(void) const
349 {
350 return FALSE;
351 }
352
353 ////////////////////////////////////////////////////////////////////////////
354 // Operations
355 ////////////////////////////////////////////////////////////////////////////
356
357 bool wxJoystick::SetCapture(wxWindow* win, int pollingFreq)
358 {
359 m_catchwin = win;
360 m_polling = pollingFreq;
361 return TRUE;
362 }
363
364 bool wxJoystick::ReleaseCapture(void)
365 {
366 m_catchwin = NULL;
367 m_polling = 0;
368 return TRUE;
369 }
370 #endif // wxUSE_JOYSTICK
371