X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/655719367ac5e131d9642e5783f3ecf64d1a3385..4b621e4ce48e0776fedaf08c927d161257b25222:/src/unix/joystick.cpp diff --git a/src/unix/joystick.cpp b/src/unix/joystick.cpp index cb88e0add9..f9f2ba9d41 100644 --- a/src/unix/joystick.cpp +++ b/src/unix/joystick.cpp @@ -1,27 +1,28 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: joystick.cpp +// Name: src/unix/joystick.cpp // Purpose: wxJoystick class // Author: Ported to Linux by Guilhem Lavaux // Modified by: // Created: 05/23/98 // RCS-ID: $Id$ // Copyright: (c) Guilhem Lavaux -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "joystick.h" -#endif - // for compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" -#include "wx/defs.h" - #if wxUSE_JOYSTICK #include "wx/joystick.h" +#ifndef WX_PRECOMP + #include "wx/event.h" + #include "wx/window.h" +#endif //WX_PRECOMP + +#include "wx/thread.h" + #include #include #include @@ -30,8 +31,11 @@ #include #include -#include "wx/event.h" -#include "wx/window.h" +#ifdef HAVE_SYS_SELECT_H +# include +#endif + +#include "wx/unix/private.h" enum { wxJS_AXIS_X = 0, @@ -40,9 +44,11 @@ enum { wxJS_AXIS_RUDDER, wxJS_AXIS_U, wxJS_AXIS_V, - + wxJS_AXIS_MAX = 32767, - wxJS_AXIS_MIN = -32767 + wxJS_AXIS_MIN = -32767, + wxJS_MAX_AXES = 15, + wxJS_MAX_BUTTONS = sizeof(int) * 8 }; @@ -60,13 +66,15 @@ public: void* Entry(); private: + void SendEvent(wxEventType type, long ts, int change = 0); int m_device; int m_joystick; wxPoint m_lastposition; - int m_axe[15]; - int m_buttons; + int m_axe[wxJS_MAX_AXES]; + int m_buttons; wxWindow* m_catchwin; - int m_polling; + int m_polling; + int m_threshold; friend class wxJoystick; }; @@ -78,12 +86,24 @@ wxJoystickThread::wxJoystickThread(int device, int joystick) m_lastposition(wxDefaultPosition), m_buttons(0), m_catchwin(NULL), - m_polling(0) -{ - for (int i=0; i<15; i++) - m_axe[i] = 0; + m_polling(0), + m_threshold(0) +{ + memset(m_axe, 0, sizeof(m_axe)); } +void wxJoystickThread::SendEvent(wxEventType type, long ts, int change) +{ + wxJoystickEvent jwx_event(type, m_buttons, m_joystick, change); + + jwx_event.SetTimestamp(ts); + jwx_event.SetPosition(m_lastposition); + jwx_event.SetZPosition(m_axe[wxJS_AXIS_Z]); + jwx_event.SetEventObject(m_catchwin); + + if (m_catchwin) + m_catchwin->GetEventHandler()->AddPendingEvent(jwx_event); +} void* wxJoystickThread::Entry() { @@ -91,8 +111,9 @@ void* wxJoystickThread::Entry() fd_set read_fds; struct timeval time_out = {0, 0}; - FD_ZERO(&read_fds); - while (true) { + wxFD_ZERO(&read_fds); + while (true) + { if (TestDestroy()) break; @@ -102,10 +123,10 @@ void* wxJoystickThread::Entry() time_out.tv_usec = m_polling * 1000; else time_out.tv_usec = 10 * 1000; // check at least every 10 msec in blocking case - - FD_SET(m_device, &read_fds); + + wxFD_SET(m_device, &read_fds); select(m_device+1, &read_fds, NULL, NULL, &time_out); - if (FD_ISSET(m_device, &read_fds)) + if (wxFD_ISSET(m_device, &read_fds)) { memset(&j_evt, 0, sizeof(j_evt)); read(m_device, &j_evt, sizeof(j_evt)); @@ -113,65 +134,51 @@ void* wxJoystickThread::Entry() //printf("time: %d\t value: %d\t type: %d\t number: %d\n", // j_evt.time, j_evt.value, j_evt.type, j_evt.number); - if (m_catchwin) + if ((j_evt.type & JS_EVENT_AXIS) && (j_evt.number < wxJS_MAX_AXES)) { - wxJoystickEvent jwx_event; - - if ((j_evt.type & JS_EVENT_AXIS) == JS_EVENT_AXIS) { - - m_axe[j_evt.number] = j_evt.value; + if ( (m_axe[j_evt.number] + m_threshold < j_evt.value) + || (m_axe[j_evt.number] - m_threshold > j_evt.value) ) + { + m_axe[j_evt.number] = j_evt.value; - switch (j_evt.number) { + switch (j_evt.number) + { case wxJS_AXIS_X: m_lastposition.x = j_evt.value; - jwx_event.SetEventType(wxEVT_JOY_MOVE); + SendEvent(wxEVT_JOY_MOVE, j_evt.time); break; case wxJS_AXIS_Y: m_lastposition.y = j_evt.value; - jwx_event.SetEventType(wxEVT_JOY_MOVE); + SendEvent(wxEVT_JOY_MOVE, j_evt.time); break; case wxJS_AXIS_Z: - jwx_event.SetEventType(wxEVT_JOY_ZMOVE); + SendEvent(wxEVT_JOY_ZMOVE, j_evt.time); break; default: - jwx_event.SetEventType(wxEVT_JOY_MOVE); + SendEvent(wxEVT_JOY_MOVE, j_evt.time); // TODO: There should be a way to indicate that the event // is for some other axes. break; - } } - - if ((j_evt.type & JS_EVENT_BUTTON) == JS_EVENT_BUTTON) { - if (j_evt.value) - { - m_buttons |= (1 << j_evt.number); - jwx_event.SetEventType(wxEVT_JOY_BUTTON_DOWN); - } - else - { - m_buttons &= ~(1 << j_evt.number); - jwx_event.SetEventType(wxEVT_JOY_BUTTON_UP); - } - - jwx_event.SetButtonChange(j_evt.number); - } - - jwx_event.SetTimestamp(j_evt.time); - jwx_event.SetJoystick(m_joystick); - jwx_event.SetButtonState(m_buttons); - jwx_event.SetPosition(m_lastposition); - jwx_event.SetZPosition(m_axe[3]); - jwx_event.SetEventObject(m_catchwin); + } + } - - m_catchwin->AddPendingEvent(jwx_event); + if ( (j_evt.type & JS_EVENT_BUTTON) && (j_evt.number < wxJS_MAX_BUTTONS) ) + { + if (j_evt.value) + { + m_buttons |= (1 << j_evt.number); + SendEvent(wxEVT_JOY_BUTTON_DOWN, j_evt.time, j_evt.number); + } + else + { + m_buttons &= ~(1 << j_evt.number); + SendEvent(wxEVT_JOY_BUTTON_UP, j_evt.time, j_evt.number); + } } - -// if (m_polling) -// wxThread::Sleep(m_polling); } } - + close(m_device); return NULL; } @@ -185,11 +192,18 @@ wxJoystick::wxJoystick(int joystick) m_thread(NULL) { wxString dev_name; - - // Assume it's the same device name on all Linux systems ... - dev_name.Printf( wxT("/dev/js%d"), (joystick == wxJOYSTICK1) ? 0 : 1); + + // old /dev structure + dev_name.Printf( wxT("/dev/js%d"), joystick); m_device = open(dev_name.fn_str(), O_RDONLY); + // new /dev structure with "input" subdirectory + if (m_device == -1) + { + dev_name.Printf( wxT("/dev/input/js%d"), joystick); + m_device = open(dev_name.fn_str(), O_RDONLY); + } + if (m_device != -1) { m_thread = new wxJoystickThread(m_device, m_joystick); @@ -219,20 +233,34 @@ wxPoint wxJoystick::GetPosition() const return pos; } +int wxJoystick::GetPosition(unsigned axis) const +{ + if (m_thread && (axis < wxJS_MAX_AXES)) + return m_thread->m_axe[axis]; + return 0; +} + int wxJoystick::GetZPosition() const { - if (m_thread) + if (m_thread) return m_thread->m_axe[wxJS_AXIS_Z]; return 0; } int wxJoystick::GetButtonState() const { - if (m_thread) + if (m_thread) return m_thread->m_buttons; return 0; } +bool wxJoystick::GetButtonState(unsigned id) const +{ + if (m_thread && (id < wxJS_MAX_BUTTONS)) + return (m_thread->m_buttons & (1 << id)) != 0; + return false; +} + int wxJoystick::GetPOVPosition() const { return -1; @@ -245,32 +273,36 @@ int wxJoystick::GetPOVCTSPosition() const int wxJoystick::GetRudderPosition() const { - if (m_thread) + if (m_thread) return m_thread->m_axe[wxJS_AXIS_RUDDER]; return 0; } int wxJoystick::GetUPosition() const { - if (m_thread) + if (m_thread) return m_thread->m_axe[wxJS_AXIS_U]; return 0; } int wxJoystick::GetVPosition() const { - if (m_thread) + if (m_thread) return m_thread->m_axe[wxJS_AXIS_V]; return 0; } int wxJoystick::GetMovementThreshold() const { + if (m_thread) + return m_thread->m_threshold; return 0; } void wxJoystick::SetMovementThreshold(int threshold) { + if (m_thread) + m_thread->m_threshold = threshold; } //////////////////////////////////////////////////////////////////////////// @@ -282,7 +314,7 @@ bool wxJoystick::IsOk() const return (m_device != -1); } -int wxJoystick::GetNumberJoysticks() const +int wxJoystick::GetNumberJoysticks() { wxString dev_name; int fd, j; @@ -291,9 +323,20 @@ int wxJoystick::GetNumberJoysticks() const dev_name.Printf(wxT("/dev/js%d"), j); fd = open(dev_name.fn_str(), O_RDONLY); if (fd == -1) - return j; + break; close(fd); } + + if (j == 0) { + for (j=0; j<4; j++) { + dev_name.Printf(wxT("/dev/input/js%d"), j); + fd = open(dev_name.fn_str(), O_RDONLY); + if (fd == -1) + return j; + close(fd); + } + } + return j; } @@ -310,10 +353,10 @@ int wxJoystick::GetProductId() const wxString wxJoystick::GetProductName() const { char name[128]; - + if (ioctl(m_device, JSIOCGNAME(sizeof(name)), name) < 0) strcpy(name, "Unknown"); - return wxString(name, wxConvLibc); + return wxString(name, wxConvLibc); } int wxJoystick::GetXMin() const @@ -353,6 +396,9 @@ int wxJoystick::GetNumberButtons() const if (m_device != -1) ioctl(m_device, JSIOCGBUTTONS, &nb); + if ((int)nb > wxJS_MAX_BUTTONS) + nb = wxJS_MAX_BUTTONS; + return nb; } @@ -363,17 +409,20 @@ int wxJoystick::GetNumberAxes() const if (m_device != -1) ioctl(m_device, JSIOCGAXES, &nb); + if ((int)nb > wxJS_MAX_AXES) + nb = wxJS_MAX_AXES; + return nb; } int wxJoystick::GetMaxButtons() const { - return 15; // internal + return wxJS_MAX_BUTTONS; // internal } int wxJoystick::GetMaxAxes() const { - return 15; // internal + return wxJS_MAX_AXES; // internal } int wxJoystick::GetPollingMin() const @@ -477,4 +526,3 @@ bool wxJoystick::ReleaseCapture() return false; } #endif // wxUSE_JOYSTICK -