-    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]);
+class wxJoystickThread : public wxThread
+{
+public:
+    wxJoystickThread(int device, int joystick);
+    void* Entry();
+
+private:
+    int       m_device;
+    int       m_joystick;
+    wxPoint   m_lastposition;
+    int              m_axe[15];
+    int              m_buttons;
+    wxWindow* m_catchwin;
+    int              m_polling;
+
+    friend class wxJoystick;
+};
+
+
+wxJoystickThread::wxJoystickThread(int device, int joystick)
+    : m_device(device),
+      m_joystick(joystick),
+      m_lastposition(wxDefaultPosition),
+      m_buttons(0),
+      m_catchwin(NULL),
+      m_polling(0)
+{    
+    for (int i=0; i<15; i++)
+        m_axe[i] = 0;
+}
+
+
+void* wxJoystickThread::Entry()
+{
+    struct js_event j_evt;
+    fd_set read_fds;
+    struct timeval time_out = {0, 0};
+
+    FD_ZERO(&read_fds);
+    while (true) {
+        if (TestDestroy())
+            break;
+
+        // We use select when either polling or 'blocking' as even in the
+        // blocking case we need to check TestDestroy periodically
+        if (m_polling)
+            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);
+        select(m_device+1, &read_fds, NULL, NULL, &time_out);
+        if (FD_ISSET(m_device, &read_fds))
+        {
+            memset(&j_evt, 0, sizeof(j_evt));
+            read(m_device, &j_evt, sizeof(j_evt));
+
+            //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)
+            {
+                wxJoystickEvent jwx_event;
+
+                if ((j_evt.type & JS_EVENT_AXIS) == JS_EVENT_AXIS) {
+
+                    m_axe[j_evt.number] = j_evt.value;
+
+                    switch (j_evt.number) {
+                    case wxJS_AXIS_X:
+                        m_lastposition.x = j_evt.value;
+                        jwx_event.SetEventType(wxEVT_JOY_MOVE);
+                        break;
+                    case wxJS_AXIS_Y:
+                        m_lastposition.y = j_evt.value;
+                        jwx_event.SetEventType(wxEVT_JOY_MOVE);
+                        break;
+                    case wxJS_AXIS_Z:
+                        jwx_event.SetEventType(wxEVT_JOY_ZMOVE);
+                        break;
+                    default:
+                        jwx_event.SetEventType(wxEVT_JOY_MOVE);
+                        // 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 (m_polling)
+//             wxThread::Sleep(m_polling);
+        }