Move HID stuff into both OSX builds. Add preliminary joystick for OSX
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@32030 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -59,8 +59,6 @@
|
||||
# if defined(WXMAKINGDLL_CORE)
|
||||
# include <mach-o/dyld.h>
|
||||
# endif
|
||||
// include hid keyboard
|
||||
# include "wx/mac/carbon/private/hid.h"
|
||||
#else
|
||||
# include <Sound.h>
|
||||
# include <Threads.h>
|
||||
@@ -121,10 +119,6 @@ long wxApp::s_macPreferencesMenuItemId = wxID_PREFERENCES ;
|
||||
long wxApp::s_macExitMenuItemId = wxID_EXIT ;
|
||||
wxString wxApp::s_macHelpMenuTitleName = wxT("&Help") ;
|
||||
|
||||
#ifdef __DARWIN__
|
||||
wxHIDKeyboard* wxApp::s_macHIDKeyboard = NULL;
|
||||
#endif
|
||||
|
||||
// Normally we're not a plugin
|
||||
bool wxApp::sm_isEmbedded = false;
|
||||
//----------------------------------------------------------------------
|
||||
@@ -725,12 +719,6 @@ void wxApp::CleanUp()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __DARWIN__
|
||||
// clean up HID Keyboard
|
||||
if (s_macHIDKeyboard)
|
||||
delete s_macHIDKeyboard;
|
||||
#endif
|
||||
|
||||
UMACleanupToolbox() ;
|
||||
if (s_macCursorRgn) {
|
||||
::DisposeRgn((RgnHandle)s_macCursorRgn);
|
||||
@@ -1179,18 +1167,9 @@ int wxMacKeyCodeToModifier(wxKeyCode key)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __DARWIN__
|
||||
bool wxGetKeyState(wxKeyCode key) //virtual key code if < 10.2.x, else see below
|
||||
{
|
||||
#ifdef __DARWIN__
|
||||
// Startup HID keyboard for getting key codes on DARWIN
|
||||
if (!wxApp::s_macHIDKeyboard)
|
||||
{
|
||||
wxApp::s_macHIDKeyboard = new wxHIDKeyboard();
|
||||
wxApp::s_macHIDKeyboard->Create();
|
||||
}
|
||||
|
||||
return wxApp::s_macHIDKeyboard->IsActive(key);
|
||||
#else
|
||||
//if OS X > 10.2 (i.e. 10.2.x)
|
||||
//a known apple bug prevents the system from determining led
|
||||
//states with GetKeys... can only determine caps lock led
|
||||
@@ -1199,8 +1178,8 @@ bool wxGetKeyState(wxKeyCode key) //virtual key code if < 10.2.x, else see below
|
||||
// KeyMapByteArray keymap;
|
||||
// GetKeys((BigEndianLong*)keymap);
|
||||
// return !!(BitTst(keymap, (sizeof(KeyMapByteArray)*8) - iKey));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey )
|
||||
|
@@ -17,6 +17,8 @@
|
||||
|
||||
#if wxUSE_JOYSTICK
|
||||
|
||||
#if !defined (__WXMAC_OSX__)
|
||||
|
||||
#include "wx/joystick.h"
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxJoystick, wxObject)
|
||||
@@ -281,6 +283,8 @@ bool wxJoystick::ReleaseCapture()
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
// !OSX
|
||||
#endif
|
||||
// wxUSE_JOYSTICK
|
||||
|
||||
|
@@ -31,7 +31,7 @@
|
||||
//DARWIN _ONLY_
|
||||
#ifdef __DARWIN__
|
||||
|
||||
#include "wx/mac/carbon/private/hid.h"
|
||||
#include "wx/mac/corefoundation/hid.h"
|
||||
#include "wx/string.h"
|
||||
#include "wx/log.h"
|
||||
|
||||
@@ -83,7 +83,7 @@ void CFShowTypeIDDescription(CFTypeRef pData)
|
||||
// wxHIDDevice
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
bool wxHIDDevice::Create (const int& nClass, const int& nType)
|
||||
bool wxHIDDevice::Create (int nClass, int nType, int nDev)
|
||||
{
|
||||
//Create the mach port
|
||||
wxIOCHECK(IOMasterPort(bootstrap_port, &m_pPort), "Could not create mach port");
|
||||
@@ -124,6 +124,9 @@ bool wxHIDDevice::Create (const int& nClass, const int& nType)
|
||||
io_object_t pObject;
|
||||
while ( (pObject = IOIteratorNext(pIterator)) != 0)
|
||||
{
|
||||
if(--nDev != 0)
|
||||
continue;
|
||||
|
||||
wxVERIFY(IORegistryEntryCreateCFProperties(pObject, &pDictionary,
|
||||
kCFAllocatorDefault, kNilOptions) == KERN_SUCCESS);
|
||||
|
||||
@@ -136,14 +139,6 @@ bool wxHIDDevice::Create (const int& nClass, const int& nType)
|
||||
CFStringGetSystemEncoding()
|
||||
);
|
||||
|
||||
//
|
||||
//Now the hard part - in order to scan things we need "cookies" -
|
||||
//
|
||||
wxCFArray CookieArray = CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDElementKey));
|
||||
BuildCookies(CookieArray);
|
||||
if (m_ppQueue != NULL)
|
||||
wxVERIFY((*m_ppQueue)->start(m_ppQueue) == S_OK);
|
||||
|
||||
//Create the interface (good grief - long function names!)
|
||||
SInt32 nScore;
|
||||
IOCFPlugInInterface** ppPlugin;
|
||||
@@ -164,6 +159,14 @@ bool wxHIDDevice::Create (const int& nClass, const int& nType)
|
||||
//open the HID interface...
|
||||
wxVERIFY((*m_ppDevice)->open(m_ppDevice, 0) == S_OK);
|
||||
|
||||
//
|
||||
//Now the hard part - in order to scan things we need "cookies" -
|
||||
//
|
||||
wxCFArray CookieArray = CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDElementKey));
|
||||
BuildCookies(CookieArray);
|
||||
if (m_ppQueue != NULL)
|
||||
wxVERIFY((*m_ppQueue)->start(m_ppQueue) == S_OK);
|
||||
|
||||
//cleanup
|
||||
CFRelease(pDictionary);
|
||||
IOObjectRelease(pObject);
|
||||
@@ -175,7 +178,60 @@ bool wxHIDDevice::Create (const int& nClass, const int& nType)
|
||||
return true;
|
||||
}//end Create()
|
||||
|
||||
void wxHIDDevice::AddCookie(CFTypeRef Data, const int& i)
|
||||
int wxHIDDevice::GetCount (int nClass, int nType)
|
||||
{
|
||||
mach_port_t m_pPort;
|
||||
|
||||
//Create the mach port
|
||||
wxIOCHECK(IOMasterPort(bootstrap_port, &m_pPort), "Could not create mach port");
|
||||
|
||||
//Dictionary that will hold first
|
||||
//the matching dictionary for determining which kind of devices we want,
|
||||
//then later some registry properties from an iterator (see below)
|
||||
CFMutableDictionaryRef pDictionary;
|
||||
|
||||
//Create a dictionary
|
||||
//The call to IOServiceMatching filters down the
|
||||
//the services we want to hid services (and also eats the
|
||||
//dictionary up for us (consumes one reference))
|
||||
wxVERIFY((pDictionary = IOServiceMatching(kIOHIDDeviceKey)) != NULL );
|
||||
|
||||
//Here we'll filter down the services to what we want
|
||||
if (nType != -1)
|
||||
{
|
||||
CFNumberRef pType = CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberIntType, &nType);
|
||||
CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsageKey), pType);
|
||||
CFRelease(pType);
|
||||
}
|
||||
if (nClass != -1)
|
||||
{
|
||||
CFNumberRef pClass = CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberIntType, &nClass);
|
||||
CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsagePageKey), pClass);
|
||||
CFRelease(pClass);
|
||||
}
|
||||
|
||||
//Now get the maching services
|
||||
io_iterator_t pIterator;
|
||||
wxIOCHECK(IOServiceGetMatchingServices(m_pPort, pDictionary, &pIterator), "No Matching HID Services");
|
||||
wxASSERT(pIterator != 0);
|
||||
|
||||
//Now we iterate through them
|
||||
io_object_t pObject;
|
||||
|
||||
int nCount = 0;
|
||||
|
||||
while ( (pObject = IOIteratorNext(pIterator)) != 0)
|
||||
++nCount;
|
||||
|
||||
//iterator cleanup
|
||||
IOObjectRelease(pIterator);
|
||||
|
||||
return nCount;
|
||||
}//end Create()
|
||||
|
||||
void wxHIDDevice::AddCookie(CFTypeRef Data, int i)
|
||||
{
|
||||
CFNumberGetValue(
|
||||
(CFNumberRef) CFDictionaryGetValue ( (CFDictionaryRef) Data
|
||||
@@ -186,24 +242,24 @@ void wxHIDDevice::AddCookie(CFTypeRef Data, const int& i)
|
||||
);
|
||||
}
|
||||
|
||||
void wxHIDDevice::AddCookieInQueue(CFTypeRef Data, const int& i)
|
||||
void wxHIDDevice::AddCookieInQueue(CFTypeRef Data, int i)
|
||||
{
|
||||
AddCookie(Data, i);
|
||||
wxVERIFY((*m_ppQueue)->addElement(m_ppQueue, m_pCookies[i], 0) == S_OK);//3rd Param flags (none yet)
|
||||
}
|
||||
|
||||
void wxHIDDevice::InitCookies(const size_t& dwSize, bool bQueue)
|
||||
void wxHIDDevice::InitCookies(size_t dwSize, bool bQueue)
|
||||
{
|
||||
m_pCookies = new IOHIDElementCookie[dwSize];
|
||||
if (bQueue)
|
||||
{
|
||||
wxASSERT( m_ppQueue != NULL);
|
||||
wxASSERT( m_ppQueue == NULL);
|
||||
wxVERIFY( (m_ppQueue = (*m_ppDevice)->allocQueue(m_ppDevice)) != NULL);
|
||||
wxVERIFY( (*m_ppQueue)->create(m_ppQueue, 0, 512) == S_OK); //Param 2, flags, none yet
|
||||
}
|
||||
}
|
||||
|
||||
bool wxHIDDevice::IsActive(const int& nIndex)
|
||||
bool wxHIDDevice::IsActive(int nIndex)
|
||||
{
|
||||
wxASSERT(m_pCookies[nIndex] != NULL);
|
||||
IOHIDEventStruct Event;
|
||||
@@ -211,11 +267,21 @@ bool wxHIDDevice::IsActive(const int& nIndex)
|
||||
return !!Event.value;
|
||||
}
|
||||
|
||||
bool wxHIDDevice::HasElement(int nIndex)
|
||||
{
|
||||
return m_pCookies[nIndex] != NULL;
|
||||
}
|
||||
|
||||
wxHIDDevice::~wxHIDDevice()
|
||||
{
|
||||
if (m_ppDevice != NULL)
|
||||
{
|
||||
if (m_ppQueue != NULL)
|
||||
{
|
||||
(*m_ppQueue)->stop(m_ppQueue);
|
||||
(*m_ppQueue)->dispose(m_ppQueue);
|
||||
(*m_ppQueue)->Release(m_ppQueue);
|
||||
}
|
||||
(*m_ppDevice)->close(m_ppDevice);
|
||||
(*m_ppDevice)->Release(m_ppDevice);
|
||||
mach_port_deallocate(mach_task_self(), m_pPort);
|
||||
@@ -224,12 +290,6 @@ wxHIDDevice::~wxHIDDevice()
|
||||
if (m_pCookies != NULL)
|
||||
{
|
||||
delete [] m_pCookies;
|
||||
if (m_ppQueue != NULL)
|
||||
{
|
||||
(*m_ppQueue)->stop(m_ppQueue);
|
||||
(*m_ppQueue)->dispose(m_ppQueue);
|
||||
(*m_ppQueue)->Release(m_ppQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,4 +426,52 @@ void wxHIDKeyboard::BuildCookies(wxCFArray& Array)
|
||||
}
|
||||
}//end buildcookies
|
||||
|
||||
//
|
||||
// wxGetKeyState
|
||||
//
|
||||
|
||||
#include "wx/utils.h"
|
||||
#include "wx/module.h"
|
||||
|
||||
class wxHIDModule : public wxModule
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS(wxHIDModule)
|
||||
|
||||
public:
|
||||
static wxHIDKeyboard* sm_keyboard;
|
||||
|
||||
virtual bool OnInit()
|
||||
{
|
||||
sm_keyboard = NULL;
|
||||
return true;
|
||||
}
|
||||
virtual void OnExit()
|
||||
{
|
||||
if (sm_keyboard)
|
||||
delete sm_keyboard;
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxHIDModule, wxModule)
|
||||
|
||||
wxHIDKeyboard* wxHIDModule::sm_keyboard;
|
||||
|
||||
bool wxGetKeyState (wxKeyCode key)
|
||||
{
|
||||
if (!wxHIDModule::sm_keyboard)
|
||||
{
|
||||
wxHIDModule::sm_keyboard = new wxHIDKeyboard();
|
||||
bool bOK = wxHIDModule::sm_keyboard->Create();
|
||||
wxASSERT(bOK);
|
||||
if(!bOK)
|
||||
{
|
||||
delete wxHIDModule::sm_keyboard;
|
||||
wxHIDModule::sm_keyboard = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return wxHIDModule::sm_keyboard->IsActive(key);
|
||||
}
|
||||
|
||||
#endif //__DARWIN__
|
505
src/mac/corefoundation/hidjoystick.cpp
Normal file
505
src/mac/corefoundation/hidjoystick.cpp
Normal file
@@ -0,0 +1,505 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: joystick.cpp
|
||||
// Purpose: wxJoystick class
|
||||
// Author: Ryan Norton
|
||||
// Modified by:
|
||||
// Created: 2/13/2005
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) Ryan Norton
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma implementation "joystick.h"
|
||||
#endif
|
||||
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __DARWIN__
|
||||
|
||||
#if wxUSE_JOYSTICK
|
||||
|
||||
#include "wx/event.h"
|
||||
#include "wx/log.h"
|
||||
#include "wx/joystick.h"
|
||||
#include "wx/thread.h"
|
||||
#include "wx/window.h"
|
||||
|
||||
#include "wx/mac/corefoundation/hid.h"
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
enum {
|
||||
wxJS_AXIS_X = 41,
|
||||
wxJS_AXIS_Y,
|
||||
wxJS_AXIS_Z,
|
||||
wxJS_AXIS_RUDDER,
|
||||
wxJS_AXIS_U,
|
||||
wxJS_AXIS_V,
|
||||
|
||||
wxJS_AXIS_MAX = 32767,
|
||||
wxJS_AXIS_MIN = -32767
|
||||
};
|
||||
|
||||
class wxHIDJoystick : public wxHIDDevice
|
||||
{
|
||||
public:
|
||||
bool Create(int nWhich);
|
||||
virtual void BuildCookies(wxCFArray& Array);
|
||||
IOHIDElementCookie* GetCookies() {return m_pCookies;}
|
||||
|
||||
IOHIDQueueInterface** GetQueue() {return m_ppQueue;}
|
||||
};
|
||||
|
||||
|
||||
bool wxHIDJoystick::Create(int nWhich)
|
||||
{
|
||||
int nJoysticks = GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick);
|
||||
|
||||
if (nWhich <= nJoysticks)
|
||||
return wxHIDDevice::Create(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick);
|
||||
else
|
||||
nWhich -= nJoysticks;
|
||||
|
||||
int nGamePads = GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad);
|
||||
|
||||
if (nWhich <= nGamePads)
|
||||
return wxHIDDevice::Create(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void wxHIDJoystick::BuildCookies(wxCFArray& Array)
|
||||
{
|
||||
Array = CFDictionaryGetValue((CFDictionaryRef)Array[0], CFSTR(kIOHIDElementKey));
|
||||
InitCookies(50, true);
|
||||
int i,
|
||||
nUsage,
|
||||
nPage;
|
||||
for (i = 0; i < Array.Count(); ++i)
|
||||
{
|
||||
CFNumberGetValue(
|
||||
(CFNumberRef) CFDictionaryGetValue((CFDictionaryRef) Array[i], CFSTR(kIOHIDElementUsageKey)),
|
||||
kCFNumberLongType, &nUsage);
|
||||
|
||||
CFNumberGetValue(
|
||||
(CFNumberRef) CFDictionaryGetValue((CFDictionaryRef) Array[i], CFSTR(kIOHIDElementUsagePageKey)),
|
||||
kCFNumberLongType, &nPage);
|
||||
|
||||
if (nPage == kHIDPage_Button && nUsage <= 40)
|
||||
AddCookieInQueue(Array[i], nUsage );
|
||||
else if (nPage == kHIDPage_GenericDesktop)
|
||||
{
|
||||
switch(nUsage)
|
||||
{
|
||||
case kHIDUsage_GD_X:
|
||||
AddCookieInQueue(Array[i], wxJS_AXIS_X);
|
||||
break;
|
||||
case kHIDUsage_GD_Y:
|
||||
AddCookieInQueue(Array[i], wxJS_AXIS_Y);
|
||||
break;
|
||||
case kHIDUsage_GD_Z:
|
||||
AddCookieInQueue(Array[i], wxJS_AXIS_Z);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nPage == kHIDPage_Simulation && nUsage == kHIDUsage_Sim_Rudder)
|
||||
AddCookieInQueue(Array[i], wxJS_AXIS_RUDDER );
|
||||
}
|
||||
}//end buildcookies
|
||||
|
||||
|
||||
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxJoystick, wxObject)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Background thread for reading the joystick device
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class wxJoystickThread : public wxThread
|
||||
{
|
||||
public:
|
||||
wxJoystickThread(wxHIDJoystick* hid, int joystick);
|
||||
void* Entry();
|
||||
|
||||
private:
|
||||
wxHIDJoystick* m_hid;
|
||||
int m_joystick;
|
||||
wxPoint m_lastposition;
|
||||
int m_axe[15];
|
||||
int m_buttons;
|
||||
wxWindow* m_catchwin;
|
||||
int m_polling;
|
||||
|
||||
friend class wxJoystick;
|
||||
};
|
||||
|
||||
|
||||
wxJoystickThread::wxJoystickThread(wxHIDJoystick* hid, int joystick)
|
||||
: m_hid(hid),
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
# define wxJSVERIFY(arg) if(!(arg)) {wxLogSysError(wxT(#arg)); return NULL;}
|
||||
# define wxJSASSERT(arg) wxJSVERIFY(arg)
|
||||
|
||||
void* wxJoystickThread::Entry()
|
||||
{
|
||||
CFRunLoopSourceRef pRLSource = NULL;
|
||||
|
||||
wxJSVERIFY( (*m_hid->GetQueue())->createAsyncEventSource(m_hid->GetQueue(), &pRLSource)
|
||||
== kIOReturnSuccess );
|
||||
wxJSASSERT(pRLSource != NULL);
|
||||
|
||||
//attach runloop source to main run loop in thread
|
||||
CFRunLoopRef pRL = CFRunLoopGetCurrent();
|
||||
CFRunLoopAddSource(pRL, pRLSource, kCFRunLoopDefaultMode);
|
||||
|
||||
// wxJSVERIFY( (*m_hid->GetQueue())->start(m_hid->GetQueue()) == kIOReturnSuccess );
|
||||
|
||||
double dTime;
|
||||
IOHIDEventStruct hidevent;
|
||||
AbsoluteTime bogustime = {0,0};
|
||||
IOReturn ret;
|
||||
|
||||
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
|
||||
|
||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, dTime, m_polling);
|
||||
|
||||
while ( (ret = (*m_hid->GetQueue())->getNextEvent(m_hid->GetQueue(),
|
||||
&hidevent, bogustime, 0)) != kIOReturnUnderrun )
|
||||
{
|
||||
if (TestDestroy())
|
||||
break;
|
||||
|
||||
wxJSASSERT(ret == kIOReturnSuccess);
|
||||
wxJoystickEvent wxevent;
|
||||
|
||||
int nIndex = 0;
|
||||
IOHIDElementCookie* pCookies = m_hid->GetCookies();
|
||||
while(nIndex < 50)
|
||||
{
|
||||
if(hidevent.elementCookie == pCookies[nIndex])
|
||||
break;
|
||||
}
|
||||
wxASSERT(nIndex != 50);
|
||||
|
||||
if (nIndex < 40)
|
||||
{
|
||||
if (hidevent.value)
|
||||
{
|
||||
m_buttons |= (1 << nIndex);
|
||||
wxevent.SetEventType(wxEVT_JOY_BUTTON_DOWN);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buttons &= ~(1 << nIndex);
|
||||
wxevent.SetEventType(wxEVT_JOY_BUTTON_UP);
|
||||
}
|
||||
|
||||
wxevent.SetButtonChange(nIndex);
|
||||
}
|
||||
else if (nIndex == wxJS_AXIS_X)
|
||||
{
|
||||
m_lastposition.x = hidevent.value;
|
||||
wxevent.SetEventType(wxEVT_JOY_MOVE);
|
||||
m_axe[nIndex - 39] = hidevent.value;
|
||||
}
|
||||
else if (nIndex == wxJS_AXIS_Y)
|
||||
{
|
||||
m_lastposition.y = hidevent.value;
|
||||
wxevent.SetEventType(wxEVT_JOY_MOVE);
|
||||
m_axe[nIndex - 39] = hidevent.value;
|
||||
}
|
||||
else if (nIndex == wxJS_AXIS_Z)
|
||||
{
|
||||
wxevent.SetEventType(wxEVT_JOY_ZMOVE);
|
||||
m_axe[nIndex - 39] = hidevent.value;
|
||||
}
|
||||
else
|
||||
wxevent.SetEventType(wxEVT_JOY_MOVE);
|
||||
|
||||
Nanoseconds timestamp = AbsoluteToNanoseconds(hidevent.timestamp);
|
||||
|
||||
wxULongLong llTime(timestamp.hi, timestamp.lo);
|
||||
|
||||
llTime /= 1000000;
|
||||
|
||||
wxevent.SetTimestamp(llTime.GetValue());
|
||||
wxevent.SetJoystick(m_joystick);
|
||||
wxevent.SetButtonState(m_buttons);
|
||||
wxevent.SetPosition(m_lastposition);
|
||||
wxevent.SetZPosition(m_axe[3]);
|
||||
wxevent.SetEventObject(m_catchwin);
|
||||
|
||||
if (m_catchwin)
|
||||
m_catchwin->AddPendingEvent(wxevent);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
wxJoystick::wxJoystick(int joystick)
|
||||
: m_joystick(joystick),
|
||||
m_thread(NULL)
|
||||
{
|
||||
m_hid = new wxHIDJoystick();
|
||||
|
||||
if (m_hid->Create(m_joystick))
|
||||
{
|
||||
m_thread = new wxJoystickThread(m_hid, m_joystick);
|
||||
m_thread->Create();
|
||||
m_thread->Run();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_hid;
|
||||
m_hid = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wxJoystick::~wxJoystick()
|
||||
{
|
||||
ReleaseCapture();
|
||||
if (m_thread)
|
||||
m_thread->Delete(); // It's detached so it will delete itself
|
||||
|
||||
if (m_hid)
|
||||
delete m_hid;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// State
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
wxPoint wxJoystick::GetPosition() const
|
||||
{
|
||||
wxPoint pos(wxDefaultPosition);
|
||||
if (m_thread) pos = m_thread->m_lastposition;
|
||||
return pos;
|
||||
}
|
||||
|
||||
int wxJoystick::GetZPosition() const
|
||||
{
|
||||
if (m_thread)
|
||||
return m_thread->m_axe[wxJS_AXIS_Z];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wxJoystick::GetButtonState() const
|
||||
{
|
||||
if (m_thread)
|
||||
return m_thread->m_buttons;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wxJoystick::GetPOVPosition() const
|
||||
{ return -1; }
|
||||
|
||||
int wxJoystick::GetPOVCTSPosition() const
|
||||
{ return -1; }
|
||||
|
||||
int wxJoystick::GetRudderPosition() const
|
||||
{
|
||||
if (m_thread)
|
||||
return m_thread->m_axe[wxJS_AXIS_RUDDER];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wxJoystick::GetUPosition() const
|
||||
{
|
||||
if (m_thread)
|
||||
return m_thread->m_axe[wxJS_AXIS_U];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wxJoystick::GetVPosition() const
|
||||
{
|
||||
if (m_thread)
|
||||
return m_thread->m_axe[wxJS_AXIS_V];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wxJoystick::GetMovementThreshold() const
|
||||
{ return 0; }
|
||||
|
||||
void wxJoystick::SetMovementThreshold(int threshold)
|
||||
{ }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Capabilities
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool wxJoystick::IsOk() const
|
||||
{ return m_hid != NULL; }
|
||||
|
||||
int wxJoystick::GetNumberJoysticks() const
|
||||
{ return wxHIDDevice::GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick) +
|
||||
wxHIDDevice::GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad); }
|
||||
|
||||
int wxJoystick::GetManufacturerId() const
|
||||
{ return 0; }
|
||||
|
||||
int wxJoystick::GetProductId() const
|
||||
{ return 0; }
|
||||
|
||||
wxString wxJoystick::GetProductName() const
|
||||
{ return wxT("unknown"); }
|
||||
|
||||
int wxJoystick::GetXMin() const
|
||||
{ return wxJS_AXIS_MIN; }
|
||||
|
||||
int wxJoystick::GetYMin() const
|
||||
{ return wxJS_AXIS_MIN; }
|
||||
|
||||
int wxJoystick::GetZMin() const
|
||||
{ return wxJS_AXIS_MIN; }
|
||||
|
||||
int wxJoystick::GetXMax() const
|
||||
{ return wxJS_AXIS_MAX; }
|
||||
|
||||
int wxJoystick::GetYMax() const
|
||||
{ return wxJS_AXIS_MAX; }
|
||||
|
||||
int wxJoystick::GetZMax() const
|
||||
{ return wxJS_AXIS_MAX; }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//
|
||||
// internal
|
||||
//
|
||||
int wxJoystick::GetMaxButtons() const
|
||||
{ return 15; }
|
||||
|
||||
int wxJoystick::GetMaxAxes() const
|
||||
{ return 10; }
|
||||
|
||||
int wxJoystick::GetPollingMin() const
|
||||
{ return 10; }
|
||||
|
||||
int wxJoystick::GetPollingMax() const
|
||||
{ return 1000; }
|
||||
|
||||
int wxJoystick::GetRudderMin() const
|
||||
{ return wxJS_AXIS_MIN; }
|
||||
|
||||
int wxJoystick::GetRudderMax() const
|
||||
{ return wxJS_AXIS_MAX; }
|
||||
|
||||
int wxJoystick::GetUMin() const
|
||||
{ return wxJS_AXIS_MIN; }
|
||||
|
||||
int wxJoystick::GetUMax() const
|
||||
{ return wxJS_AXIS_MAX; }
|
||||
|
||||
int wxJoystick::GetVMin() const
|
||||
{ return wxJS_AXIS_MIN; }
|
||||
|
||||
int wxJoystick::GetVMax() const
|
||||
{ return wxJS_AXIS_MAX; }
|
||||
|
||||
bool wxJoystick::HasRudder() const
|
||||
{ return m_hid->HasElement(wxJS_AXIS_RUDDER); }
|
||||
|
||||
bool wxJoystick::HasZ() const
|
||||
{ return m_hid->HasElement(wxJS_AXIS_Z); }
|
||||
|
||||
bool wxJoystick::HasU() const
|
||||
{ return m_hid->HasElement(wxJS_AXIS_U); }
|
||||
|
||||
bool wxJoystick::HasV() const
|
||||
{ return m_hid->HasElement(wxJS_AXIS_V); }
|
||||
|
||||
bool wxJoystick::HasPOV() const
|
||||
{ return false; }
|
||||
|
||||
bool wxJoystick::HasPOV4Dir() const
|
||||
{ return false; }
|
||||
|
||||
bool wxJoystick::HasPOVCTS() const
|
||||
{ return false; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Operations
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool wxJoystick::SetCapture(wxWindow* win, int pollingFreq)
|
||||
{
|
||||
if (m_thread)
|
||||
{
|
||||
m_thread->m_catchwin = win;
|
||||
m_thread->m_polling = pollingFreq;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wxJoystick::ReleaseCapture()
|
||||
{
|
||||
if (m_thread)
|
||||
{
|
||||
m_thread->m_catchwin = NULL;
|
||||
m_thread->m_polling = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
//OSX
|
||||
|
||||
#endif
|
||||
// wxUSE_JOYSTICK
|
||||
|
Reference in New Issue
Block a user