Fix assert when adding items with bitmaps wxBitmapComboBox.
[wxWidgets.git] / src / msw / joystick.cpp
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$
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
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
79 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
89 int wxJoystick::GetPosition(unsigned axis) const
90 {
91 switch (axis) {
92 case 0:
93 return GetPosition().x;
94 case 1:
95 return GetPosition().y;
96 case 2:
97 return GetZPosition();
98 case 3:
99 return GetRudderPosition();
100 case 4:
101 return GetUPosition();
102 case 5:
103 return GetVPosition();
104 default:
105 return 0;
106 }
107 }
108
109 int wxJoystick::GetZPosition() const
110 {
111 JOYINFO joyInfo;
112 MMRESULT res = joyGetPos(m_joystick, & joyInfo);
113 if (res == JOYERR_NOERROR )
114 return joyInfo.wZpos;
115 else
116 return 0;
117 }
118
119 /**
120 johan@linkdata.se 2002-08-20:
121 Return a bitmap with all button states in it,
122 like the GTK version does and Win32 does.
123 */
124 int wxJoystick::GetButtonState() const
125 {
126 JOYINFO joyInfo;
127 MMRESULT res = joyGetPos(m_joystick, & joyInfo);
128 if (res == JOYERR_NOERROR )
129 {
130 return joyInfo.wButtons;
131 #if 0
132 int buttons = 0;
133
134 if (joyInfo.wButtons & JOY_BUTTON1)
135 buttons |= wxJOY_BUTTON1;
136 if (joyInfo.wButtons & JOY_BUTTON2)
137 buttons |= wxJOY_BUTTON2;
138 if (joyInfo.wButtons & JOY_BUTTON3)
139 buttons |= wxJOY_BUTTON3;
140 if (joyInfo.wButtons & JOY_BUTTON4)
141 buttons |= wxJOY_BUTTON4;
142
143 return buttons;
144 #endif
145 }
146 else
147 return 0;
148 }
149
150 bool wxJoystick::GetButtonState(unsigned id) const
151 {
152 if (id > sizeof(int) * 8)
153 return false;
154
155 return (GetButtonState() & (1 << id)) != 0;
156 }
157
158 /**
159 JLI 2002-08-20:
160 Returns -1 to signify error.
161 */
162 int wxJoystick::GetPOVPosition() const
163 {
164 #ifndef NO_JOYGETPOSEX
165 JOYINFOEX joyInfo;
166 joyInfo.dwFlags = JOY_RETURNPOV;
167 joyInfo.dwSize = sizeof(joyInfo);
168 MMRESULT res = joyGetPosEx(m_joystick, & joyInfo);
169 if (res == JOYERR_NOERROR )
170 {
171 return joyInfo.dwPOV;
172 }
173 else
174 return -1;
175 #else
176 return -1;
177 #endif
178 }
179
180 /**
181 johan@linkdata.se 2002-08-20:
182 Returns -1 to signify error.
183 */
184 int wxJoystick::GetPOVCTSPosition() const
185 {
186 #ifndef NO_JOYGETPOSEX
187 JOYINFOEX joyInfo;
188 joyInfo.dwFlags = JOY_RETURNPOVCTS;
189 joyInfo.dwSize = sizeof(joyInfo);
190 MMRESULT res = joyGetPosEx(m_joystick, & joyInfo);
191 if (res == JOYERR_NOERROR )
192 {
193 return joyInfo.dwPOV;
194 }
195 else
196 return -1;
197 #else
198 return -1;
199 #endif
200 }
201
202 int wxJoystick::GetRudderPosition() const
203 {
204 #ifndef NO_JOYGETPOSEX
205 JOYINFOEX joyInfo;
206 joyInfo.dwFlags = JOY_RETURNR;
207 joyInfo.dwSize = sizeof(joyInfo);
208 MMRESULT res = joyGetPosEx(m_joystick, & joyInfo);
209 if (res == JOYERR_NOERROR )
210 {
211 return joyInfo.dwRpos;
212 }
213 else
214 return 0;
215 #else
216 return 0;
217 #endif
218 }
219
220 int wxJoystick::GetUPosition() const
221 {
222 #ifndef NO_JOYGETPOSEX
223 JOYINFOEX joyInfo;
224 joyInfo.dwFlags = JOY_RETURNU;
225 joyInfo.dwSize = sizeof(joyInfo);
226 MMRESULT res = joyGetPosEx(m_joystick, & joyInfo);
227 if (res == JOYERR_NOERROR )
228 {
229 return joyInfo.dwUpos;
230 }
231 else
232 return 0;
233 #else
234 return 0;
235 #endif
236 }
237
238 int wxJoystick::GetVPosition() const
239 {
240 #ifndef NO_JOYGETPOSEX
241 JOYINFOEX joyInfo;
242 joyInfo.dwFlags = JOY_RETURNV;
243 joyInfo.dwSize = sizeof(joyInfo);
244 MMRESULT res = joyGetPosEx(m_joystick, & joyInfo);
245 if (res == JOYERR_NOERROR )
246 {
247 return joyInfo.dwVpos;
248 }
249 else
250 return 0;
251 #else
252 return 0;
253 #endif
254 }
255
256 int wxJoystick::GetMovementThreshold() const
257 {
258 UINT thresh = 0;
259 MMRESULT res = joyGetThreshold(m_joystick, & thresh);
260 if (res == JOYERR_NOERROR )
261 {
262 return thresh;
263 }
264 else
265 return 0;
266 }
267
268 void wxJoystick::SetMovementThreshold(int threshold)
269 {
270 UINT thresh = threshold;
271 joySetThreshold(m_joystick, thresh);
272 }
273
274 // Capabilities
275 ////////////////////////////////////////////////////////////////////////////
276
277 /**
278 johan@linkdata.se 2002-08-20:
279 Now returns the number of connected, functioning
280 joysticks, as intended.
281 */
282 int wxJoystick::GetNumberJoysticks()
283 {
284 JOYINFO joyInfo;
285 int i, maxsticks, actualsticks;
286 maxsticks = joyGetNumDevs();
287 actualsticks = 0;
288 for( i=0; i<maxsticks; i++ )
289 {
290 if( joyGetPos( i, & joyInfo ) == JOYERR_NOERROR )
291 {
292 actualsticks ++;
293 }
294 }
295 return actualsticks;
296 }
297
298 /**
299 johan@linkdata.se 2002-08-20:
300 The old code returned true if there were any
301 joystick capable drivers loaded (=always).
302 */
303 bool wxJoystick::IsOk() const
304 {
305 JOYINFO joyInfo;
306 return (joyGetPos(m_joystick, & joyInfo) == JOYERR_NOERROR);
307 }
308
309 int wxJoystick::GetManufacturerId() const
310 {
311 JOYCAPS joyCaps;
312 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
313 return 0;
314 else
315 return joyCaps.wMid;
316 }
317
318 int wxJoystick::GetProductId() const
319 {
320 JOYCAPS joyCaps;
321 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
322 return 0;
323 else
324 return joyCaps.wPid;
325 }
326
327 wxString wxJoystick::GetProductName() const
328 {
329 wxString str;
330 #ifndef __WINE__
331 JOYCAPS joyCaps;
332 if (joyGetDevCaps(m_joystick, &joyCaps, sizeof(joyCaps)) != JOYERR_NOERROR)
333 return wxEmptyString;
334
335 wxRegKey key1(wxString::Format(wxT("HKEY_LOCAL_MACHINE\\%s\\%s\\%s"),
336 REGSTR_PATH_JOYCONFIG, joyCaps.szRegKey, REGSTR_KEY_JOYCURR));
337
338 key1.QueryValue(wxString::Format(wxT("Joystick%d%s"),
339 m_joystick + 1, REGSTR_VAL_JOYOEMNAME),
340 str);
341
342 wxRegKey key2(wxString::Format(wxT("HKEY_LOCAL_MACHINE\\%s\\%s"),
343 REGSTR_PATH_JOYOEM, str.c_str()));
344 key2.QueryValue(REGSTR_VAL_JOYOEMNAME, str);
345 #endif
346 return str;
347 }
348
349 int wxJoystick::GetXMin() const
350 {
351 JOYCAPS joyCaps;
352 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
353 return 0;
354 else
355 return joyCaps.wXmin;
356 }
357
358 int wxJoystick::GetYMin() const
359 {
360 JOYCAPS joyCaps;
361 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
362 return 0;
363 else
364 return joyCaps.wYmin;
365 }
366
367 int wxJoystick::GetZMin() const
368 {
369 JOYCAPS joyCaps;
370 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
371 return 0;
372 else
373 return joyCaps.wZmin;
374 }
375
376 int wxJoystick::GetXMax() const
377 {
378 JOYCAPS joyCaps;
379 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
380 return 0;
381 else
382 return joyCaps.wXmax;
383 }
384
385 int wxJoystick::GetYMax() const
386 {
387 JOYCAPS joyCaps;
388 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
389 return 0;
390 else
391 return joyCaps.wYmax;
392 }
393
394 int wxJoystick::GetZMax() const
395 {
396 JOYCAPS joyCaps;
397 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
398 return 0;
399 else
400 return joyCaps.wZmax;
401 }
402
403 int wxJoystick::GetNumberButtons() const
404 {
405 JOYCAPS joyCaps;
406 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
407 return 0;
408 else
409 return joyCaps.wNumButtons;
410 }
411
412 int wxJoystick::GetNumberAxes() const
413 {
414 #if defined(__WIN32__)
415 JOYCAPS joyCaps;
416 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
417 return 0;
418 else
419 return joyCaps.wNumAxes;
420 #else
421 return 0;
422 #endif
423 }
424
425 int wxJoystick::GetMaxButtons() const
426 {
427 #if defined(__WIN32__)
428 JOYCAPS joyCaps;
429 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
430 return 0;
431 else
432 return joyCaps.wMaxButtons;
433 #else
434 return 0;
435 #endif
436 }
437
438 int wxJoystick::GetMaxAxes() const
439 {
440 #if defined(__WIN32__)
441 JOYCAPS joyCaps;
442 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
443 return 0;
444 else
445 return joyCaps.wMaxAxes;
446 #else
447 return 0;
448 #endif
449 }
450
451 int wxJoystick::GetPollingMin() const
452 {
453 JOYCAPS joyCaps;
454 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
455 return 0;
456 else
457 return joyCaps.wPeriodMin;
458 }
459
460 int wxJoystick::GetPollingMax() const
461 {
462 JOYCAPS joyCaps;
463 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
464 return 0;
465 else
466 return joyCaps.wPeriodMax;
467 }
468
469 int wxJoystick::GetRudderMin() const
470 {
471 #if defined(__WIN32__)
472 JOYCAPS joyCaps;
473 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
474 return 0;
475 else
476 return joyCaps.wRmin;
477 #else
478 return 0;
479 #endif
480 }
481
482 int wxJoystick::GetRudderMax() const
483 {
484 #if defined(__WIN32__)
485 JOYCAPS joyCaps;
486 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
487 return 0;
488 else
489 return joyCaps.wRmax;
490 #else
491 return 0;
492 #endif
493 }
494
495 int wxJoystick::GetUMin() const
496 {
497 #if defined(__WIN32__)
498 JOYCAPS joyCaps;
499 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
500 return 0;
501 else
502 return joyCaps.wUmin;
503 #else
504 return 0;
505 #endif
506 }
507
508 int wxJoystick::GetUMax() const
509 {
510 #if defined(__WIN32__)
511 JOYCAPS joyCaps;
512 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
513 return 0;
514 else
515 return joyCaps.wUmax;
516 #else
517 return 0;
518 #endif
519 }
520
521 int wxJoystick::GetVMin() const
522 {
523 #if defined(__WIN32__)
524 JOYCAPS joyCaps;
525 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
526 return 0;
527 else
528 return joyCaps.wVmin;
529 #else
530 return 0;
531 #endif
532 }
533
534 int wxJoystick::GetVMax() const
535 {
536 #if defined(__WIN32__)
537 JOYCAPS joyCaps;
538 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
539 return 0;
540 else
541 return joyCaps.wVmax;
542 #else
543 return 0;
544 #endif
545 }
546
547
548 bool wxJoystick::HasRudder() const
549 {
550 #if defined(__WIN32__)
551 JOYCAPS joyCaps;
552 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
553 return false;
554 else
555 return ((joyCaps.wCaps & JOYCAPS_HASR) == JOYCAPS_HASR);
556 #else
557 return false;
558 #endif
559 }
560
561 bool wxJoystick::HasZ() const
562 {
563 #if defined(__WIN32__)
564 JOYCAPS joyCaps;
565 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
566 return false;
567 else
568 return ((joyCaps.wCaps & JOYCAPS_HASZ) == JOYCAPS_HASZ);
569 #else
570 return false;
571 #endif
572 }
573
574 bool wxJoystick::HasU() const
575 {
576 #if defined(__WIN32__)
577 JOYCAPS joyCaps;
578 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
579 return false;
580 else
581 return ((joyCaps.wCaps & JOYCAPS_HASU) == JOYCAPS_HASU);
582 #else
583 return false;
584 #endif
585 }
586
587 bool wxJoystick::HasV() const
588 {
589 #if defined(__WIN32__)
590 JOYCAPS joyCaps;
591 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
592 return false;
593 else
594 return ((joyCaps.wCaps & JOYCAPS_HASV) == JOYCAPS_HASV);
595 #else
596 return false;
597 #endif
598 }
599
600 bool wxJoystick::HasPOV() const
601 {
602 #if defined(__WIN32__)
603 JOYCAPS joyCaps;
604 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
605 return false;
606 else
607 return ((joyCaps.wCaps & JOYCAPS_HASPOV) == JOYCAPS_HASPOV);
608 #else
609 return false;
610 #endif
611 }
612
613 bool wxJoystick::HasPOV4Dir() const
614 {
615 #if defined(__WIN32__)
616 JOYCAPS joyCaps;
617 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
618 return false;
619 else
620 return ((joyCaps.wCaps & JOYCAPS_POV4DIR) == JOYCAPS_POV4DIR);
621 #else
622 return false;
623 #endif
624 }
625
626 bool wxJoystick::HasPOVCTS() const
627 {
628 #if defined(__WIN32__)
629 JOYCAPS joyCaps;
630 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
631 return false;
632 else
633 return ((joyCaps.wCaps & JOYCAPS_POVCTS) == JOYCAPS_POVCTS);
634 #else
635 return false;
636 #endif
637 }
638
639 // Operations
640 ////////////////////////////////////////////////////////////////////////////
641
642 bool wxJoystick::SetCapture(wxWindow* win, int pollingFreq)
643 {
644 #ifdef __WXMSW__
645 BOOL changed = (pollingFreq == 0);
646 MMRESULT res = joySetCapture((HWND) win->GetHWND(), m_joystick, pollingFreq, changed);
647 return (res == JOYERR_NOERROR);
648 #else
649 wxUnusedVar(win);
650 wxUnusedVar(pollingFreq);
651 return false;
652 #endif
653 }
654
655 bool wxJoystick::ReleaseCapture()
656 {
657 MMRESULT res = joyReleaseCapture(m_joystick);
658 return (res == JOYERR_NOERROR);
659 }
660
661 #endif // wxUSE_JOYSTICK