applying patch 1411230

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38620 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Csomor 2006-04-08 11:43:13 +00:00
parent a074f61eae
commit 32efab35c1
3 changed files with 430 additions and 249 deletions

View File

@ -8,6 +8,7 @@
// Copyright: (c) Ryan Norton // Copyright: (c) Ryan Norton
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// =========================================================================== // ===========================================================================
// declarations // declarations
// =========================================================================== // ===========================================================================
@ -22,10 +23,6 @@
#include "wx/defs.h" #include "wx/defs.h"
#include "wx/string.h" #include "wx/string.h"
// ---------------------------------------------------------------------------
// definitions
// ---------------------------------------------------------------------------
//Mac OSX only //Mac OSX only
#ifdef __DARWIN__ #ifdef __DARWIN__
@ -44,28 +41,24 @@ extern "C" {
#include <mach/mach.h> //this actually includes mach_port.h (see above) #include <mach/mach.h> //this actually includes mach_port.h (see above)
//Utility wrapper around CFArray // ===========================================================================
class wxCFArray // definitions
{ // ===========================================================================
public:
wxCFArray(CFTypeRef pData) : pArray((CFArrayRef) pData) {}
CFTypeRef operator [] (const int& nIndex) {return CFArrayGetValueAtIndex(pArray, nIndex); }
int Count() {return CFArrayGetCount(pArray);}
private:
CFArrayRef pArray;
};
// ---------------------------------------------------------------------------
// wxHIDDevice
// //
// A wrapper around OS X HID Manager procedures. // A wrapper around OS X HID Manager procedures.
// The tutorial "Working With HID Class Device Interfaces" Is // The tutorial "Working With HID Class Device Interfaces" Is
// Quite good, as is the sample program associated with it // Quite good, as is the sample program associated with it
// (Depite the author's protests!). // (Depite the author's protests!).
// ---------------------------------------------------------------------------
class wxHIDDevice class wxHIDDevice
{ {
public: public:
wxHIDDevice() : m_ppDevice(NULL), m_ppQueue(NULL), m_pCookies(NULL) {} wxHIDDevice() : m_ppDevice(NULL), m_ppQueue(NULL), m_pCookies(NULL) {}
//kHIDPage_GenericDesktop
//kHIDUsage_GD_Joystick,kHIDUsage_GD_Mouse,kHIDUsage_GD_Keyboard
bool Create (int nClass = -1, int nType = -1, int nDev = 1); bool Create (int nClass = -1, int nType = -1, int nDev = 1);
static size_t GetCount(int nClass = -1, int nType = -1); static size_t GetCount(int nClass = -1, int nType = -1);
@ -78,12 +71,13 @@ public:
//builds the cookie array - //builds the cookie array -
//first call InitCookies to initialize the cookie //first call InitCookies to initialize the cookie
//array, then AddCookie to add a cookie at a certain point in an array //array, then AddCookie to add a cookie at a certain point in an array
virtual void BuildCookies(wxCFArray& Array) = 0; virtual void BuildCookies(CFArrayRef Array) = 0;
//checks to see whether the cookie at nIndex is active (element value != 0) //checks to see whether the cookie at nIndex is active (element value != 0)
bool IsActive(int nIndex); bool IsActive(int nIndex);
//checks to see whether the cookie at nIndex exists //checks to see whether an element in the internal cookie array
//exists
bool HasElement(int nIndex); bool HasElement(int nIndex);
//closes the device and cleans the queue and cookies //closes the device and cleans the queue and cookies
@ -97,17 +91,25 @@ protected:
wxString m_szProductName; //product name wxString m_szProductName; //product name
int m_nProductId; //product id int m_nProductId; //product id
int m_nManufacturerId; //manufacturer id int m_nManufacturerId; //manufacturer id
mach_port_t m_pPort; mach_port_t m_pPort; //mach port to use
}; };
// ---------------------------------------------------------------------------
// wxHIDKeyboard
//
// Semi-simple implementation that opens a connection to the first
// keyboard of the machine. Used in wxGetKeyState.
// ---------------------------------------------------------------------------
class wxHIDKeyboard : public wxHIDDevice class wxHIDKeyboard : public wxHIDDevice
{ {
public: public:
bool Create(); static int GetCount();
virtual void BuildCookies(wxCFArray& Array); bool Create(int nDev = 1);
void AddCookie(CFTypeRef Data, int i);
virtual void BuildCookies(CFArrayRef Array);
void DoBuildCookies(CFArrayRef Array);
}; };
#endif //__DARWIN__ #endif //__DARWIN__
#endif #endif //WX_MACCARBONHID_H
//WX_MACCARBONHID_H

View File

@ -32,52 +32,38 @@
#include "wx/log.h" #include "wx/log.h"
#include "wx/mac/corefoundation/cfstring.h" #include "wx/mac/corefoundation/cfstring.h"
#include "wx/utils.h"
// --------------------------------------------------------------------------- #include "wx/module.h"
// assertion macros #include "wx/dynarray.h"
// ---------------------------------------------------------------------------
#define wxFORCECHECK_MSG(arg, msg) \
{\
if (arg) \
{\
wxLogSysError(wxString::Format(wxT("Message:%s\nHID: %s failed!"), wxT(msg), wxT(#arg)));\
return false;\
}\
}
#define wxIOCHECK(arg, msg) wxFORCECHECK_MSG(arg != kIOReturnSuccess, msg)
#define wxKERNCHECK(arg, msg) wxFORCECHECK_MSG(arg != KERN_SUCCESS, msg)
#define wxSCHECK(arg, msg) wxFORCECHECK_MSG(arg != S_OK, msg)
/*
void CFShowTypeIDDescription(CFTypeRef pData)
{
if(!pData)
{
wxASSERT(false);
return;
}
wxMessageBox(
CFStringGetCStringPtr(
CFCopyTypeIDDescription(CFGetTypeID(pData)),CFStringGetSystemEncoding()
)
);
}
*/
// ============================================================================ // ============================================================================
// implementation // implementation
// ============================================================================ // ============================================================================
// --------------------------------------------------------------------------- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// wxHIDDevice // wxHIDDevice
// --------------------------------------------------------------------------- //
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ----------------------------------------------------------------------------
// wxHIDDevice::Create
//
// nClass is the HID Page such as
// kHIDPage_GenericDesktop
// nType is the HID Usage such as
// kHIDUsage_GD_Joystick,kHIDUsage_GD_Mouse,kHIDUsage_GD_Keyboard
// nDev is the device number to use
//
// ----------------------------------------------------------------------------
bool wxHIDDevice::Create (int nClass, int nType, int nDev) bool wxHIDDevice::Create (int nClass, int nType, int nDev)
{ {
//Create the mach port //Create the mach port
wxIOCHECK(IOMasterPort(bootstrap_port, &m_pPort), "Could not create mach port"); if(IOMasterPort(bootstrap_port, &m_pPort) != kIOReturnSuccess)
{
wxLogSysError(wxT("Could not create mach port"));
return false;
}
//Dictionary that will hold first //Dictionary that will hold first
//the matching dictionary for determining which kind of devices we want, //the matching dictionary for determining which kind of devices we want,
@ -87,10 +73,11 @@ bool wxHIDDevice::Create (int nClass, int nType, int nDev)
//the services we want to hid services (and also eats the //the services we want to hid services (and also eats the
//dictionary up for us (consumes one reference)) //dictionary up for us (consumes one reference))
CFMutableDictionaryRef pDictionary = IOServiceMatching(kIOHIDDeviceKey); CFMutableDictionaryRef pDictionary = IOServiceMatching(kIOHIDDeviceKey);
wxCHECK_MSG( pDictionary, false, if(pDictionary == NULL)
_T("IOServiceMatching(kIOHIDDeviceKey) failed") ); {
wxLogSysError( _T("IOServiceMatching(kIOHIDDeviceKey) failed") );
wxASSERT( pDictionary ); return false;
}
//Here we'll filter down the services to what we want //Here we'll filter down the services to what we want
if (nType != -1) if (nType != -1)
@ -110,7 +97,14 @@ bool wxHIDDevice::Create (int nClass, int nType, int nDev)
//Now get the maching services //Now get the maching services
io_iterator_t pIterator; io_iterator_t pIterator;
wxIOCHECK(IOServiceGetMatchingServices(m_pPort, pDictionary, &pIterator), "No Matching HID Services"); if( IOServiceGetMatchingServices(m_pPort,
pDictionary, &pIterator) != kIOReturnSuccess )
{
wxLogSysError(_T("No Matching HID Services"));
return false;
}
//Were there any devices matched?
if(pIterator == 0) if(pIterator == 0)
return false; // No devices found return false; // No devices found
@ -119,7 +113,10 @@ bool wxHIDDevice::Create (int nClass, int nType, int nDev)
while ( (pObject = IOIteratorNext(pIterator)) != 0) while ( (pObject = IOIteratorNext(pIterator)) != 0)
{ {
if(--nDev != 0) if(--nDev != 0)
{
IOObjectRelease(pObject);
continue; continue;
}
if ( IORegistryEntryCreateCFProperties if ( IORegistryEntryCreateCFProperties
( (
@ -132,57 +129,62 @@ bool wxHIDDevice::Create (int nClass, int nType, int nDev)
wxLogDebug(_T("IORegistryEntryCreateCFProperties failed")); wxLogDebug(_T("IORegistryEntryCreateCFProperties failed"));
} }
//Just for sanity :) //
wxASSERT(CFGetTypeID(CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey))) == CFStringGetTypeID()); // Now we get the attributes of each "product" in the iterator
//
/*
kIOHIDTransportKey;
kIOHIDVendorIDKey;
kIOHIDProductIDKey;
kIOHIDVersionNumberKey;
kIOHIDManufacturerKey;
kIOHIDSerialNumberKey;
if !kIOHIDLocationIDKey
kUSBDevicePropertyLocationID
kIOHIDPrimaryUsageKey
kIOHIDPrimaryUsagePageKey
idProduct
idVendor
USB Product Name
*/
//Get [product] name //Get [product] name
m_szProductName = wxMacCFStringHolder( (CFStringRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey)), false ).AsString(); CFStringRef cfsProduct = (CFStringRef)
CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey));
m_szProductName =
wxMacCFStringHolder( cfsProduct,
false
).AsString();
CFNumberRef nref = (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductIDKey)); //Get the Product ID Key
CFNumberRef cfnProductId = (CFNumberRef)
CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductIDKey));
if (cfnProductId)
{
CFNumberGetValue(cfnProductId, kCFNumberIntType, &m_nProductId);
}
if (nref) //Get the Vendor ID Key
CFNumberGetValue( CFNumberRef cfnVendorId = (CFNumberRef)
nref, CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDVendorIDKey));
kCFNumberIntType, if (cfnVendorId)
&m_nProductId {
); CFNumberGetValue(cfnVendorId, kCFNumberIntType, &m_nManufacturerId);
}
nref = (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDVendorIDKey)); //
if (nref) // End attribute getting
CFNumberGetValue( //
nref,
kCFNumberIntType,
&m_nManufacturerId
);
//Create the interface (good grief - long function names!) //Create the interface (good grief - long function names!)
SInt32 nScore; SInt32 nScore;
IOCFPlugInInterface** ppPlugin; IOCFPlugInInterface** ppPlugin;
wxIOCHECK(IOCreatePlugInInterfaceForService(pObject, kIOHIDDeviceUserClientTypeID, if(IOCreatePlugInInterfaceForService(pObject,
kIOCFPlugInInterfaceID, &ppPlugin, &nScore), ""); kIOHIDDeviceUserClientTypeID,
kIOCFPlugInInterfaceID, &ppPlugin,
&nScore) != kIOReturnSuccess)
{
wxLogSysError(wxT("Could not create HID Interface for product"));
return false;
}
//Now, the final thing we can check before we fall back to asserts //Now, the final thing we can check before we fall back to asserts
//(because the dtor only checks if the device is ok, so if anything //(because the dtor only checks if the device is ok, so if anything
//fails from now on the dtor will delete the device anyway, so we can't break from this). //fails from now on the dtor will delete the device anyway, so we can't break from this).
//Get the HID interface from the plugin to the mach port //Get the HID interface from the plugin to the mach port
wxSCHECK((*ppPlugin)->QueryInterface(ppPlugin, if((*ppPlugin)->QueryInterface(ppPlugin,
CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void**) &m_ppDevice), ""); CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID),
(void**) &m_ppDevice) != S_OK)
{
wxLogSysError(wxT("Could not get device interface from HID interface"));
return false;
}
//release the plugin //release the plugin
(*ppPlugin)->Release(ppPlugin); (*ppPlugin)->Release(ppPlugin);
@ -192,35 +194,53 @@ USB Product Name
wxLogDebug(_T("HID device: open failed")); wxLogDebug(_T("HID device: open failed"));
// //
//Now the hard part - in order to scan things we need "cookies" - //Now the hard part - in order to scan things we need "cookies"
// //
wxCFArray CookieArray = CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDElementKey)); CFArrayRef cfaCookies = (CFArrayRef)CFDictionaryGetValue(pDictionary,
BuildCookies(CookieArray); CFSTR(kIOHIDElementKey));
BuildCookies(cfaCookies);
//cleanup //cleanup
CFRelease(pDictionary); CFRelease(pDictionary);
IOObjectRelease(pObject); IOObjectRelease(pObject);
break;
//iterator cleanup
IOObjectRelease(pIterator);
return true;
} }
//iterator cleanup //iterator cleanup
IOObjectRelease(pIterator); IOObjectRelease(pIterator);
return true; return false; //no device
}//end Create() }//end Create()
// ----------------------------------------------------------------------------
// wxHIDDevice::GetCount [static]
//
// Obtains the number of devices on a system for a given HID Page (nClass)
// and HID Usage (nType).
// ----------------------------------------------------------------------------
size_t wxHIDDevice::GetCount (int nClass, int nType) size_t wxHIDDevice::GetCount (int nClass, int nType)
{ {
mach_port_t m_pPort;
//Create the mach port //Create the mach port
wxIOCHECK(IOMasterPort(bootstrap_port, &m_pPort), "Could not create mach port"); mach_port_t pPort;
if(IOMasterPort(bootstrap_port, &pPort) != kIOReturnSuccess)
{
wxLogSysError(wxT("Could not create mach port"));
return false;
}
//Dictionary that will hold first //Dictionary that will hold first
//the matching dictionary for determining which kind of devices we want, //the matching dictionary for determining which kind of devices we want,
//then later some registry properties from an iterator (see below) //then later some registry properties from an iterator (see below)
CFMutableDictionaryRef pDictionary = IOServiceMatching(kIOHIDDeviceKey); CFMutableDictionaryRef pDictionary = IOServiceMatching(kIOHIDDeviceKey);
wxCHECK_MSG( pDictionary, 0, if(pDictionary == NULL)
_T("IOServiceMatching(kIOHIDDeviceKey) failed") ); {
wxLogSysError( _T("IOServiceMatching(kIOHIDDeviceKey) failed") );
return false;
}
//Here we'll filter down the services to what we want //Here we'll filter down the services to what we want
if (nType != -1) if (nType != -1)
@ -240,25 +260,38 @@ size_t wxHIDDevice::GetCount (int nClass, int nType)
//Now get the maching services //Now get the maching services
io_iterator_t pIterator; io_iterator_t pIterator;
wxIOCHECK(IOServiceGetMatchingServices(m_pPort, pDictionary, &pIterator), "No Matching HID Services"); if( IOServiceGetMatchingServices(pPort,
pDictionary, &pIterator) != kIOReturnSuccess )
{
wxLogSysError(_T("No Matching HID Services"));
return false;
}
//If the iterator doesn't exist there are no devices :)
if ( !pIterator ) if ( !pIterator )
return 0; return 0;
//Now we iterate through them //Now we iterate through them
io_object_t pObject;
size_t nCount = 0; size_t nCount = 0;
io_object_t pObject;
while ( (pObject = IOIteratorNext(pIterator)) != 0) while ( (pObject = IOIteratorNext(pIterator)) != 0)
{
++nCount; ++nCount;
IOObjectRelease(pObject);
//iterator cleanup }
//cleanup
IOObjectRelease(pIterator); IOObjectRelease(pIterator);
mach_port_deallocate(mach_task_self(), pPort);
return nCount; return nCount;
}//end Create() }//end Create()
// ----------------------------------------------------------------------------
// wxHIDDevice::AddCookie
//
// Adds a cookie to the internal cookie array from a CFType
// ----------------------------------------------------------------------------
void wxHIDDevice::AddCookie(CFTypeRef Data, int i) void wxHIDDevice::AddCookie(CFTypeRef Data, int i)
{ {
CFNumberGetValue( CFNumberGetValue(
@ -270,6 +303,12 @@ void wxHIDDevice::AddCookie(CFTypeRef Data, int i)
); );
} }
// ----------------------------------------------------------------------------
// wxHIDDevice::AddCookieInQueue
//
// Adds a cookie to the internal cookie array from a CFType and additionally
// adds it to the internal HID Queue
// ----------------------------------------------------------------------------
void wxHIDDevice::AddCookieInQueue(CFTypeRef Data, int i) void wxHIDDevice::AddCookieInQueue(CFTypeRef Data, int i)
{ {
//3rd Param flags (none yet) //3rd Param flags (none yet)
@ -278,6 +317,11 @@ void wxHIDDevice::AddCookieInQueue(CFTypeRef Data, int i)
wxLogDebug(_T("HID device: adding element failed")); wxLogDebug(_T("HID device: adding element failed"));
} }
// ----------------------------------------------------------------------------
// wxHIDDevice::InitCookies
//
// Create the internal cookie array, optionally creating a HID Queue
// ----------------------------------------------------------------------------
void wxHIDDevice::InitCookies(size_t dwSize, bool bQueue) void wxHIDDevice::InitCookies(size_t dwSize, bool bQueue)
{ {
m_pCookies = new IOHIDElementCookie[dwSize]; m_pCookies = new IOHIDElementCookie[dwSize];
@ -297,27 +341,47 @@ void wxHIDDevice::InitCookies(size_t dwSize, bool bQueue)
wxLogDebug(_T("HID device: create failed")); wxLogDebug(_T("HID device: create failed"));
} }
} }
//make sure that cookie array is clear
memset(m_pCookies, 0, sizeof(*m_pCookies) * dwSize);
} }
// ----------------------------------------------------------------------------
// wxHIDDevice::IsActive
//
// Returns true if a cookie of the device is active - for example if a key is
// held down, joystick button pressed, caps lock active, etc..
// ----------------------------------------------------------------------------
bool wxHIDDevice::IsActive(int nIndex) bool wxHIDDevice::IsActive(int nIndex)
{ {
wxASSERT(m_pCookies[nIndex] != NULL); if(!HasElement(nIndex))
{
//cookie at index does not exist - getElementValue
//could return true which would be incorrect so we
//check here
return false;
}
IOHIDEventStruct Event; IOHIDEventStruct Event;
(*m_ppDevice)->getElementValue(m_ppDevice, m_pCookies[nIndex], &Event); (*m_ppDevice)->getElementValue(m_ppDevice, m_pCookies[nIndex], &Event);
/*
wxString ss;
ss << _T("[") << (int) m_pCookies[nIndex] << _T("] = ") << Event.value << _T(" SIZE:") << Event.longValueSize;
wxLogDebug(ss);
*/
return !!Event.value; return !!Event.value;
} }
// ----------------------------------------------------------------------------
// wxHIDDevice::HasElement
//
// Returns true if the element in the internal cookie array exists
// ----------------------------------------------------------------------------
bool wxHIDDevice::HasElement(int nIndex) bool wxHIDDevice::HasElement(int nIndex)
{ {
return m_pCookies[nIndex] != NULL; return m_pCookies[nIndex] != NULL;
} }
// ----------------------------------------------------------------------------
// wxHIDDevice Destructor
//
// Frees all memory and objects from the structure
// ----------------------------------------------------------------------------
wxHIDDevice::~wxHIDDevice() wxHIDDevice::~wxHIDDevice()
{ {
if (m_ppDevice != NULL) if (m_ppDevice != NULL)
@ -339,36 +403,107 @@ wxHIDDevice::~wxHIDDevice()
} }
} }
// --------------------------------------------------------------------------- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// wxHIDKeyboard // wxHIDKeyboard
// --------------------------------------------------------------------------- //
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//There are no right shift, alt etc. in the wx headers yet so just sort
//of "define our own" for now
enum enum
{ {
WXK_RSHIFT = 400, WXK_RSHIFT = 400,
WXK_RALT, WXK_RALT,
WXK_RCONTROL, WXK_RCONTROL,
WXK_RMENU WXK_RMENU
}; };
bool wxHIDKeyboard::Create() // ----------------------------------------------------------------------------
// wxHIDKeyboard::GetCount [static]
//
// Get number of HID keyboards available
// ----------------------------------------------------------------------------
int wxHIDKeyboard::GetCount()
{ {
return wxHIDDevice::Create(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard); return wxHIDDevice::GetCount(kHIDPage_GenericDesktop,
kHIDUsage_GD_Keyboard);
} }
void wxHIDKeyboard::BuildCookies(wxCFArray& Array) // ----------------------------------------------------------------------------
// wxHIDKeyboard::Create
//
// Create the HID Keyboard
// ----------------------------------------------------------------------------
bool wxHIDKeyboard::Create(int nDev /* = 1*/)
{ {
Array = CFDictionaryGetValue((CFDictionaryRef)Array[0], CFSTR(kIOHIDElementKey)); return wxHIDDevice::Create(kHIDPage_GenericDesktop,
kHIDUsage_GD_Keyboard,
nDev);
}
// ----------------------------------------------------------------------------
// wxHIDKeyboard::AddCookie
//
// Overloaded version of wxHIDDevice::AddCookie that simply does not
// add a cookie if a duplicate is found
// ----------------------------------------------------------------------------
void wxHIDKeyboard::AddCookie(CFTypeRef Data, int i)
{
if(!HasElement(i))
wxHIDDevice::AddCookie(Data, i);
}
// ----------------------------------------------------------------------------
// wxHIDKeyboard::BuildCookies
//
// Callback from Create() to build the HID cookies for the internal cookie
// array
// ----------------------------------------------------------------------------
void wxHIDKeyboard::BuildCookies(CFArrayRef Array)
{
//Create internal cookie array
InitCookies(500); InitCookies(500);
//Begin recursing in array
DoBuildCookies(Array);
}
void wxHIDKeyboard::DoBuildCookies(CFArrayRef Array)
{
//Now go through each possible cookie
int i, int i,
nUsage; nUsage;
bool bEOTriggered = false; // bool bEOTriggered = false;
for (i = 0; i < Array.Count(); ++i) for (i = 0; i < CFArrayGetCount(Array); ++i)
{ {
const void* ref = CFDictionaryGetValue(
(CFDictionaryRef)CFArrayGetValueAtIndex(Array, i),
CFSTR(kIOHIDElementKey)
);
if (ref != NULL)
{
DoBuildCookies((CFArrayRef) ref);
}
else
{
//
// Get the usage #
//
CFNumberGetValue( CFNumberGetValue(
(CFNumberRef) CFDictionaryGetValue((CFDictionaryRef) Array[i], CFSTR(kIOHIDElementUsageKey)), (CFNumberRef)
kCFNumberLongType, &nUsage); CFDictionaryGetValue((CFDictionaryRef)
CFArrayGetValueAtIndex(Array, i),
CFSTR(kIOHIDElementUsageKey)
),
kCFNumberLongType,
&nUsage);
//
// Now translate the usage # into a wx keycode
//
// //
// OK, this is strange - basically this kind of strange - // OK, this is strange - basically this kind of strange -
@ -382,200 +517,223 @@ void wxHIDKeyboard::BuildCookies(wxCFArray& Array)
// //
// Something to spend a support request on, if I had one, LOL. // Something to spend a support request on, if I had one, LOL.
// //
if(nUsage == 0xE0) //if(nUsage == 0xE0)
{ //{
if(bEOTriggered) // if(bEOTriggered)
break; // break;
bEOTriggered = true; // bEOTriggered = true;
} //}
/* //Instead of that though we now just don't add duplicate keys
wxString msg;
int cookie;
CFNumberGetValue(
(CFNumberRef) CFDictionaryGetValue ( (CFDictionaryRef) Array[i]
, CFSTR(kIOHIDElementCookieKey)
),
kCFNumberIntType,
&cookie
);
msg << wxT("KEY:") << nUsage << wxT("COOKIE:") << cookie;
wxLogDebug(msg);
*/
if (nUsage >= kHIDUsage_KeyboardA && nUsage <= kHIDUsage_KeyboardZ) if (nUsage >= kHIDUsage_KeyboardA && nUsage <= kHIDUsage_KeyboardZ)
AddCookie(Array[i], 'A' + (nUsage - kHIDUsage_KeyboardA) ); AddCookie(CFArrayGetValueAtIndex(Array, i), 'A' + (nUsage - kHIDUsage_KeyboardA) );
else if (nUsage >= kHIDUsage_Keyboard1 && nUsage <= kHIDUsage_Keyboard9) else if (nUsage >= kHIDUsage_Keyboard1 && nUsage <= kHIDUsage_Keyboard9)
AddCookie(Array[i], '1' + (nUsage - kHIDUsage_Keyboard1) ); AddCookie(CFArrayGetValueAtIndex(Array, i), '1' + (nUsage - kHIDUsage_Keyboard1) );
else if (nUsage >= kHIDUsage_KeyboardF1 && nUsage <= kHIDUsage_KeyboardF12) else if (nUsage >= kHIDUsage_KeyboardF1 && nUsage <= kHIDUsage_KeyboardF12)
AddCookie(Array[i], WXK_F1 + (nUsage - kHIDUsage_KeyboardF1) ); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_F1 + (nUsage - kHIDUsage_KeyboardF1) );
else if (nUsage >= kHIDUsage_KeyboardF13 && nUsage <= kHIDUsage_KeyboardF24) else if (nUsage >= kHIDUsage_KeyboardF13 && nUsage <= kHIDUsage_KeyboardF24)
AddCookie(Array[i], WXK_F13 + (nUsage - kHIDUsage_KeyboardF13) ); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_F13 + (nUsage - kHIDUsage_KeyboardF13) );
else if (nUsage >= kHIDUsage_Keypad1 && nUsage <= kHIDUsage_Keypad9) else if (nUsage >= kHIDUsage_Keypad1 && nUsage <= kHIDUsage_Keypad9)
AddCookie(Array[i], WXK_NUMPAD1 + (nUsage - kHIDUsage_Keypad1) ); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_NUMPAD1 + (nUsage - kHIDUsage_Keypad1) );
else switch (nUsage) else switch (nUsage)
{ {
//0's (wx & ascii go 0-9, but HID goes 1-0) //0's (wx & ascii go 0-9, but HID goes 1-0)
case kHIDUsage_Keyboard0: case kHIDUsage_Keyboard0:
AddCookie(Array[i],'0'); AddCookie(CFArrayGetValueAtIndex(Array, i), '0');
break; break;
case kHIDUsage_Keypad0: case kHIDUsage_Keypad0:
AddCookie(Array[i],WXK_NUMPAD0); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_NUMPAD0);
break; break;
//Basic //Basic
case kHIDUsage_KeyboardReturnOrEnter: case kHIDUsage_KeyboardReturnOrEnter:
AddCookie(Array[i], WXK_RETURN); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_RETURN);
break; break;
case kHIDUsage_KeyboardEscape: case kHIDUsage_KeyboardEscape:
AddCookie(Array[i], WXK_ESCAPE); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_ESCAPE);
break; break;
case kHIDUsage_KeyboardDeleteOrBackspace: case kHIDUsage_KeyboardDeleteOrBackspace:
AddCookie(Array[i], WXK_BACK); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_BACK);
break; break;
case kHIDUsage_KeyboardTab: case kHIDUsage_KeyboardTab:
AddCookie(Array[i], WXK_TAB); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_TAB);
break; break;
case kHIDUsage_KeyboardSpacebar: case kHIDUsage_KeyboardSpacebar:
AddCookie(Array[i], WXK_SPACE); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_SPACE);
break; break;
case kHIDUsage_KeyboardPageUp: case kHIDUsage_KeyboardPageUp:
AddCookie(Array[i], WXK_PAGEUP); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_PAGEUP);
break; break;
case kHIDUsage_KeyboardEnd: case kHIDUsage_KeyboardEnd:
AddCookie(Array[i], WXK_END); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_END);
break; break;
case kHIDUsage_KeyboardPageDown: case kHIDUsage_KeyboardPageDown:
AddCookie(Array[i], WXK_PAGEDOWN); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_PAGEDOWN);
break; break;
case kHIDUsage_KeyboardRightArrow: case kHIDUsage_KeyboardRightArrow:
AddCookie(Array[i], WXK_RIGHT); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_RIGHT);
break; break;
case kHIDUsage_KeyboardLeftArrow: case kHIDUsage_KeyboardLeftArrow:
AddCookie(Array[i], WXK_LEFT); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_LEFT);
break; break;
case kHIDUsage_KeyboardDownArrow: case kHIDUsage_KeyboardDownArrow:
AddCookie(Array[i], WXK_DOWN); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_DOWN);
break; break;
case kHIDUsage_KeyboardUpArrow: case kHIDUsage_KeyboardUpArrow:
AddCookie(Array[i], WXK_UP); AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_UP);
break; break;
//LEDS //LEDS
case kHIDUsage_KeyboardCapsLock: case kHIDUsage_KeyboardCapsLock:
AddCookie(Array[i],WXK_CAPITAL); AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_CAPITAL);
break; break;
case kHIDUsage_KeypadNumLock: case kHIDUsage_KeypadNumLock:
AddCookie(Array[i],WXK_NUMLOCK); AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_NUMLOCK);
break; break;
case kHIDUsage_KeyboardScrollLock: case kHIDUsage_KeyboardScrollLock:
AddCookie(Array[i],WXK_SCROLL); AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_SCROLL);
break; break;
//Menu keys, Shift, other specials //Menu keys, Shift, other specials
case kHIDUsage_KeyboardLeftControl: case kHIDUsage_KeyboardLeftControl:
AddCookie(Array[i],WXK_CONTROL); AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_CONTROL);
break; break;
case kHIDUsage_KeyboardLeftShift: case kHIDUsage_KeyboardLeftShift:
AddCookie(Array[i],WXK_SHIFT); AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_SHIFT);
break; break;
case kHIDUsage_KeyboardLeftAlt: case kHIDUsage_KeyboardLeftAlt:
AddCookie(Array[i],WXK_ALT); AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_ALT);
break; break;
case kHIDUsage_KeyboardLeftGUI: case kHIDUsage_KeyboardLeftGUI:
AddCookie(Array[i],WXK_MENU); AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_MENU);
break; break;
case kHIDUsage_KeyboardRightControl: case kHIDUsage_KeyboardRightControl:
AddCookie(Array[i],WXK_RCONTROL); AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_RCONTROL);
break; break;
case kHIDUsage_KeyboardRightShift: case kHIDUsage_KeyboardRightShift:
AddCookie(Array[i],WXK_RSHIFT); AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_RSHIFT);
break; break;
case kHIDUsage_KeyboardRightAlt: case kHIDUsage_KeyboardRightAlt:
AddCookie(Array[i],WXK_RALT); AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_RALT);
break; break;
case kHIDUsage_KeyboardRightGUI: case kHIDUsage_KeyboardRightGUI:
AddCookie(Array[i],WXK_RMENU); AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_RMENU);
break; break;
//Default //Default
default: default:
//not in wx keycodes - do nothing.... //not in wx keycodes - do nothing....
break; break;
} } //end mightly long switch
} } //end if the current element is not an array...
} //end for loop for Array
}//end buildcookies }//end buildcookies
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// //
// wxGetKeyState // wxHIDModule
// //
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include "wx/utils.h"
#include "wx/module.h"
class wxHIDModule : public wxModule class wxHIDModule : public wxModule
{ {
DECLARE_DYNAMIC_CLASS(wxHIDModule) DECLARE_DYNAMIC_CLASS(wxHIDModule)
public: public:
static wxHIDKeyboard* sm_keyboard; static wxArrayPtrVoid sm_keyboards;
virtual bool OnInit() virtual bool OnInit()
{ {
sm_keyboard = NULL;
return true; return true;
} }
virtual void OnExit() virtual void OnExit()
{ {
if (sm_keyboard) for(size_t i = 0; i < sm_keyboards.GetCount(); ++i)
delete sm_keyboard; delete (wxHIDKeyboard*) sm_keyboards[i];
} }
}; };
IMPLEMENT_DYNAMIC_CLASS(wxHIDModule, wxModule) IMPLEMENT_DYNAMIC_CLASS(wxHIDModule, wxModule)
wxHIDKeyboard* wxHIDModule::sm_keyboard; wxArrayPtrVoid wxHIDModule::sm_keyboards;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// wxGetKeyState()
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bool wxGetKeyState (wxKeyCode key) bool wxGetKeyState (wxKeyCode key)
{ {
wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key != wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons")); WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons"));
if (!wxHIDModule::sm_keyboard) if (wxHIDModule::sm_keyboards.GetCount() == 0)
{ {
wxHIDModule::sm_keyboard = new wxHIDKeyboard(); int nKeyboards = wxHIDKeyboard::GetCount();
bool bOK = wxHIDModule::sm_keyboard->Create();
wxASSERT(bOK); for(int i = 1; i <= nKeyboards; ++i)
if(!bOK)
{ {
delete wxHIDModule::sm_keyboard; wxHIDKeyboard* keyboard = new wxHIDKeyboard();
wxHIDModule::sm_keyboard = NULL; if(keyboard->Create(i))
return false; {
wxHIDModule::sm_keyboards.Add(keyboard);
}
else
{
delete keyboard;
break;
}
} }
wxASSERT_MSG(wxHIDModule::sm_keyboards.GetCount() != 0,
wxT("No keyboards found!"));
} }
for(size_t i = 0; i < wxHIDModule::sm_keyboards.GetCount(); ++i)
{
wxHIDKeyboard* keyboard = (wxHIDKeyboard*)
wxHIDModule::sm_keyboards[i];
switch(key) switch(key)
{ {
case WXK_SHIFT: case WXK_SHIFT:
return wxHIDModule::sm_keyboard->IsActive(WXK_SHIFT) || if( keyboard->IsActive(WXK_SHIFT) ||
wxHIDModule::sm_keyboard->IsActive(WXK_RSHIFT); keyboard->IsActive(WXK_RSHIFT) )
{
return true;
}
break; break;
case WXK_ALT: case WXK_ALT:
return wxHIDModule::sm_keyboard->IsActive(WXK_ALT) || if( keyboard->IsActive(WXK_ALT) ||
wxHIDModule::sm_keyboard->IsActive(WXK_RALT); keyboard->IsActive(WXK_RALT) )
{
return true;
}
break; break;
case WXK_CONTROL: case WXK_CONTROL:
return wxHIDModule::sm_keyboard->IsActive(WXK_CONTROL) || if( keyboard->IsActive(WXK_CONTROL) ||
wxHIDModule::sm_keyboard->IsActive(WXK_RCONTROL); keyboard->IsActive(WXK_RCONTROL) )
{
return true;
}
break; break;
case WXK_MENU: case WXK_MENU:
return wxHIDModule::sm_keyboard->IsActive(WXK_MENU) || if( keyboard->IsActive(WXK_MENU) ||
wxHIDModule::sm_keyboard->IsActive(WXK_RMENU); keyboard->IsActive(WXK_RMENU) )
{
return true;
}
break; break;
default: default:
return wxHIDModule::sm_keyboard->IsActive(key); if( keyboard->IsActive(key) )
{
return true;
}
break; break;
} }
}
return false; //not down/error
} }
#endif //__DARWIN__ #endif //__DARWIN__

View File

@ -74,8 +74,8 @@ public:
~wxHIDJoystick(); ~wxHIDJoystick();
bool Create(int nWhich); bool Create(int nWhich);
virtual void BuildCookies(wxCFArray& Array); virtual void BuildCookies(CFArrayRef Array);
void MakeCookies(wxCFArray& Array); void MakeCookies(CFArrayRef Array);
IOHIDElementCookie* GetCookies(); IOHIDElementCookie* GetCookies();
IOHIDQueueInterface** GetQueue(); IOHIDQueueInterface** GetQueue();
@ -145,7 +145,7 @@ wxJoystick::wxJoystick(int joystick)
{ {
m_hid = new wxHIDJoystick(); 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 = new wxJoystickThread(m_hid, m_joystick);
m_thread->Create(); m_thread->Create();
@ -449,14 +449,18 @@ bool wxHIDJoystick::Create(int nWhich)
int nJoysticks = GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); int nJoysticks = GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick);
if (nWhich <= nJoysticks) if (nWhich <= nJoysticks)
return wxHIDDevice::Create(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); return wxHIDDevice::Create(kHIDPage_GenericDesktop,
kHIDUsage_GD_Joystick,
nWhich);
else else
nWhich -= nJoysticks; nWhich -= nJoysticks;
int nGamePads = GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad); int nGamePads = GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad);
if (nWhich <= nGamePads) if (nWhich <= nGamePads)
return wxHIDDevice::Create(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad); return wxHIDDevice::Create(kHIDPage_GenericDesktop,
kHIDUsage_GD_GamePad,
nWhich);
else else
return false; return false;
} }
@ -471,13 +475,10 @@ bool wxHIDJoystick::Create(int nWhich)
// MakeCookies is just a recursive function for each array within // MakeCookies is just a recursive function for each array within
// BuildCookies. // BuildCookies.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void wxHIDJoystick::BuildCookies(wxCFArray& Array) void wxHIDJoystick::BuildCookies(CFArrayRef Array)
{ {
Array = CFDictionaryGetValue((CFDictionaryRef)Array[0], CFSTR(kIOHIDElementKey));
InitCookies(50, true); InitCookies(50, true);
memset(m_pCookies, 0, sizeof(*m_pCookies) * 50);
// //
// I wasted two hours of my life on this line :( // I wasted two hours of my life on this line :(
// accidently removed it during some source cleaning... // accidently removed it during some source cleaning...
@ -491,58 +492,76 @@ void wxHIDJoystick::BuildCookies(wxCFArray& Array)
#endif #endif
}//end buildcookies }//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) if (ref != NULL)
{ {
wxCFArray newarray(ref); MakeCookies((CFArrayRef) ref);
MakeCookies(newarray);
} }
else else
{ {
CFNumberGetValue( CFNumberGetValue(
(CFNumberRef) CFDictionaryGetValue((CFDictionaryRef) Array[i], CFSTR(kIOHIDElementUsageKey)), (CFNumberRef)
kCFNumberIntType, &nUsage); CFDictionaryGetValue(
(CFDictionaryRef) CFArrayGetValueAtIndex(Array, i),
CFSTR(kIOHIDElementUsageKey)
),
kCFNumberIntType,
&nUsage );
CFNumberGetValue( CFNumberGetValue(
(CFNumberRef) CFDictionaryGetValue((CFDictionaryRef) Array[i], CFSTR(kIOHIDElementUsagePageKey)), (CFNumberRef)
kCFNumberIntType, &nPage); CFDictionaryGetValue(
(CFDictionaryRef) CFArrayGetValueAtIndex(Array, i),
CFSTR(kIOHIDElementUsagePageKey)
),
kCFNumberIntType,
&nPage );
#if 0 #if 0
wxLogSysError(wxT("[%i][%i]"), nUsage, nPage); wxLogSysError(wxT("[%i][%i]"), nUsage, nPage);
#endif #endif
if (nPage == kHIDPage_Button && nUsage <= 40) if (nPage == kHIDPage_Button && nUsage <= 40)
AddCookieInQueue(Array[i], nUsage-1 ); AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), nUsage-1 );
else if (nPage == kHIDPage_GenericDesktop) else if (nPage == kHIDPage_GenericDesktop)
{ {
//axis... //axis...
switch(nUsage) switch(nUsage)
{ {
case kHIDUsage_GD_X: case kHIDUsage_GD_X:
AddCookieInQueue(Array[i], wxJS_AXIS_X); AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_X);
wxGetIntFromCFDictionary(Array[i], CFSTR(kIOHIDElementMaxKey), wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
CFSTR(kIOHIDElementMaxKey),
&m_nXMax); &m_nXMax);
wxGetIntFromCFDictionary(Array[i], CFSTR(kIOHIDElementMinKey), wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
CFSTR(kIOHIDElementMinKey),
&m_nXMin); &m_nXMin);
break; break;
case kHIDUsage_GD_Y: case kHIDUsage_GD_Y:
AddCookieInQueue(Array[i], wxJS_AXIS_Y); AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_Y);
wxGetIntFromCFDictionary(Array[i], CFSTR(kIOHIDElementMaxKey), wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
CFSTR(kIOHIDElementMaxKey),
&m_nYMax); &m_nYMax);
wxGetIntFromCFDictionary(Array[i], CFSTR(kIOHIDElementMinKey), wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
CFSTR(kIOHIDElementMinKey),
&m_nYMin); &m_nYMin);
break; break;
case kHIDUsage_GD_Z: case kHIDUsage_GD_Z:
AddCookieInQueue(Array[i], wxJS_AXIS_Z); AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_Z);
wxGetIntFromCFDictionary(Array[i], CFSTR(kIOHIDElementMaxKey), wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
CFSTR(kIOHIDElementMaxKey),
&m_nZMax); &m_nZMax);
wxGetIntFromCFDictionary(Array[i], CFSTR(kIOHIDElementMinKey), wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
CFSTR(kIOHIDElementMinKey),
&m_nZMin); &m_nZMin);
break; break;
default: default:
@ -552,10 +571,12 @@ void wxHIDJoystick::MakeCookies(wxCFArray& Array)
else if (nPage == kHIDPage_Simulation && nUsage == kHIDUsage_Sim_Rudder) else if (nPage == kHIDPage_Simulation && nUsage == kHIDUsage_Sim_Rudder)
{ {
//rudder... //rudder...
AddCookieInQueue(Array[i], wxJS_AXIS_RUDDER ); AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_RUDDER );
wxGetIntFromCFDictionary(Array[i], CFSTR(kIOHIDElementMaxKey), wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
CFSTR(kIOHIDElementMaxKey),
&m_nRudderMax); &m_nRudderMax);
wxGetIntFromCFDictionary(Array[i], CFSTR(kIOHIDElementMinKey), wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
CFSTR(kIOHIDElementMinKey),
&m_nRudderMin); &m_nRudderMin);
} }
} }