+++ /dev/null
-#include "hid.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)
- {
- wxMessageBox("AHHH!");
- return;
- }
-
- wxMessageBox(
- CFStringGetCStringPtr(
- CFCopyTypeIDDescription(CFGetTypeID(pData)),CFStringGetSystemEncoding()
- )
- );
-}
-
-// ============================================================================
-// implementation
-// ============================================================================
-
-
-bool wxHIDDevice::Create (const int& nClass, const int& nType)
-{
- //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))
- wxASSERT((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 != NULL);
-
- //Now we iterate through them
- io_object_t pObject;
- while ( (pObject = IOIteratorNext(pIterator)) != NULL)
- {
- wxASSERT(IORegistryEntryCreateCFProperties(pObject, &pDictionary,
- kCFAllocatorDefault, kNilOptions) == KERN_SUCCESS);
-
- //Just for sanity :)
- wxASSERT(CFGetTypeID(CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey))) == CFStringGetTypeID());
-
- //Get [product] name
- m_szName = CFStringGetCStringPtr (
- (CFStringRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey)),
- 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)
- wxASSERT((*m_ppQueue)->start(m_ppQueue) == S_OK);
-
- //Create the interface (good grief - long function names!)
- SInt32 nScore;
- IOCFPlugInInterface** ppPlugin;
- wxIOCHECK(IOCreatePlugInInterfaceForService(pObject, kIOHIDDeviceUserClientTypeID,
- kIOCFPlugInInterfaceID, &ppPlugin, &nScore), "");
-
- //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
- //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
- wxSCHECK((*ppPlugin)->QueryInterface(ppPlugin,
- CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void**) &m_ppDevice), "");
-
- //release the plugin
- (*ppPlugin)->Release(ppPlugin);
-
- //open the HID interface...
- wxASSERT((*m_ppDevice)->open(m_ppDevice, 0) == S_OK);
-
- //cleanup
- CFRelease(pDictionary);
- IOObjectRelease(pObject);
- break;
- }
- //iterator cleanup
- IOObjectRelease(pIterator);
-
- return true;
-}//end Create()
-
-void wxHIDDevice::AddCookie(CFTypeRef Data, const int& i)
-{
- CFNumberGetValue(
- (CFNumberRef) CFDictionaryGetValue ( (CFDictionaryRef) Data
- , CFSTR(kIOHIDElementCookieKey)
- ),
- kCFNumberIntType,
- &m_pCookies[i]
- );
-}
-
-void wxHIDDevice::AddCookieInQueue(CFTypeRef Data, const int& i)
-{
- AddCookie(Data, i);
- wxASSERT((*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)
-{
- m_pCookies = new IOHIDElementCookie[dwSize];
- if (bQueue)
- {
- wxASSERT( m_ppQueue != NULL);
- wxASSERT( (m_ppQueue = (*m_ppDevice)->allocQueue(m_ppDevice)) != NULL);
- wxASSERT( (*m_ppQueue)->create(m_ppQueue, 0, 512) == S_OK); //Param 2, flags, none yet
- }
-}
-
-bool wxHIDDevice::IsActive(const int& nIndex)
-{
- wxASSERT(m_pCookies[nIndex] != NULL);
- IOHIDEventStruct Event;
- (*m_ppDevice)->getElementValue(m_ppDevice, m_pCookies[nIndex], &Event);
- return !!Event.value;
-}
-
-
-wxHIDDevice::~wxHIDDevice()
-{
- if (m_ppDevice != NULL)
- {
- (*m_ppDevice)->close(m_ppDevice);
- (*m_ppDevice)->Release(m_ppDevice);
- mach_port_deallocate(mach_task_self(), m_pPort);
- }
-
- 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);
- }
- }
-}
-/*
-enum
-{
- kHIDUsage_KeyboardHyphen = 0x2D,
- kHIDUsage_KeyboardEqualSign = 0x2E,
- kHIDUsage_KeyboardOpenBracket = 0x2F,
- kHIDUsage_KeyboardCloseBracket = 0x30,
- kHIDUsage_KeyboardBackslash = 0x31, //* \ or | *
- kHIDUsage_KeyboardNonUSPound = 0x32, /* Non-US # or _ *
- kHIDUsage_KeyboardSemicolon = 0x33, /* ; or : *
- kHIDUsage_KeyboardQuote = 0x34, /* ' or " *
- kHIDUsage_KeyboardGraveAccentAndTilde = 0x35, /* Grave Accent and Tilde *
- kHIDUsage_KeyboardComma = 0x36, /* , or < *
- kHIDUsage_KeyboardPeriod = 0x37, /* . or > *
- kHIDUsage_KeyboardSlash = 0x38, /* / or ? *
- kHIDUsage_KeyboardCapsLock = 0x39, /* Caps Lock *
-
- kHIDUsage_KeyboardPrintScreen = 0x46, /* Print Screen *
- kHIDUsage_KeyboardScrollLock = 0x47, /* Scroll Lock *
- kHIDUsage_KeyboardPause = 0x48, /* Pause *
- kHIDUsage_KeyboardInsert = 0x49, /* Insert *
- kHIDUsage_KeyboardHome = 0x4A, /* Home *
- kHIDUsage_KeyboardDeleteForward = 0x4C, /* Delete Forward *
-
- kHIDUsage_KeyboardUpArrow
- kHIDUsage_KeypadNumLock
- kHIDUsage_KeypadSlash
- kHIDUsage_KeypadAsterisk
- kHIDUsage_KeypadHyphen
- kHIDUsage_KeypadPlus
- kHIDUsage_KeypadEnter
- kHIDUsage_KeypadPeriod
- kHIDUsage_KeyboardNonUSBackslash
- kHIDUsage_KeyboardApplication
- kHIDUsage_KeyboardPower
- kHIDUsage_KeypadEqualSign
-};
-/*
- enum wxKeyCode
- {
-
- WXK_START = 300,
- WXK_LBUTTON,
- WXK_RBUTTON,
- WXK_CANCEL,
- WXK_MBUTTON,
- WXK_CLEAR,
- WXK_SHIFT,
- WXK_ALT,
- WXK_CONTROL,
- WXK_MENU,
- WXK_PAUSE,
- WXK_PRIOR, * Page up *
- WXK_NEXT, * Page down *
- WXK_END,
- WXK_HOME,
- WXK_LEFT,
- WXK_UP,
- WXK_RIGHT,
- WXK_DOWN,
- WXK_SELECT,
- WXK_PRINT,
- WXK_EXECUTE,
- WXK_SNAPSHOT,
- WXK_INSERT,
- WXK_HELP,
- WXK_MULTIPLY,
- WXK_ADD,
- WXK_SEPARATOR,
- WXK_SUBTRACT,
- WXK_DECIMAL,
- WXK_DIVIDE,
- WXK_PAGEUP,
- WXK_PAGEDOWN,
-
- WXK_NUMPAD_SPACE,
- WXK_NUMPAD_TAB,
- WXK_NUMPAD_ENTER,
- WXK_NUMPAD_HOME,
- WXK_NUMPAD_LEFT,
- WXK_NUMPAD_UP,
- WXK_NUMPAD_RIGHT,
- WXK_NUMPAD_DOWN,
- WXK_NUMPAD_PRIOR,
- WXK_NUMPAD_PAGEUP,
- WXK_NUMPAD_NEXT,
- WXK_NUMPAD_PAGEDOWN,
- WXK_NUMPAD_END,
- WXK_NUMPAD_BEGIN,
- WXK_NUMPAD_INSERT,
- WXK_NUMPAD_DELETE,
- WXK_NUMPAD_EQUAL,
- WXK_NUMPAD_MULTIPLY,
- WXK_NUMPAD_ADD,
- WXK_NUMPAD_SEPARATOR,
- WXK_NUMPAD_SUBTRACT,
- WXK_NUMPAD_DECIMAL,
- WXK_NUMPAD_DIVIDE,
-
- WXK_WINDOWS_LEFT,
- WXK_WINDOWS_RIGHT,
- WXK_WINDOWS_MENU ,
- WXK_COMMAND
- };
-
- */
-enum
-{
- WXK_RSHIFT = 400,
- WXK_RALT,
- WXK_RCONTROL,
- WXK_RMENU
-
-};
-
-bool wxHIDKeyboard::Create()
-{
- return wxHIDDevice::Create(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard);
-}
-
-void wxHIDKeyboard::BuildCookies(wxCFArray& Array)
-{
- Array = CFDictionaryGetValue((CFDictionaryRef)Array[0], CFSTR(kIOHIDElementKey));
- InitCookies(500);
- int i,
- nUsage;
- for (i = 0; i < Array.Count(); ++i)
- {
- CFNumberGetValue(
- (CFNumberRef) CFDictionaryGetValue((CFDictionaryRef) Array[i], CFSTR(kIOHIDElementUsageKey)),
- kCFNumberLongType, &nUsage);
-
- if (nUsage >= kHIDUsage_KeyboardA && nUsage <= kHIDUsage_KeyboardZ)
- AddCookie(Array[i], 'A' + (nUsage - kHIDUsage_KeyboardA) );
- else if (nUsage >= kHIDUsage_Keyboard1 && nUsage <= kHIDUsage_Keyboard9)
- AddCookie(Array[i], '1' + (nUsage - kHIDUsage_Keyboard1) );
- else if (nUsage >= kHIDUsage_KeyboardF1 && nUsage <= kHIDUsage_KeyboardF12)
- AddCookie(Array[i], WXK_F1 + (nUsage - kHIDUsage_KeyboardF1) );
- else if (nUsage >= kHIDUsage_KeyboardF13 && nUsage <= kHIDUsage_KeyboardF24)
- AddCookie(Array[i], WXK_F13 + (nUsage - kHIDUsage_KeyboardF13) );
- else if (nUsage >= kHIDUsage_Keypad1 && nUsage <= kHIDUsage_Keypad9)
- AddCookie(Array[i], WXK_NUMPAD1 + (nUsage - kHIDUsage_Keypad1) );
- else switch (nUsage)
- {
- //0's (wx & ascii go 0-9, but HID goes 1-0)
- case kHIDUsage_Keyboard0:
- AddCookie(Array[i],'0');
- break;
- case kHIDUsage_Keypad0:
- AddCookie(Array[i],WXK_NUMPAD0);
- break;
-
- //Basic
- case kHIDUsage_KeyboardReturnOrEnter:
- AddCookie(Array[i], WXK_RETURN);
- break;
- case kHIDUsage_KeyboardEscape:
- AddCookie(Array[i], WXK_ESCAPE);
- break;
- case kHIDUsage_KeyboardDeleteOrBackspace:
- AddCookie(Array[i], WXK_BACK);
- break;
- case kHIDUsage_KeyboardTab:
- AddCookie(Array[i], WXK_TAB);
- break;
- case kHIDUsage_KeyboardSpacebar:
- AddCookie(Array[i], WXK_SPACE);
- break;
- case kHIDUsage_KeyboardPageUp:
- AddCookie(Array[i], WXK_PRIOR);
- break;
- case kHIDUsage_KeyboardEnd:
- AddCookie(Array[i], WXK_END);
- break;
- case kHIDUsage_KeyboardPageDown:
- AddCookie(Array[i], WXK_NEXT);
- break;
- case kHIDUsage_KeyboardRightArrow:
- AddCookie(Array[i], WXK_RIGHT);
- break;
- case kHIDUsage_KeyboardLeftArrow:
- AddCookie(Array[i], WXK_LEFT);
- break;
- case kHIDUsage_KeyboardDownArrow:
- AddCookie(Array[i], WXK_DOWN);
- break;
- case kHIDUsage_KeyboardUpArrow:
- AddCookie(Array[i], WXK_UP);
- break;
-
- //LEDS
- case kHIDUsage_KeyboardCapsLock:
- AddCookie(Array[i],WXK_CAPITAL);
- break;
- case kHIDUsage_KeypadNumLock:
- AddCookie(Array[i],WXK_NUMLOCK);
- break;
- case kHIDUsage_KeyboardScrollLock:
- AddCookie(Array[i],WXK_SCROLL);
- break;
-
- //Menu keys, Shift, other specials
- case kHIDUsage_KeyboardLeftControl:
- AddCookie(Array[i],WXK_CONTROL);
- break;
- case kHIDUsage_KeyboardLeftShift:
- AddCookie(Array[i],WXK_SHIFT);
- break;
- case kHIDUsage_KeyboardLeftAlt:
- AddCookie(Array[i],WXK_ALT);
- break;
- case kHIDUsage_KeyboardLeftGUI:
- AddCookie(Array[i],WXK_MENU);
- break;
- case kHIDUsage_KeyboardRightControl:
- AddCookie(Array[i],WXK_RCONTROL);
- break;
- case kHIDUsage_KeyboardRightShift:
- AddCookie(Array[i],WXK_RSHIFT);
- break;
- case kHIDUsage_KeyboardRightAlt:
- AddCookie(Array[i],WXK_RALT);
- break;
- case kHIDUsage_KeyboardRightGUI:
- AddCookie(Array[i],WXK_RMENU);
- break;
-
- //Default
- default:
- //not in wx keycodes - do nothing....
- break;
- }
- }
-}//end buildcookies