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