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 99void IOHIDPointing::stop(IOService *provider) 100{ 101 _provider = NULL; 102 super::stop(provider); 103} 104 105//==================================================================================================== 106// IOHIDPointing::dispatchAbsolutePointerEvent 107//==================================================================================================== 108void IOHIDPointing::dispatchAbsolutePointerEvent( 109 AbsoluteTime timeStamp, 110 IOGPoint * newLoc, 111 IOGBounds * bounds, 112 UInt32 buttonState, 113 bool inRange, 114 SInt32 tipPressure, 115 SInt32 tipPressureMin, 116 SInt32 tipPressureMax, 117 IOOptionBits options) 118{ 119 bool convertToRelative = ((options & kHIDDispatchOptionPointerAbsolutToRelative) != 0); 120 bool accelerate = ((options & kHIDDispatchOptionPointerNoAcceleration) == 0); 121 UInt32 pointingMode = getPointingMode(); 122 123 if ( (((pointingMode & kAccelMouse) != 0) != accelerate) && (((pointingMode & kAbsoluteConvertMouse) != 0) != convertToRelative)) 124 { 125 if ( accelerate ) 126 pointingMode |= kAccelMouse; 127 else 128 pointingMode &= ~kAccelMouse; 129 130 if ( convertToRelative ) 131 pointingMode |= kAbsoluteConvertMouse; 132 else 133 pointingMode &= ~kAbsoluteConvertMouse; 134 135 setPointingMode(pointingMode); 136 } 137 138 super::dispatchAbsolutePointerEvent(newLoc, bounds, buttonState, inRange, tipPressure, tipPressureMin, tipPressureMax, 90, timeStamp); 139} 140 141//==================================================================================================== 142// IOHIDPointing::dispatchRelativePointerEvent 143//==================================================================================================== 144void IOHIDPointing::dispatchRelativePointerEvent( 145 AbsoluteTime timeStamp, 146 SInt32 dx, 147 SInt32 dy, 148 UInt32 buttonState, 149 IOOptionBits options) 150{ 151 bool accelerate = ((options & kHIDDispatchOptionPointerNoAcceleration) == 0); 152 UInt32 pointingMode = getPointingMode(); 153 154 if ( ((pointingMode & kAccelMouse) != 0) != accelerate) 155 { 156 if ( accelerate ) 157 pointingMode |= kAccelMouse; 158 else 159 pointingMode &= ~kAccelMouse; 160 161 setPointingMode(pointingMode); 162 } 163 164 super::dispatchRelativePointerEvent(dx, dy, buttonState, timeStamp); 165} 166 167//==================================================================================================== 168// IOHIDPointing::dispatchScrollWheelEvent 169//==================================================================================================== 170void IOHIDPointing::dispatchScrollWheelEvent( 171 AbsoluteTime timeStamp, 172 SInt32 deltaAxis1, 173 SInt32 deltaAxis2, 174 UInt32 deltaAxis3, 175 IOOptionBits options) 176{ 177 // no good initial check 178 { 179 UInt32 oldEventType = getScrollType(); 180 UInt32 newEventType = oldEventType & ~( kScrollTypeMomentumAny | kScrollTypeOptionPhaseAny ); 181 bool setScroll = false; 182 183 UInt32 dispatchKey = kHIDDispatchOptionScrollMomentumContinue; 184 UInt32 eventKey = kScrollTypeMomentumContinue; 185 bool dispatchVal = options & dispatchKey ? true : false; 186 bool eventVal = oldEventType & eventKey ? true : false; 187 if (dispatchVal != eventVal) { 188 if (dispatchVal) { 189 newEventType |= eventKey; 190 } 191 setScroll = true; 192 } 193 194 dispatchKey = kHIDDispatchOptionScrollMomentumStart; 195 eventKey = kScrollTypeMomentumStart; 196 dispatchVal = options & dispatchKey ? true : false; 197 eventVal = oldEventType & eventKey ? true : false; 198 if (dispatchVal != eventVal) { 199 if (dispatchVal) { 200 newEventType |= eventKey; 201 } 202 setScroll = true; 203 } 204 205 dispatchKey = kHIDDispatchOptionScrollMomentumEnd; 206 eventKey = kScrollTypeMomentumEnd; 207 dispatchVal = options & dispatchKey ? true : false; 208 eventVal = oldEventType & eventKey ? true : false; 209 if (dispatchVal != eventVal) { 210 if (dispatchVal) { 211 newEventType |= eventKey; 212 } 213 setScroll = true; 214 } 215 216 // Slight idiom change here because kHIDDispatchOptionPhaseAny << 4 == kScrollTypeOptionPhaseAny 217 dispatchKey = (options & kHIDDispatchOptionPhaseAny) << 4; 218 eventKey = (oldEventType & kScrollTypeOptionPhaseAny); 219 if (dispatchKey != eventKey) { 220 newEventType |= dispatchKey; 221 setScroll = true; 222 } 223 224 if (setScroll) { 225 setScrollType(newEventType); 226 } 227 } 228 229 // rdar://13002702 230 bool accelerate = ((options & kHIDDispatchOptionScrollNoAcceleration) == 0) && ((options & kHIDDispatchOptionPhaseEnded) == 0); 231 UInt32 pointingMode = getPointingMode(); 232 233 if (((pointingMode & kAccelScroll) != 0) != accelerate) 234 { 235 if ( accelerate ) 236 pointingMode |= kAccelScroll; 237 else 238 pointingMode &= ~kAccelScroll; 239 240 setPointingMode(pointingMode); 241 } 242 243 super::dispatchScrollWheelEvent(deltaAxis1, deltaAxis2, deltaAxis3, timeStamp); 244} 245 246//==================================================================================================== 247// IOHIDPointing::generateDeviceID 248//==================================================================================================== 249UInt16 IOHIDPointing::generateDeviceID() 250{ 251 static UInt16 sNextDeviceID = 0x8000; 252 return sNextDeviceID++; 253} 254 255//==================================================================================================== 256// IOHIDPointing::dispatchTabletPointEvent 257//==================================================================================================== 258void IOHIDPointing::dispatchTabletEvent( 259 NXEventData * tabletEvent, 260 AbsoluteTime ts) 261{ 262 super::dispatchTabletEvent(tabletEvent, ts); 263} 264 265//==================================================================================================== 266// IOHIDPointing::dispatchTabletProximityEvent 267//==================================================================================================== 268void IOHIDPointing::dispatchProximityEvent( 269 NXEventData * proximityEvent, 270 AbsoluteTime ts) 271{ 272 super::dispatchProximityEvent(proximityEvent, ts); 273} 274 275 276// subclasses override 277 278//==================================================================================================== 279// IOHIDPointing::buttonCount 280//==================================================================================================== 281IOItemCount IOHIDPointing::buttonCount() 282{ 283 return _numButtons; 284} 285 286//==================================================================================================== 287// IOHIDPointing::resolution 288//==================================================================================================== 289IOFixed IOHIDPointing::resolution() 290{ 291 return _resolution; 292} 293 294 295//==================================================================================================== 296// IOHIDPointing::setupProperties 297//==================================================================================================== 298void IOHIDPointing::setupProperties() 299{ 300 OSNumber * number = NULL; 301 302 // Store the resolution 303 number = _provider ? (OSNumber*)_provider->copyProperty(kIOHIDPointerResolutionKey) : NULL; 304 if ( OSDynamicCast(OSNumber, number) ) 305 { 306 IOFixed newResolution = number->unsigned32BitValue(); 307 if ( newResolution != 0 ) { 308 _resolution = number->unsigned32BitValue(); 309 setProperty(kIOHIDPointerResolutionKey, number); 310 _isDispatcher = FALSE; 311 } 312 } 313 else if ( _resolution ) 314 { 315 setProperty(kIOHIDPointerResolutionKey, _resolution, 32); 316 } 317 OSSafeReleaseNULL(number); 318 319 // Store the scroll resolution 320 number = _provider ? (OSNumber*)_provider->copyProperty(kIOHIDScrollResolutionKey) : NULL; 321 if ( OSDynamicCast(OSNumber, number) ) 322 { 323 _scrollResolution = number->unsigned32BitValue(); 324 setProperty(kIOHIDScrollResolutionKey, number); 325 _isDispatcher = FALSE; 326 } 327 else if ( _scrollResolution ) 328 { 329 setProperty(kIOHIDScrollResolutionKey, _scrollResolution, 32); 330 } 331 OSSafeReleaseNULL(number); 332 333 // deal with buttons 334 if ( (_numButtons == 1) && 335 (NULL != (number = _provider ? (OSNumber*)_provider->copyProperty(kIOHIDPointerButtonCountKey) : NULL)) && 336 OSDynamicCast(OSNumber, number) ) 337 { 338 _numButtons = number->unsigned32BitValue(); 339 _isDispatcher = FALSE; 340 } 341 OSSafeReleaseNULL(number); 342 343 if ( _isDispatcher ) 344 setProperty(kIOHIDVirtualHIDevice, kOSBooleanTrue); 345 346 // vtn3: These unsafe, but unlikely to cause a problem. Additionally, making it "safe" is going to be cumbersome and irritating. 347 if (_provider) { 348 setProperty(kIOHIDScrollAccelerationTypeKey, _provider->getProperty( kIOHIDScrollAccelerationTypeKey )); 349 setProperty(kIOHIDPointerAccelerationTypeKey, _provider->getProperty( kIOHIDPointerAccelerationTypeKey )); 350 351 setProperty(kIOHIDPointerAccelerationTableKey, _provider->getProperty( kIOHIDPointerAccelerationTableKey )); 352 setProperty(kIOHIDScrollAccelerationTableKey, _provider->getProperty( kIOHIDScrollAccelerationTableKey )); 353 setProperty(kIOHIDScrollAccelerationTableXKey, _provider->getProperty( kIOHIDScrollAccelerationTableXKey )); 354 setProperty(kIOHIDScrollAccelerationTableYKey, _provider->getProperty( kIOHIDScrollAccelerationTableYKey )); 355 setProperty(kIOHIDScrollAccelerationTableZKey, _provider->getProperty( kIOHIDScrollAccelerationTableZKey )); 356 357 setProperty(kIOHIDScrollReportRateKey, _provider->getProperty( kIOHIDScrollReportRateKey )); 358 359 setProperty( kIOHIDScrollMouseButtonKey, _provider->getProperty( kIOHIDScrollMouseButtonKey )); 360 361 setProperty(kIOHIDScrollResolutionXKey, _provider->getProperty( kIOHIDScrollResolutionXKey )); 362 setProperty(kIOHIDScrollResolutionYKey, _provider->getProperty( kIOHIDScrollResolutionYKey )); 363 setProperty(kIOHIDScrollResolutionZKey, _provider->getProperty( kIOHIDScrollResolutionZKey )); 364 } 365} 366