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