~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to src/osx/core/hid.cpp

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

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