1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/msw/joystick.cpp
3 // Purpose:     wxJoystick class
4 // Author:      Julian Smart
5 // Modified by:
6 // Created:     04/01/98
7 // RCS-ID:      $Id: joystick.cpp 39021 2006-05-04 07:57:04Z ABX $
8 // Copyright:   (c) Julian Smart
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14 
15 #ifdef __BORLANDC__
16     #pragma hdrstop
17 #endif
18 
19 #if wxUSE_JOYSTICK
20 
21 #include "wx/joystick.h"
22 
23 #ifndef WX_PRECOMP
24     #include "wx/string.h"
25     #include "wx/window.h"
26 #endif
27 
28 #include "wx/msw/private.h"
29 
30 #if !defined(__GNUWIN32_OLD__) || defined(__CYGWIN10__)
31     #include <mmsystem.h>
32 #endif
33 
34 // Why doesn't BC++ have joyGetPosEx?
35 #if !defined(__WIN32__) || defined(__BORLANDC__)
36 #define NO_JOYGETPOSEX
37 #endif
38 
39 #include "wx/msw/registry.h"
40 
41 #include <regstr.h>
42 
IMPLEMENT_DYNAMIC_CLASS(wxJoystick,wxObject)43 IMPLEMENT_DYNAMIC_CLASS(wxJoystick, wxObject)
44 
45 // Attributes
46 ////////////////////////////////////////////////////////////////////////////
47 
48 /**
49     johan@linkdata.se 2002-08-20:
50     Now returns only valid, functioning
51     joysticks, counting from the first
52     available and upwards.
53 */
54 wxJoystick::wxJoystick(int joystick)
55 {
56     JOYINFO joyInfo;
57     int i, maxsticks;
58 
59     maxsticks = joyGetNumDevs();
60     for( i=0; i<maxsticks; i++ )
61     {
62         if( joyGetPos(i, & joyInfo) == JOYERR_NOERROR )
63         {
64             if( !joystick )
65             {
66                 /* Found the one we want, store actual OS id and return */
67                 m_joystick = i;
68                 return;
69             }
70             joystick --;
71         }
72     }
73 
74     /* No such joystick, return ID 0 */
75     m_joystick = 0;
76     return;
77 }
78 
GetPosition() const79 wxPoint wxJoystick::GetPosition() const
80 {
81     JOYINFO joyInfo;
82     MMRESULT res = joyGetPos(m_joystick, & joyInfo);
83     if (res == JOYERR_NOERROR )
84         return wxPoint(joyInfo.wXpos, joyInfo.wYpos);
85     else
86         return wxPoint(0,0);
87 }
88 
GetZPosition() const89 int wxJoystick::GetZPosition() const
90 {
91     JOYINFO joyInfo;
92     MMRESULT res = joyGetPos(m_joystick, & joyInfo);
93     if (res == JOYERR_NOERROR )
94         return joyInfo.wZpos;
95     else
96         return 0;
97 }
98 
99 /**
100     johan@linkdata.se 2002-08-20:
101     Return a bitmap with all button states in it,
102     like the GTK version does and Win32 does.
103 */
GetButtonState() const104 int wxJoystick::GetButtonState() const
105 {
106     JOYINFO joyInfo;
107     MMRESULT res = joyGetPos(m_joystick, & joyInfo);
108     if (res == JOYERR_NOERROR )
109     {
110         return joyInfo.wButtons;
111 #if 0
112         int buttons = 0;
113 
114         if (joyInfo.wButtons & JOY_BUTTON1)
115             buttons |= wxJOY_BUTTON1;
116         if (joyInfo.wButtons & JOY_BUTTON2)
117             buttons |= wxJOY_BUTTON2;
118         if (joyInfo.wButtons & JOY_BUTTON3)
119             buttons |= wxJOY_BUTTON3;
120         if (joyInfo.wButtons & JOY_BUTTON4)
121             buttons |= wxJOY_BUTTON4;
122 
123         return buttons;
124 #endif
125     }
126     else
127         return 0;
128 }
129 
130 /**
131     JLI 2002-08-20:
132     Returns -1 to signify error.
133 */
GetPOVPosition() const134 int wxJoystick::GetPOVPosition() const
135 {
136 #ifndef NO_JOYGETPOSEX
137     JOYINFOEX joyInfo;
138     joyInfo.dwFlags = JOY_RETURNPOV;
139     joyInfo.dwSize = sizeof(joyInfo);
140     MMRESULT res = joyGetPosEx(m_joystick, & joyInfo);
141     if (res == JOYERR_NOERROR )
142     {
143         return joyInfo.dwPOV;
144     }
145     else
146         return -1;
147 #else
148     return -1;
149 #endif
150 }
151 
152 /**
153     johan@linkdata.se 2002-08-20:
154     Returns -1 to signify error.
155 */
GetPOVCTSPosition() const156 int wxJoystick::GetPOVCTSPosition() const
157 {
158 #ifndef NO_JOYGETPOSEX
159     JOYINFOEX joyInfo;
160     joyInfo.dwFlags = JOY_RETURNPOVCTS;
161     joyInfo.dwSize = sizeof(joyInfo);
162     MMRESULT res = joyGetPosEx(m_joystick, & joyInfo);
163     if (res == JOYERR_NOERROR )
164     {
165         return joyInfo.dwPOV;
166     }
167     else
168         return -1;
169 #else
170     return -1;
171 #endif
172 }
173 
GetRudderPosition() const174 int wxJoystick::GetRudderPosition() const
175 {
176 #ifndef NO_JOYGETPOSEX
177     JOYINFOEX joyInfo;
178     joyInfo.dwFlags = JOY_RETURNR;
179     joyInfo.dwSize = sizeof(joyInfo);
180     MMRESULT res = joyGetPosEx(m_joystick, & joyInfo);
181     if (res == JOYERR_NOERROR )
182     {
183         return joyInfo.dwRpos;
184     }
185     else
186         return 0;
187 #else
188     return 0;
189 #endif
190 }
191 
GetUPosition() const192 int wxJoystick::GetUPosition() const
193 {
194 #ifndef NO_JOYGETPOSEX
195     JOYINFOEX joyInfo;
196     joyInfo.dwFlags = JOY_RETURNU;
197     joyInfo.dwSize = sizeof(joyInfo);
198     MMRESULT res = joyGetPosEx(m_joystick, & joyInfo);
199     if (res == JOYERR_NOERROR )
200     {
201         return joyInfo.dwUpos;
202     }
203     else
204         return 0;
205 #else
206     return 0;
207 #endif
208 }
209 
GetVPosition() const210 int wxJoystick::GetVPosition() const
211 {
212 #ifndef NO_JOYGETPOSEX
213     JOYINFOEX joyInfo;
214     joyInfo.dwFlags = JOY_RETURNV;
215     joyInfo.dwSize = sizeof(joyInfo);
216     MMRESULT res = joyGetPosEx(m_joystick, & joyInfo);
217     if (res == JOYERR_NOERROR )
218     {
219         return joyInfo.dwVpos;
220     }
221     else
222         return 0;
223 #else
224     return 0;
225 #endif
226 }
227 
GetMovementThreshold() const228 int wxJoystick::GetMovementThreshold() const
229 {
230     UINT thresh = 0;
231     MMRESULT res = joyGetThreshold(m_joystick, & thresh);
232     if (res == JOYERR_NOERROR )
233     {
234         return thresh;
235     }
236     else
237         return 0;
238 }
239 
SetMovementThreshold(int threshold)240 void wxJoystick::SetMovementThreshold(int threshold)
241 {
242     UINT thresh = threshold;
243     joySetThreshold(m_joystick, thresh);
244 }
245 
246 // Capabilities
247 ////////////////////////////////////////////////////////////////////////////
248 
249 /**
250     johan@linkdata.se 2002-08-20:
251     Now returns the number of connected, functioning
252     joysticks, as intended.
253 */
GetNumberJoysticks()254 int wxJoystick::GetNumberJoysticks()
255 {
256     JOYINFO joyInfo;
257     int i, maxsticks, actualsticks;
258     maxsticks = joyGetNumDevs();
259     actualsticks = 0;
260     for( i=0; i<maxsticks; i++ )
261     {
262         if( joyGetPos( i, & joyInfo ) == JOYERR_NOERROR )
263         {
264             actualsticks ++;
265         }
266     }
267     return actualsticks;
268 }
269 
270 /**
271     johan@linkdata.se 2002-08-20:
272     The old code returned true if there were any
273     joystick capable drivers loaded (=always).
274 */
IsOk() const275 bool wxJoystick::IsOk() const
276 {
277     JOYINFO joyInfo;
278     return (joyGetPos(m_joystick, & joyInfo) == JOYERR_NOERROR);
279 }
280 
GetManufacturerId() const281 int wxJoystick::GetManufacturerId() const
282 {
283     JOYCAPS joyCaps;
284     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
285         return 0;
286     else
287         return joyCaps.wMid;
288 }
289 
GetProductId() const290 int wxJoystick::GetProductId() const
291 {
292     JOYCAPS joyCaps;
293     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
294         return 0;
295     else
296         return joyCaps.wPid;
297 }
298 
GetProductName() const299 wxString wxJoystick::GetProductName() const
300 {
301     wxString str;
302 #ifndef __WINE__
303     JOYCAPS joyCaps;
304     if (joyGetDevCaps(m_joystick, &joyCaps, sizeof(joyCaps)) != JOYERR_NOERROR)
305         return wxEmptyString;
306 
307     wxRegKey key1(wxString::Format(wxT("HKEY_LOCAL_MACHINE\\%s\\%s\\%s"),
308                    REGSTR_PATH_JOYCONFIG, joyCaps.szRegKey, REGSTR_KEY_JOYCURR));
309 
310     key1.QueryValue(wxString::Format(wxT("Joystick%d%s"),
311                                      m_joystick + 1, REGSTR_VAL_JOYOEMNAME),
312                     str);
313 
314     wxRegKey key2(wxString::Format(wxT("HKEY_LOCAL_MACHINE\\%s\\%s"),
315                                         REGSTR_PATH_JOYOEM, str.c_str()));
316     key2.QueryValue(REGSTR_VAL_JOYOEMNAME, str);
317 #endif
318     return str;
319 }
320 
GetXMin() const321 int wxJoystick::GetXMin() const
322 {
323     JOYCAPS joyCaps;
324     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
325         return 0;
326     else
327         return joyCaps.wXmin;
328 }
329 
GetYMin() const330 int wxJoystick::GetYMin() const
331 {
332     JOYCAPS joyCaps;
333     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
334         return 0;
335     else
336         return joyCaps.wYmin;
337 }
338 
GetZMin() const339 int wxJoystick::GetZMin() const
340 {
341     JOYCAPS joyCaps;
342     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
343         return 0;
344     else
345         return joyCaps.wZmin;
346 }
347 
GetXMax() const348 int wxJoystick::GetXMax() const
349 {
350     JOYCAPS joyCaps;
351     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
352         return 0;
353     else
354         return joyCaps.wXmax;
355 }
356 
GetYMax() const357 int wxJoystick::GetYMax() const
358 {
359     JOYCAPS joyCaps;
360     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
361         return 0;
362     else
363         return joyCaps.wYmax;
364 }
365 
GetZMax() const366 int wxJoystick::GetZMax() const
367 {
368     JOYCAPS joyCaps;
369     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
370         return 0;
371     else
372         return joyCaps.wZmax;
373 }
374 
GetNumberButtons() const375 int wxJoystick::GetNumberButtons() const
376 {
377     JOYCAPS joyCaps;
378     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
379         return 0;
380     else
381         return joyCaps.wNumButtons;
382 }
383 
GetNumberAxes() const384 int wxJoystick::GetNumberAxes() const
385 {
386 #if defined(__WIN32__)
387     JOYCAPS joyCaps;
388     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
389         return 0;
390     else
391         return joyCaps.wNumAxes;
392 #else
393     return 0;
394 #endif
395 }
396 
GetMaxButtons() const397 int wxJoystick::GetMaxButtons() const
398 {
399 #if defined(__WIN32__)
400     JOYCAPS joyCaps;
401     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
402         return 0;
403     else
404         return joyCaps.wMaxButtons;
405 #else
406     return 0;
407 #endif
408 }
409 
GetMaxAxes() const410 int wxJoystick::GetMaxAxes() const
411 {
412 #if defined(__WIN32__)
413     JOYCAPS joyCaps;
414     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
415         return 0;
416     else
417         return joyCaps.wMaxAxes;
418 #else
419     return 0;
420 #endif
421 }
422 
GetPollingMin() const423 int wxJoystick::GetPollingMin() const
424 {
425     JOYCAPS joyCaps;
426     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
427         return 0;
428     else
429         return joyCaps.wPeriodMin;
430 }
431 
GetPollingMax() const432 int wxJoystick::GetPollingMax() const
433 {
434     JOYCAPS joyCaps;
435     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
436         return 0;
437     else
438         return joyCaps.wPeriodMax;
439 }
440 
GetRudderMin() const441 int wxJoystick::GetRudderMin() const
442 {
443 #if defined(__WIN32__)
444     JOYCAPS joyCaps;
445     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
446         return 0;
447     else
448         return joyCaps.wRmin;
449 #else
450     return 0;
451 #endif
452 }
453 
GetRudderMax() const454 int wxJoystick::GetRudderMax() const
455 {
456 #if defined(__WIN32__)
457     JOYCAPS joyCaps;
458     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
459         return 0;
460     else
461         return joyCaps.wRmax;
462 #else
463     return 0;
464 #endif
465 }
466 
GetUMin() const467 int wxJoystick::GetUMin() const
468 {
469 #if defined(__WIN32__)
470     JOYCAPS joyCaps;
471     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
472         return 0;
473     else
474         return joyCaps.wUmin;
475 #else
476     return 0;
477 #endif
478 }
479 
GetUMax() const480 int wxJoystick::GetUMax() const
481 {
482 #if defined(__WIN32__)
483     JOYCAPS joyCaps;
484     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
485         return 0;
486     else
487         return joyCaps.wUmax;
488 #else
489     return 0;
490 #endif
491 }
492 
GetVMin() const493 int wxJoystick::GetVMin() const
494 {
495 #if defined(__WIN32__)
496     JOYCAPS joyCaps;
497     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
498         return 0;
499     else
500         return joyCaps.wVmin;
501 #else
502     return 0;
503 #endif
504 }
505 
GetVMax() const506 int wxJoystick::GetVMax() const
507 {
508 #if defined(__WIN32__)
509     JOYCAPS joyCaps;
510     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
511         return 0;
512     else
513         return joyCaps.wVmax;
514 #else
515     return 0;
516 #endif
517 }
518 
519 
HasRudder() const520 bool wxJoystick::HasRudder() const
521 {
522 #if defined(__WIN32__)
523     JOYCAPS joyCaps;
524     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
525         return false;
526     else
527         return ((joyCaps.wCaps & JOYCAPS_HASR) == JOYCAPS_HASR);
528 #else
529     return false;
530 #endif
531 }
532 
HasZ() const533 bool wxJoystick::HasZ() const
534 {
535 #if defined(__WIN32__)
536     JOYCAPS joyCaps;
537     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
538         return false;
539     else
540         return ((joyCaps.wCaps & JOYCAPS_HASZ) == JOYCAPS_HASZ);
541 #else
542     return false;
543 #endif
544 }
545 
HasU() const546 bool wxJoystick::HasU() const
547 {
548 #if defined(__WIN32__)
549     JOYCAPS joyCaps;
550     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
551         return false;
552     else
553         return ((joyCaps.wCaps & JOYCAPS_HASU) == JOYCAPS_HASU);
554 #else
555     return false;
556 #endif
557 }
558 
HasV() const559 bool wxJoystick::HasV() const
560 {
561 #if defined(__WIN32__)
562     JOYCAPS joyCaps;
563     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
564         return false;
565     else
566         return ((joyCaps.wCaps & JOYCAPS_HASV) == JOYCAPS_HASV);
567 #else
568     return false;
569 #endif
570 }
571 
HasPOV() const572 bool wxJoystick::HasPOV() const
573 {
574 #if defined(__WIN32__)
575     JOYCAPS joyCaps;
576     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
577         return false;
578     else
579         return ((joyCaps.wCaps & JOYCAPS_HASPOV) == JOYCAPS_HASPOV);
580 #else
581     return false;
582 #endif
583 }
584 
HasPOV4Dir() const585 bool wxJoystick::HasPOV4Dir() const
586 {
587 #if defined(__WIN32__)
588     JOYCAPS joyCaps;
589     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
590         return false;
591     else
592         return ((joyCaps.wCaps & JOYCAPS_POV4DIR) == JOYCAPS_POV4DIR);
593 #else
594     return false;
595 #endif
596 }
597 
HasPOVCTS() const598 bool wxJoystick::HasPOVCTS() const
599 {
600 #if defined(__WIN32__)
601     JOYCAPS joyCaps;
602     if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
603         return false;
604     else
605         return ((joyCaps.wCaps & JOYCAPS_POVCTS) == JOYCAPS_POVCTS);
606 #else
607     return false;
608 #endif
609 }
610 
611 // Operations
612 ////////////////////////////////////////////////////////////////////////////
613 
SetCapture(wxWindow * win,int pollingFreq)614 bool wxJoystick::SetCapture(wxWindow* win, int pollingFreq)
615 {
616     BOOL changed = (pollingFreq == 0);
617     MMRESULT res = joySetCapture((HWND) win->GetHWND(), m_joystick, pollingFreq, changed);
618     return (res == JOYERR_NOERROR);
619 }
620 
ReleaseCapture()621 bool wxJoystick::ReleaseCapture()
622 {
623     MMRESULT res = joyReleaseCapture(m_joystick);
624     return (res == JOYERR_NOERROR);
625 }
626 
627 #endif // wxUSE_JOYSTICK
628