]> git.saurik.com Git - wxWidgets.git/blame - src/mac/corefoundation/hid.cpp
applying patch 1411230
[wxWidgets.git] / src / mac / corefoundation / hid.cpp
CommitLineData
ec8bd392 1/////////////////////////////////////////////////////////////////////////////
3b38e2a0 2// Name: src/mac/corefoundation/hid.cpp
ec8bd392
RN
3// Purpose: DARWIN HID layer for WX Implementation
4// Author: Ryan Norton
5// Modified by:
6// Created: 11/11/2003
7// RCS-ID: $Id$
8// Copyright: (c) Ryan Norton
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
1553abf4
RN
12// ===========================================================================
13// declarations
14// ===========================================================================
15
16// ---------------------------------------------------------------------------
17// headers
18// ---------------------------------------------------------------------------
19
1553abf4
RN
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
ec8bd392
RN
27//DARWIN _ONLY_
28#ifdef __DARWIN__
29
4cb1d3da 30#include "wx/mac/corefoundation/hid.h"
ec8bd392
RN
31#include "wx/string.h"
32#include "wx/log.h"
65442ab6 33#include "wx/mac/corefoundation/cfstring.h"
7f71c4c8 34
32efab35
SC
35#include "wx/utils.h"
36#include "wx/module.h"
37#include "wx/dynarray.h"
7f71c4c8
RN
38
39// ============================================================================
40// implementation
41// ============================================================================
42
32efab35
SC
43// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
44//
1553abf4 45// wxHIDDevice
32efab35
SC
46//
47// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7f71c4c8 48
32efab35
SC
49// ----------------------------------------------------------------------------
50// wxHIDDevice::Create
51//
52// nClass is the HID Page such as
53// kHIDPage_GenericDesktop
54// nType is the HID Usage such as
55// kHIDUsage_GD_Joystick,kHIDUsage_GD_Mouse,kHIDUsage_GD_Keyboard
56// nDev is the device number to use
57//
58// ----------------------------------------------------------------------------
4cb1d3da 59bool wxHIDDevice::Create (int nClass, int nType, int nDev)
7f71c4c8 60{
26dfc728 61 //Create the mach port
32efab35
SC
62 if(IOMasterPort(bootstrap_port, &m_pPort) != kIOReturnSuccess)
63 {
64 wxLogSysError(wxT("Could not create mach port"));
65 return false;
66 }
26dfc728
VZ
67
68 //Dictionary that will hold first
69 //the matching dictionary for determining which kind of devices we want,
70 //then later some registry properties from an iterator (see below)
a8ee8060 71 //
26dfc728
VZ
72 //The call to IOServiceMatching filters down the
73 //the services we want to hid services (and also eats the
74 //dictionary up for us (consumes one reference))
a8ee8060 75 CFMutableDictionaryRef pDictionary = IOServiceMatching(kIOHIDDeviceKey);
32efab35
SC
76 if(pDictionary == NULL)
77 {
78 wxLogSysError( _T("IOServiceMatching(kIOHIDDeviceKey) failed") );
79 return false;
80 }
26dfc728
VZ
81
82 //Here we'll filter down the services to what we want
83 if (nType != -1)
84 {
85 CFNumberRef pType = CFNumberCreate(kCFAllocatorDefault,
86 kCFNumberIntType, &nType);
87 CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsageKey), pType);
88 CFRelease(pType);
89 }
90 if (nClass != -1)
91 {
92 CFNumberRef pClass = CFNumberCreate(kCFAllocatorDefault,
93 kCFNumberIntType, &nClass);
94 CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsagePageKey), pClass);
95 CFRelease(pClass);
96 }
97
98 //Now get the maching services
99 io_iterator_t pIterator;
32efab35
SC
100 if( IOServiceGetMatchingServices(m_pPort,
101 pDictionary, &pIterator) != kIOReturnSuccess )
102 {
103 wxLogSysError(_T("No Matching HID Services"));
104 return false;
105 }
106
107 //Were there any devices matched?
ce0d1032
SC
108 if(pIterator == 0)
109 return false; // No devices found
26dfc728
VZ
110
111 //Now we iterate through them
112 io_object_t pObject;
113 while ( (pObject = IOIteratorNext(pIterator)) != 0)
114 {
4cb1d3da 115 if(--nDev != 0)
32efab35
SC
116 {
117 IOObjectRelease(pObject);
4cb1d3da 118 continue;
32efab35 119 }
7f71c4c8 120
a8ee8060
VZ
121 if ( IORegistryEntryCreateCFProperties
122 (
123 pObject,
124 &pDictionary,
125 kCFAllocatorDefault,
126 kNilOptions
127 ) != KERN_SUCCESS )
128 {
129 wxLogDebug(_T("IORegistryEntryCreateCFProperties failed"));
130 }
26dfc728 131
32efab35
SC
132 //
133 // Now we get the attributes of each "product" in the iterator
134 //
26dfc728 135
32efab35
SC
136 //Get [product] name
137 CFStringRef cfsProduct = (CFStringRef)
138 CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey));
139 m_szProductName =
140 wxMacCFStringHolder( cfsProduct,
141 false
142 ).AsString();
143
144 //Get the Product ID Key
145 CFNumberRef cfnProductId = (CFNumberRef)
146 CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductIDKey));
147 if (cfnProductId)
148 {
149 CFNumberGetValue(cfnProductId, kCFNumberIntType, &m_nProductId);
150 }
26dfc728 151
32efab35
SC
152 //Get the Vendor ID Key
153 CFNumberRef cfnVendorId = (CFNumberRef)
154 CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDVendorIDKey));
155 if (cfnVendorId)
156 {
157 CFNumberGetValue(cfnVendorId, kCFNumberIntType, &m_nManufacturerId);
158 }
65442ab6 159
32efab35
SC
160 //
161 // End attribute getting
162 //
26dfc728
VZ
163
164 //Create the interface (good grief - long function names!)
165 SInt32 nScore;
166 IOCFPlugInInterface** ppPlugin;
32efab35
SC
167 if(IOCreatePlugInInterfaceForService(pObject,
168 kIOHIDDeviceUserClientTypeID,
169 kIOCFPlugInInterfaceID, &ppPlugin,
170 &nScore) != kIOReturnSuccess)
171 {
172 wxLogSysError(wxT("Could not create HID Interface for product"));
173 return false;
174 }
26dfc728
VZ
175
176 //Now, the final thing we can check before we fall back to asserts
177 //(because the dtor only checks if the device is ok, so if anything
178 //fails from now on the dtor will delete the device anyway, so we can't break from this).
179
180 //Get the HID interface from the plugin to the mach port
32efab35
SC
181 if((*ppPlugin)->QueryInterface(ppPlugin,
182 CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID),
183 (void**) &m_ppDevice) != S_OK)
184 {
185 wxLogSysError(wxT("Could not get device interface from HID interface"));
186 return false;
187 }
26dfc728
VZ
188
189 //release the plugin
190 (*ppPlugin)->Release(ppPlugin);
191
192 //open the HID interface...
a8ee8060
VZ
193 if ( (*m_ppDevice)->open(m_ppDevice, 0) != S_OK )
194 wxLogDebug(_T("HID device: open failed"));
26dfc728
VZ
195
196 //
32efab35 197 //Now the hard part - in order to scan things we need "cookies"
26dfc728 198 //
32efab35
SC
199 CFArrayRef cfaCookies = (CFArrayRef)CFDictionaryGetValue(pDictionary,
200 CFSTR(kIOHIDElementKey));
201 BuildCookies(cfaCookies);
202
26dfc728
VZ
203 //cleanup
204 CFRelease(pDictionary);
205 IOObjectRelease(pObject);
32efab35
SC
206
207 //iterator cleanup
208 IOObjectRelease(pIterator);
209
210 return true;
26dfc728 211 }
32efab35 212
26dfc728
VZ
213 //iterator cleanup
214 IOObjectRelease(pIterator);
215
32efab35 216 return false; //no device
7f71c4c8 217}//end Create()
26dfc728 218
32efab35
SC
219// ----------------------------------------------------------------------------
220// wxHIDDevice::GetCount [static]
221//
222// Obtains the number of devices on a system for a given HID Page (nClass)
223// and HID Usage (nType).
224// ----------------------------------------------------------------------------
3b38e2a0 225size_t wxHIDDevice::GetCount (int nClass, int nType)
4cb1d3da 226{
26dfc728 227 //Create the mach port
32efab35
SC
228 mach_port_t pPort;
229 if(IOMasterPort(bootstrap_port, &pPort) != kIOReturnSuccess)
230 {
231 wxLogSysError(wxT("Could not create mach port"));
232 return false;
233 }
234
26dfc728
VZ
235 //Dictionary that will hold first
236 //the matching dictionary for determining which kind of devices we want,
237 //then later some registry properties from an iterator (see below)
a8ee8060 238 CFMutableDictionaryRef pDictionary = IOServiceMatching(kIOHIDDeviceKey);
32efab35
SC
239 if(pDictionary == NULL)
240 {
241 wxLogSysError( _T("IOServiceMatching(kIOHIDDeviceKey) failed") );
242 return false;
243 }
26dfc728
VZ
244
245 //Here we'll filter down the services to what we want
246 if (nType != -1)
247 {
248 CFNumberRef pType = CFNumberCreate(kCFAllocatorDefault,
249 kCFNumberIntType, &nType);
250 CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsageKey), pType);
251 CFRelease(pType);
252 }
253 if (nClass != -1)
254 {
255 CFNumberRef pClass = CFNumberCreate(kCFAllocatorDefault,
256 kCFNumberIntType, &nClass);
257 CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsagePageKey), pClass);
258 CFRelease(pClass);
259 }
260
261 //Now get the maching services
262 io_iterator_t pIterator;
32efab35
SC
263 if( IOServiceGetMatchingServices(pPort,
264 pDictionary, &pIterator) != kIOReturnSuccess )
265 {
266 wxLogSysError(_T("No Matching HID Services"));
267 return false;
268 }
269
270 //If the iterator doesn't exist there are no devices :)
a8ee8060 271 if ( !pIterator )
65442ab6 272 return 0;
4cb1d3da 273
26dfc728 274 //Now we iterate through them
3b38e2a0 275 size_t nCount = 0;
32efab35 276 io_object_t pObject;
26dfc728 277 while ( (pObject = IOIteratorNext(pIterator)) != 0)
32efab35 278 {
4cb1d3da 279 ++nCount;
32efab35
SC
280 IOObjectRelease(pObject);
281 }
282
283 //cleanup
26dfc728 284 IOObjectRelease(pIterator);
32efab35
SC
285 mach_port_deallocate(mach_task_self(), pPort);
286
26dfc728 287 return nCount;
4cb1d3da
RN
288}//end Create()
289
32efab35
SC
290// ----------------------------------------------------------------------------
291// wxHIDDevice::AddCookie
292//
293// Adds a cookie to the internal cookie array from a CFType
294// ----------------------------------------------------------------------------
4cb1d3da 295void wxHIDDevice::AddCookie(CFTypeRef Data, int i)
7f71c4c8 296{
26dfc728
VZ
297 CFNumberGetValue(
298 (CFNumberRef) CFDictionaryGetValue ( (CFDictionaryRef) Data
299 , CFSTR(kIOHIDElementCookieKey)
300 ),
301 kCFNumberIntType,
302 &m_pCookies[i]
303 );
7f71c4c8
RN
304}
305
32efab35
SC
306// ----------------------------------------------------------------------------
307// wxHIDDevice::AddCookieInQueue
308//
309// Adds a cookie to the internal cookie array from a CFType and additionally
310// adds it to the internal HID Queue
311// ----------------------------------------------------------------------------
4cb1d3da 312void wxHIDDevice::AddCookieInQueue(CFTypeRef Data, int i)
7f71c4c8 313{
a8ee8060 314 //3rd Param flags (none yet)
26dfc728 315 AddCookie(Data, i);
a8ee8060
VZ
316 if ( (*m_ppQueue)->addElement(m_ppQueue, m_pCookies[i], 0) != S_OK )
317 wxLogDebug(_T("HID device: adding element failed"));
7f71c4c8 318}
26dfc728 319
32efab35
SC
320// ----------------------------------------------------------------------------
321// wxHIDDevice::InitCookies
322//
323// Create the internal cookie array, optionally creating a HID Queue
324// ----------------------------------------------------------------------------
4cb1d3da 325void wxHIDDevice::InitCookies(size_t dwSize, bool bQueue)
7f71c4c8 326{
26dfc728
VZ
327 m_pCookies = new IOHIDElementCookie[dwSize];
328 if (bQueue)
329 {
330 wxASSERT( m_ppQueue == NULL);
a8ee8060
VZ
331 m_ppQueue = (*m_ppDevice)->allocQueue(m_ppDevice);
332 if ( !m_ppQueue )
333 {
334 wxLogDebug(_T("HID device: allocQueue failed"));
335 return;
336 }
337
338 //Param 2, flags, none yet
339 if ( (*m_ppQueue)->create(m_ppQueue, 0, 512) != S_OK )
340 {
341 wxLogDebug(_T("HID device: create failed"));
342 }
26dfc728 343 }
32efab35
SC
344
345 //make sure that cookie array is clear
346 memset(m_pCookies, 0, sizeof(*m_pCookies) * dwSize);
7f71c4c8
RN
347}
348
32efab35
SC
349// ----------------------------------------------------------------------------
350// wxHIDDevice::IsActive
351//
352// Returns true if a cookie of the device is active - for example if a key is
353// held down, joystick button pressed, caps lock active, etc..
354// ----------------------------------------------------------------------------
4cb1d3da 355bool wxHIDDevice::IsActive(int nIndex)
7f71c4c8 356{
32efab35
SC
357 if(!HasElement(nIndex))
358 {
359 //cookie at index does not exist - getElementValue
360 //could return true which would be incorrect so we
361 //check here
362 return false;
363 }
364
26dfc728
VZ
365 IOHIDEventStruct Event;
366 (*m_ppDevice)->getElementValue(m_ppDevice, m_pCookies[nIndex], &Event);
26dfc728 367 return !!Event.value;
7f71c4c8 368}
26dfc728 369
32efab35
SC
370// ----------------------------------------------------------------------------
371// wxHIDDevice::HasElement
372//
373// Returns true if the element in the internal cookie array exists
374// ----------------------------------------------------------------------------
4cb1d3da
RN
375bool wxHIDDevice::HasElement(int nIndex)
376{
377 return m_pCookies[nIndex] != NULL;
378}
7f71c4c8 379
32efab35
SC
380// ----------------------------------------------------------------------------
381// wxHIDDevice Destructor
382//
383// Frees all memory and objects from the structure
384// ----------------------------------------------------------------------------
7f71c4c8
RN
385wxHIDDevice::~wxHIDDevice()
386{
26dfc728
VZ
387 if (m_ppDevice != NULL)
388 {
389 if (m_ppQueue != NULL)
390 {
391 (*m_ppQueue)->stop(m_ppQueue);
392 (*m_ppQueue)->dispose(m_ppQueue);
393 (*m_ppQueue)->Release(m_ppQueue);
394 }
395 (*m_ppDevice)->close(m_ppDevice);
396 (*m_ppDevice)->Release(m_ppDevice);
397 mach_port_deallocate(mach_task_self(), m_pPort);
398 }
399
400 if (m_pCookies != NULL)
401 {
402 delete [] m_pCookies;
403 }
7f71c4c8 404}
7f71c4c8 405
32efab35
SC
406// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
407//
1553abf4 408// wxHIDKeyboard
32efab35
SC
409//
410// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1553abf4 411
32efab35
SC
412//There are no right shift, alt etc. in the wx headers yet so just sort
413//of "define our own" for now
7f71c4c8
RN
414enum
415{
26dfc728
VZ
416 WXK_RSHIFT = 400,
417 WXK_RALT,
418 WXK_RCONTROL,
419 WXK_RMENU
7f71c4c8
RN
420};
421
32efab35
SC
422// ----------------------------------------------------------------------------
423// wxHIDKeyboard::GetCount [static]
424//
425// Get number of HID keyboards available
426// ----------------------------------------------------------------------------
427int wxHIDKeyboard::GetCount()
428{
429 return wxHIDDevice::GetCount(kHIDPage_GenericDesktop,
430 kHIDUsage_GD_Keyboard);
431}
432
433// ----------------------------------------------------------------------------
434// wxHIDKeyboard::Create
435//
436// Create the HID Keyboard
437// ----------------------------------------------------------------------------
438bool wxHIDKeyboard::Create(int nDev /* = 1*/)
439{
440 return wxHIDDevice::Create(kHIDPage_GenericDesktop,
441 kHIDUsage_GD_Keyboard,
442 nDev);
443}
444
445// ----------------------------------------------------------------------------
446// wxHIDKeyboard::AddCookie
447//
448// Overloaded version of wxHIDDevice::AddCookie that simply does not
449// add a cookie if a duplicate is found
450// ----------------------------------------------------------------------------
451void wxHIDKeyboard::AddCookie(CFTypeRef Data, int i)
7f71c4c8 452{
32efab35
SC
453 if(!HasElement(i))
454 wxHIDDevice::AddCookie(Data, i);
7f71c4c8
RN
455}
456
32efab35
SC
457// ----------------------------------------------------------------------------
458// wxHIDKeyboard::BuildCookies
459//
460// Callback from Create() to build the HID cookies for the internal cookie
461// array
462// ----------------------------------------------------------------------------
463void wxHIDKeyboard::BuildCookies(CFArrayRef Array)
7f71c4c8 464{
32efab35 465 //Create internal cookie array
26dfc728 466 InitCookies(500);
32efab35
SC
467
468 //Begin recursing in array
469 DoBuildCookies(Array);
470}
471
472void wxHIDKeyboard::DoBuildCookies(CFArrayRef Array)
473{
474 //Now go through each possible cookie
26dfc728
VZ
475 int i,
476 nUsage;
32efab35
SC
477// bool bEOTriggered = false;
478 for (i = 0; i < CFArrayGetCount(Array); ++i)
479 {
480 const void* ref = CFDictionaryGetValue(
481 (CFDictionaryRef)CFArrayGetValueAtIndex(Array, i),
482 CFSTR(kIOHIDElementKey)
483 );
484
485 if (ref != NULL)
486 {
487 DoBuildCookies((CFArrayRef) ref);
488 }
489 else
26dfc728 490 {
32efab35
SC
491
492 //
493 // Get the usage #
494 //
26dfc728 495 CFNumberGetValue(
32efab35
SC
496 (CFNumberRef)
497 CFDictionaryGetValue((CFDictionaryRef)
498 CFArrayGetValueAtIndex(Array, i),
499 CFSTR(kIOHIDElementUsageKey)
500 ),
501 kCFNumberLongType,
502 &nUsage);
503
504 //
505 // Now translate the usage # into a wx keycode
506 //
26dfc728 507
09d27083 508 //
26dfc728 509 // OK, this is strange - basically this kind of strange -
09d27083
RN
510 // Starting from 0xEO these elements (like shift) appear twice in
511 // the array! The ones at the end are bogus I guess - the funny part
512 // is that besides the fact that the ones at the front have a Unit
513 // and UnitExponent key with a value of 0 and a different cookie value,
26dfc728 514 // there is no discernable difference between the two...
09d27083
RN
515 //
516 // Will the real shift please stand up?
517 //
518 // Something to spend a support request on, if I had one, LOL.
519 //
32efab35
SC
520 //if(nUsage == 0xE0)
521 //{
522 // if(bEOTriggered)
523 // break;
524 // bEOTriggered = true;
525 //}
526 //Instead of that though we now just don't add duplicate keys
527
26dfc728 528 if (nUsage >= kHIDUsage_KeyboardA && nUsage <= kHIDUsage_KeyboardZ)
32efab35 529 AddCookie(CFArrayGetValueAtIndex(Array, i), 'A' + (nUsage - kHIDUsage_KeyboardA) );
26dfc728 530 else if (nUsage >= kHIDUsage_Keyboard1 && nUsage <= kHIDUsage_Keyboard9)
32efab35 531 AddCookie(CFArrayGetValueAtIndex(Array, i), '1' + (nUsage - kHIDUsage_Keyboard1) );
26dfc728 532 else if (nUsage >= kHIDUsage_KeyboardF1 && nUsage <= kHIDUsage_KeyboardF12)
32efab35 533 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_F1 + (nUsage - kHIDUsage_KeyboardF1) );
26dfc728 534 else if (nUsage >= kHIDUsage_KeyboardF13 && nUsage <= kHIDUsage_KeyboardF24)
32efab35 535 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_F13 + (nUsage - kHIDUsage_KeyboardF13) );
26dfc728 536 else if (nUsage >= kHIDUsage_Keypad1 && nUsage <= kHIDUsage_Keypad9)
32efab35 537 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_NUMPAD1 + (nUsage - kHIDUsage_Keypad1) );
26dfc728
VZ
538 else switch (nUsage)
539 {
540 //0's (wx & ascii go 0-9, but HID goes 1-0)
541 case kHIDUsage_Keyboard0:
32efab35 542 AddCookie(CFArrayGetValueAtIndex(Array, i), '0');
26dfc728
VZ
543 break;
544 case kHIDUsage_Keypad0:
32efab35 545 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_NUMPAD0);
26dfc728
VZ
546 break;
547
548 //Basic
549 case kHIDUsage_KeyboardReturnOrEnter:
32efab35 550 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_RETURN);
26dfc728
VZ
551 break;
552 case kHIDUsage_KeyboardEscape:
32efab35 553 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_ESCAPE);
26dfc728
VZ
554 break;
555 case kHIDUsage_KeyboardDeleteOrBackspace:
32efab35 556 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_BACK);
26dfc728
VZ
557 break;
558 case kHIDUsage_KeyboardTab:
32efab35 559 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_TAB);
26dfc728
VZ
560 break;
561 case kHIDUsage_KeyboardSpacebar:
32efab35 562 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_SPACE);
26dfc728
VZ
563 break;
564 case kHIDUsage_KeyboardPageUp:
32efab35 565 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_PAGEUP);
26dfc728
VZ
566 break;
567 case kHIDUsage_KeyboardEnd:
32efab35 568 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_END);
26dfc728
VZ
569 break;
570 case kHIDUsage_KeyboardPageDown:
32efab35 571 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_PAGEDOWN);
26dfc728
VZ
572 break;
573 case kHIDUsage_KeyboardRightArrow:
32efab35 574 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_RIGHT);
26dfc728
VZ
575 break;
576 case kHIDUsage_KeyboardLeftArrow:
32efab35 577 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_LEFT);
26dfc728
VZ
578 break;
579 case kHIDUsage_KeyboardDownArrow:
32efab35 580 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_DOWN);
26dfc728
VZ
581 break;
582 case kHIDUsage_KeyboardUpArrow:
32efab35 583 AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_UP);
26dfc728
VZ
584 break;
585
586 //LEDS
587 case kHIDUsage_KeyboardCapsLock:
32efab35 588 AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_CAPITAL);
26dfc728
VZ
589 break;
590 case kHIDUsage_KeypadNumLock:
32efab35 591 AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_NUMLOCK);
26dfc728
VZ
592 break;
593 case kHIDUsage_KeyboardScrollLock:
32efab35 594 AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_SCROLL);
26dfc728
VZ
595 break;
596
597 //Menu keys, Shift, other specials
598 case kHIDUsage_KeyboardLeftControl:
32efab35 599 AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_CONTROL);
26dfc728
VZ
600 break;
601 case kHIDUsage_KeyboardLeftShift:
32efab35 602 AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_SHIFT);
26dfc728
VZ
603 break;
604 case kHIDUsage_KeyboardLeftAlt:
32efab35 605 AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_ALT);
26dfc728
VZ
606 break;
607 case kHIDUsage_KeyboardLeftGUI:
32efab35 608 AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_MENU);
26dfc728
VZ
609 break;
610 case kHIDUsage_KeyboardRightControl:
32efab35 611 AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_RCONTROL);
26dfc728
VZ
612 break;
613 case kHIDUsage_KeyboardRightShift:
32efab35 614 AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_RSHIFT);
26dfc728
VZ
615 break;
616 case kHIDUsage_KeyboardRightAlt:
32efab35 617 AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_RALT);
26dfc728
VZ
618 break;
619 case kHIDUsage_KeyboardRightGUI:
32efab35 620 AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_RMENU);
26dfc728
VZ
621 break;
622
623 //Default
624 default:
625 //not in wx keycodes - do nothing....
626 break;
32efab35
SC
627 } //end mightly long switch
628 } //end if the current element is not an array...
629 } //end for loop for Array
7f71c4c8 630}//end buildcookies
ec8bd392 631
32efab35 632// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4cb1d3da 633//
32efab35 634// wxHIDModule
4cb1d3da 635//
32efab35 636// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4cb1d3da
RN
637
638class wxHIDModule : public wxModule
639{
640 DECLARE_DYNAMIC_CLASS(wxHIDModule)
26dfc728 641
4cb1d3da 642 public:
32efab35 643 static wxArrayPtrVoid sm_keyboards;
4cb1d3da
RN
644 virtual bool OnInit()
645 {
4cb1d3da
RN
646 return true;
647 }
648 virtual void OnExit()
649 {
32efab35
SC
650 for(size_t i = 0; i < sm_keyboards.GetCount(); ++i)
651 delete (wxHIDKeyboard*) sm_keyboards[i];
4cb1d3da
RN
652 }
653};
654
655IMPLEMENT_DYNAMIC_CLASS(wxHIDModule, wxModule)
656
32efab35
SC
657wxArrayPtrVoid wxHIDModule::sm_keyboards;
658
659// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
660//
661// wxGetKeyState()
662//
663// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4cb1d3da
RN
664
665bool wxGetKeyState (wxKeyCode key)
666{
44353523
VZ
667 wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
668 WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons"));
669
32efab35 670 if (wxHIDModule::sm_keyboards.GetCount() == 0)
4cb1d3da 671 {
32efab35
SC
672 int nKeyboards = wxHIDKeyboard::GetCount();
673
674 for(int i = 1; i <= nKeyboards; ++i)
4cb1d3da 675 {
32efab35
SC
676 wxHIDKeyboard* keyboard = new wxHIDKeyboard();
677 if(keyboard->Create(i))
678 {
679 wxHIDModule::sm_keyboards.Add(keyboard);
680 }
681 else
682 {
683 delete keyboard;
684 break;
685 }
4cb1d3da 686 }
32efab35
SC
687
688 wxASSERT_MSG(wxHIDModule::sm_keyboards.GetCount() != 0,
689 wxT("No keyboards found!"));
4cb1d3da 690 }
26dfc728 691
32efab35
SC
692 for(size_t i = 0; i < wxHIDModule::sm_keyboards.GetCount(); ++i)
693 {
694 wxHIDKeyboard* keyboard = (wxHIDKeyboard*)
695 wxHIDModule::sm_keyboards[i];
696
09d27083
RN
697 switch(key)
698 {
699 case WXK_SHIFT:
32efab35
SC
700 if( keyboard->IsActive(WXK_SHIFT) ||
701 keyboard->IsActive(WXK_RSHIFT) )
702 {
703 return true;
704 }
09d27083 705 break;
26dfc728 706 case WXK_ALT:
32efab35
SC
707 if( keyboard->IsActive(WXK_ALT) ||
708 keyboard->IsActive(WXK_RALT) )
709 {
710 return true;
711 }
09d27083 712 break;
26dfc728 713 case WXK_CONTROL:
32efab35
SC
714 if( keyboard->IsActive(WXK_CONTROL) ||
715 keyboard->IsActive(WXK_RCONTROL) )
716 {
717 return true;
718 }
09d27083 719 break;
26dfc728 720 case WXK_MENU:
32efab35
SC
721 if( keyboard->IsActive(WXK_MENU) ||
722 keyboard->IsActive(WXK_RMENU) )
723 {
724 return true;
725 }
09d27083
RN
726 break;
727 default:
32efab35
SC
728 if( keyboard->IsActive(key) )
729 {
730 return true;
731 }
09d27083
RN
732 break;
733 }
32efab35
SC
734 }
735
736 return false; //not down/error
4cb1d3da
RN
737}
738
ec8bd392 739#endif //__DARWIN__