1/*
2 *
3 * @APPLE_LICENSE_HEADER_START@
4 *
5 * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24#include <AssertMacros.h>
25#include <IOKit/IOLib.h>
26#include "IOHIDEventTypes.h"
27#include "IOHIDEvent.h"
28#include "IOHIDEventData.h"
29#include "IOHIDUsageTables.h"
30
31#if !TARGET_OS_EMBEDDED
32#include "ev_keymap.h"
33#endif /* TARGET_OS_EMBEDDED */
34
35#define EXTERNAL ((unsigned int) -1)
36
37#define super OSObject
38
39OSDefineMetaClassAndStructors(IOHIDEvent, OSObject)
40
41//==============================================================================
42// IOHIDEvent::initWithCapacity
43//==============================================================================
44bool IOHIDEvent::initWithCapacity(IOByteCount capacity)
45{
46    if (!super::init())
47        return false;
48
49    if (_data && (!capacity || _capacity < capacity) ) {
50        // clean out old data's storage if it isn't big enough
51        IOFree(_data, _capacity);
52        _data = 0;
53    }
54
55    _capacity = capacity;
56
57    if ( !_capacity )
58        return false;
59
60    if ( !_data && !(_data = (IOHIDEventData *) IOMalloc(_capacity)))
61        return false;
62
63    bzero(_data, _capacity);
64    _data->size = _capacity;
65    _children = NULL;
66
67    clock_get_uptime(&_creationTimeStamp);
68
69    return true;
70}
71
72//==============================================================================
73// IOHIDEvent::initWithType
74//==============================================================================
75bool IOHIDEvent::initWithType(IOHIDEventType type, IOByteCount additionalCapacity)
76{
77    size_t capacity = 0;
78
79    IOHIDEventGetSize(type,capacity);
80
81    if ( !initWithCapacity(capacity+additionalCapacity) )
82        return false;
83
84    _data->type = type;
85    _typeMask   = IOHIDEventTypeMask(type);
86
87    return true;
88}
89
90//==============================================================================
91// IOHIDEvent::initWithTypeTimeStamp
92//==============================================================================
93bool IOHIDEvent::initWithTypeTimeStamp(IOHIDEventType type, AbsoluteTime timeStamp, IOOptionBits options, IOByteCount additionalCapacity)
94{
95    if ( !initWithType(type, additionalCapacity))
96        return false;
97
98    _timeStamp  = timeStamp;
99    _options    = options;
100
101    _data->options = options;
102
103    return true;
104}
105
106//==============================================================================
107// IOHIDEvent::free
108//==============================================================================
109void IOHIDEvent::free()
110{
111    if (_capacity != EXTERNAL && _data && _capacity) {
112        IOFree(_data, _capacity);
113        _data = NULL;
114        _capacity = 0;
115    }
116
117    if ( _children ) {
118        // We should probably iterate over each child to clear the parent
119        _children->release();
120        _children = NULL;
121    }
122    super::free();
123}
124
125//==============================================================================
126// IOHIDEvent::getTimeStamp
127//==============================================================================
128AbsoluteTime IOHIDEvent::getTimeStamp()
129{
130    return _timeStamp;
131}
132
133//==============================================================================
134// IOHIDEvent::setTimeStamp
135//==============================================================================
136void IOHIDEvent::setTimeStamp( AbsoluteTime timeStamp )
137{
138    _timeStamp = timeStamp;
139}
140
141//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
142// IOHIDEvent::withType
143//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
144IOHIDEvent * IOHIDEvent::withType(      IOHIDEventType          type,
145                                        IOOptionBits            options)
146{
147    IOHIDEvent *me = new IOHIDEvent;
148
149    if (me && !me->initWithType(type)) {
150        me->release();
151        return 0;
152    }
153
154    me->_options = options;
155
156    return me;
157}
158
159#if !TARGET_OS_EMBEDDED
160
161extern unsigned int hid_adb_2_usb_keymap[];
162
163//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
164// IOHIDEvent::withEventData
165//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
166IOHIDEvent * IOHIDEvent::withEventData (
167                                        AbsoluteTime            timeStamp,
168                                        UInt32                  type,
169                                        NXEventData *           data,
170                                        IOOptionBits            options)
171{
172    IOHIDEvent *me = NULL;
173
174    switch ( type ) {
175        case NX_LMOUSEDOWN:
176        case NX_LMOUSEUP:
177        case NX_RMOUSEDOWN:
178        case NX_RMOUSEUP:
179        case NX_OMOUSEDOWN:
180        case NX_OMOUSEUP:
181            break;
182        case NX_MOUSEMOVED:
183        case NX_LMOUSEDRAGGED:
184        case NX_RMOUSEDRAGGED:
185        case NX_OMOUSEDRAGGED:
186            me = IOHIDEvent::translationEvent(timeStamp, (data->mouseMove.dx<<16) + (data->mouseMove.subx<<8), (data->mouseMove.dy<<16) + (data->mouseMove.suby<<8), 0, options);
187            break;
188
189        case NX_KEYDOWN:
190        case NX_KEYUP:
191            {
192            uint32_t usage = hid_adb_2_usb_keymap[data->key.keyCode];
193
194            if ( usage < kHIDUsage_KeyboardLeftControl || usage > kHIDUsage_KeyboardRightGUI || !data->key.repeat )
195                me = IOHIDEvent::keyboardEvent(timeStamp, kHIDPage_KeyboardOrKeypad, hid_adb_2_usb_keymap[data->key.keyCode], type==NX_KEYDOWN, options | (data->key.repeat ? kIOHIDKeyboardIsRepeat : 0));
196            }
197            break;
198        case NX_SCROLLWHEELMOVED:
199            me = IOHIDEvent::scrollEvent(timeStamp, data->scrollWheel.pointDeltaAxis2<<16, data->scrollWheel.pointDeltaAxis1<<16, data->scrollWheel.pointDeltaAxis3<<16, options);
200            break;
201        case NX_ZOOM:
202            me = IOHIDEvent::zoomEvent(timeStamp, data->scrollWheel.pointDeltaAxis2<<16, data->scrollWheel.pointDeltaAxis1<<16, data->scrollWheel.pointDeltaAxis3<<16, options);
203            break;
204        case NX_SYSDEFINED:
205            switch (data->compound.subType) {
206                case NX_SUBTYPE_AUX_MOUSE_BUTTONS:
207                    me = IOHIDEvent::buttonEvent(timeStamp, data->compound.misc.L[1], options);
208                    break;
209                case NX_SUBTYPE_AUX_CONTROL_BUTTONS:
210                    uint16_t flavor = data->compound.misc.L[0] >> 16;
211                    switch ( flavor ) {
212                        case NX_KEYTYPE_SOUND_UP:
213                        case NX_KEYTYPE_SOUND_DOWN:
214                        case NX_KEYTYPE_BRIGHTNESS_UP:
215                        case NX_KEYTYPE_BRIGHTNESS_DOWN:
216                        case NX_KEYTYPE_HELP:
217                        case NX_POWER_KEY:
218                        case NX_KEYTYPE_MUTE:
219                        case NX_KEYTYPE_NUM_LOCK:
220
221                        case NX_KEYTYPE_EJECT:
222                        case NX_KEYTYPE_VIDMIRROR:
223
224                        case NX_KEYTYPE_PLAY:
225                        case NX_KEYTYPE_NEXT:
226                        case NX_KEYTYPE_PREVIOUS:
227                        case NX_KEYTYPE_FAST:
228                        case NX_KEYTYPE_REWIND:
229
230                        case NX_KEYTYPE_ILLUMINATION_UP:
231                        case NX_KEYTYPE_ILLUMINATION_DOWN:
232                        case NX_KEYTYPE_ILLUMINATION_TOGGLE:
233                            break;
234                    }
235            }
236            break;
237    }
238
239    return me;
240}
241
242#endif /* TARGET_OS_EMBEDDED */
243
244
245//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
246// IOHIDEvent::keyboardEvent
247//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
248IOHIDEvent * IOHIDEvent::keyboardEvent( AbsoluteTime            timeStamp,
249                                        UInt32                  usagePage,
250                                        UInt32                  usage,
251                                        Boolean                 down,
252                                        IOOptionBits            options)
253{
254    IOHIDEvent *me = new IOHIDEvent;
255
256    if (me && !me->initWithTypeTimeStamp(kIOHIDEventTypeKeyboard, timeStamp, options | kIOHIDEventOptionIsAbsolute)) {
257        me->release();
258        return 0;
259    }
260
261    IOHIDKeyboardEventData * keyboard = (IOHIDKeyboardEventData *)me->_data;
262    keyboard->usagePage = usagePage;
263    keyboard->usage = usage;
264    keyboard->down = down;
265
266    return me;
267}
268
269//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
270// IOHIDEvent::_axisEvent
271//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
272IOHIDEvent * IOHIDEvent::_axisEvent(    IOHIDEventType          type,
273                                        AbsoluteTime            timeStamp,
274                                        IOFixed                 x,
275                                        IOFixed                 y,
276                                        IOFixed                 z,
277                                        IOOptionBits            options)
278{
279    IOHIDEvent *me = new IOHIDEvent;
280
281    if (me && !me->initWithTypeTimeStamp(type, timeStamp, options)) {
282        me->release();
283        return 0;
284    }
285
286    IOHIDAxisEventData * event = (IOHIDAxisEventData *)me->_data;
287    event->position.x = x;
288    event->position.y = y;
289    event->position.z = z;
290
291    return me;
292}
293
294//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
295// IOHIDEvent::_motionEvent
296//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
297IOHIDEvent * IOHIDEvent::_motionEvent ( IOHIDEventType          type,
298                                        AbsoluteTime            timeStamp,
299                                        IOFixed                 x,
300                                        IOFixed                 y,
301                                        IOFixed                 z,
302                                        uint32_t                motionType,
303                                        uint32_t                motionSubType,
304                                        UInt32                  sequence,
305                                        IOOptionBits            options)
306{
307    IOHIDEvent *            event;
308    IOHIDMotionEventData *  data;
309
310    event = IOHIDEvent::_axisEvent( type,
311                                    timeStamp,
312                                    x,
313                                    y,
314                                    z,
315                                    options);
316
317    if ( event ) {
318        data = (IOHIDMotionEventData *)event->_data;
319        data->motionType = motionType;
320        data->motionSubType = motionSubType;
321        data->motionSequence = sequence;
322    }
323
324    return event;
325}
326
327
328//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
329// IOHIDEvent::translationEvent
330//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
331IOHIDEvent * IOHIDEvent::translationEvent(
332                                        AbsoluteTime            timeStamp,
333                                        IOFixed                 x,
334                                        IOFixed                 y,
335                                        IOFixed                 z,
336                                        IOOptionBits            options)
337{
338    return IOHIDEvent::_axisEvent(      kIOHIDEventTypeTranslation,
339                                        timeStamp,
340                                        x,
341                                        y,
342                                        z,
343                                        options);
344}
345
346//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
347// IOHIDEvent::scrollEvet
348//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
349IOHIDEvent * IOHIDEvent::scrollEvent(
350                                        AbsoluteTime            timeStamp,
351                                        SInt32                  x,
352                                        SInt32                  y,
353                                        SInt32                  z,
354                                        IOOptionBits            options)
355{
356    return IOHIDEvent::_axisEvent(      kIOHIDEventTypeScroll,
357                                        timeStamp,
358                                        x<<16,
359                                        y<<16,
360                                        z<<16,
361                                        options);
362}
363
364//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
365// IOHIDEvent::zoomEvent
366//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
367IOHIDEvent * IOHIDEvent::zoomEvent(
368                                        AbsoluteTime            timeStamp,
369                                        IOFixed                 x,
370                                        IOFixed                 y,
371                                        IOFixed                 z,
372                                        IOOptionBits            options)
373{
374    return IOHIDEvent::_axisEvent(      kIOHIDEventTypeZoom,
375                                        timeStamp,
376                                        x,
377                                        y,
378                                        z,
379                                        options);
380}
381
382
383//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
384// IOHIDEvent::accelerometerEvent
385//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
386IOHIDEvent * IOHIDEvent::accelerometerEvent(
387                                    AbsoluteTime            timeStamp,
388                                    IOFixed                 x,
389                                    IOFixed                 y,
390                                    IOFixed                 z,
391                                    IOHIDMotionType         type,
392                                    IOHIDMotionPath         subType,
393                                    UInt32                  sequence,
394                                    IOOptionBits            options)
395{
396    return IOHIDEvent::_motionEvent( kIOHIDEventTypeAccelerometer,
397                                    timeStamp,
398                                    x,
399                                    y,
400                                    z,
401                                    type,
402                                    subType,
403                                    sequence,
404                                    options);
405}
406
407//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
408// IOHIDEvent::gyroEvent
409//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
410IOHIDEvent * IOHIDEvent::gyroEvent(
411                                    AbsoluteTime            timeStamp,
412                                    IOFixed                 x,
413                                    IOFixed                 y,
414                                    IOFixed                 z,
415                                    IOHIDMotionType         type,
416                                    IOHIDMotionPath         subType,
417                                    UInt32                  sequence,
418                                    IOOptionBits            options)
419{
420    return IOHIDEvent::_motionEvent( kIOHIDEventTypeGyro,
421                                    timeStamp,
422                                    x,
423                                    y,
424                                    z,
425                                    type,
426                                    subType,
427                                    sequence,
428                                    options);
429}
430
431//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
432// IOHIDEvent::compassEvent
433//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
434IOHIDEvent * IOHIDEvent::compassEvent(
435                                   AbsoluteTime             timeStamp,
436                                   IOFixed                  x,
437                                   IOFixed                  y,
438                                   IOFixed                  z,
439                                   IOHIDMotionType          type,
440                                   IOHIDMotionPath          subType,
441                                   UInt32                   sequence,
442                                   IOOptionBits             options)
443{
444    return IOHIDEvent::_motionEvent( kIOHIDEventTypeCompass,
445                                    timeStamp,
446                                    x,
447                                    y,
448                                    z,
449                                    type,
450                                    subType,
451                                    sequence,
452                                    options);
453}
454
455//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
456// IOHIDEvent::ambientLightSensorEvent
457//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
458IOHIDEvent * IOHIDEvent::ambientLightSensorEvent(
459                                        AbsoluteTime            timeStamp,
460                                        UInt32                  level,
461                                        UInt32                  channel0,
462                                        UInt32                  channel1,
463										UInt32                  channel2,
464										UInt32                  channel3,
465                                        IOOptionBits            options)
466{
467    IOHIDEvent *me = new IOHIDEvent;
468
469    if (me && !me->initWithTypeTimeStamp(kIOHIDEventTypeAmbientLightSensor, timeStamp, options)) {
470        me->release();
471        return 0;
472    }
473
474    IOHIDAmbientLightSensorEventData * event = (IOHIDAmbientLightSensorEventData *)me->_data;
475    event->level = level;
476    event->ch0 = channel0;
477    event->ch1 = channel1;
478    event->ch2 = channel2;
479    event->ch3 = channel3;
480
481    return me;
482}
483
484//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
485// IOHIDEvent::proximityEvent
486//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
487IOHIDEvent * IOHIDEvent::proximityEvent (
488                                        AbsoluteTime				timeStamp,
489                                        IOHIDProximityDetectionMask	mask,
490										UInt32						level,
491                                        IOOptionBits				options)
492{
493    IOHIDEvent *me = new IOHIDEvent;
494
495    if (me && !me->initWithTypeTimeStamp(kIOHIDEventTypeProximity, timeStamp, options)) {
496        me->release();
497        return 0;
498    }
499
500    IOHIDProximityEventData * event = (IOHIDProximityEventData *)me->_data;
501    event->detectionMask	= mask;
502	event->level			= level;
503
504    return me;
505}
506
507
508
509//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
510// IOHIDEvent::temperatureEvent
511//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
512IOHIDEvent * IOHIDEvent::temperatureEvent(
513                                        AbsoluteTime            timeStamp,
514                                        IOFixed                 temperature,
515                                        IOOptionBits            options)
516{
517    IOHIDEvent *me = new IOHIDEvent;
518
519    if (me && !me->initWithTypeTimeStamp(kIOHIDEventTypeTemperature, timeStamp, options)) {
520        me->release();
521        return 0;
522    }
523
524    IOHIDTemperatureEventData * event = (IOHIDTemperatureEventData *)me->_data;
525    event->level = temperature;
526
527    return me;
528}
529
530//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
531// IOHIDEvent::buttonEvent
532//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
533IOHIDEvent * IOHIDEvent::buttonEvent(
534                                        AbsoluteTime            timeStamp,
535                                        UInt32                  buttonMask,
536                                        IOOptionBits            options)
537{
538    return IOHIDEvent::buttonEvent(timeStamp, buttonMask, 0, options);
539}
540
541//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
542// IOHIDEvent::buttonEvent
543//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
544IOHIDEvent * IOHIDEvent::buttonEvent(
545                                        AbsoluteTime            timeStamp,
546                                        UInt32                  buttonMask,
547                                        IOFixed                 pressure,
548                                        IOOptionBits            options)
549{
550    IOHIDEvent *me = new IOHIDEvent;
551
552    if (me && !me->initWithTypeTimeStamp(kIOHIDEventTypeButton, timeStamp, options)) {
553        me->release();
554        return 0;
555    }
556
557    IOHIDButtonEventData * event = (IOHIDButtonEventData *)me->_data;
558    event->button.buttonMask = buttonMask;
559    event->button.pressure   = pressure;
560
561    return me;
562}
563
564//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
565// IOHIDEvent::relativePointerEvent
566//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
567IOHIDEvent * IOHIDEvent::relativePointerEvent(
568                                        AbsoluteTime            timeStamp,
569                                        SInt32                  x,
570                                        SInt32                  y,
571                                        SInt32                  z,
572                                        UInt32                  buttonState,
573                                        IOOptionBits            options)
574{
575    IOHIDEvent *me = new IOHIDEvent;
576
577    if (me && !me->initWithTypeTimeStamp(kIOHIDEventTypePointer, timeStamp, options)) {
578        me->release();
579        return NULL;
580    }
581
582    IOHIDPointerEventData *event = (IOHIDPointerEventData *)me->_data;
583
584    event->position.x = x<<16;
585    event->position.y = y<<16;
586    event->position.z = z<<16;
587    event->button.buttonMask = buttonState;
588
589    return me;
590}
591
592//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
593// IOHIDEvent::multiAxisPointerEvent
594//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
595IOHIDEvent * IOHIDEvent::multiAxisPointerEvent(
596                                        AbsoluteTime            timeStamp,
597                                        UInt32                  buttonState,
598                                        IOFixed                 x,
599                                        IOFixed                 y,
600                                        IOFixed                 z,
601                                        IOFixed                 rX,
602                                        IOFixed                 rY,
603                                        IOFixed                 rZ,
604                                        IOOptionBits            options)
605{
606    IOHIDEvent *me = new IOHIDEvent;
607
608    if (me && !me->initWithTypeTimeStamp(kIOHIDEventTypeMultiAxisPointer, timeStamp, options | kIOHIDEventOptionIsAbsolute | kIOHIDEventOptionIsCenterOrigin)) {
609        me->release();
610        return NULL;
611    }
612
613    IOHIDMultiAxisPointerEventData *event = (IOHIDMultiAxisPointerEventData *)me->_data;
614
615    event->position.x = x;
616    event->position.y = y;
617    event->position.z = z;
618    event->rotation.x = rX;
619    event->rotation.y = rY;
620    event->rotation.z = rZ;
621    event->button.buttonMask = buttonState;
622
623    return me;
624}
625
626//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
627// IOHIDEvent::digitizerEvent
628//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
629IOHIDEvent * IOHIDEvent::digitizerEvent(
630                                        AbsoluteTime                    timeStamp,
631                                        UInt32                          transducerID,
632                                        IOHIDDigitizerTransducerType    type,
633                                        bool                            inRange,
634                                        UInt32                          buttonState,
635                                        IOFixed                         x,
636                                        IOFixed                         y,
637                                        IOFixed                         z,
638                                        IOFixed                         tipPressure,
639                                        IOFixed                         auxPressure,
640                                        IOFixed                         twist,
641                                        IOOptionBits                    options)
642{
643    IOHIDEvent *me = new IOHIDEvent;
644
645    if (me && !me->initWithTypeTimeStamp(kIOHIDEventTypeDigitizer, timeStamp, options | kIOHIDEventOptionIsAbsolute)) {
646        me->release();
647        return NULL;
648    }
649
650    IOHIDDigitizerEventData *event = (IOHIDDigitizerEventData *)me->_data;
651
652    if ( inRange ) {
653        event->options |= kIOHIDTransducerRange;
654    }
655
656    event->eventMask        = 0;       // todo:
657    event->transducerIndex  = transducerID; // Multitouch uses this as a path ID
658    event->transducerType   = type;
659    event->buttonMask       = buttonState;
660    event->position.x       = x;
661    event->position.y       = y;
662    event->position.z       = z;
663    event->pressure         = tipPressure;
664    event->auxPressure      = auxPressure;
665    event->twist            = twist;
666
667
668    // Let's assume no tip pressure means finger
669    switch ( event->transducerType ) {
670        case kIOHIDDigitizerTransducerTypeFinger:
671            event->identity = 2;        // Multitouch interprets this as 'finger', hard code to 2 or index finger
672            event->orientationType = kIOHIDDigitizerOrientationTypeQuality;
673            event->orientation.quality.quality = 0;
674            event->orientation.quality.density = 0;
675            event->orientation.quality.irregularity = 0;
676            event->orientation.quality.majorRadius = 6<<16;
677            event->orientation.quality.minorRadius = 6<<16;
678            break;
679    }
680
681    return me;
682}
683
684//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
685// IOHIDEvent::digitizerEventWithTiltOrientation
686//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
687IOHIDEvent * IOHIDEvent::digitizerEventWithTiltOrientation(
688                                        AbsoluteTime                    timeStamp,
689                                        UInt32                          transducerID,
690                                        IOHIDDigitizerTransducerType    type,
691                                        bool                            inRange,
692                                        UInt32                          buttonState,
693                                        IOFixed                         x,
694                                        IOFixed                         y,
695                                        IOFixed                         z __unused,
696                                        IOFixed                         tipPressure,
697                                        IOFixed                         auxPressure,
698                                        IOFixed                         twist,
699                                        IOFixed                         xTilt,
700                                        IOFixed                         yTilt __unused,
701                                        IOOptionBits                    options)
702{
703    IOHIDEvent * me                 = NULL;
704    IOHIDDigitizerEventData * event = NULL;
705
706    me = IOHIDEvent::digitizerEvent(timeStamp, transducerID, type, inRange, buttonState, x, y, tipPressure, auxPressure, twist, options);
707    require(me, exit);
708
709    event = (IOHIDDigitizerEventData *)me->_data;
710    require(event, exit);
711
712    event->orientationType = kIOHIDDigitizerOrientationTypeTilt;
713
714    event->orientation.tilt.x = xTilt;
715    event->orientation.tilt.y = xTilt;
716
717exit:
718    return me;
719}
720
721//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
722// IOHIDEvent::digitizerEventWithPolarOrientation
723//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
724IOHIDEvent * IOHIDEvent::digitizerEventWithPolarOrientation(
725                                        AbsoluteTime                    timeStamp,
726                                        UInt32                          transducerID,
727                                        IOHIDDigitizerTransducerType    type,
728                                        bool                            inRange,
729                                        UInt32                          buttonState,
730                                        IOFixed                         x,
731                                        IOFixed                         y,
732                                        IOFixed                         z __unused,
733                                        IOFixed                         tipPressure,
734                                        IOFixed                         auxPressure,
735                                        IOFixed                         twist,
736                                        IOFixed                         altitude,
737                                        IOFixed                         azimuth,
738                                        IOOptionBits                    options)
739{
740    IOHIDEvent * me                 = NULL;
741    IOHIDDigitizerEventData * event = NULL;
742
743    me = IOHIDEvent::digitizerEvent(timeStamp, transducerID, type, inRange, buttonState, x, y, tipPressure, auxPressure, twist, options);
744    require(me, exit);
745
746    event = (IOHIDDigitizerEventData *)me->_data;
747    require(event, exit);
748
749    event->orientationType = kIOHIDDigitizerOrientationTypePolar;
750
751    event->orientation.polar.altitude   = altitude;
752    event->orientation.polar.azimuth    = azimuth;
753
754exit:
755    return me;
756}
757
758//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
759// IOHIDEvent::digitizerEventWithQualityOrientation
760//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
761IOHIDEvent * IOHIDEvent::digitizerEventWithQualityOrientation(
762                                        AbsoluteTime                    timeStamp,
763                                        UInt32                          transducerID,
764                                        IOHIDDigitizerTransducerType    type,
765                                        bool                            inRange,
766                                        UInt32                          buttonState,
767                                        IOFixed                         x,
768                                        IOFixed                         y,
769                                        IOFixed                         z __unused,
770                                        IOFixed                         tipPressure,
771                                        IOFixed                         auxPressure,
772                                        IOFixed                         twist,
773                                        IOFixed                         quality,
774                                        IOFixed                         density,
775                                        IOFixed                         irregularity,
776                                        IOFixed                         majorRadius,
777                                        IOFixed                         minorRadius,
778                                        IOOptionBits                    options)
779{
780    IOHIDEvent * me                 = NULL;
781    IOHIDDigitizerEventData * event = NULL;
782
783    me = IOHIDEvent::digitizerEvent(timeStamp, transducerID, type, inRange, buttonState, x, y, tipPressure, auxPressure, twist, options);
784    require(me, exit);
785
786    event = (IOHIDDigitizerEventData *)me->_data;
787    require(event, exit);
788
789    event->orientationType = kIOHIDDigitizerOrientationTypeQuality;
790
791    event->orientation.quality.quality          = quality;
792    event->orientation.quality.density          = density;
793    event->orientation.quality.irregularity     = irregularity;
794    event->orientation.quality.majorRadius      = majorRadius;
795    event->orientation.quality.minorRadius      = minorRadius;
796
797exit:
798    return me;
799}
800
801//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
802// IOHIDEvent::powerEvent
803//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
804IOHIDEvent * IOHIDEvent::powerEvent(
805                                   AbsoluteTime            timeStamp,
806                                   int64_t                 measurement,
807                                   IOHIDPowerType          powerType,
808                                   IOHIDPowerSubType       powerSubType,
809                                   IOOptionBits            options)
810{
811    IOHIDEvent *me = new IOHIDEvent;
812
813    if (me && !me->initWithTypeTimeStamp(kIOHIDEventTypePower, timeStamp, options)) {
814        me->release();
815        return 0;
816    }
817
818    IOHIDPowerEventData *event = (IOHIDPowerEventData *)me->_data;
819
820    event->measurement = measurement;
821    event->powerType = powerType;
822    event->powerSubType = powerSubType;
823
824    return me;
825}
826
827//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
828// IOHIDEvent::vendorDefinedEvent
829//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
830IOHIDEvent * IOHIDEvent::vendorDefinedEvent(
831                                           AbsoluteTime            timeStamp,
832                                           UInt32                  usagePage,
833                                           UInt32                  usage,
834                                           UInt32                  version,
835                                           UInt8 *                 data,
836                                           UInt32                  length,
837                                           IOOptionBits            options)
838{
839    UInt32      dataLength  = length;
840    IOHIDEvent * me         = new IOHIDEvent;
841
842    if ( dataLength < sizeof(natural_t))
843        dataLength = sizeof(natural_t);
844
845    if (me && !me->initWithTypeTimeStamp(kIOHIDEventTypeVendorDefined, timeStamp, options, dataLength)) {
846        me->release();
847        return 0;
848    }
849
850    IOHIDVendorDefinedEventData *event = (IOHIDVendorDefinedEventData *)me->_data;
851
852    event->usagePage    = usagePage;
853    event->usage        = usage;
854    event->version      = version;
855    event->length       = dataLength;
856
857    bcopy(data, event->data, length);
858
859    return me;
860}
861
862#if TARGET_OS_EMBEDDED
863//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
864// IOHIDEvent::biometricEvent
865//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
866IOHIDEvent * IOHIDEvent::biometricEvent(AbsoluteTime timeStamp, IOFixed level, IOHIDBiometricEventType eventType, IOOptionBits options)
867{
868    IOHIDEvent *me = new IOHIDEvent;
869
870    if (me && !me->initWithTypeTimeStamp(kIOHIDEventTypeBiometric, timeStamp, options)) {
871        me->release();
872        return 0;
873    }
874
875    IOHIDBiometricEventData *event = (IOHIDBiometricEventData *)me->_data;
876
877    event->eventType    = eventType;
878    event->level        = level;
879
880    return me;
881}
882#endif /* TARGET_OS_EMBEDDED */
883
884//==============================================================================
885// IOHIDEvent::appendChild
886//==============================================================================
887void IOHIDEvent::appendChild(IOHIDEvent *childEvent)
888{
889    if (!_children) {
890        const OSObject *events[] = { childEvent };
891
892        _children = OSArray::withObjects(events, 1);
893    } else {
894        _children->setObject(childEvent);
895    }
896
897}
898
899//==============================================================================
900// IOHIDEvent::getType
901//==============================================================================
902IOHIDEventType IOHIDEvent::getType()
903{
904    return _data->type;
905}
906
907//==============================================================================
908// IOHIDEvent::setType
909//==============================================================================
910void IOHIDEvent::setType(IOHIDEventType type)
911{
912    initWithType(type);
913}
914
915//==============================================================================
916// IOHIDEvent::getEvent
917//==============================================================================
918IOHIDEvent * IOHIDEvent::getEvent(      IOHIDEventType          type,
919                                        IOOptionBits            options __unused)
920{
921    return (_data->type == type) ? this : NULL;
922}
923
924//==============================================================================
925// IOHIDEvent::getIntegerValue
926//==============================================================================
927SInt32 IOHIDEvent::getIntegerValue(     IOHIDEventField         key,
928                                        IOOptionBits            options)
929{
930    SInt32 value = 0;
931
932    GET_EVENT_VALUE(this, key, value, options);
933
934    return value;
935}
936
937//==============================================================================
938// IOHIDEvent::getFixedValue
939//==============================================================================
940IOFixed IOHIDEvent::getFixedValue(      IOHIDEventField         key,
941                                        IOOptionBits            options)
942{
943    IOFixed value = 0;
944
945    GET_EVENT_VALUE_FIXED(this, key, value, options);
946
947    return value;
948}
949
950//==============================================================================
951// IOHIDEvent::setIntegerValue
952//==============================================================================
953void IOHIDEvent::setIntegerValue(       IOHIDEventField         key,
954                                        SInt32                  value,
955                                        IOOptionBits            options)
956{
957    SET_EVENT_VALUE(this, key, value, options);
958}
959
960//==============================================================================
961// IOHIDEvent::setFixedValue
962//==============================================================================
963void IOHIDEvent::setFixedValue(         IOHIDEventField         key,
964                                        IOFixed                 value,
965                                        IOOptionBits            options)
966{
967    SET_EVENT_VALUE_FIXED(this, key, value, options);
968}
969
970
971//==============================================================================
972// IOHIDEvent::getLength
973//==============================================================================
974size_t IOHIDEvent::getLength()
975{
976    _eventCount = 0;
977    return getLength(&_eventCount);
978}
979
980//==============================================================================
981// IOHIDEvent::getLength
982//==============================================================================
983IOByteCount IOHIDEvent::getLength(UInt32 * count)
984{
985    IOByteCount length = _data->size;
986
987    length += sizeof(IOHIDSystemQueueElement);
988
989    if ( _children )
990    {
991        UInt32          i, childCount;
992        IOHIDEvent *    child;
993
994        childCount = _children->getCount();
995
996        for(i=0 ;i<childCount; i++) {
997            if ( (child = (IOHIDEvent *)_children->getObject(i)) ) {
998                length += child->getLength(count) - sizeof(IOHIDSystemQueueElement);
999            }
1000        }
1001    }
1002
1003    if ( count )
1004        *count = *count + 1;
1005
1006    return length;
1007}
1008
1009//==============================================================================
1010// IOHIDEvent::appendBytes
1011//==============================================================================
1012IOByteCount IOHIDEvent::appendBytes(UInt8 * bytes, IOByteCount withLength)
1013{
1014    IOByteCount size = 0;
1015
1016    size = _data->size;
1017
1018    if ( size > withLength )
1019        return 0;
1020
1021    bcopy(_data, bytes, size);
1022
1023    if ( _children )
1024    {
1025        UInt32          i, childCount;
1026        IOHIDEvent *    child;
1027
1028        childCount = _children->getCount();
1029
1030        for(i=0 ;i<childCount; i++) {
1031            if ( (child = (IOHIDEvent *)_children->getObject(i)) ) {
1032                size += child->appendBytes(bytes + size, withLength - size);
1033            }
1034        }
1035    }
1036
1037    return size;
1038}
1039
1040//==============================================================================
1041// IOHIDEvent::withBytes
1042//==============================================================================
1043IOHIDEvent * IOHIDEvent::withBytes(     const void *            bytes,
1044                                        IOByteCount             size)
1045{
1046    IOHIDSystemQueueElement *   queueElement= NULL;
1047    IOHIDEvent *                parent      = NULL;
1048    UInt32                      index       = 0;
1049    UInt32                      total       = 0;
1050    UInt32                      offset      = 0;
1051
1052    if ( !bytes || !size )
1053        return NULL;
1054
1055    queueElement    = (IOHIDSystemQueueElement *)bytes;
1056    total           = size - sizeof(IOHIDSystemQueueElement);
1057
1058    for (index=0; index<queueElement->eventCount && offset<total; index++)
1059    {
1060        IOHIDEventData *    eventData   = (IOHIDEventData *)(queueElement->payload + queueElement->attributeLength + offset);
1061        IOHIDEvent *        event       = IOHIDEvent::withType(eventData->type);
1062
1063        if ( !event )
1064            continue;
1065
1066        bcopy(eventData, event->_data, event->_data->size);
1067        AbsoluteTime_to_scalar(&(event->_timeStamp)) = queueElement->timeStamp;
1068        AbsoluteTime_to_scalar(&(event->_creationTimeStamp)) = queueElement->creationTimeStamp;
1069        event->_options = queueElement->options;
1070        event->_senderID = queueElement->senderID;
1071
1072        if ( !parent )
1073            parent = event;
1074        else {
1075            //Append event here;
1076            event->release();
1077        }
1078        offset += eventData->size;
1079    }
1080
1081    return parent;
1082}
1083
1084//==============================================================================
1085// IOHIDEvent::readBytes
1086//==============================================================================
1087IOByteCount IOHIDEvent::readBytes(void * bytes, IOByteCount withLength)
1088{
1089    IOHIDSystemQueueElement *   queueElement= NULL;
1090
1091    queueElement    = (IOHIDSystemQueueElement *)bytes;
1092
1093    queueElement->timeStamp         = *((uint64_t *)&_timeStamp);
1094    queueElement->creationTimeStamp = *((uint64_t *)&_creationTimeStamp);
1095    queueElement->options           = _options;
1096    queueElement->eventCount        = _eventCount;
1097    queueElement->senderID          = _senderID;
1098    queueElement->attributeLength   = 0;
1099
1100    //bytes += sizeof(IOHIDSystemQueueElement);
1101    withLength -= sizeof(IOHIDSystemQueueElement);
1102
1103    return appendBytes((UInt8 *)queueElement->payload, withLength);
1104}
1105
1106//==============================================================================
1107// IOHIDEvent::getPhase
1108//==============================================================================
1109IOHIDEventPhaseBits IOHIDEvent::getPhase()
1110{
1111    return (_data->options >> kIOHIDEventEventOptionPhaseShift) & kIOHIDEventEventPhaseMask;
1112}
1113
1114//==============================================================================
1115// IOHIDEvent::setPhase
1116//==============================================================================
1117void IOHIDEvent::setPhase(IOHIDEventPhaseBits phase)
1118{
1119    _data->options &= ~(kIOHIDEventEventPhaseMask << kIOHIDEventEventOptionPhaseShift);
1120    _data->options |= ((phase & kIOHIDEventEventPhaseMask) << kIOHIDEventEventOptionPhaseShift);
1121}
1122
1123//==============================================================================
1124// IOHIDEvent::setSenderID
1125//==============================================================================
1126void IOHIDEvent::setSenderID(uint64_t senderID)
1127{
1128    _senderID = senderID;
1129}
1130
1131//==============================================================================
1132// IOHIDEvent::getLatency
1133//==============================================================================
1134uint64_t IOHIDEvent::getLatency(uint32_t scaleFactor)
1135{
1136    AbsoluteTime    delta = mach_absolute_time();
1137    uint64_t        ns;
1138
1139    SUB_ABSOLUTETIME(&delta, &_timeStamp);
1140
1141    absolutetime_to_nanoseconds(delta, &ns);
1142
1143    return ns / scaleFactor;
1144}
1145
1146