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 int index; 42 43 if ( !super::handleStart(provider) ) 44 return false; 45 46 for ( index=0; index<32; index++ ) { 47 _buttonMap[index].eventType = kIOHIDEventTypePointer; 48 _buttonMap[index].u.pointer.mask = (1<<index); 49 } 50 51 maps = OSDynamicCast(OSArray, getProperty("ButtonMaps")); 52 if ( maps ) { 53 54 for ( index=0; index<maps->getCount(); index++ ) { 55 OSDictionary * map; 56 OSNumber * number; 57 uint32_t button; 58 59 map = OSDynamicCast(OSDictionary, maps->getObject(index)); 60 if ( !map ) 61 continue; 62 63 number = OSDynamicCast(OSNumber, map->getObject("ButtonNumber")); 64 if ( !number ) 65 continue; 66 67 button = number->unsigned32BitValue(); 68 if ( !button || button>32 ) 69 continue; 70 71 number = OSDynamicCast(OSNumber, map->getObject("EventType")); 72 if ( !number ) 73 continue; 74 75 _buttonMap[button-1].eventType = number->unsigned32BitValue(); 76 77 switch ( _buttonMap[button-1].eventType ) { 78 case kIOHIDEventTypeKeyboard: 79 { 80 uint32_t usagePage, usage; 81 82 number = OSDynamicCast(OSNumber, map->getObject("UsagePage")); 83 if ( !number ) 84 break; 85 86 usagePage = number->unsigned32BitValue(); 87 88 number = OSDynamicCast(OSNumber, map->getObject("Usage")); 89 if ( !number ) 90 break; 91 92 usage = number->unsigned32BitValue(); 93 94 _buttonMap[button-1].u.keyboard.usagePage = usagePage; 95 _buttonMap[button-1].u.keyboard.usage = usage; 96 97 } 98 break; 99 case kIOHIDEventTypePointer: 100 { 101 uint32_t mask; 102 103 number = OSDynamicCast(OSNumber, map->getObject("Mask")); 104 if ( !number ) 105 break; 106 107 mask = number->unsigned32BitValue(); 108 109 110 _buttonMap[button-1].u.pointer.mask = mask; 111 } 112 break; 113 default: 114 break; 115 } 116 117 } 118 } 119 120 return true; 121} 122 123//==================================================================================================== 124// IOHIDEventOverrideDriver::dispatchEvent 125//==================================================================================================== 126void IOHIDEventOverrideDriver::dispatchEvent(IOHIDEvent * event, IOOptionBits options) 127{ 128 IOHIDEvent * targetEvent = NULL; 129 130 if ( (targetEvent = event->getEvent(kIOHIDEventTypePointer)) ) { 131 132 IOHIDEvent * newEvent = NULL; 133 AbsoluteTime timestamp = targetEvent->getTimeStamp(); 134 uint32_t rawPointerButtonMask = targetEvent->getIntegerValue(kIOHIDEventFieldPointerButtonMask); 135 uint32_t rawPointerButtonMaskDelta = _rawPointerButtonMask ^ rawPointerButtonMask; 136 uint32_t resultantPointerButtonMask = _resultantPointerButtonMask; 137 int index; 138 139 for ( index=0; index<32; index++ ) { 140 141 bool value = rawPointerButtonMask & (1<<index); 142 143 if ( (rawPointerButtonMaskDelta & (1<<index)) == 0 ) 144 continue; 145 146 switch (_buttonMap[index].eventType ) { 147 case kIOHIDEventTypeKeyboard: 148 dispatchKeyboardEvent(timestamp, _buttonMap[index].u.keyboard.usagePage, _buttonMap[index].u.keyboard.usage, value); 149 break; 150 case kIOHIDEventTypePointer: 151 if ( value ) 152 resultantPointerButtonMask |= _buttonMap[index].u.pointer.mask; 153 else 154 resultantPointerButtonMask &= ~_buttonMap[index].u.pointer.mask; 155 break; 156 default: 157 break; 158 } 159 } 160 161 _rawPointerButtonMask = rawPointerButtonMask; 162 163 newEvent = IOHIDEvent::relativePointerEvent(timestamp, event->getIntegerValue(kIOHIDEventFieldPointerX), event->getIntegerValue(kIOHIDEventFieldPointerY), event->getIntegerValue(kIOHIDEventFieldPointerZ), resultantPointerButtonMask, _resultantPointerButtonMask); 164 if ( newEvent ) { 165 super::dispatchEvent(newEvent); 166 newEvent->release(); 167 } 168 169 _resultantPointerButtonMask = resultantPointerButtonMask; 170 171 } else { 172 super::dispatchEvent(event, options); 173 } 174} 175 176