1/* 2 * 3 * @APPLE_LICENSE_HEADER_START@ 4 * 5 * Copyright (c) 1999-2013 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 25#include "IOHIDEventOverrideDriver.h" 26#include "IOHIDUsageTables.h" 27 28//=========================================================================== 29// IOHIDEventOverrideDriver class 30 31#define super IOHIDEventDriver 32 33OSDefineMetaClassAndStructors( IOHIDEventOverrideDriver, IOHIDEventDriver ) 34 35//==================================================================================================== 36// IOHIDEventOverrideDriver::dispatchKeyboardEvent 37//==================================================================================================== 38bool IOHIDEventOverrideDriver::handleStart( IOService * provider ) 39{ 40 OSArray * maps = NULL; 41 42 if ( !super::handleStart(provider) ) 43 return false; 44 45 maps = OSDynamicCast(OSArray, getProperty("ButtonMaps")); 46 if ( maps ) { 47 int index; 48 49 for ( index=0; index<maps->getCount(); index++ ) { 50 OSDictionary * map; 51 OSNumber * number; 52 uint32_t button; 53 uint32_t usagePage; 54 uint32_t usage; 55 uint32_t eventType; 56 57 map = OSDynamicCast(OSDictionary, maps->getObject(index)); 58 if ( !map ) 59 continue; 60 61 number = OSDynamicCast(OSNumber, map->getObject("ButtonNumber")); 62 if ( !number ) 63 continue; 64 65 button = number->unsigned32BitValue(); 66 if ( !button || button>32 ) 67 continue; 68 69 number = OSDynamicCast(OSNumber, map->getObject("EventType")); 70 if ( !number ) 71 continue; 72 73 eventType = number->unsigned32BitValue(); 74 75 number = OSDynamicCast(OSNumber, map->getObject("UsagePage")); 76 if ( !number ) 77 continue; 78 79 usagePage = number->unsigned32BitValue(); 80 81 number = OSDynamicCast(OSNumber, map->getObject("Usage")); 82 if ( !number ) 83 continue; 84 85 usage = number->unsigned32BitValue(); 86 87 _buttonMap[button-1].eventType = eventType; 88 _buttonMap[button-1].usagePage = usagePage; 89 _buttonMap[button-1].usage = usage; 90 } 91 } 92 93 return true; 94} 95 96//==================================================================================================== 97// IOHIDEventOverrideDriver::dispatchKeyboardEvent 98//==================================================================================================== 99void IOHIDEventOverrideDriver::dispatchEvent(IOHIDEvent * event, IOOptionBits options) 100{ 101 IOHIDEvent * targetEvent = NULL; 102 if ( (targetEvent = event->getEvent(kIOHIDEventTypePointer)) ) { 103 AbsoluteTime timestamp = targetEvent->getTimeStamp(); 104 uint32_t pointerButtonMaskNew = targetEvent->getIntegerValue(kIOHIDEventFieldPointerButtonMask); 105 uint32_t pointerButtonMaskDelta = _pointerButtonMask ^ pointerButtonMaskNew; 106 int index; 107 108 for ( index=0; index<32; index++ ) { 109 bool value; 110 if ( (pointerButtonMaskDelta & (1<<index)) == 0 ) 111 continue; 112 113 switch (_buttonMap[index].eventType ) { 114 case kIOHIDEventTypeKeyboard: 115 value = pointerButtonMaskNew & (1<<index); 116 dispatchKeyboardEvent(timestamp, _buttonMap[index].usagePage, _buttonMap[index].usage, value); 117 break; 118 default: 119 break; 120 } 121 } 122 123 _pointerButtonMask = pointerButtonMaskNew; 124 } else { 125 super::dispatchEvent(event, options); 126 } 127} 128 129