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