1/* 2 * @APPLE_LICENSE_HEADER_START@ 3 * 4 * Copyright (c) 1999-2009 Apple Computer, Inc. All Rights Reserved. 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * 07 Jan 2002 ryepez 25 * This class is based off IOHIPointing and handles 26 * USB HID report based pointing devices 27 */ 28 29#include <IOKit/IOLib.h> 30#include <IOKit/assert.h> 31#include <IOKit/hidsystem/IOHIDShared.h> 32#include <IOKit/hidsystem/IOHIDDescriptorParser.h> 33 34#include "IOHIDParameter.h" 35#include "IOHIDPointing.h" 36#include "IOHIDKeys.h" 37#include "IOHIDElement.h" 38 39#define super IOHITablet 40OSDefineMetaClassAndStructors(IOHIDPointing, IOHITablet); 41 42//==================================================================================================== 43// IOHIDPointing::Pointing 44//==================================================================================================== 45IOHIDPointing * IOHIDPointing::Pointing( 46 UInt32 buttonCount, 47 IOFixed pointerResolution, 48 IOFixed scrollResolution, 49 bool isDispatcher) 50{ 51 IOHIDPointing *nub = new IOHIDPointing; 52 53 if ((nub == 0) || !nub->initWithMouseProperties(buttonCount, pointerResolution, scrollResolution, isDispatcher) ) 54 { 55 if (nub) nub->release(); 56 return 0; 57 } 58 59 return nub; 60} 61 62 63//==================================================================================================== 64// IOHIDPointing::initWithMouseProperties 65//==================================================================================================== 66bool IOHIDPointing::initWithMouseProperties( 67 UInt32 buttonCnt, 68 IOFixed pointerResolution, 69 IOFixed scrollResolution, 70 bool isDispatcher) 71{ 72 if (!super::init(0)) return false; 73 74 _numButtons = (buttonCnt > 0) ? buttonCnt : 1; 75 _resolution = pointerResolution; 76 _scrollResolution = scrollResolution; 77 _isDispatcher = isDispatcher; 78 79 return true; 80} 81 82//==================================================================================================== 83// IOHIDPointing::start 84//==================================================================================================== 85bool IOHIDPointing::start(IOService *provider) 86{ 87 88 _provider = OSDynamicCast(IOHIDEventService, provider); 89 90 if (!_provider) 91 return false; 92 93 // push up properties from our provider 94 setupProperties(); 95 96 return super::start(provider); 97} 98 99//==================================================================================================== 100// IOHIDPointing::dispatchAbsolutePointerEvent 101//==================================================================================================== 102void IOHIDPointing::dispatchAbsolutePointerEvent( 103 AbsoluteTime timeStamp, 104 IOGPoint * newLoc, 105 IOGBounds * bounds, 106 UInt32 buttonState, 107 bool inRange, 108 SInt32 tipPressure, 109 SInt32 tipPressureMin, 110 SInt32 tipPressureMax, 111 IOOptionBits options) 112{ 113 bool convertToRelative = ((options & kHIDDispatchOptionPointerAbsolutToRelative) != 0); 114 bool accelerate = ((options & kHIDDispatchOptionPointerNoAcceleration) == 0); 115 UInt32 pointingMode = getPointingMode(); 116 117 if ( (((pointingMode & kAccelMouse) != 0) != accelerate) && (((pointingMode & kAbsoluteConvertMouse) != 0) != convertToRelative)) 118 { 119 if ( accelerate ) 120 pointingMode |= kAccelMouse; 121 else 122 pointingMode &= ~kAccelMouse; 123 124 if ( convertToRelative ) 125 pointingMode |= kAbsoluteConvertMouse; 126 else 127 pointingMode &= ~kAbsoluteConvertMouse; 128 129 setPointingMode(pointingMode); 130 } 131 132 super::dispatchAbsolutePointerEvent(newLoc, bounds, buttonState, inRange, tipPressure, tipPressureMin, tipPressureMax, 90, timeStamp); 133} 134 135//==================================================================================================== 136// IOHIDPointing::dispatchRelativePointerEvent 137//==================================================================================================== 138void IOHIDPointing::dispatchRelativePointerEvent( 139 AbsoluteTime timeStamp, 140 SInt32 dx, 141 SInt32 dy, 142 UInt32 buttonState, 143 IOOptionBits options) 144{ 145 bool accelerate = ((options & kHIDDispatchOptionPointerNoAcceleration) == 0); 146 UInt32 pointingMode = getPointingMode(); 147 148 if ( ((pointingMode & kAccelMouse) != 0) != accelerate) 149 { 150 if ( accelerate ) 151 pointingMode |= kAccelMouse; 152 else 153 pointingMode &= ~kAccelMouse; 154 155 setPointingMode(pointingMode); 156 } 157 158 super::dispatchRelativePointerEvent(dx, dy, buttonState, timeStamp); 159} 160 161//==================================================================================================== 162// IOHIDPointing::dispatchScrollWheelEvent 163//==================================================================================================== 164void IOHIDPointing::dispatchScrollWheelEvent( 165 AbsoluteTime timeStamp, 166 SInt32 deltaAxis1, 167 SInt32 deltaAxis2, 168 UInt32 deltaAxis3, 169 IOOptionBits options) 170{ 171 // no good initial check 172 { 173 UInt32 oldEventType = getScrollType(); 174 UInt32 newEventType = oldEventType & ~( kScrollTypeMomentumAny | kScrollTypeOptionPhaseAny ); 175 bool setScroll = false; 176 177 UInt32 dispatchKey = kHIDDispatchOptionScrollMomentumContinue; 178 UInt32 eventKey = kScrollTypeMomentumContinue; 179 bool dispatchVal = options & dispatchKey ? true : false; 180 bool eventVal = oldEventType & eventKey ? true : false; 181 if (dispatchVal != eventVal) { 182 if (dispatchVal) { 183 newEventType |= eventKey; 184 } 185 setScroll = true; 186 } 187 188 dispatchKey = kHIDDispatchOptionScrollMomentumStart; 189 eventKey = kScrollTypeMomentumStart; 190 dispatchVal = options & dispatchKey ? true : false; 191 eventVal = oldEventType & eventKey ? true : false; 192 if (dispatchVal != eventVal) { 193 if (dispatchVal) { 194 newEventType |= eventKey; 195 } 196 setScroll = true; 197 } 198 199 dispatchKey = kHIDDispatchOptionScrollMomentumEnd; 200 eventKey = kScrollTypeMomentumEnd; 201 dispatchVal = options & dispatchKey ? true : false; 202 eventVal = oldEventType & eventKey ? true : false; 203 if (dispatchVal != eventVal) { 204 if (dispatchVal) { 205 newEventType |= eventKey; 206 } 207 setScroll = true; 208 } 209 210 // Slight idiom change here because kHIDDispatchOptionPhaseAny << 4 == kScrollTypeOptionPhaseAny 211 dispatchKey = (options & kHIDDispatchOptionPhaseAny) << 4; 212 eventKey = (oldEventType & kScrollTypeOptionPhaseAny); 213 if (dispatchKey != eventKey) { 214 newEventType |= dispatchKey; 215 setScroll = true; 216 } 217 218 if (setScroll) { 219 setScrollType(newEventType); 220 } 221 } 222 223 // rdar://13002702 224 bool accelerate = ((options & kHIDDispatchOptionScrollNoAcceleration) == 0) && ((options & kHIDDispatchOptionPhaseEnded) == 0); 225 UInt32 pointingMode = getPointingMode(); 226 227 if (((pointingMode & kAccelScroll) != 0) != accelerate) 228 { 229 if ( accelerate ) 230 pointingMode |= kAccelScroll; 231 else 232 pointingMode &= ~kAccelScroll; 233 234 setPointingMode(pointingMode); 235 } 236 237 super::dispatchScrollWheelEvent(deltaAxis1, deltaAxis2, deltaAxis3, timeStamp); 238} 239 240//==================================================================================================== 241// IOHIDPointing::generateDeviceID 242//==================================================================================================== 243UInt16 IOHIDPointing::generateDeviceID() 244{ 245 static UInt16 sNextDeviceID = 0x8000; 246 return sNextDeviceID++; 247} 248 249//==================================================================================================== 250// IOHIDPointing::dispatchTabletPointEvent 251//==================================================================================================== 252void IOHIDPointing::dispatchTabletEvent( 253 NXEventData * tabletEvent, 254 AbsoluteTime ts) 255{ 256 super::dispatchTabletEvent(tabletEvent, ts); 257} 258 259//==================================================================================================== 260// IOHIDPointing::dispatchTabletProximityEvent 261//==================================================================================================== 262void IOHIDPointing::dispatchProximityEvent( 263 NXEventData * proximityEvent, 264 AbsoluteTime ts) 265{ 266 super::dispatchProximityEvent(proximityEvent, ts); 267} 268 269 270// subclasses override 271 272//==================================================================================================== 273// IOHIDPointing::buttonCount 274//==================================================================================================== 275IOItemCount IOHIDPointing::buttonCount() 276{ 277 return _numButtons; 278} 279 280//==================================================================================================== 281// IOHIDPointing::resolution 282//==================================================================================================== 283IOFixed IOHIDPointing::resolution() 284{ 285 return _resolution; 286} 287 288 289//==================================================================================================== 290// IOHIDPointing::setupProperties 291//==================================================================================================== 292void IOHIDPointing::setupProperties() 293{ 294 OSNumber * number = NULL; 295 296 // Store the resolution 297 number = (OSNumber*)_provider->copyProperty(kIOHIDPointerResolutionKey); 298 if ( OSDynamicCast(OSNumber, number) ) 299 { 300 IOFixed newResolution = number->unsigned32BitValue(); 301 if ( newResolution != 0 ) { 302 _resolution = number->unsigned32BitValue(); 303 setProperty(kIOHIDPointerResolutionKey, number); 304 _isDispatcher = FALSE; 305 } 306 } 307 else if ( _resolution ) 308 { 309 setProperty(kIOHIDPointerResolutionKey, _resolution, 32); 310 } 311 OSSafeReleaseNULL(number); 312 313 // Store the scroll resolution 314 number = (OSNumber*)_provider->copyProperty(kIOHIDScrollResolutionKey); 315 if ( OSDynamicCast(OSNumber, number) ) 316 { 317 _scrollResolution = number->unsigned32BitValue(); 318 setProperty(kIOHIDScrollResolutionKey, number); 319 _isDispatcher = FALSE; 320 } 321 else if ( _scrollResolution ) 322 { 323 setProperty(kIOHIDScrollResolutionKey, _scrollResolution, 32); 324 } 325 OSSafeReleaseNULL(number); 326 327 // deal with buttons 328 if ( (_numButtons == 1) && 329 (NULL != (number = (OSNumber*)_provider->copyProperty(kIOHIDPointerButtonCountKey))) && 330 OSDynamicCast(OSNumber, number) ) 331 { 332 _numButtons = number->unsigned32BitValue(); 333 _isDispatcher = FALSE; 334 } 335 OSSafeReleaseNULL(number); 336 337 if ( _isDispatcher ) 338 setProperty(kIOHIDVirtualHIDevice, kOSBooleanTrue); 339 340 // vtn3: These unsafe, but unlikely to cause a problem. Additionally, making it "safe" is going to be cumbersome and irritating. 341 setProperty(kIOHIDScrollAccelerationTypeKey, _provider->getProperty( kIOHIDScrollAccelerationTypeKey )); 342 setProperty(kIOHIDPointerAccelerationTypeKey, _provider->getProperty( kIOHIDPointerAccelerationTypeKey )); 343 344 setProperty(kIOHIDPointerAccelerationTableKey, _provider->getProperty( kIOHIDPointerAccelerationTableKey )); 345 setProperty(kIOHIDScrollAccelerationTableKey, _provider->getProperty( kIOHIDScrollAccelerationTableKey )); 346 setProperty(kIOHIDScrollAccelerationTableXKey, _provider->getProperty( kIOHIDScrollAccelerationTableXKey )); 347 setProperty(kIOHIDScrollAccelerationTableYKey, _provider->getProperty( kIOHIDScrollAccelerationTableYKey )); 348 setProperty(kIOHIDScrollAccelerationTableZKey, _provider->getProperty( kIOHIDScrollAccelerationTableZKey )); 349 350 setProperty(kIOHIDScrollReportRateKey, _provider->getProperty( kIOHIDScrollReportRateKey )); 351 352 setProperty( kIOHIDScrollMouseButtonKey, _provider->getProperty( kIOHIDScrollMouseButtonKey )); 353 354 setProperty(kIOHIDScrollResolutionXKey, _provider->getProperty( kIOHIDScrollResolutionXKey )); 355 setProperty(kIOHIDScrollResolutionYKey, _provider->getProperty( kIOHIDScrollResolutionYKey )); 356 setProperty(kIOHIDScrollResolutionZKey, _provider->getProperty( kIOHIDScrollResolutionZKey )); 357} 358