3 #define wxFORCECHECK_MSG(arg, msg) \
7 wxLogSysError(wxString::Format(wxT("Message:%s\nHID: %s failed!"), wxT(msg), wxT(#arg)));\
11 #define wxIOCHECK(arg, msg) wxFORCECHECK_MSG(arg != kIOReturnSuccess, msg)
12 #define wxKERNCHECK(arg, msg) wxFORCECHECK_MSG(arg != KERN_SUCCESS, msg)
13 #define wxSCHECK(arg, msg) wxFORCECHECK_MSG(arg != S_OK, msg)
15 void CFShowTypeIDDescription(CFTypeRef pData
)
19 wxMessageBox("AHHH!");
24 CFStringGetCStringPtr(
25 CFCopyTypeIDDescription(CFGetTypeID(pData
)),CFStringGetSystemEncoding()
30 // ============================================================================
32 // ============================================================================
35 bool wxHIDDevice::Create (const int& nClass
, const int& nType
)
37 //Create the mach port
38 wxIOCHECK(IOMasterPort(bootstrap_port
, &m_pPort
), "Could not create mach port");
40 //Dictionary that will hold first
41 //the matching dictionary for determining which kind of devices we want,
42 //then later some registry properties from an iterator (see below)
43 CFMutableDictionaryRef pDictionary
;
46 //The call to IOServiceMatching filters down the
47 //the services we want to hid services (and also eats the
48 //dictionary up for us (consumes one reference))
49 wxASSERT((pDictionary
= IOServiceMatching(kIOHIDDeviceKey
)) != NULL
);
51 //Here we'll filter down the services to what we want
54 CFNumberRef pType
= CFNumberCreate(kCFAllocatorDefault
,
55 kCFNumberIntType
, &nType
);
56 CFDictionarySetValue(pDictionary
, CFSTR(kIOHIDPrimaryUsageKey
), pType
);
61 CFNumberRef pClass
= CFNumberCreate(kCFAllocatorDefault
,
62 kCFNumberIntType
, &nClass
);
63 CFDictionarySetValue(pDictionary
, CFSTR(kIOHIDPrimaryUsagePageKey
), pClass
);
67 //Now get the maching services
68 io_iterator_t pIterator
;
69 wxIOCHECK(IOServiceGetMatchingServices(m_pPort
, pDictionary
, &pIterator
), "No Matching HID Services");
70 wxASSERT(pIterator
!= NULL
);
72 //Now we iterate through them
74 while ( (pObject
= IOIteratorNext(pIterator
)) != NULL
)
76 wxASSERT(IORegistryEntryCreateCFProperties(pObject
, &pDictionary
,
77 kCFAllocatorDefault
, kNilOptions
) == KERN_SUCCESS
);
80 wxASSERT(CFGetTypeID(CFDictionaryGetValue(pDictionary
, CFSTR(kIOHIDProductKey
))) == CFStringGetTypeID());
83 m_szName
= CFStringGetCStringPtr (
84 (CFStringRef
) CFDictionaryGetValue(pDictionary
, CFSTR(kIOHIDProductKey
)),
85 CFStringGetSystemEncoding()
89 //Now the hard part - in order to scan things we need "cookies" -
91 wxCFArray CookieArray
= CFDictionaryGetValue(pDictionary
, CFSTR(kIOHIDElementKey
));
92 BuildCookies(CookieArray
);
93 if (m_ppQueue
!= NULL
)
94 wxASSERT((*m_ppQueue
)->start(m_ppQueue
) == S_OK
);
96 //Create the interface (good grief - long function names!)
98 IOCFPlugInInterface
** ppPlugin
;
99 wxIOCHECK(IOCreatePlugInInterfaceForService(pObject
, kIOHIDDeviceUserClientTypeID
,
100 kIOCFPlugInInterfaceID
, &ppPlugin
, &nScore
), "");
102 //Now, the final thing we can check before we fall back to asserts
103 //(because the dtor only checks if the device is ok, so if anything
104 //fails from now on the dtor will delete the device anyway, so we can't break from this).
106 //Get the HID interface from the plugin to the mach port
107 wxSCHECK((*ppPlugin
)->QueryInterface(ppPlugin
,
108 CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID
), (void**) &m_ppDevice
), "");
111 (*ppPlugin
)->Release(ppPlugin
);
113 //open the HID interface...
114 wxASSERT((*m_ppDevice
)->open(m_ppDevice
, 0) == S_OK
);
117 CFRelease(pDictionary
);
118 IOObjectRelease(pObject
);
122 IOObjectRelease(pIterator
);
127 void wxHIDDevice::AddCookie(CFTypeRef Data
, const int& i
)
130 (CFNumberRef
) CFDictionaryGetValue ( (CFDictionaryRef
) Data
131 , CFSTR(kIOHIDElementCookieKey
)
138 void wxHIDDevice::AddCookieInQueue(CFTypeRef Data
, const int& i
)
141 wxASSERT((*m_ppQueue
)->addElement(m_ppQueue
, m_pCookies
[i
], 0) == S_OK
);//3rd Param flags (none yet)
144 void wxHIDDevice::InitCookies(const size_t& dwSize
, bool bQueue
)
146 m_pCookies
= new IOHIDElementCookie
[dwSize
];
149 wxASSERT( m_ppQueue
!= NULL
);
150 wxASSERT( (m_ppQueue
= (*m_ppDevice
)->allocQueue(m_ppDevice
)) != NULL
);
151 wxASSERT( (*m_ppQueue
)->create(m_ppQueue
, 0, 512) == S_OK
); //Param 2, flags, none yet
155 bool wxHIDDevice::IsActive(const int& nIndex
)
157 wxASSERT(m_pCookies
[nIndex
] != NULL
);
158 IOHIDEventStruct Event
;
159 (*m_ppDevice
)->getElementValue(m_ppDevice
, m_pCookies
[nIndex
], &Event
);
160 return !!Event
.value
;
164 wxHIDDevice::~wxHIDDevice()
166 if (m_ppDevice
!= NULL
)
168 (*m_ppDevice
)->close(m_ppDevice
);
169 (*m_ppDevice
)->Release(m_ppDevice
);
170 mach_port_deallocate(mach_task_self(), m_pPort
);
173 if (m_pCookies
!= NULL
)
175 delete [] m_pCookies
;
176 if (m_ppQueue
!= NULL
)
178 (*m_ppQueue
)->stop(m_ppQueue
);
179 (*m_ppQueue
)->dispose(m_ppQueue
);
180 (*m_ppQueue
)->Release(m_ppQueue
);
187 kHIDUsage_KeyboardHyphen = 0x2D,
188 kHIDUsage_KeyboardEqualSign = 0x2E,
189 kHIDUsage_KeyboardOpenBracket = 0x2F,
190 kHIDUsage_KeyboardCloseBracket = 0x30,
191 kHIDUsage_KeyboardBackslash = 0x31, //* \ or | *
192 kHIDUsage_KeyboardNonUSPound = 0x32, /* Non-US # or _ *
193 kHIDUsage_KeyboardSemicolon = 0x33, /* ; or : *
194 kHIDUsage_KeyboardQuote = 0x34, /* ' or " *
195 kHIDUsage_KeyboardGraveAccentAndTilde = 0x35, /* Grave Accent and Tilde *
196 kHIDUsage_KeyboardComma = 0x36, /* , or < *
197 kHIDUsage_KeyboardPeriod = 0x37, /* . or > *
198 kHIDUsage_KeyboardSlash = 0x38, /* / or ? *
199 kHIDUsage_KeyboardCapsLock = 0x39, /* Caps Lock *
201 kHIDUsage_KeyboardPrintScreen = 0x46, /* Print Screen *
202 kHIDUsage_KeyboardScrollLock = 0x47, /* Scroll Lock *
203 kHIDUsage_KeyboardPause = 0x48, /* Pause *
204 kHIDUsage_KeyboardInsert = 0x49, /* Insert *
205 kHIDUsage_KeyboardHome = 0x4A, /* Home *
206 kHIDUsage_KeyboardDeleteForward = 0x4C, /* Delete Forward *
208 kHIDUsage_KeyboardUpArrow
209 kHIDUsage_KeypadNumLock
210 kHIDUsage_KeypadSlash
211 kHIDUsage_KeypadAsterisk
212 kHIDUsage_KeypadHyphen
214 kHIDUsage_KeypadEnter
215 kHIDUsage_KeypadPeriod
216 kHIDUsage_KeyboardNonUSBackslash
217 kHIDUsage_KeyboardApplication
218 kHIDUsage_KeyboardPower
219 kHIDUsage_KeypadEqualSign
236 WXK_PRIOR, * Page up *
237 WXK_NEXT, * Page down *
278 WXK_NUMPAD_SEPARATOR,
299 bool wxHIDKeyboard::Create()
301 return wxHIDDevice::Create(kHIDPage_GenericDesktop
, kHIDUsage_GD_Keyboard
);
304 void wxHIDKeyboard::BuildCookies(wxCFArray
& Array
)
306 Array
= CFDictionaryGetValue((CFDictionaryRef
)Array
[0], CFSTR(kIOHIDElementKey
));
310 for (i
= 0; i
< Array
.Count(); ++i
)
313 (CFNumberRef
) CFDictionaryGetValue((CFDictionaryRef
) Array
[i
], CFSTR(kIOHIDElementUsageKey
)),
314 kCFNumberLongType
, &nUsage
);
316 if (nUsage
>= kHIDUsage_KeyboardA
&& nUsage
<= kHIDUsage_KeyboardZ
)
317 AddCookie(Array
[i
], 'A' + (nUsage
- kHIDUsage_KeyboardA
) );
318 else if (nUsage
>= kHIDUsage_Keyboard1
&& nUsage
<= kHIDUsage_Keyboard9
)
319 AddCookie(Array
[i
], '1' + (nUsage
- kHIDUsage_Keyboard1
) );
320 else if (nUsage
>= kHIDUsage_KeyboardF1
&& nUsage
<= kHIDUsage_KeyboardF12
)
321 AddCookie(Array
[i
], WXK_F1
+ (nUsage
- kHIDUsage_KeyboardF1
) );
322 else if (nUsage
>= kHIDUsage_KeyboardF13
&& nUsage
<= kHIDUsage_KeyboardF24
)
323 AddCookie(Array
[i
], WXK_F13
+ (nUsage
- kHIDUsage_KeyboardF13
) );
324 else if (nUsage
>= kHIDUsage_Keypad1
&& nUsage
<= kHIDUsage_Keypad9
)
325 AddCookie(Array
[i
], WXK_NUMPAD1
+ (nUsage
- kHIDUsage_Keypad1
) );
328 //0's (wx & ascii go 0-9, but HID goes 1-0)
329 case kHIDUsage_Keyboard0
:
330 AddCookie(Array
[i
],'0');
332 case kHIDUsage_Keypad0
:
333 AddCookie(Array
[i
],WXK_NUMPAD0
);
337 case kHIDUsage_KeyboardReturnOrEnter
:
338 AddCookie(Array
[i
], WXK_RETURN
);
340 case kHIDUsage_KeyboardEscape
:
341 AddCookie(Array
[i
], WXK_ESCAPE
);
343 case kHIDUsage_KeyboardDeleteOrBackspace
:
344 AddCookie(Array
[i
], WXK_BACK
);
346 case kHIDUsage_KeyboardTab
:
347 AddCookie(Array
[i
], WXK_TAB
);
349 case kHIDUsage_KeyboardSpacebar
:
350 AddCookie(Array
[i
], WXK_SPACE
);
352 case kHIDUsage_KeyboardPageUp
:
353 AddCookie(Array
[i
], WXK_PRIOR
);
355 case kHIDUsage_KeyboardEnd
:
356 AddCookie(Array
[i
], WXK_END
);
358 case kHIDUsage_KeyboardPageDown
:
359 AddCookie(Array
[i
], WXK_NEXT
);
361 case kHIDUsage_KeyboardRightArrow
:
362 AddCookie(Array
[i
], WXK_RIGHT
);
364 case kHIDUsage_KeyboardLeftArrow
:
365 AddCookie(Array
[i
], WXK_LEFT
);
367 case kHIDUsage_KeyboardDownArrow
:
368 AddCookie(Array
[i
], WXK_DOWN
);
370 case kHIDUsage_KeyboardUpArrow
:
371 AddCookie(Array
[i
], WXK_UP
);
375 case kHIDUsage_KeyboardCapsLock
:
376 AddCookie(Array
[i
],WXK_CAPITAL
);
378 case kHIDUsage_KeypadNumLock
:
379 AddCookie(Array
[i
],WXK_NUMLOCK
);
381 case kHIDUsage_KeyboardScrollLock
:
382 AddCookie(Array
[i
],WXK_SCROLL
);
385 //Menu keys, Shift, other specials
386 case kHIDUsage_KeyboardLeftControl
:
387 AddCookie(Array
[i
],WXK_CONTROL
);
389 case kHIDUsage_KeyboardLeftShift
:
390 AddCookie(Array
[i
],WXK_SHIFT
);
392 case kHIDUsage_KeyboardLeftAlt
:
393 AddCookie(Array
[i
],WXK_ALT
);
395 case kHIDUsage_KeyboardLeftGUI
:
396 AddCookie(Array
[i
],WXK_MENU
);
398 case kHIDUsage_KeyboardRightControl
:
399 AddCookie(Array
[i
],WXK_RCONTROL
);
401 case kHIDUsage_KeyboardRightShift
:
402 AddCookie(Array
[i
],WXK_RSHIFT
);
404 case kHIDUsage_KeyboardRightAlt
:
405 AddCookie(Array
[i
],WXK_RALT
);
407 case kHIDUsage_KeyboardRightGUI
:
408 AddCookie(Array
[i
],WXK_RMENU
);
413 //not in wx keycodes - do nothing....