]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/joystick.cpp
Added GTK/Linux joystick class (Guilhem Lavaux)
[wxWidgets.git] / src / gtk1 / joystick.cpp
diff --git a/src/gtk1/joystick.cpp b/src/gtk1/joystick.cpp
new file mode 100644 (file)
index 0000000..e783f12
--- /dev/null
@@ -0,0 +1,358 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        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 license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "joystick.h"
+#endif
+
+#include <linux/joystick.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "wx/event.h"
+#include "wx/window.h"
+#include "wx/gtk/joystick.h"
+
+#define JOYSTICK_AXE_MAX 32767
+#define JOYSTICK_AXE_MIN -32767
+
+IMPLEMENT_DYNAMIC_CLASS(wxJoystick, wxObject)
+
+wxJoystick::wxJoystick(int joystick)
+{
+  wxString dev_name;
+  // Assume it's the same device name on all Linux systems ...
+  dev_name.Printf("/dev/js%d", (joystick == wxJOYSTICK1) ? 0 : 1);
+
+  m_joystick = open(dev_name, O_RDWR);
+  m_lastposition = wxPoint(-1, -1);
+  for (int i=0;i<15;i++)
+    m_axe[i] = 0;
+  if (m_joystick != -1)
+    Create();
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Background thread
+////////////////////////////////////////////////////////////////////////////
+void *wxJoystick::Entry(void)
+{
+  struct js_event j_evt;
+  wxJoystickEvent jwx_event;
+  fd_set read_fds;
+  struct timeval time_out = {0, 0};
+
+  FD_ZERO(&read_fds);
+  DeferDestroy(TRUE);
+  while (1) {
+    TestDestroy();
+
+    if (m_polling) {
+      FD_SET(m_joystick, &read_fds);
+      select(m_joystick+1, &read_fds, NULL, NULL, &time_out);
+      if (FD_ISSET(m_joystick, &read_fds))
+        read(m_joystick, &j_evt, sizeof(j_evt));
+      else
+        j_evt.type = 0;
+    } else {
+      read(m_joystick, &j_evt, sizeof(j_evt));
+    }
+
+    if ((j_evt.type & JS_EVENT_AXIS) == JS_EVENT_AXIS) {
+      switch (j_evt.number) {
+      case 1:
+        m_lastposition.x = j_evt.value;
+        jwx_event.SetEventType(wxEVT_JOY_MOVE);
+        break;
+      case 2:
+        m_lastposition.y = j_evt.value;
+        jwx_event.SetEventType(wxEVT_JOY_MOVE);
+        break;
+      case 3:
+        m_axe[3] = j_evt.value;
+        jwx_event.SetEventType(wxEVT_JOY_ZMOVE);
+        break;
+      default:
+        m_axe[j_evt.number] = j_evt.value;
+        jwx_event.SetEventType(wxEVT_JOY_MOVE);
+        break;
+      }
+      jwx_event.SetPosition(m_lastposition);
+      jwx_event.SetZPosition(m_axe[3]);
+    }
+    if ((j_evt.type & JS_EVENT_BUTTON) == JS_EVENT_BUTTON) {
+      register int mask = 1 << j_evt.number;
+      char button = m_buttons & mask;
+
+      m_buttons &= ~mask;
+      if (button) {
+        jwx_event.SetEventType(wxEVT_JOY_BUTTON_UP);
+      } else {
+        jwx_event.SetEventType(wxEVT_JOY_BUTTON_DOWN);
+        m_buttons |= mask;
+      }
+
+      jwx_event.SetButtonState(m_buttons);
+      jwx_event.SetButtonChange(j_evt.number);
+    }
+  }
+  if (m_catchwin)
+    m_catchwin->ProcessEvent(jwx_event);
+  if (m_polling)
+    usleep(m_polling*1000);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// State
+////////////////////////////////////////////////////////////////////////////
+
+wxPoint wxJoystick::GetPosition(void) const
+{
+  return m_lastposition;
+}
+
+int wxJoystick::GetZPosition(void) const
+{
+  return m_axe[3];
+}
+
+int wxJoystick::GetButtonState(void) const
+{
+  return m_buttons;
+}
+
+int wxJoystick::GetPOVPosition(void) const
+{
+  return 0;
+}
+
+int wxJoystick::GetPOVCTSPosition(void) const
+{
+  return 0;
+}
+
+int wxJoystick::GetRudderPosition(void) const
+{
+  return m_axe[4];
+}
+
+int wxJoystick::GetUPosition(void) const
+{
+  return m_axe[5];
+}
+
+int wxJoystick::GetVPosition(void) const
+{
+  return m_axe[6];
+}
+
+int wxJoystick::GetMovementThreshold(void) const
+{
+  return 0;
+}
+
+void wxJoystick::SetMovementThreshold(int threshold)
+{
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Capabilities
+////////////////////////////////////////////////////////////////////////////
+
+bool wxJoystick::IsOk(void) const
+{
+  return (m_joystick != -1);
+}
+
+int wxJoystick::GetNumberJoysticks(void) const
+{
+  wxString dev_name;
+  int fd, j;
+
+  for (j=0;j<2;j++) {
+    dev_name.Printf("/dev/js%d", j);
+    fd = open(dev_name, O_RDONLY);
+    if (fd == -1)
+      return j;
+    close(fd);
+  }
+  return j;
+}
+
+int wxJoystick::GetManufacturerId(void) const
+{
+  return 0;
+}
+
+int wxJoystick::GetProductId(void) const
+{
+  return 0;
+}
+
+wxString wxJoystick::GetProductName(void) const
+{
+  return "";
+}
+
+int wxJoystick::GetXMin(void) const
+{
+  return JOYSTICK_AXE_MAX;
+}
+
+int wxJoystick::GetYMin(void) const
+{
+  return JOYSTICK_AXE_MAX;
+}
+
+int wxJoystick::GetZMin(void) const
+{
+  return JOYSTICK_AXE_MAX;
+}
+
+int wxJoystick::GetXMax(void) const
+{
+  return JOYSTICK_AXE_MAX;
+}
+
+int wxJoystick::GetYMax(void) const
+{
+  return JOYSTICK_AXE_MAX;
+}
+
+int wxJoystick::GetZMax(void) const
+{
+  return JOYSTICK_AXE_MAX;
+}
+
+int wxJoystick::GetNumberButtons(void) const
+{
+  int nb;
+
+  ioctl(m_joystick, JSIOCGBUTTONS, &nb);
+
+  return nb;
+}
+
+int wxJoystick::GetNumberAxes(void) const
+{
+  int nb;
+
+  ioctl(m_joystick, JSIOCGAXES, &nb);
+
+  return nb;
+}
+
+int wxJoystick::GetMaxButtons(void) const
+{
+  return 15; // internal
+}
+
+int wxJoystick::GetMaxAxes(void) const
+{
+  return 15; // internal
+}
+
+int wxJoystick::GetPollingMin(void) const
+{
+  return -1;
+}
+
+int wxJoystick::GetPollingMax(void) const
+{
+  return -1;
+}
+
+int wxJoystick::GetRudderMin(void) const
+{
+  return JOYSTICK_AXE_MIN;
+}
+
+int wxJoystick::GetRudderMax(void) const
+{
+  return JOYSTICK_AXE_MAX;
+}
+
+int wxJoystick::GetUMin(void) const
+{
+  return JOYSTICK_AXE_MIN;
+}
+
+int wxJoystick::GetUMax(void) const
+{
+  return JOYSTICK_AXE_MAX;
+}
+
+int wxJoystick::GetVMin(void) const
+{
+  return JOYSTICK_AXE_MIN;
+}
+
+int wxJoystick::GetVMax(void) const
+{
+  return JOYSTICK_AXE_MAX;
+}
+
+bool wxJoystick::HasRudder(void) const
+{
+  return GetNumberAxes() >= 4;
+}
+
+bool wxJoystick::HasZ(void) const
+{
+  return GetNumberAxes() >= 3;
+}
+
+bool wxJoystick::HasU(void) const
+{
+  return GetNumberAxes() >= 5;
+}
+
+bool wxJoystick::HasV(void) const
+{
+  return GetNumberAxes() >= 6;
+}
+
+bool wxJoystick::HasPOV(void) const
+{
+  return FALSE;
+}
+
+bool wxJoystick::HasPOV4Dir(void) const
+{
+  return FALSE;
+}
+
+bool wxJoystick::HasPOVCTS(void) const
+{
+  return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Operations
+////////////////////////////////////////////////////////////////////////////
+
+bool wxJoystick::SetCapture(wxWindow* win, int pollingFreq = 0)
+{
+  m_catchwin = win;
+  m_polling = pollingFreq;
+  return TRUE;
+}
+
+bool wxJoystick::ReleaseCapture(void)
+{
+  m_catchwin = NULL;
+  m_polling = 0;
+  return TRUE;
+}
+