+
+//---------------------------------------------------------------------------
+// wxHIDJoystick::Get[XXX]
+//
+// Simple accessors so that the HID callback and the thread procedure
+// can access members from wxHIDDevice (our parent here).
+//---------------------------------------------------------------------------
+IOHIDElementCookie* wxHIDJoystick::GetCookies()
+{ return m_pCookies; }
+IOHIDQueueInterface** wxHIDJoystick::GetQueue()
+{ return m_ppQueue; }
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//
+// wxJoystickThread
+//
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+//---------------------------------------------------------------------------
+// wxJoystickThread Constructor
+//
+// Just initializes members
+//---------------------------------------------------------------------------
+wxJoystickThread::wxJoystickThread(wxHIDJoystick* hid, int joystick)
+ : m_hid(hid),
+ m_joystick(joystick),
+ m_lastposition(127,127),
+ m_buttons(0),
+ m_catchwin(NULL),
+ m_polling(0)
+{
+ memset(m_axe, 0, sizeof(int) * wxJS_MAX_AXES);
+}
+
+//---------------------------------------------------------------------------
+// wxJoystickThread::Entry
+//
+// Thread procedure
+//
+// Runs a CFRunLoop for polling. Basically, it sets the HID queue to
+// call wxJoystickThread::HIDCallback in the context of this thread
+// when something changes on the device. It polls as long as the user
+// wants, or a certain amount if the user wants to "block". Note that
+// we don't actually block here since this is in a secondary thread.
+//---------------------------------------------------------------------------
+void* wxJoystickThread::Entry()
+{
+ CFRunLoopSourceRef pRLSource = NULL;
+
+ if ((*m_hid->GetQueue())->createAsyncEventSource(
+ m_hid->GetQueue(), &pRLSource) != kIOReturnSuccess )
+ {
+ wxLogSysError(wxT("Couldn't create async event source"));
+ return NULL;
+ }
+
+ wxASSERT(pRLSource != NULL);
+
+ //attach runloop source to main run loop in thread
+ CFRunLoopRef pRL = CFRunLoopGetCurrent();
+ CFRunLoopAddSource(pRL, pRLSource, kCFRunLoopDefaultMode);
+ wxASSERT( CFRunLoopContainsSource(pRL, pRLSource, kCFRunLoopDefaultMode) );
+
+
+ if( (*m_hid->GetQueue())->setEventCallout(m_hid->GetQueue(),
+ wxJoystickThread::HIDCallback, this, this) != kIOReturnSuccess )
+ {
+ wxLogSysError(wxT("Could not set event callout for queue"));
+ return NULL;
+ }
+
+ if( (*m_hid->GetQueue())->start(m_hid->GetQueue()) != kIOReturnSuccess )
+ {
+ wxLogSysError(wxT("Could not start queue"));
+ return NULL;
+ }
+
+ double dTime;
+
+ while(true)
+ {
+ if (TestDestroy())
+ break;
+
+ if (m_polling)
+ dTime = 0.0001 * m_polling;
+ else
+ dTime = 0.0001 * 10; // check at least every 10 msec in "blocking" case
+
+ //true just "handles and returns" - false forces it to stay the time
+ //amount
+#if 1
+ CFRunLoopRunInMode(kCFRunLoopDefaultMode, dTime, true);
+#else
+ IOReturn ret = NULL;
+ HIDCallback(this, ret, this, this);
+ Sleep(3000);