/////////////////////////////////////////////////////////////////////////////
-// Name: joystick.cpp
+// Name: src/mac/corefoundation/joystick.cpp
// Purpose: wxJoystick class
// Author: Ryan Norton
// Modified by:
// Created: 2/13/2005
// RCS-ID: $Id$
// Copyright: (c) Ryan Norton
-// Licence: wxWindows licence
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
//===========================================================================
//---------------------------------------------------------------------------
//we only support HID on OSX (DARWIN), since it requires DARWIN...
-#if wxUSE_JOYSTICK && defined(__DARWIN__)
+#if wxUSE_JOYSTICK && defined(__DARWIN__) && wxUSE_THREADS
//---------------------------------------------------------------------------
// Includes
//---------------------------------------------------------------------------
-#include "wx/event.h" //joystick wxEvents
-#include "wx/log.h" //logging...
+
+#ifndef WX_PRECOMP
+ #include "wx/log.h"
+ #include "wx/event.h" //joystick wxEvents
+ #include "wx/window.h" //for wxWindow to "capture" joystick
+#endif
+
#include "wx/joystick.h" //...
#include "wx/thread.h" //wxThread for polling thread/ wxCriticalSection
-#include "wx/window.h" //for wxWindow to "capture" joystick
//private headers
#include "wx/mac/corefoundation/hid.h" //private mac hid stuff
#define wxJS_MAX_AXES 10 /*max number of axes*/
#define wxJS_MAX_BUTTONS 40 /*max number of buttons*/
-enum
+enum
{
//These are positions within the cookie array
//in wxHIDJoystick that the cookies that store the axis' are
wxJS_AXIS_RUDDER,
wxJS_AXIS_U,
wxJS_AXIS_V,
-
- //For the Get[XXX](Min/Max) functions
- wxJS_AXIS_MAX = 255, //32767,
- wxJS_AXIS_MIN = 0, //-32767
};
//---------------------------------------------------------------------------
class wxHIDJoystick : public wxHIDDevice
{
public:
- bool Create(int nWhich);
- virtual void BuildCookies(wxCFArray& Array);
- void MakeCookies(wxCFArray& Array);
+ wxHIDJoystick();
+ virtual ~wxHIDJoystick();
+
+ bool Create(int nWhich);
+ virtual void BuildCookies(CFArrayRef Array);
+ void MakeCookies(CFArrayRef Array);
IOHIDElementCookie* GetCookies();
IOHIDQueueInterface** GetQueue();
-
+
+ int m_nXMax, m_nYMax, m_nZMax, m_nRudderMax, m_nUMax, m_nVMax,
+ m_nXMin, m_nYMin, m_nZMin, m_nRudderMin, m_nUMin, m_nVMin;
+
friend class wxJoystick;
};
wxJoystickThread(wxHIDJoystick* hid, int joystick);
void* Entry();
static void HIDCallback(void* target, IOReturn res, void* context, void* sender);
-
+
private:
wxHIDJoystick* m_hid;
int m_joystick;
// IMPLEMENTATION
//===========================================================================
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+// wxGetIntFromCFDictionary
+//
+// Helper function that gets a integer from a dictionary key
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+void wxGetIntFromCFDictionary(CFTypeRef cfDict, CFStringRef key, int* pOut)
+{
+ CFNumberGetValue(
+ (CFNumberRef) CFDictionaryGetValue((CFDictionaryRef) cfDict,
+ key),
+ kCFNumberIntType, pOut);
+}
+
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// wxJoystick
{
m_hid = new wxHIDJoystick();
- if (m_hid->Create(m_joystick))
+ if (m_hid->Create(m_joystick+1)) //wxHIDDevice is 1-based while this is 0
{
m_thread = new wxJoystickThread(m_hid, m_joystick);
m_thread->Create();
//---------------------------------------------------------------------------
// wxJoystick Destructor
//
-// Releases the capture of the thread, deletes it, and deletes
+// Releases the capture of the thread, deletes it, and deletes
// the native implementation.
//---------------------------------------------------------------------------
wxJoystick::~wxJoystick()
ReleaseCapture();
if (m_thread)
m_thread->Delete(); // It's detached so it will delete itself
-
+
if (m_hid)
delete m_hid;
}
// wxJoystick::Get[XXX]Position
//
// Returns the value of an axis that was polled from the thread. In the
-// case of GetPosition returns the X and Y values in a wxPoint
+// case of GetPosition returns the X and Y values in a wxPoint
//---------------------------------------------------------------------------
wxPoint wxJoystick::GetPosition() const
{
return 0;
}
int wxJoystick::GetRudderPosition() const
-{
+{
if (m_thread)
return m_thread->m_axe[wxJS_AXIS_RUDDER];
return 0;
// if the native implementation doesn't exist (in constructor)
//---------------------------------------------------------------------------
bool wxJoystick::IsOk() const
-{
- return m_hid != NULL;
+{
+ return m_hid != NULL;
}
-
+
//---------------------------------------------------------------------------
// wxJoystick::Get[XXX](Id/Name)
//
// Simple accessors to the native HID implementation
//---------------------------------------------------------------------------
int wxJoystick::GetManufacturerId() const
-{ return m_hid->m_nManufacturerId; }
+{
+ return m_hid->m_nManufacturerId;
+}
+
int wxJoystick::GetProductId() const
-{ return m_hid->m_nProductId; }
+{
+ return m_hid->m_nProductId;
+}
+
wxString wxJoystick::GetProductName() const
-{ return m_hid->m_szProductName; }
+{
+ return m_hid->m_szProductName;
+}
//---------------------------------------------------------------------------
// wxJoystick::GetNumberButtons
// wxJoystick::GetNumberAxes
//
-// Queries the joystick for an active number of buttons/axes.
+// Queries the joystick for an active number of buttons/axes.
//
// In the native HID implementation, the cookies:
// 0-40 are the buttons of the joystick
int wxJoystick::GetNumberButtons() const
{
int nCount = 0;
-
+
for(int nIndex = 0; nIndex < 40; ++nIndex)
{
if(m_hid->HasElement(nIndex))
++nCount;
}
-
+
return nCount;
}
int wxJoystick::GetNumberAxes() const
{
int nCount = 0;
-
+
for(int nIndex = 40; nIndex < 50; ++nIndex)
{
if(m_hid->HasElement(nIndex))
++nCount;
}
-
+
return nCount;
}
// identifiers.
//---------------------------------------------------------------------------
int wxJoystick::GetNumberJoysticks()
-{
- return
+{
+ return
wxHIDDevice::GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick) +
- wxHIDDevice::GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad);
+ wxHIDDevice::GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// wxJoystick::Get[XXX]
//
-// All values in hid range from 0 to 255, making these all kind of
-// superflous. These are mainly here due to the msw-centric api
-// that wxJoystick has... it should REALLY do its own scaling... oh well :)
+// Gets the minimum and maximum values for each axis, returning 0 if the
+// axis doesn't exist.
//---------------------------------------------------------------------------
int wxJoystick::GetXMin() const
-{ return wxJS_AXIS_MIN; }
+{
+ return m_hid->m_nXMin;
+}
+
int wxJoystick::GetYMin() const
-{ return wxJS_AXIS_MIN; }
+{
+ return m_hid->m_nYMin;
+}
+
int wxJoystick::GetZMin() const
-{ return wxJS_AXIS_MIN; }
+{
+ return m_hid->m_nZMin;
+}
+
+int wxJoystick::GetRudderMin() const
+{
+ return m_hid->m_nRudderMin;
+}
+
int wxJoystick::GetUMin() const
-{ return wxJS_AXIS_MIN; }
+{
+ return m_hid->m_nUMin;
+}
+
int wxJoystick::GetVMin() const
-{ return wxJS_AXIS_MIN; }
-int wxJoystick::GetRudderMin() const
-{ return wxJS_AXIS_MIN; }
+{
+ return m_hid->m_nVMin;
+}
int wxJoystick::GetXMax() const
-{ return wxJS_AXIS_MAX; }
+{
+ return m_hid->m_nXMax;
+}
+
int wxJoystick::GetYMax() const
-{ return wxJS_AXIS_MAX; }
+{
+ return m_hid->m_nYMax;
+}
+
int wxJoystick::GetZMax() const
-{ return wxJS_AXIS_MAX; }
+{
+ return m_hid->m_nZMax;
+}
+
+int wxJoystick::GetRudderMax() const
+{
+ return m_hid->m_nRudderMax;
+}
+
int wxJoystick::GetUMax() const
-{ return wxJS_AXIS_MAX; }
+{
+ return m_hid->m_nUMax;
+}
+
int wxJoystick::GetVMax() const
-{ return wxJS_AXIS_MAX; }
-int wxJoystick::GetRudderMax() const
-{ return wxJS_AXIS_MAX; }
+{
+ return m_hid->m_nVMax;
+}
//---------------------------------------------------------------------------
// wxJoystick::Get[XXX]
// what the linux port has.
//---------------------------------------------------------------------------
int wxJoystick::GetMaxButtons() const
-{ return wxJS_MAX_BUTTONS; }
+{
+ return wxJS_MAX_BUTTONS;
+}
+
int wxJoystick::GetMaxAxes() const
-{ return wxJS_MAX_AXES; }
+{
+ return wxJS_MAX_AXES;
+}
+
int wxJoystick::GetPollingMin() const
-{ return 10; }
+{
+ return 10;
+}
+
int wxJoystick::GetPollingMax() const
-{ return 1000; }
+{
+ return 1000;
+}
//---------------------------------------------------------------------------
// wxJoystick::Has[XXX]
// Just queries the native hid implementation if the cookie was found
// when enumerating the cookies of the joystick device
//---------------------------------------------------------------------------
-bool wxJoystick::HasRudder() const
-{ return m_hid->HasElement(wxJS_AXIS_RUDDER); }
bool wxJoystick::HasZ() const
-{ return m_hid->HasElement(wxJS_AXIS_Z); }
+{
+ return m_hid->HasElement(wxJS_AXIS_Z);
+}
+
+bool wxJoystick::HasRudder() const
+{
+ return m_hid->HasElement(wxJS_AXIS_RUDDER);
+}
+
bool wxJoystick::HasU() const
-{ return m_hid->HasElement(wxJS_AXIS_U); }
+{
+ return m_hid->HasElement(wxJS_AXIS_U);
+}
+
bool wxJoystick::HasV() const
-{ return m_hid->HasElement(wxJS_AXIS_V); }
+{
+ return m_hid->HasElement(wxJS_AXIS_V);
+}
//---------------------------------------------------------------------------
// UNSUPPORTED
//---------------------------------------------------------------------------
int wxJoystick::GetPOVPosition() const
-{ return -1; }
+{
+ return -1;
+}
+
int wxJoystick::GetPOVCTSPosition() const
-{ return -1; }
+{
+ return -1;
+}
+
int wxJoystick::GetMovementThreshold() const
-{ return 0; }
+{
+ return 0;
+}
+
void wxJoystick::SetMovementThreshold(int threshold)
-{ }
+{
+}
+
bool wxJoystick::HasPOV() const
-{ return false; }
+{
+ return false;
+}
+
bool wxJoystick::HasPOV4Dir() const
-{ return false; }
+{
+ return false;
+}
+
bool wxJoystick::HasPOVCTS() const
-{ return false; }
+{
+ return false;
+}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//---------------------------------------------------------------------------
+// wxHIDJoystick ctor
+//
+// Initializes the min/max members
+//---------------------------------------------------------------------------
+wxHIDJoystick::wxHIDJoystick() :
+ m_nXMax(0), m_nYMax(0), m_nZMax(0), m_nRudderMax(0), m_nUMax(0), m_nVMax(0),
+ m_nXMin(0), m_nYMin(0), m_nZMin(0), m_nRudderMin(0), m_nUMin(0), m_nVMin(0)
+{
+}
+
+//---------------------------------------------------------------------------
+// wxHIDJoystick dtor
+//
+// Nothing...
+//---------------------------------------------------------------------------
+wxHIDJoystick::~wxHIDJoystick()
+{
+}
+
//---------------------------------------------------------------------------
// wxHIDJoystick::Create
//
bool wxHIDJoystick::Create(int nWhich)
{
int nJoysticks = GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick);
-
+
if (nWhich <= nJoysticks)
- return wxHIDDevice::Create(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick);
+ return wxHIDDevice::Create(kHIDPage_GenericDesktop,
+ kHIDUsage_GD_Joystick,
+ nWhich);
else
nWhich -= nJoysticks;
-
+
int nGamePads = GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad);
-
+
if (nWhich <= nGamePads)
- return wxHIDDevice::Create(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad);
+ return wxHIDDevice::Create(kHIDPage_GenericDesktop,
+ kHIDUsage_GD_GamePad,
+ nWhich);
else
return false;
}
// Sets up the cookies for the HID device (called from Create) - as
// mentioned 0-40 are the buttons and 40-50 are the axes.
//
-// MakeCookies is just a recursive function for each array within
+// MakeCookies is just a recursive function for each array within
// BuildCookies.
//---------------------------------------------------------------------------
-void wxHIDJoystick::BuildCookies(wxCFArray& Array)
+void wxHIDJoystick::BuildCookies(CFArrayRef Array)
{
- Array = CFDictionaryGetValue((CFDictionaryRef)Array[0], CFSTR(kIOHIDElementKey));
- InitCookies(50, true);
-
- memset(m_pCookies, 0, sizeof(*m_pCookies) * 50);
+ InitCookies(50, true);
//
// I wasted two hours of my life on this line :(
// accidently removed it during some source cleaning...
//
MakeCookies(Array);
-
- //paranoid debugging stuff
+
+ //paranoid debugging stuff
#if 0
for(int i = 0; i < 50; ++i)
wxPrintf(wxT("\nVAL #%i:[%i]"), i, m_pCookies[i]);
#endif
}//end buildcookies
-void wxHIDJoystick::MakeCookies(wxCFArray& Array)
+void wxHIDJoystick::MakeCookies(CFArrayRef Array)
{
- int i, nUsage, nPage;
+ int i, nUsage, nPage;
- for (i = 0; i < Array.Count(); ++i)
+ for (i = 0; i < CFArrayGetCount(Array); ++i)
{
- const void* ref = CFDictionaryGetValue((CFDictionaryRef)Array[i], CFSTR(kIOHIDElementKey));
+ const void* ref = CFDictionaryGetValue(
+ (CFDictionaryRef)CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementKey)
+ );
if (ref != NULL)
{
- wxCFArray newarray(ref);
- MakeCookies(newarray);
+ MakeCookies((CFArrayRef) ref);
}
else
{
CFNumberGetValue(
- (CFNumberRef) CFDictionaryGetValue((CFDictionaryRef) Array[i], CFSTR(kIOHIDElementUsageKey)),
- kCFNumberLongType, &nUsage);
-
+ (CFNumberRef)
+ CFDictionaryGetValue(
+ (CFDictionaryRef) CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementUsageKey)
+ ),
+ kCFNumberIntType,
+ &nUsage );
+
CFNumberGetValue(
- (CFNumberRef) CFDictionaryGetValue((CFDictionaryRef) Array[i], CFSTR(kIOHIDElementUsagePageKey)),
- kCFNumberLongType, &nPage);
+ (CFNumberRef)
+ CFDictionaryGetValue(
+ (CFDictionaryRef) CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementUsagePageKey)
+ ),
+ kCFNumberIntType,
+ &nPage );
#if 0
wxLogSysError(wxT("[%i][%i]"), nUsage, nPage);
#endif
if (nPage == kHIDPage_Button && nUsage <= 40)
- AddCookieInQueue(Array[i], nUsage-1 );
+ AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), nUsage-1 );
else if (nPage == kHIDPage_GenericDesktop)
{
+ //axis...
switch(nUsage)
{
case kHIDUsage_GD_X:
- AddCookieInQueue(Array[i], wxJS_AXIS_X);
- break;
+ AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_X);
+ wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementMaxKey),
+ &m_nXMax);
+ wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementMinKey),
+ &m_nXMin);
+ break;
case kHIDUsage_GD_Y:
- AddCookieInQueue(Array[i], wxJS_AXIS_Y);
+ AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_Y);
+ wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementMaxKey),
+ &m_nYMax);
+ wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementMinKey),
+ &m_nYMin);
break;
case kHIDUsage_GD_Z:
- AddCookieInQueue(Array[i], wxJS_AXIS_Z);
+ AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_Z);
+ wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementMaxKey),
+ &m_nZMax);
+ wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementMinKey),
+ &m_nZMin);
break;
default:
break;
}
}
else if (nPage == kHIDPage_Simulation && nUsage == kHIDUsage_Sim_Rudder)
- AddCookieInQueue(Array[i], wxJS_AXIS_RUDDER );
+ {
+ //rudder...
+ AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_RUDDER );
+ wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementMaxKey),
+ &m_nRudderMax);
+ wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementMinKey),
+ &m_nRudderMin);
+ }
}
- }
+ }
}
//---------------------------------------------------------------------------
// Simple accessors so that the HID callback and the thread procedure
// can access members from wxHIDDevice (our parent here).
//---------------------------------------------------------------------------
-IOHIDElementCookie* wxHIDJoystick::GetCookies()
+IOHIDElementCookie* wxHIDJoystick::GetCookies()
{ return m_pCookies; }
-IOHIDQueueInterface** wxHIDJoystick::GetQueue()
+IOHIDQueueInterface** wxHIDJoystick::GetQueue()
{ return m_ppQueue; }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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(),
+
+ if( (*m_hid->GetQueue())->setEventCallout(m_hid->GetQueue(),
wxJoystickThread::HIDCallback, this, this) != kIOReturnSuccess )
{
wxLogSysError(wxT("Could not set event callout for queue"));
}
double dTime;
-
+
while(true)
{
if (TestDestroy())
//true just "handles and returns" - false forces it to stay the time
//amount
#if 1
- CFRunLoopRunInMode(kCFRunLoopDefaultMode, dTime, true);
+ CFRunLoopRunInMode(kCFRunLoopDefaultMode, dTime, true);
#else
IOReturn ret = NULL;
HIDCallback(this, ret, this, this);
Sleep(3000);
#endif
}
-
+
wxASSERT( CFRunLoopContainsSource(pRL, pRLSource, kCFRunLoopDefaultMode) );
-
+
CFRunLoopRemoveSource(pRL, pRLSource, kCFRunLoopDefaultMode);
CFRelease(pRLSource);
// This is where the REAL dirty work gets done.
//
// 1) Loops through each event the queue has recieved
-// 2) First, checks if the thread that is running the loop for
+// 2) First, checks if the thread that is running the loop for
// the polling has ended - if so it breaks out
// 3) Next, it checks if there was an error getting this event from
// the HID queue, if there was, it logs an error and returns
// 5) Sends the event to the polling window (if any)
// 6) Gets the next event and goes back to (1)
//---------------------------------------------------------------------------
-/*static*/ void wxJoystickThread::HIDCallback(void* target, IOReturn res,
+/*static*/ void wxJoystickThread::HIDCallback(void* target, IOReturn res,
void* context, void* sender)
{
IOHIDEventStruct hidevent;
IOReturn ret;
wxJoystickThread* pThis = (wxJoystickThread*) context;
wxHIDJoystick* m_hid = pThis->m_hid;
-
+
//Get the "first" event from the queue
//bogustime tells it we don't care at what time to start
//where it gets the next from
- ret = (*m_hid->GetQueue())->getNextEvent(m_hid->GetQueue(),
+ ret = (*m_hid->GetQueue())->getNextEvent(m_hid->GetQueue(),
&hidevent, bogustime, 0);
-
+
while (ret != kIOReturnUnderrun)
{
if (pThis->TestDestroy())
{
wxLogSysError(wxString::Format(wxT("wxJoystick Error:[%i]"), ret));
return;
- }
-
+ }
+
wxJoystickEvent wxevent;
-
+
//Find the cookie that changed
int nIndex = 0;
IOHIDElementCookie* pCookies = m_hid->GetCookies();
{
if(hidevent.elementCookie == pCookies[nIndex])
break;
-
+
++nIndex;
- }
-
+ }
+
//debugging stuff
#if 0
- if(nIndex == 50)
+ if(nIndex == 50)
{
wxLogSysError(wxString::Format(wxT("wxJoystick Out Of Bounds Error")));
break;
- }
+ }
#endif
- //is the cookie a button?
+ //is the cookie a button?
if (nIndex < 40)
{
if (hidevent.value)
pThis->m_axe[2] = hidevent.value;
}
else
- wxevent.SetEventType(wxEVT_JOY_MOVE);
+ wxevent.SetEventType(wxEVT_JOY_MOVE);
Nanoseconds timestamp = AbsoluteToNanoseconds(hidevent.timestamp);
-
+
wxULongLong llTime(timestamp.hi, timestamp.lo);
-
+
llTime /= 1000000;
-
+
wxevent.SetTimestamp(llTime.GetValue());
wxevent.SetJoystick(pThis->m_joystick);
wxevent.SetButtonState(pThis->m_buttons);
wxevent.SetEventObject(pThis->m_catchwin);
if (pThis->m_catchwin)
- pThis->m_catchwin->AddPendingEvent(wxevent);
+ pThis->m_catchwin->AddPendingEvent(wxevent);
- ret = (*m_hid->GetQueue())->getNextEvent(m_hid->GetQueue(),
+ ret = (*m_hid->GetQueue())->getNextEvent(m_hid->GetQueue(),
&hidevent, bogustime, 0);
}
}
#endif // wxUSE_JOYSTICK && defined(__DARWIN__)
-