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 <AssertMacros.h> 26#include <TargetConditionals.h> 27#include <stdint.h> 28#include <IOKit/hid/IOHIDUsageTables.h> 29#include <IOKit/IOLib.h> 30#include <IOKit/usb/USB.h> 31 32#include "IOHIDKeys.h" 33#include "IOHIDSystem.h" 34#include "IOHIDEventService.h" 35#include "IOHIDInterface.h" 36#include "IOHIDPrivateKeys.h" 37#include "AppleHIDUsageTables.h" 38#include "OSStackRetain.h" 39 40#if !TARGET_OS_EMBEDDED 41 #include "IOHIDPointing.h" 42 #include "IOHIDKeyboard.h" 43 #include "IOHIDConsumer.h" 44#endif /* !TARGET_OS_EMBEDDED */ 45 46#include "IOHIDEventData.h" 47 48#include "IOHIDFamilyPrivate.h" 49#include "IOHIDevicePrivateKeys.h" 50#include "ev_private.h" 51#include "IOHIDFamilyTrace.h" 52 53enum { 54 kBootProtocolNone = 0, 55 kBootProtocolKeyboard, 56 kBootProtocolMouse 57}; 58 59enum { 60 kShimEventProcessor = 0x01 61}; 62 63#define kDefaultFixedResolution (400 << 16) 64#define kDefaultScrollFixedResolution (9 << 16) 65 66#define kMaxSystemAbsoluteRangeUnsigned 65535 67#define kMaxSystemAbsoluteRangeSigned 32767 68#define kMaxSystemBarrelPressure kMaxSystemAbsoluteRangeSigned 69#define kMaxSystemTipPressure kMaxSystemAbsoluteRangeUnsigned 70 71#define kDelayedOption (1<<31) 72 73#define NUB_LOCK if (_nubLock) IORecursiveLockLock(_nubLock) 74#define NUB_UNLOCK if (_nubLock) IORecursiveLockUnlock(_nubLock) 75 76#if TARGET_OS_EMBEDDED 77 #define SET_HID_PROPERTIES_EMBEDDED(service) \ 78 service->setProperty(kIOHIDPrimaryUsagePageKey, getPrimaryUsagePage(), 32); \ 79 service->setProperty(kIOHIDPrimaryUsageKey, getPrimaryUsage(), 32); 80#else 81 #define SET_HID_PROPERTIES_EMBEDDED(service) \ 82 {}; 83#endif 84 85 86#define SET_HID_PROPERTIES(service) \ 87 service->setProperty(kIOHIDTransportKey, getTransport()); \ 88 service->setProperty(kIOHIDLocationIDKey, getLocationID(), 32); \ 89 service->setProperty(kIOHIDVendorIDKey, getVendorID(), 32); \ 90 service->setProperty(kIOHIDVendorIDSourceKey, getVendorIDSource(), 32); \ 91 service->setProperty(kIOHIDProductIDKey, getProductID(), 32); \ 92 service->setProperty(kIOHIDVersionNumberKey, getVersion(), 32); \ 93 service->setProperty(kIOHIDCountryCodeKey, getCountryCode(), 32); \ 94 service->setProperty(kIOHIDManufacturerKey, getManufacturer()); \ 95 service->setProperty(kIOHIDProductKey, getProduct()); \ 96 service->setProperty(kIOHIDSerialNumberKey, getSerialNumber()); \ 97 service->setProperty(kIOHIDDeviceUsagePairsKey, getDeviceUsagePairs()); \ 98 service->setProperty(kIOHIDReportIntervalKey, getReportInterval(), 32); 99 100#define _provider _reserved->provider 101#define _workLoop _reserved->workLoop 102#define _deviceUsagePairs _reserved->deviceUsagePairs 103#define _commandGate _reserved->commandGate 104#define _keyboard _reserved->keyboard 105#define _multiAxis _reserved->multiAxis 106#define _digitizer _reserved->digitizer 107 108#if TARGET_OS_EMBEDDED 109 #define _clientDict _reserved->clientDict 110 111 #define kDebuggerDelayMS 2500 112 113 //=========================================================================== 114 // IOHIDClientData class 115 class IOHIDClientData : public OSObject 116 { 117 OSDeclareDefaultStructors(IOHIDClientData) 118 119 IOService * client; 120 void * context; 121 void * action; 122 123 public: 124 static IOHIDClientData* withClientInfo(IOService *client, void* context, void * action); 125 inline IOService * getClient() { return client; } 126 inline void * getContext() { return context; } 127 inline void * getAction() { return action; } 128 }; 129 130#endif /* TARGET_OS_EMBEDDED */ 131 132struct TransducerData { 133 UInt32 reportID; 134 UInt32 deviceID; 135 UInt32 type; 136 UInt32 capabilities; 137 bool digitizerCollection; 138 bool supportsTransducerIndex; 139}; 140 141//=========================================================================== 142// IOHIDEventService class 143 144#define super IOService 145 146OSDefineMetaClassAndAbstractStructors( IOHIDEventService, IOService ) 147//==================================================================================================== 148// IOHIDEventService::init 149//==================================================================================================== 150bool IOHIDEventService::init ( OSDictionary * properties ) 151{ 152 if (!super::init(properties)) 153 return false; 154 155 _reserved = IONew(ExpansionData, 1); 156 bzero(_reserved, sizeof(ExpansionData)); 157 158 _nubLock = IORecursiveLockAlloc(); 159 160#if TARGET_OS_EMBEDDED 161 _clientDict = OSDictionary::withCapacity(2); 162 if ( _clientDict == 0 ) 163 return false; 164#endif /* TARGET_OS_EMBEDDED */ 165 166 _keyboard.eject.delayMS = kEjectKeyDelayMS; 167 168 return true; 169} 170//==================================================================================================== 171// IOHIDEventService::start 172//==================================================================================================== 173bool IOHIDEventService::start ( IOService * provider ) 174{ 175 UInt32 bootProtocol = 0; 176 OSNumber *number = NULL; 177 178 _provider = provider; 179 180 if ( !super::start(provider) ) 181 return false; 182 183 if ( !handleStart(provider) ) 184 return false; 185 186 _workLoop = getWorkLoop(); 187 if ( !_workLoop ) 188 return false; 189 190 _workLoop->retain(); 191 192 _keyboard.eject.timer = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &IOHIDEventService::ejectTimerCallback)); 193 if (!_keyboard.eject.timer || (_workLoop->addEventSource(_keyboard.eject.timer) != kIOReturnSuccess)) 194 return false; 195 196 number = (OSNumber*)copyProperty(kIOHIDKeyboardEjectDelay); 197 if ( OSDynamicCast(OSNumber, number) ) 198 _keyboard.eject.delayMS = number->unsigned32BitValue(); 199 OSSafeReleaseNULL(number); 200 201 _keyboard.caps.timer = 202 IOTimerEventSource::timerEventSource(this, 203 OSMemberFunctionCast(IOTimerEventSource::Action, 204 this, 205 &IOHIDEventService::capsTimerCallback)); 206 if (!_keyboard.caps.timer || (_workLoop->addEventSource(_keyboard.caps.timer) != kIOReturnSuccess)) 207 return false; 208 209 _multiAxis.timer = 210 IOTimerEventSource::timerEventSource(this, 211 OSMemberFunctionCast(IOTimerEventSource::Action, 212 this, 213 &IOHIDEventService::multiAxisTimerCallback)); 214 if (!_multiAxis.timer || (_workLoop->addEventSource(_multiAxis.timer) != kIOReturnSuccess)) 215 return false; 216 217 218 _commandGate = IOCommandGate::commandGate(this); 219 if (!_commandGate || (_workLoop->addEventSource(_commandGate) != kIOReturnSuccess)) 220 return false; 221 222 calculateCapsLockDelay(); 223 224 calculateStandardType(); 225 226 SET_HID_PROPERTIES(this); 227 SET_HID_PROPERTIES_EMBEDDED(this); 228 229 number = (OSNumber*)copyProperty("BootProtocol"); 230 if (OSDynamicCast(OSNumber, number)) 231 bootProtocol = number->unsigned32BitValue(); 232 OSSafeReleaseNULL(number); 233 234 parseSupportedElements (getReportElements(), bootProtocol); 235 236#if !TARGET_OS_EMBEDDED 237 if ((!_consumerNub && _keyboardNub) || (!_keyboardNub && _consumerNub)) { 238 OSDictionary * matchingDictionary = IOService::serviceMatching( "IOHIDEventService" ); 239 if ( matchingDictionary ) { 240 OSDictionary * propertyMatch = OSDictionary::withCapacity(4); 241 242 if (propertyMatch) { 243 OSObject * object; 244 object = copyProperty(kIOHIDTransportKey); 245 if (object) propertyMatch->setObject(kIOHIDTransportKey, object); 246 OSSafeReleaseNULL(object); 247 248 object = copyProperty(kIOHIDVendorIDKey); 249 if (object) propertyMatch->setObject(kIOHIDVendorIDKey, object); 250 OSSafeReleaseNULL(object); 251 252 object = copyProperty(kIOHIDProductIDKey); 253 if (object) propertyMatch->setObject(kIOHIDProductIDKey, object); 254 OSSafeReleaseNULL(object); 255 256 object = copyProperty(kIOHIDLocationIDKey); 257 if (object) propertyMatch->setObject(kIOHIDLocationIDKey, object); 258 OSSafeReleaseNULL(object); 259 260 matchingDictionary->setObject(gIOPropertyMatchKey, propertyMatch); 261 262 propertyMatch->release(); 263 } 264 _publishNotify = addMatchingNotification( gIOPublishNotification, 265 matchingDictionary, 266 &IOHIDEventService::_publishMatchingNotificationHandler, 267 this, 0 ); 268 matchingDictionary->release(); 269 } 270 } 271#endif /* TARGET_OS_EMBEDDED */ 272 273 _readyForInputReports = true; 274 275 registerService(kIOServiceAsynchronous); 276 277 return true; 278} 279 280#if !TARGET_OS_EMBEDDED 281 282//==================================================================================================== 283// stopAndReleaseShim 284//==================================================================================================== 285 286static void stopAndReleaseShim ( IOService * service, IOService * provider ) 287{ 288 if ( !service ) 289 return; 290 291 IOService * serviceProvider = service->getProvider(); 292 293 if ( serviceProvider == provider ) 294 { 295 service->stop(provider); 296 service->detach(provider); 297 } 298 service->release(); 299} 300 301#endif /* TARGET_OS_EMBEDDED */ 302 303//==================================================================================================== 304// IOHIDEventService::stop 305//==================================================================================================== 306void IOHIDEventService::stop( IOService * provider ) 307{ 308 handleStop ( provider ); 309 310 if (_keyboard.caps.timer) { 311 _keyboard.caps.timer->cancelTimeout(); 312 if ( _workLoop ) 313 _workLoop->removeEventSource(_keyboard.caps.timer); 314 315 _keyboard.caps.timer->release(); 316 _keyboard.caps.timer = 0; 317 } 318 319 if (_keyboard.eject.timer) { 320 _keyboard.eject.timer->cancelTimeout(); 321 if ( _workLoop ) 322 _workLoop->removeEventSource(_keyboard.eject.timer); 323 324 _keyboard.eject.timer->release(); 325 _keyboard.eject.timer = 0; 326 } 327 328 if (_multiAxis.timer) { 329 _multiAxis.timer->cancelTimeout(); 330 if ( _workLoop ) 331 _workLoop->removeEventSource(_multiAxis.timer); 332 333 _multiAxis.timer->release(); 334 _multiAxis.timer = 0; 335 } 336 337 if (_commandGate) { 338 if ( _workLoop ) 339 _workLoop->removeEventSource(_commandGate); 340 341 _commandGate->release(); 342 _commandGate = 0; 343 } 344 345#if TARGET_OS_EMBEDDED 346 347 if ( _keyboard.debug.timer ) { 348 _keyboard.debug.timer->cancelTimeout(); 349 if ( _workLoop ) 350 _workLoop->removeEventSource(_keyboard.debug.timer); 351 352 _keyboard.debug.timer->release(); 353 _keyboard.debug.timer = 0; 354 } 355 356#else 357 358 NUB_LOCK; 359 360 stopAndReleaseShim ( _keyboardNub, this ); 361 _keyboardNub = 0; 362 363 stopAndReleaseShim ( _pointingNub, this ); 364 _pointingNub = 0; 365 366 stopAndReleaseShim ( _consumerNub, this ); 367 _consumerNub = 0; 368 369 if (_publishNotify) { 370 _publishNotify->remove(); 371 _publishNotify = 0; 372 } 373 374 NUB_UNLOCK; 375#endif /* TARGET_OS_EMBEDDED */ 376 377 super::stop( provider ); 378} 379 380//==================================================================================================== 381// IOHIDEventService::matchPropertyTable 382//==================================================================================================== 383bool IOHIDEventService::matchPropertyTable(OSDictionary * table, SInt32 * score) 384{ 385 RETAIN_ON_STACK(this); 386 // Ask our superclass' opinion. 387 if (super::matchPropertyTable(table, score) == false) 388 return false; 389 390 return MatchPropertyTable(this, table, score); 391} 392 393//==================================================================================================== 394// IOHIDEventService::_publishMatchingNotificationHandler 395//==================================================================================================== 396bool IOHIDEventService::_publishMatchingNotificationHandler( 397 void * target, 398 void * /* ref */, 399 IOService * newService, 400 IONotifier * /* notifier */) 401{ 402#if !TARGET_OS_EMBEDDED 403 IOHIDEventService * self = (IOHIDEventService *) target; 404 IOHIDEventService * service = (IOHIDEventService *) newService; 405 406 // NUB_LOCK; 407 if (self->_nubLock) IORecursiveLockLock(self->_nubLock); 408 409 if ( service->_keyboardNub ) { 410 if ( self->_keyboardNub 411 && self->_keyboardNub->isDispatcher() 412 && !service->_keyboardNub->isDispatcher() ) { 413 stopAndReleaseShim ( self->_keyboardNub, self ); 414 self->_keyboardNub = 0; 415 } 416 417 if ( !self->_keyboardNub ) { 418 self->_keyboardNub = service->_keyboardNub; 419 self->_keyboardNub->retain(); 420 421 if (self->_publishNotify) { 422 self->_publishNotify->remove(); 423 self->_publishNotify = 0; 424 } 425 } 426 } 427 428 if ( service->_consumerNub ) { 429 if ( self->_consumerNub 430 && self->_consumerNub->isDispatcher() 431 && !service->_consumerNub->isDispatcher() ) { 432 stopAndReleaseShim ( self->_consumerNub, self ); 433 self->_consumerNub = 0; 434 } 435 436 if ( !self->_consumerNub ) { 437 self->_consumerNub = service->_consumerNub; 438 self->_consumerNub->retain(); 439 440 if (self->_publishNotify) { 441 self->_publishNotify->remove(); 442 self->_publishNotify = 0; 443 } 444 } 445 } 446 447 // NUB_UNLOCK; 448 if (self->_nubLock) IORecursiveLockUnlock(self->_nubLock); 449 450#endif /* TARGET_OS_EMBEDDED */ 451 return true; 452} 453 454//==================================================================================================== 455// IOHIDEventService::calculateCapsLockDelay 456//==================================================================================================== 457void IOHIDEventService::calculateCapsLockDelay() 458{ 459 OSNumber *delay = NULL; 460 OSNumber *delayOverride = NULL; 461 OSDictionary *deviceParameters = NULL; 462 OSArray *mappings = NULL; 463 UInt32 count = 0; 464 465 // default to no delay 466 _keyboard.caps.delayMS = 0; 467 468 // If this keyboard does not support delay, get out. Otherwise, use it. 469 delay = (OSNumber*)copyProperty(kIOHIDKeyboardCapsLockDelay); 470 if (!OSDynamicCast(OSNumber, delay)) 471 goto GET_OUT; 472 _keyboard.caps.delayMS = delay->unsigned32BitValue(); 473 474 // If there is an override in place, use that. 475 476 delayOverride = (OSNumber*)copyProperty(kIOHIDKeyboardCapsLockDelayOverride); 477 if (OSDynamicCast(OSNumber, delayOverride)) 478 _keyboard.caps.delayMS = delayOverride->unsigned32BitValue(); 479 OSSafeReleaseNULL(delayOverride); 480 481 // If there is no delay at this point, get out. 482 if (!_keyboard.caps.delayMS) 483 goto GET_OUT; 484 485 // At this point, we need to scan all of the modifier mappings (if any) to see 486 // if the NX_MODIFIERKEY_ALPHALOCK is remapped to something other than the 487 // NX_MODIFIERKEY_ALPHALOCK. 488 deviceParameters = (OSDictionary*)copyProperty(kIOHIDEventServicePropertiesKey); 489 if (!OSDynamicCast(OSDictionary, deviceParameters)) 490 goto GET_OUT; 491 492 mappings = OSDynamicCast(OSArray, deviceParameters->getObject(kIOHIDKeyboardModifierMappingPairsKey)); 493 if (!mappings) goto GET_OUT; 494 495 count = mappings->getCount(); 496 if ( count ) { 497 for ( unsigned i=0; i < count; i++ ) { 498 OSDictionary *pair = OSDynamicCast(OSDictionary, mappings->getObject(i)); 499 OSNumber *number = NULL; 500 SInt32 src = 0; 501 SInt32 dst = 0; 502 503 if ( !pair ) continue; 504 505 number = OSDynamicCast(OSNumber, pair->getObject(kIOHIDKeyboardModifierMappingSrcKey)); 506 507 if ( !number ) continue; 508 509 src = number->unsigned32BitValue(); 510 511 if (src != NX_MODIFIERKEY_ALPHALOCK) continue; 512 513 number = OSDynamicCast(OSNumber, pair->getObject(kIOHIDKeyboardModifierMappingDstKey)); 514 515 if ( !number ) continue; 516 517 dst = number->unsigned32BitValue(); 518 519 if (dst == NX_MODIFIERKEY_ALPHALOCK) continue; 520 521 // NX_MODIFIERKEY_ALPHALOCK is remapped. Set delay to 0 and get out. 522 _keyboard.caps.delayMS = 0; 523 goto GET_OUT; 524 } 525 } 526 527GET_OUT: 528 OSSafeReleaseNULL(deviceParameters); 529 OSSafeReleaseNULL(delay); 530 IOHID_DEBUG(kIOHIDDebugCode_CalculatedCapsDelay, _keyboard.caps.delayMS, 0, 0, 0); 531} 532 533//==================================================================================================== 534// IOHIDEventService::calculateStandardType 535//==================================================================================================== 536void IOHIDEventService::calculateStandardType() 537{ 538 IOHIDStandardType result = kIOHIDStandardTypeANSI; 539 OSNumber * number; 540 541 number = (OSNumber*)copyProperty(kIOHIDStandardTypeKey); 542 if ( OSDynamicCast(OSNumber, number) ) { 543 result = number->unsigned32BitValue(); 544 } 545 else { 546 OSSafeReleaseNULL(number); 547 UInt16 productID = getProductID(); 548 UInt16 vendorID = getVendorID(); 549 550 if (vendorID == kIOUSBVendorIDAppleComputer) { 551 552 switch (productID) { 553 case kprodUSBCosmoISOKbd: //Cosmo ISO 554 case kprodUSBAndyISOKbd: //Andy ISO 555 case kprodQ6ISOKbd: //Q6 ISO 556 case kprodQ30ISOKbd: //Q30 ISO 557#if TARGET_OS_EMBEDDED 558 _keyboard.swapISO = true; 559#endif /* TARGET_OS_EMBEDDED */ 560 // fall through 561 case kprodFountainISOKbd: //Fountain ISO 562 case kprodSantaISOKbd: //Santa ISO 563 result = kIOHIDStandardTypeISO; 564 break; 565 case kprodUSBCosmoJISKbd: //Cosmo JIS 566 case kprodUSBAndyJISKbd: //Andy JIS is 0x206 567 case kprodQ6JISKbd: //Q6 JIS 568 case kprodQ30JISKbd: //Q30 JIS 569 case kprodFountainJISKbd: //Fountain JIS 570 case kprodSantaJISKbd: //Santa JIS 571 result = kIOHIDStandardTypeJIS; 572 break; 573 } 574 575 setProperty(kIOHIDStandardTypeKey, result, 32); 576 } 577 } 578 OSSafeReleaseNULL(number); 579 580#if TARGET_OS_EMBEDDED 581 if ( !_keyboard.swapISO && result == kIOHIDStandardTypeISO ) { 582 number = (OSNumber*)copyProperty("alt_handler_id"); 583 if ( OSDynamicCast(OSNumber, number) ) { 584 switch (number->unsigned32BitValue()) { 585 case kgestUSBCosmoISOKbd: 586 case kgestUSBAndyISOKbd: 587 case kgestQ6ISOKbd: 588 case kgestQ30ISOKbd: 589 case kgestM89ISOKbd: 590 case kgestUSBGenericISOkd: 591 _keyboard.swapISO = true; 592 break; 593 } 594 } 595 OSSafeReleaseNULL(number); 596 } 597#endif /* TARGET_OS_EMBEDDED */ 598} 599 600//==================================================================================================== 601// IOHIDEventService::setSystemProperties 602//==================================================================================================== 603IOReturn IOHIDEventService::setSystemProperties( OSDictionary * properties ) 604{ 605 OSDictionary * dict = NULL; 606 OSArray * array = NULL; 607 OSNumber * number = NULL; 608 bool setCapsDelay= false; 609 610 if ( !properties ) 611 return kIOReturnBadArgument; 612 613 if ( properties->getObject(kIOHIDDeviceParametersKey) != kOSBooleanTrue ) { 614 OSDictionary * propsCopy = OSDictionary::withDictionary(properties); 615 if ( propsCopy ) { 616 propsCopy->setObject(kIOHIDEventServicePropertiesKey, kOSBooleanTrue); 617 618#if !TARGET_OS_EMBEDDED 619 if ( _keyboardNub ) 620 _keyboardNub->setParamProperties(properties); 621 622 if ( _pointingNub ) 623 _pointingNub->setParamProperties(properties); 624 625 if ( _consumerNub ) 626 _consumerNub->setParamProperties(properties); 627#endif 628 propsCopy->release(); 629 } 630 } 631 632 number = OSDynamicCast(OSNumber, properties->getObject(kIOHIDKeyboardCapsLockDelayOverride)); 633 if (number) { 634 setProperty(kIOHIDKeyboardCapsLockDelayOverride, number); 635 setCapsDelay = true; 636 } 637 638 if ( ( array = OSDynamicCast(OSArray, properties->getObject(kIOHIDKeyboardModifierMappingPairsKey)) ) ) { 639 UInt32 srcVirtualCode, dstVirtualCode; 640 Boolean capsMap = FALSE; 641 642 for (UInt32 index=0; index<array->getCount(); index++) { 643 644 dict = OSDynamicCast(OSDictionary, array->getObject(index)); 645 if ( !dict ) 646 continue; 647 648 number = OSDynamicCast(OSNumber, dict->getObject(kIOHIDKeyboardModifierMappingSrcKey)); 649 if ( !number ) 650 continue; 651 652 srcVirtualCode = number->unsigned32BitValue(); 653 if ( srcVirtualCode != NX_MODIFIERKEY_ALPHALOCK ) 654 continue; 655 656 number = OSDynamicCast(OSNumber, dict->getObject(kIOHIDKeyboardModifierMappingDstKey)); 657 if ( !number ) 658 continue; 659 660 dstVirtualCode = number->unsigned32BitValue(); 661 if ( dstVirtualCode == srcVirtualCode ) 662 continue; 663 664 capsMap = TRUE; 665 666 break; 667 } 668 669 if ( capsMap ) { 670 // Clear out the delay 671 _keyboard.caps.delayMS = 0; 672 setCapsDelay = false; 673 } 674 else if ( !_keyboard.caps.delayMS ) { 675 setCapsDelay = true; 676 } 677 } 678 679 if (setCapsDelay) 680 calculateCapsLockDelay(); 681 682 if ( properties->getObject(kIOHIDDeviceParametersKey) == kOSBooleanTrue ) { 683 OSDictionary * eventServiceProperties = (OSDictionary*)copyProperty(kIOHIDEventServicePropertiesKey); 684 if ( OSDynamicCast(OSDictionary, eventServiceProperties) ) { 685 if (eventServiceProperties->setOptions(0, 0) & OSDictionary::kImmutable) { 686 OSDictionary * temp = eventServiceProperties; 687 eventServiceProperties = OSDynamicCast(OSDictionary, temp->copyCollection()); 688 temp->release(); 689 } 690 else { 691 // do nothing 692 } 693 } 694 else { 695 OSSafeReleaseNULL(eventServiceProperties); 696 eventServiceProperties = OSDictionary::withCapacity(4); 697 } 698 699 if ( eventServiceProperties ) { 700 eventServiceProperties->merge(properties); 701 eventServiceProperties->removeObject(kIOHIDResetKeyboardKey); 702 eventServiceProperties->removeObject(kIOHIDResetPointerKey); 703 eventServiceProperties->removeObject(kIOHIDDeviceParametersKey); 704 705 setProperty(kIOHIDEventServicePropertiesKey, eventServiceProperties); 706 eventServiceProperties->release(); 707 } 708 } 709 710 return kIOReturnSuccess; 711} 712 713//==================================================================================================== 714// IOHIDEventService::setProperties 715//==================================================================================================== 716IOReturn IOHIDEventService::setProperties( OSObject * properties ) 717{ 718 OSDictionary * propertyDict = OSDynamicCast(OSDictionary, properties); 719 IOReturn ret = kIOReturnBadArgument; 720 721 if ( propertyDict ) { 722 propertyDict->setObject(kIOHIDDeviceParametersKey, kOSBooleanTrue); 723 ret = setSystemProperties( propertyDict ); 724 propertyDict->removeObject(kIOHIDDeviceParametersKey); 725 } 726 727 return ret; 728} 729 730 731//==================================================================================================== 732// IOHIDEventService::parseSupportedElements 733//==================================================================================================== 734void IOHIDEventService::parseSupportedElements ( OSArray * elementArray, UInt32 bootProtocol ) 735{ 736 UInt32 count = 0; 737 UInt32 index = 0; 738 UInt32 usage = 0; 739 UInt32 usagePage = 0; 740 UInt32 supportedModifiers = 0; 741 UInt32 buttonCount = 0; 742 IOHIDElement * element = 0; 743 OSArray * functions = 0; 744 IOFixed pointingResolution = 0; 745 IOFixed scrollResolution = 0; 746 bool pointingDevice = false; 747 bool keyboardDevice = false; 748 bool consumerDevice = false; 749 750 switch ( bootProtocol ) 751 { 752 case kBootProtocolMouse: 753 pointingDevice = true; 754 break; 755 case kBootProtocolKeyboard: 756 keyboardDevice = true; 757 break; 758 } 759 760 if ( elementArray ) 761 { 762 count = elementArray->getCount(); 763 764 for ( index = 0; index < count; index++ ) 765 { 766 element = OSDynamicCast(IOHIDElement, elementArray->getObject(index)); 767 768 if ( !element ) 769 continue; 770 771 usagePage = element->getUsagePage(); 772 usage = element->getUsage(); 773 774 switch ( usagePage ) 775 { 776 case kHIDPage_GenericDesktop: 777 switch ( usage ) 778 { 779 case kHIDUsage_GD_Mouse: 780 pointingDevice = true; 781 break; 782 case kHIDUsage_GD_X: 783 if ( !(pointingResolution = determineResolution(element)) ) 784 pointingResolution = kDefaultFixedResolution; 785 case kHIDUsage_GD_Y: 786 case kHIDUsage_GD_Z: 787 if ((element->getFlags() & kIOHIDElementFlagsRelativeMask) == 0) 788 { 789 processTabletElement ( element ); 790 } 791 break; 792 case kHIDUsage_GD_Wheel: 793 if ( !(scrollResolution = determineResolution(element)) ) 794 scrollResolution = kDefaultScrollFixedResolution; 795 break; 796 case kHIDUsage_GD_SystemPowerDown: 797 case kHIDUsage_GD_SystemSleep: 798 case kHIDUsage_GD_SystemWakeUp: 799 consumerDevice = true; 800 break; 801 } 802 break; 803 804 case kHIDPage_Button: 805 processTabletElement ( element ); 806 buttonCount ++; 807 break; 808 809 case kHIDPage_KeyboardOrKeypad: 810 keyboardDevice = true; 811 switch ( usage ) 812 { 813 case kHIDUsage_KeyboardLeftControl: 814 supportedModifiers |= NX_CONTROLMASK; 815 supportedModifiers |= NX_DEVICELCTLKEYMASK; 816 break; 817 case kHIDUsage_KeyboardLeftShift: 818 supportedModifiers |= NX_SHIFTMASK; 819 supportedModifiers |= NX_DEVICELSHIFTKEYMASK; 820 break; 821 case kHIDUsage_KeyboardLeftAlt: 822 supportedModifiers |= NX_ALTERNATEMASK; 823 supportedModifiers |= NX_DEVICELALTKEYMASK; 824 break; 825 case kHIDUsage_KeyboardLeftGUI: 826 supportedModifiers |= NX_COMMANDMASK; 827 supportedModifiers |= NX_DEVICELCMDKEYMASK; 828 break; 829 case kHIDUsage_KeyboardRightControl: 830 supportedModifiers |= NX_CONTROLMASK; 831 supportedModifiers |= NX_DEVICERCTLKEYMASK; 832 break; 833 case kHIDUsage_KeyboardRightShift: 834 supportedModifiers |= NX_SHIFTMASK; 835 supportedModifiers |= NX_DEVICERSHIFTKEYMASK; 836 break; 837 case kHIDUsage_KeyboardRightAlt: 838 supportedModifiers |= NX_ALTERNATEMASK; 839 supportedModifiers |= NX_DEVICERALTKEYMASK; 840 break; 841 case kHIDUsage_KeyboardRightGUI: 842 supportedModifiers |= NX_COMMANDMASK; 843 supportedModifiers |= NX_DEVICERCMDKEYMASK; 844 break; 845 case kHIDUsage_KeyboardCapsLock: 846 supportedModifiers |= NX_ALPHASHIFT_STATELESS_MASK; 847 supportedModifiers |= NX_DEVICE_ALPHASHIFT_STATELESS_MASK; 848 break; 849 } 850 break; 851 852 case kHIDPage_Consumer: 853 consumerDevice = true; 854 break; 855 case kHIDPage_Digitizer: 856 pointingDevice = true; 857 switch ( usage ) 858 { 859 case kHIDUsage_Dig_Pen: 860 case kHIDUsage_Dig_LightPen: 861 case kHIDUsage_Dig_TouchScreen: 862 setProperty(kIOHIDDisplayIntegratedKey, true); 863 break; 864 case kHIDUsage_Dig_TipSwitch: 865 case kHIDUsage_Dig_BarrelSwitch: 866 case kHIDUsage_Dig_Eraser: 867 buttonCount ++; 868 default: 869 processTabletElement ( element ); 870 break; 871 } 872 break; 873 case kHIDPage_AppleVendorTopCase: 874 if ((getVendorID() == kIOUSBVendorIDAppleComputer) && 875 (usage == kHIDUsage_AV_TopCase_KeyboardFn)) 876 { 877 supportedModifiers |= NX_SECONDARYFNMASK; 878 } 879 break; 880 } 881 882 // Cache device functions 883 if ((element->getType() == kIOHIDElementTypeCollection) && 884 ((element->getCollectionType() == kIOHIDElementCollectionTypeApplication) || 885 (element->getCollectionType() == kIOHIDElementCollectionTypePhysical))) 886 { 887 OSNumber * usagePageRef, * usageRef; 888 OSDictionary * pairRef; 889 890 if(!functions) functions = OSArray::withCapacity(2); 891 892 pairRef = OSDictionary::withCapacity(2); 893 usageRef = OSNumber::withNumber(usage, 32); 894 usagePageRef= OSNumber::withNumber(usagePage, 32); 895 896 pairRef->setObject(kIOHIDDeviceUsageKey, usageRef); 897 pairRef->setObject(kIOHIDDeviceUsagePageKey, usagePageRef); 898 899 UInt32 pairCount = functions->getCount(); 900 bool found = false; 901 for(unsigned i=0; i<pairCount; i++) 902 { 903 OSDictionary *tempPair = (OSDictionary *)functions->getObject(i); 904 905 if ( NULL != (found = tempPair->isEqualTo(pairRef)) ) 906 break; 907 } 908 909 if (!found) 910 { 911 functions->setObject(functions->getCount(), pairRef); 912 } 913 914 pairRef->release(); 915 usageRef->release(); 916 usagePageRef->release(); 917 } 918 } 919 920 _deviceUsagePairs = functions; 921 } 922 923 processTransducerData(); 924 925 NUB_LOCK; 926 927 if ( pointingDevice ) 928 { 929 _pointingNub = newPointingShim(buttonCount, pointingResolution, scrollResolution, kShimEventProcessor); 930 } 931 if ( keyboardDevice ) 932 { 933 _keyboardNub = newKeyboardShim(supportedModifiers, kShimEventProcessor); 934 } 935 if ( consumerDevice ) 936 { 937 _consumerNub = newConsumerShim(kShimEventProcessor); 938 } 939 940 NUB_UNLOCK; 941} 942 943//==================================================================================================== 944// IOHIDEventService::processTabletElement 945//==================================================================================================== 946void IOHIDEventService::processTabletElement ( IOHIDElement * element ) 947{ 948 TransducerData * transducerRef; 949 IOHIDElement * parent; 950 951 transducerRef = getTransducerData(element->getReportID()); 952 953 if ( !transducerRef ) 954 { 955 transducerRef = createTransducerData ( element->getReportID() ); 956 } 957 958 if ( element->getUsagePage() == kHIDPage_Digitizer ) 959 { 960 switch (element->getUsage()) 961 { 962 case kHIDUsage_Dig_Stylus: 963 transducerRef->type = NX_TABLET_POINTER_PEN; 964 break; 965 case kHIDUsage_Dig_Puck: 966 transducerRef->type = NX_TABLET_POINTER_CURSOR; 967 break; 968 case kHIDUsage_Dig_XTilt: 969 transducerRef->capabilities |= NX_TABLET_CAPABILITY_TILTXMASK; 970 break; 971 case kHIDUsage_Dig_YTilt: 972 transducerRef->capabilities |= NX_TABLET_CAPABILITY_TILTYMASK; 973 break; 974 case kHIDUsage_Dig_TipPressure: 975 if ( transducerRef->type == NX_TABLET_POINTER_UNKNOWN ) 976 transducerRef->type = NX_TABLET_POINTER_PEN; 977 978 transducerRef->capabilities |= NX_TABLET_CAPABILITY_PRESSUREMASK; 979 break; 980 case kHIDUsage_Dig_BarrelPressure: 981 if ( transducerRef->type == NX_TABLET_POINTER_UNKNOWN ) 982 transducerRef->type = NX_TABLET_POINTER_PEN; 983 984 transducerRef->capabilities |= NX_TABLET_CAPABILITY_TANGENTIALPRESSUREMASK; 985 break; 986 case kHIDUsage_Dig_Twist: 987 transducerRef->capabilities |= NX_TABLET_CAPABILITY_ROTATIONMASK; 988 break; 989 case kHIDUsage_Dig_TransducerIndex: 990 transducerRef->supportsTransducerIndex = true; 991 break; 992 case kHIDUsage_Dig_Eraser: 993 if ( transducerRef->type == NX_TABLET_POINTER_UNKNOWN ) 994 transducerRef->type = NX_TABLET_POINTER_ERASER; 995 case kHIDUsage_Dig_TipSwitch: 996 case kHIDUsage_Dig_BarrelSwitch: 997 if ( transducerRef->type == NX_TABLET_POINTER_UNKNOWN ) 998 transducerRef->type = NX_TABLET_POINTER_PEN; 999 1000 transducerRef->capabilities |= NX_TABLET_CAPABILITY_BUTTONSMASK; 1001 break; 1002 } 1003 } 1004 else if ( element->getUsagePage() == kHIDPage_GenericDesktop ) 1005 { 1006 switch (element->getUsage()) 1007 { 1008 case kHIDUsage_GD_X: 1009 transducerRef->capabilities |= NX_TABLET_CAPABILITY_ABSXMASK; 1010 break; 1011 case kHIDUsage_GD_Y: 1012 transducerRef->capabilities |= NX_TABLET_CAPABILITY_ABSYMASK; 1013 break; 1014 case kHIDUsage_GD_Z: 1015 transducerRef->capabilities |= NX_TABLET_CAPABILITY_ABSZMASK; 1016 break; 1017 } 1018 } 1019 else if ( element->getUsagePage() == kHIDPage_Button ) 1020 { 1021 transducerRef->capabilities |= NX_TABLET_CAPABILITY_BUTTONSMASK; 1022 } 1023 1024 if ( element->getType() != kIOHIDElementTypeCollection ) 1025 { 1026 parent = element->getParentElement(); 1027 1028 if ( parent && ( parent->getUsagePage() == kHIDPage_Digitizer )) 1029 { 1030 transducerRef->digitizerCollection = true; 1031 } 1032 } 1033} 1034 1035//==================================================================================================== 1036// IOHIDEventService::createTransducerData 1037//==================================================================================================== 1038TransducerData * IOHIDEventService::createTransducerData ( UInt32 transducerID ) 1039{ 1040 TransducerData temp; 1041 OSData * data; 1042 1043 if ( ! _transducerDataArray ) 1044 _transducerDataArray = OSArray::withCapacity(4); 1045 1046 bzero(&temp, sizeof(TransducerData)); 1047 1048 temp.reportID = transducerID; 1049 temp.type = NX_TABLET_POINTER_UNKNOWN; 1050 1051 data = OSData::withBytes(&temp, sizeof(TransducerData)); 1052 1053 _transducerDataArray->setObject(data); 1054 data->release(); 1055 1056 return (data) ? (TransducerData *)data->getBytesNoCopy() : 0; 1057} 1058 1059//==================================================================================================== 1060// IOHIDEventService::getTransducerData 1061//==================================================================================================== 1062TransducerData * IOHIDEventService::getTransducerData ( UInt32 transducerID ) 1063{ 1064 TransducerData * transducerRef = 0; 1065 TransducerData * transducerIndexRef = 0; 1066 OSData * data = 0; 1067 bool found = 0; 1068 1069 if ( !_transducerDataArray ) 1070 return NULL; 1071 1072 UInt32 count = _transducerDataArray->getCount(); 1073 1074 for (unsigned i=0; i<count; i++) 1075 { 1076 data = (OSData *)_transducerDataArray->getObject(i); 1077 1078 if (!data) continue; 1079 1080 transducerRef = (TransducerData *)data->getBytesNoCopy(); 1081 1082 if (!transducerRef) continue; 1083 1084 if (transducerRef->supportsTransducerIndex) 1085 transducerIndexRef = transducerRef; 1086 1087 if (transducerRef->reportID != transducerID) continue; 1088 1089 found = true; 1090 break; 1091 } 1092 1093 return ( found ) ? transducerRef : transducerIndexRef; 1094} 1095 1096//==================================================================================================== 1097// IOHIDEventService::processTransducerData 1098//==================================================================================================== 1099void IOHIDEventService::processTransducerData () 1100{ 1101#if !TARGET_OS_EMBEDDED 1102 TransducerData * transducerRef; 1103 OSData * data; 1104 1105 if ( ! _transducerDataArray ) 1106 return; 1107 1108 for (unsigned i=0; i<_transducerDataArray->getCount(); i++) 1109 { 1110 data = (OSData *)_transducerDataArray->getObject(i); 1111 1112 if (!data) continue; 1113 1114 transducerRef = (TransducerData *)data->getBytesNoCopy(); 1115 1116 if ( (transducerRef->capabilities & ~NX_TABLET_CAPABILITY_BUTTONSMASK) || 1117 (transducerRef->digitizerCollection)) 1118 { 1119 transducerRef->deviceID = IOHIDPointing::generateDeviceID(); 1120 transducerRef->capabilities |= NX_TABLET_CAPABILITY_DEVICEIDMASK; 1121 } 1122 else 1123 { 1124 _transducerDataArray->removeObject(i--); 1125 } 1126 } 1127 1128 if ( _transducerDataArray->getCount() == 0 ) 1129 { 1130 _transducerDataArray->release(); 1131 _transducerDataArray = 0; 1132 } 1133#endif /* TARGET_OS_EMBEDDED */ 1134} 1135 1136//==================================================================================================== 1137// IOHIDEventService::newPointingShim 1138//==================================================================================================== 1139IOHIDPointing * IOHIDEventService::newPointingShim ( 1140 UInt32 buttonCount, 1141 IOFixed pointerResolution, 1142 IOFixed scrollResolution, 1143 IOOptionBits options) 1144{ 1145#if !TARGET_OS_EMBEDDED // { 1146 bool isDispatcher = ((options & kShimEventProcessor) == 0); 1147 IOHIDPointing *pointingNub = IOHIDPointing::Pointing(buttonCount, pointerResolution, scrollResolution, isDispatcher);; 1148 1149 require(pointingNub, no_nub); 1150 1151 SET_HID_PROPERTIES(pointingNub); 1152 1153 require(pointingNub->attach(this), no_attach); 1154 require(pointingNub->start(this), no_start); 1155 1156 return pointingNub; 1157 1158no_start: 1159 pointingNub->detach(this); 1160 1161no_attach: 1162 pointingNub->release(); 1163 pointingNub = NULL; 1164 1165no_nub: 1166 1167#endif // } TARGET_OS_EMBEDDED 1168 return NULL; 1169} 1170 1171//==================================================================================================== 1172// IOHIDEventService::newKeyboardShim 1173//==================================================================================================== 1174IOHIDKeyboard * IOHIDEventService::newKeyboardShim ( 1175 UInt32 supportedModifiers, 1176 IOOptionBits options) 1177{ 1178#if !TARGET_OS_EMBEDDED // { 1179 bool isDispatcher = ((options & kShimEventProcessor) == 0); 1180 IOHIDKeyboard *keyboardNub = IOHIDKeyboard::Keyboard(supportedModifiers, isDispatcher); 1181 1182 require(keyboardNub, no_nub); 1183 1184 SET_HID_PROPERTIES(keyboardNub); 1185 1186 require(keyboardNub->attach(this), no_attach); 1187 require(keyboardNub->start(this), no_start); 1188 1189 return keyboardNub; 1190 1191no_start: 1192 keyboardNub->detach(this); 1193 1194no_attach: 1195 keyboardNub->release(); 1196 keyboardNub = NULL; 1197 1198no_nub: 1199 1200#endif // } TARGET_OS_EMBEDDED 1201 return NULL; 1202} 1203 1204//==================================================================================================== 1205// IOHIDEventService::newConsumerShim 1206//==================================================================================================== 1207IOHIDConsumer * IOHIDEventService::newConsumerShim ( IOOptionBits options ) 1208{ 1209#if !TARGET_OS_EMBEDDED // { 1210 bool isDispatcher = ((options & kShimEventProcessor) == 0); 1211 IOHIDConsumer *consumerNub = IOHIDConsumer::Consumer(isDispatcher);; 1212 1213 require(consumerNub, no_nub); 1214 1215 SET_HID_PROPERTIES(consumerNub); 1216 1217 require(consumerNub->attach(this), no_attach); 1218 require(consumerNub->start(this), no_start); 1219 1220 return consumerNub; 1221 1222no_start: 1223 consumerNub->detach(this); 1224 1225no_attach: 1226 consumerNub->release(); 1227 consumerNub = NULL; 1228 1229no_nub: 1230 1231#endif // } TARGET_OS_EMBEDDED 1232 return NULL; 1233} 1234 1235//==================================================================================================== 1236// IOHIDEventService::determineResolution 1237//==================================================================================================== 1238IOFixed IOHIDEventService::determineResolution ( IOHIDElement * element ) 1239{ 1240 IOFixed resolution = 0; 1241 bool supportResolution = true; 1242 1243 if ((element->getFlags() & kIOHIDElementFlagsRelativeMask) != 0) { 1244 1245 if ( element->conformsTo(kHIDPage_GenericDesktop, kHIDUsage_GD_MultiAxisController) ) 1246 supportResolution = false; 1247 } 1248 else { 1249 supportResolution = false; 1250 } 1251 1252 if ( supportResolution ) { 1253 if ((element->getPhysicalMin() != element->getLogicalMin()) && 1254 (element->getPhysicalMax() != element->getLogicalMax())) 1255 { 1256 SInt32 logicalDiff = (element->getLogicalMax() - element->getLogicalMin()); 1257 SInt32 physicalDiff = (element->getPhysicalMax() - element->getPhysicalMin()); 1258 1259 // Since IOFixedDivide truncated fractional part and can't use floating point 1260 // within the kernel, have to convert equation when using negative exponents: 1261 // _resolution = ((logMax -logMin) * 10 **(-exp))/(physMax -physMin) 1262 1263 // Even though unitExponent is stored as SInt32, The real values are only 1264 // a signed nibble that doesn't expand to the full 32 bits. 1265 SInt32 resExponent = element->getUnitExponent() & 0x0F; 1266 1267 if (resExponent < 8) 1268 { 1269 for (int i = resExponent; i > 0; i--) 1270 { 1271 physicalDiff *= 10; 1272 } 1273 } 1274 else 1275 { 1276 for (int i = 0x10 - resExponent; i > 0; i--) 1277 { 1278 logicalDiff *= 10; 1279 } 1280 } 1281 resolution = (logicalDiff / physicalDiff) << 16; 1282 } 1283 } 1284 1285 return resolution; 1286} 1287 1288//==================================================================================================== 1289// IOHIDEventService::free 1290//==================================================================================================== 1291void IOHIDEventService::free() 1292{ 1293 IORecursiveLock* tempLock = NULL; 1294 1295 if ( _nubLock ) { 1296 IORecursiveLockLock(_nubLock); 1297 tempLock = _nubLock; 1298 _nubLock = NULL; 1299 } 1300 1301 if ( _transducerDataArray ) { 1302 _transducerDataArray->release(); 1303 _transducerDataArray = 0; 1304 } 1305 1306 if ( _transducerDataArray ) { 1307 _transducerDataArray->release(); 1308 _transducerDataArray = 0; 1309 } 1310 1311 if (_keyboard.eject.timer) { 1312 if ( _workLoop ) 1313 _workLoop->removeEventSource(_keyboard.eject.timer); 1314 1315 _keyboard.eject.timer->release(); 1316 _keyboard.eject.timer = 0; 1317 } 1318 1319 if (_commandGate) { 1320 if ( _workLoop ) 1321 _workLoop->removeEventSource(_commandGate); 1322 1323 _commandGate->release(); 1324 _commandGate = 0; 1325 } 1326 1327 if (_keyboard.caps.timer) { 1328 if ( _workLoop ) 1329 _workLoop->removeEventSource(_keyboard.caps.timer); 1330 1331 _keyboard.caps.timer->release(); 1332 _keyboard.caps.timer = 0; 1333 } 1334 1335#if TARGET_OS_EMBEDDED 1336 if ( _deviceUsagePairs ) { 1337 _deviceUsagePairs->release(); 1338 _deviceUsagePairs = NULL; 1339 } 1340 1341 if ( _clientDict ) { 1342 assert(_clientDict->getCount() == 0); 1343 _clientDict->release(); 1344 _clientDict = NULL; 1345 } 1346 1347 if (_keyboard.debug.timer) { 1348 if ( _workLoop ) 1349 _workLoop->removeEventSource(_keyboard.debug.timer); 1350 1351 _keyboard.debug.timer->release(); 1352 _keyboard.debug.timer = 0; 1353 } 1354 1355#endif /* TARGET_OS_EMBEDDED */ 1356 1357 if ( _workLoop ) { 1358 // not our workloop. don't stop it. 1359 _workLoop->release(); 1360 _workLoop = NULL; 1361 } 1362 1363 if (_reserved) { 1364 IODelete(_reserved, ExpansionData, 1); 1365 _reserved = NULL; 1366 } 1367 1368 if ( tempLock ) { 1369 IORecursiveLockUnlock(tempLock); 1370 IORecursiveLockFree(tempLock); 1371 } 1372 1373 super::free(); 1374} 1375 1376//============================================================================== 1377// IOHIDEventService::handleOpen 1378//============================================================================== 1379bool IOHIDEventService::handleOpen(IOService * client, 1380 IOOptionBits options, 1381 void * argument) 1382{ 1383#if TARGET_OS_EMBEDDED 1384 1385 bool accept = false; 1386 do { 1387 // Was this object already registered as our client? 1388 1389 if ( _clientDict->getObject((const OSSymbol *)client) ) { 1390 accept = true; 1391 break; 1392 } 1393 1394 // Add the new client object to our client dict. 1395 if ( !OSDynamicCast(IOHIDClientData, (OSObject *)argument) || 1396 !_clientDict->setObject((const OSSymbol *)client, (IOHIDClientData *)argument)) 1397 break; 1398 1399 accept = true; 1400 } while (false); 1401 1402 return accept; 1403 1404#else 1405 1406 return super::handleOpen(client, options, argument); 1407 1408#endif /* TARGET_OS_EMBEDDED */ 1409 1410} 1411 1412//============================================================================== 1413// IOHIDEventService::handleClose 1414//============================================================================== 1415void IOHIDEventService::handleClose(IOService * client, IOOptionBits options) 1416{ 1417#if TARGET_OS_EMBEDDED 1418 if ( _clientDict->getObject((const OSSymbol *)client) ) 1419 _clientDict->removeObject((const OSSymbol *)client); 1420#else 1421 super::handleClose(client, options); 1422#endif /* TARGET_OS_EMBEDDED */ 1423} 1424 1425//============================================================================== 1426// IOHIDEventService::handleIsOpen 1427//============================================================================== 1428bool IOHIDEventService::handleIsOpen(const IOService * client) const 1429{ 1430#if TARGET_OS_EMBEDDED 1431 if (client) 1432 return _clientDict->getObject((const OSSymbol *)client) != NULL; 1433 else 1434 return (_clientDict->getCount() > 0); 1435#else 1436 return super::handleIsOpen(client); 1437#endif /* TARGET_OS_EMBEDDED */ 1438} 1439 1440//==================================================================================================== 1441// IOHIDEventService::handleStart 1442//==================================================================================================== 1443bool IOHIDEventService::handleStart( IOService * provider __unused ) 1444{ 1445 return true; 1446} 1447 1448//==================================================================================================== 1449// IOHIDEventService::handleStop 1450//==================================================================================================== 1451void IOHIDEventService::handleStop( IOService * provider __unused ) 1452{} 1453 1454//==================================================================================================== 1455// IOHIDEventService::getTransport 1456//==================================================================================================== 1457OSString * IOHIDEventService::getTransport () 1458{ 1459 return _provider ? OSDynamicCast(OSString, _provider->getProperty(kIOHIDTransportKey)) : 0; 1460} 1461 1462//==================================================================================================== 1463// IOHIDEventService::getManufacturer 1464//==================================================================================================== 1465OSString * IOHIDEventService::getManufacturer () 1466{ 1467 // vtn3: This is not safe, but I am unsure how to fix it 1468 return _provider ? OSDynamicCast(OSString, _provider->getProperty(kIOHIDManufacturerKey)) : 0; 1469} 1470 1471//==================================================================================================== 1472// IOHIDEventService::getProduct 1473//==================================================================================================== 1474OSString * IOHIDEventService::getProduct () 1475{ 1476 // vtn3: This is not safe, but I am unsure how to fix it 1477 return _provider ? OSDynamicCast(OSString, _provider->getProperty(kIOHIDProductKey)) : 0; 1478} 1479 1480//==================================================================================================== 1481// IOHIDEventService::getSerialNumber 1482//==================================================================================================== 1483OSString * IOHIDEventService::getSerialNumber () 1484{ 1485 // vtn3: This is not safe, but I am unsure how to fix it 1486 return _provider ? OSDynamicCast(OSString, _provider->getProperty(kIOHIDSerialNumberKey)) : 0; 1487} 1488 1489//==================================================================================================== 1490// IOHIDEventService::getLocationID 1491//==================================================================================================== 1492UInt32 IOHIDEventService::getLocationID () 1493{ 1494 UInt32 value = 0; 1495 1496 if ( _provider ) { 1497 OSNumber * number = (OSNumber*)_provider->copyProperty(kIOHIDSerialNumberKey); 1498 if ( OSDynamicCast(OSNumber, number) ) 1499 value = number->unsigned32BitValue(); 1500 OSSafeReleaseNULL(number); 1501 } 1502 return value; 1503} 1504 1505//==================================================================================================== 1506// IOHIDEventService::getVendorID 1507//==================================================================================================== 1508UInt32 IOHIDEventService::getVendorID () 1509{ 1510 UInt32 value = 0; 1511 1512 if ( _provider ) { 1513 OSNumber * number = (OSNumber*)_provider->copyProperty(kIOHIDVendorIDKey); 1514 if ( OSDynamicCast(OSNumber, number) ) 1515 value = number->unsigned32BitValue(); 1516 OSSafeReleaseNULL(number); 1517 } 1518 return value; 1519} 1520 1521//==================================================================================================== 1522// IOHIDEventService::getVendorIDSource 1523//==================================================================================================== 1524UInt32 IOHIDEventService::getVendorIDSource () 1525{ 1526 UInt32 value = 0; 1527 1528 if ( _provider ) { 1529 OSNumber * number = (OSNumber*)_provider->copyProperty(kIOHIDVendorIDSourceKey); 1530 if ( OSDynamicCast(OSNumber, number) ) 1531 value = number->unsigned32BitValue(); 1532 OSSafeReleaseNULL(number); 1533 } 1534 return value; 1535} 1536 1537//==================================================================================================== 1538// IOHIDEventService::getProductID 1539//==================================================================================================== 1540UInt32 IOHIDEventService::getProductID () 1541{ 1542 UInt32 value = 0; 1543 1544 if ( _provider ) { 1545 OSNumber * number = (OSNumber*)_provider->copyProperty(kIOHIDProductIDKey); 1546 if ( OSDynamicCast(OSNumber, number) ) 1547 value = number->unsigned32BitValue(); 1548 OSSafeReleaseNULL(number); 1549 } 1550 return value; 1551} 1552 1553//==================================================================================================== 1554// IOHIDEventService::getVersion 1555//==================================================================================================== 1556UInt32 IOHIDEventService::getVersion () 1557{ 1558 UInt32 value = 0; 1559 1560 if ( _provider ) { 1561 OSNumber * number = (OSNumber*)_provider->copyProperty(kIOHIDVersionNumberKey); 1562 if ( OSDynamicCast(OSNumber, number) ) 1563 value = number->unsigned32BitValue(); 1564 OSSafeReleaseNULL(number); 1565 } 1566 return value; 1567} 1568 1569//==================================================================================================== 1570// IOHIDEventService::getCountryCode 1571//==================================================================================================== 1572UInt32 IOHIDEventService::getCountryCode () 1573{ 1574 UInt32 value = 0; 1575 1576 if ( _provider ) { 1577 OSNumber * number = (OSNumber*)_provider->copyProperty(kIOHIDCountryCodeKey); 1578 if ( OSDynamicCast(OSNumber, number) ) 1579 value = number->unsigned32BitValue(); 1580 OSSafeReleaseNULL(number); 1581 } 1582 return value; 1583} 1584 1585//==================================================================================================== 1586// IOHIDEventService::getReportElements 1587//==================================================================================================== 1588OSArray * IOHIDEventService::getReportElements() 1589{ 1590 return 0; 1591} 1592 1593//==================================================================================================== 1594// IOHIDEventService::setElementValue 1595//==================================================================================================== 1596void IOHIDEventService::setElementValue ( 1597 UInt32 usagePage __unused, 1598 UInt32 usage __unused, 1599 UInt32 value __unused ) 1600{ 1601} 1602 1603//==================================================================================================== 1604// IOHIDEventService::getElementValue 1605//==================================================================================================== 1606UInt32 IOHIDEventService::getElementValue ( 1607 UInt32 usagePage __unused, 1608 UInt32 usage __unused ) 1609{ 1610 return 0; 1611} 1612 1613 1614//==================================================================================================== 1615// ejectTimerCallback 1616//==================================================================================================== 1617void IOHIDEventService::ejectTimerCallback(IOTimerEventSource *sender __unused) 1618{ 1619 IOHID_DEBUG(kIOHIDDebugCode_EjectCallback, _keyboard.eject.state, 0, 0, 0); 1620 if ( _keyboard.eject.state ) { 1621 AbsoluteTime timeStamp; 1622 1623 clock_get_uptime(&timeStamp); 1624 1625 dispatchKeyboardEvent(timeStamp, kHIDPage_Consumer, kHIDUsage_Csmr_Eject, 1, _keyboard.eject.options | kDelayedOption); 1626 dispatchKeyboardEvent(timeStamp, kHIDPage_Consumer, kHIDUsage_Csmr_Eject, 0, _keyboard.eject.options | kDelayedOption); 1627 1628 _keyboard.eject.state = 0; 1629 } 1630} 1631 1632//==================================================================================================== 1633// capsTimerCallback 1634//==================================================================================================== 1635void IOHIDEventService::capsTimerCallback(IOTimerEventSource *sender __unused) 1636{ 1637 IOHID_DEBUG(kIOHIDDebugCode_CapsCallback, _keyboard.caps.state, 0, 0, 0); 1638 if ( _keyboard.caps.state ) { 1639 AbsoluteTime timeStamp; 1640 1641 clock_get_uptime(&timeStamp); 1642 1643 dispatchKeyboardEvent(timeStamp, kHIDPage_KeyboardOrKeypad, kHIDUsage_KeyboardCapsLock, 1, _keyboard.caps.options | kDelayedOption); 1644 dispatchKeyboardEvent(timeStamp, kHIDPage_KeyboardOrKeypad, kHIDUsage_KeyboardCapsLock, 0, _keyboard.caps.options | kDelayedOption); 1645 1646 _keyboard.caps.state = 0; 1647 } 1648} 1649 1650 1651#if TARGET_OS_EMBEDDED 1652//============================================================================== 1653// IOHIDEventService::debuggerTimerCallback 1654//============================================================================== 1655void IOHIDEventService::debuggerTimerCallback(IOTimerEventSource *sender) 1656{ 1657 if ( _keyboard.debug.mask && _keyboard.debug.mask == _keyboard.debug.startMask ) 1658 PE_enter_debugger("NMI"); 1659} 1660 1661#endif /* TARGET_OS_EMBEDDED */ 1662 1663//============================================================================== 1664// IOHIDEventService::multiAxisTimerCallback 1665//============================================================================== 1666void IOHIDEventService::multiAxisTimerCallback(IOTimerEventSource *sender __unused) 1667{ 1668 AbsoluteTime timestamp; 1669 1670 clock_get_uptime(×tamp); 1671 dispatchMultiAxisPointerEvent(timestamp, _multiAxis.buttonState, _multiAxis.x, _multiAxis.y, _multiAxis.z, _multiAxis.rX, _multiAxis.rY, _multiAxis.rZ, _multiAxis.options | kIOHIDEventOptionIsRepeat); 1672} 1673 1674 1675//==================================================================================================== 1676// IOHIDEventService::dispatchKeyboardEvent 1677//==================================================================================================== 1678void IOHIDEventService::dispatchKeyboardEvent( 1679 AbsoluteTime timeStamp, 1680 UInt32 usagePage, 1681 UInt32 usage, 1682 UInt32 value, 1683 IOOptionBits options) 1684{ 1685 if ( ! _readyForInputReports ) 1686 return; 1687 1688#if TARGET_OS_EMBEDDED // { 1689 IOHIDEvent * event = NULL; 1690 UInt32 debugMask = 0; 1691 1692 switch (usagePage) { 1693 case kHIDPage_KeyboardOrKeypad: 1694 if ( _keyboard.swapISO ) { 1695 1696 switch ( usage ) { 1697 case kHIDUsage_KeyboardGraveAccentAndTilde: 1698 usage = kHIDUsage_KeyboardNonUSBackslash; 1699 break; 1700 case kHIDUsage_KeyboardNonUSBackslash: 1701 usage = kHIDUsage_KeyboardGraveAccentAndTilde; 1702 break; 1703 } 1704 } 1705 break; 1706 case kHIDPage_Consumer: 1707 switch (usage) { 1708 case kHIDUsage_Csmr_Power: 1709 debugMask = 0x1; 1710 break; 1711 case kHIDUsage_Csmr_VolumeIncrement: 1712 case kHIDUsage_Csmr_VolumeDecrement: 1713 debugMask = 0x2; 1714 break; 1715 }; 1716 break; 1717 case kHIDPage_Telephony: 1718 switch (usage) { 1719 case kHIDUsage_Tfon_Hold: 1720 debugMask = 0x1; 1721 break; 1722 }; 1723 break; 1724 }; 1725 1726 if ( value ) 1727 _keyboard.debug.mask |= debugMask; 1728 else 1729 _keyboard.debug.mask &= ~debugMask; 1730 1731 if ( _keyboard.debug.mask == 0x3) { 1732 if ( !_keyboard.debug.timer ) { 1733 _keyboard.debug.timer = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &IOHIDEventService::debuggerTimerCallback)); 1734 if (_keyboard.debug.timer) { 1735 if ((_workLoop->addEventSource(_keyboard.debug.timer) != kIOReturnSuccess)) { 1736 _keyboard.debug.timer->release(); 1737 _keyboard.debug.timer = NULL; 1738 } 1739 } 1740 } 1741 if ( _keyboard.debug.timer ) { 1742 _keyboard.debug.timer->setTimeoutMS( kDebuggerDelayMS ); 1743 _keyboard.debug.startMask = _keyboard.debug.mask; 1744 } 1745 } 1746 1747 event = IOHIDEvent::keyboardEvent(timeStamp, usagePage, usage, value, options); 1748 if ( !event ) 1749 return; 1750 1751 dispatchEvent(event); 1752 1753 event->release(); 1754 1755#else // } { 1756 1757 NUB_LOCK; 1758 1759 IOHID_DEBUG(kIOHIDDebugCode_DispatchKeyboard, usagePage, usage, value, options); 1760 1761 if ((( usagePage == kHIDPage_KeyboardOrKeypad ) && 1762 (usage != kHIDUsage_KeyboardLockingNumLock) && 1763 !(_keyboard.caps.delayMS && (usage == kHIDUsage_KeyboardCapsLock))) || 1764 ((getVendorID() == kIOUSBVendorIDAppleComputer) && 1765 ((usagePage == kHIDPage_AppleVendorKeyboard) || 1766 ((usagePage == kHIDPage_AppleVendorTopCase) && 1767 (usage == kHIDUsage_AV_TopCase_KeyboardFn))))) { 1768 if ( !_keyboardNub ) 1769 _keyboardNub = newKeyboardShim(); 1770 1771 if ( _keyboardNub ) 1772 _keyboardNub->dispatchKeyboardEvent(timeStamp, usagePage, usage, (value != 0), options); 1773 1774 } 1775 else { 1776 if ( !_consumerNub ) 1777 _consumerNub = newConsumerShim(); 1778 1779 if ( _consumerNub ) { 1780 if ( (usagePage == kHIDPage_Consumer) && (usage == kHIDUsage_Csmr_Eject) && ((options & kDelayedOption) == 0) && _keyboardNub && ((_keyboardNub->eventFlags() & SPECIALKEYS_MODIFIER_MASK) == 0)) { 1781 if (( _keyboard.eject.state != value ) && _keyboard.eject.timer) { 1782 if ( value ) { 1783 _keyboard.eject.options = options; 1784 1785 _keyboard.eject.timer->setTimeoutMS( _keyboard.eject.delayMS ); 1786 } 1787 else { 1788 _keyboard.eject.timer->cancelTimeout(); 1789 } 1790 1791 _keyboard.eject.state = value; 1792 } 1793 } 1794 else if (!(((options & kDelayedOption) == 0) && _keyboard.eject.state && (usagePage == kHIDPage_Consumer) && (usage == kHIDUsage_Csmr_Eject))) { 1795 _consumerNub->dispatchConsumerEvent(_keyboardNub, timeStamp, usagePage, usage, value, options); 1796 } 1797 } 1798 1799 if ( _keyboard.caps.delayMS && (usagePage == kHIDPage_KeyboardOrKeypad) && (usage == kHIDUsage_KeyboardCapsLock)) { 1800 if ( (options & kDelayedOption) == 0) { 1801 1802 if ( getElementValue(kHIDPage_LEDs, kHIDUsage_LED_CapsLock) == 0 ) { 1803 if (( _keyboard.caps.state != value ) && _keyboard.caps.timer ) { 1804 if ( value ) { 1805 _keyboard.caps.options = options; 1806 1807 _keyboard.caps.timer->setTimeoutMS( _keyboard.caps.delayMS ); 1808 } 1809 else { 1810 _keyboard.caps.timer->cancelTimeout(); 1811 } 1812 1813 _keyboard.caps.state = value; 1814 } 1815 } 1816 else { 1817 _keyboardNub->dispatchKeyboardEvent(timeStamp, usagePage, usage, value, options); 1818 } 1819 } 1820 else if (!( ((options & kDelayedOption) == 0) && _keyboard.caps.state ) ) { 1821 _keyboardNub->dispatchKeyboardEvent(timeStamp, usagePage, usage, value, options); 1822 } 1823 } 1824 } 1825 1826 NUB_UNLOCK; 1827 1828#endif /* TARGET_OS_EMBEDDED */ // } 1829 1830} 1831 1832 1833//==================================================================================================== 1834// IOHIDEventService::dispatchRelativePointerEvent 1835//==================================================================================================== 1836void IOHIDEventService::dispatchRelativePointerEvent( 1837 AbsoluteTime timeStamp, 1838 SInt32 dx, 1839 SInt32 dy, 1840 UInt32 buttonState, 1841 IOOptionBits options) 1842{ 1843 IOHID_DEBUG(kIOHIDDebugCode_DispatchRelativePointer, dx, dy, buttonState, options); 1844 1845 if ( ! _readyForInputReports ) 1846 return; 1847 1848#if TARGET_OS_EMBEDDED 1849 1850 IOHIDEvent *event = IOHIDEvent::relativePointerEvent(timeStamp, dx, dy, 0, buttonState); 1851 1852 if ( event ) { 1853 dispatchEvent(event); 1854 event->release(); 1855 } 1856 1857#else 1858 NUB_LOCK; 1859 1860 if ( !_pointingNub ) 1861 _pointingNub = newPointingShim(); 1862 1863 if ( _pointingNub ) 1864 _pointingNub->dispatchRelativePointerEvent(timeStamp, dx, dy, buttonState, options); 1865 1866 NUB_UNLOCK; 1867#endif /* TARGET_OS_EMBEDDED */ 1868} 1869 1870#if TARGET_OS_EMBEDDED 1871static IOFixed __ScaleToFixed(int32_t value, int32_t min, int32_t max) 1872{ 1873 int32_t range = max - min; 1874 int32_t offset = value - min; 1875 1876 return IOFixedDivide(offset<<16, range<<16); 1877} 1878#endif 1879 1880//==================================================================================================== 1881// IOHIDEventService::dispatchAbsolutePointerEvent 1882//==================================================================================================== 1883void IOHIDEventService::dispatchAbsolutePointerEvent( 1884 AbsoluteTime timeStamp, 1885 SInt32 x, 1886 SInt32 y, 1887 IOGBounds * bounds, 1888 UInt32 buttonState, 1889 bool inRange, 1890 SInt32 tipPressure, 1891 SInt32 tipPressureMin, 1892 SInt32 tipPressureMax, 1893 IOOptionBits options) 1894{ 1895#if TARGET_OS_EMBEDDED 1896 1897 dispatchDigitizerEvent(timeStamp, 0, kDigitizerTransducerTypeStylus, inRange, buttonState, __ScaleToFixed(x, bounds->minx, bounds->maxx), __ScaleToFixed(y, bounds->miny, bounds->maxy), __ScaleToFixed(tipPressure, tipPressureMin, tipPressureMax)); 1898 1899#else 1900 IOHID_DEBUG(kIOHIDDebugCode_DispatchAbsolutePointer, x, y, buttonState, options); 1901 1902 if ( ! _readyForInputReports ) 1903 return; 1904 1905 if ( !inRange ) { 1906 buttonState = 0; 1907 tipPressure = tipPressureMin; 1908 } 1909 1910 NUB_LOCK; 1911 1912 if ( !_pointingNub ) 1913 _pointingNub = newPointingShim(); 1914 1915 IOGPoint newLoc; 1916 1917 newLoc.x = x; 1918 newLoc.y = y; 1919 1920 _pointingNub->dispatchAbsolutePointerEvent(timeStamp, &newLoc, bounds, buttonState, inRange, tipPressure, tipPressureMin, tipPressureMax, options); 1921 1922 NUB_UNLOCK; 1923#endif /* !TARGET_OS_EMBEDDED */ 1924 1925} 1926 1927//==================================================================================================== 1928// IOHIDEventService::dispatchScrollWheelEvent 1929//==================================================================================================== 1930void IOHIDEventService::dispatchScrollWheelEvent( 1931 AbsoluteTime timeStamp, 1932 SInt32 deltaAxis1, 1933 SInt32 deltaAxis2, 1934 SInt32 deltaAxis3, 1935 IOOptionBits options) 1936{ 1937 IOHID_DEBUG(kIOHIDDebugCode_DispatchScroll, deltaAxis1, deltaAxis2, deltaAxis3, options); 1938 1939 if ( ! _readyForInputReports ) 1940 return; 1941 1942#if TARGET_OS_EMBEDDED 1943 1944 IOHIDEvent *event = IOHIDEvent::scrollEvent(timeStamp, deltaAxis2, deltaAxis1, deltaAxis3); //yxz should be xyz 1945 1946 if ( event ) { 1947 dispatchEvent(event); 1948 event->release(); 1949 } 1950 1951#else 1952 1953 NUB_LOCK; 1954 1955 if ( !_pointingNub ) 1956 _pointingNub = newPointingShim(); 1957 1958 if ( _pointingNub ) 1959 _pointingNub->dispatchScrollWheelEvent(timeStamp, deltaAxis1, deltaAxis2, deltaAxis3, options); 1960 1961 NUB_UNLOCK; 1962#endif /* TARGET_OS_EMBEDDED */ 1963} 1964 1965#if !TARGET_OS_EMBEDDED 1966static void ScalePressure(SInt32 *pressure, SInt32 pressureMin, SInt32 pressureMax, SInt32 systemPressureMin, SInt32 systemPressureMax) 1967{ 1968 SInt64 systemScale = systemPressureMax - systemPressureMin; 1969 1970 1971 *pressure = ((pressureMin != pressureMax)) ? 1972 (((unsigned)(*pressure - pressureMin) * systemScale) / 1973 (unsigned)( pressureMax - pressureMin)) + systemPressureMin: 0; 1974} 1975#endif /* TARGET_OS_EMBEDDED */ 1976 1977//==================================================================================================== 1978// IOHIDEventService::dispatchTabletPointEvent 1979//==================================================================================================== 1980void IOHIDEventService::dispatchTabletPointerEvent( 1981 AbsoluteTime timeStamp, 1982 UInt32 transducerID, 1983 SInt32 x, 1984 SInt32 y, 1985 SInt32 z, 1986 IOGBounds * bounds __unused, 1987 UInt32 buttonState, 1988 SInt32 tipPressure, 1989 SInt32 tipPressureMin, 1990 SInt32 tipPressureMax, 1991 SInt32 barrelPressure, 1992 SInt32 barrelPressureMin, 1993 SInt32 barrelPressureMax, 1994 SInt32 tiltX, 1995 SInt32 tiltY, 1996 UInt32 twist, 1997 IOOptionBits options) 1998{ 1999#if !TARGET_OS_EMBEDDED 2000 IOHID_DEBUG(kIOHIDDebugCode_DispatchTabletPointer, x, y, buttonState, options); 2001 2002 if ( ! _readyForInputReports ) 2003 return; 2004 2005 NUB_LOCK; 2006 2007 if ( !_pointingNub ) 2008 _pointingNub = newPointingShim(); 2009 2010 TransducerData * transducerRef = getTransducerData(transducerID); 2011 2012 if (transducerRef) { 2013 NXEventData tabletData = {}; 2014 2015 ScalePressure(&tipPressure, tipPressureMin, tipPressureMax, 0, kMaxSystemTipPressure); 2016 ScalePressure(&barrelPressure, barrelPressureMin, barrelPressureMax, -kMaxSystemBarrelPressure, kMaxSystemBarrelPressure); 2017 2018 IOGPoint newLoc; 2019 2020 newLoc.x = x; 2021 newLoc.y = y; 2022 2023 //IOHIDSystem::scaleLocationToCurrentScreen(&newLoc, bounds); 2024 2025 tabletData.tablet.x = newLoc.x; 2026 tabletData.tablet.y = newLoc.y; 2027 tabletData.tablet.z = z; 2028 tabletData.tablet.buttons = buttonState; 2029 tabletData.tablet.pressure = tipPressure; 2030 tabletData.tablet.tilt.x = tiltX; 2031 tabletData.tablet.tilt.y = tiltY; 2032 tabletData.tablet.rotation = twist; 2033 tabletData.tablet.tangentialPressure = barrelPressure; 2034 tabletData.tablet.deviceID = transducerRef->deviceID; 2035 2036 _pointingNub->dispatchTabletEvent(&tabletData, timeStamp); 2037 } 2038 2039 NUB_UNLOCK; 2040#endif /* !TARGET_OS_EMBEDDED */ 2041} 2042 2043//==================================================================================================== 2044// IOHIDEventService::dispatchTabletProximityEvent 2045//==================================================================================================== 2046void IOHIDEventService::dispatchTabletProximityEvent( 2047 AbsoluteTime timeStamp, 2048 UInt32 transducerID, 2049 bool inRange, 2050 bool invert, 2051 UInt32 vendorTransducerUniqueID, 2052 UInt32 vendorTransducerSerialNumber, 2053 IOOptionBits options) 2054{ 2055#if !TARGET_OS_EMBEDDED 2056 IOHID_DEBUG(kIOHIDDebugCode_DispatchTabletProx, transducerID, vendorTransducerUniqueID, vendorTransducerSerialNumber, options); 2057 2058 if ( ! _readyForInputReports ) 2059 return; 2060 2061 NUB_LOCK; 2062 2063 if ( !_pointingNub ) 2064 _pointingNub = newPointingShim(); 2065 2066 TransducerData * transducerRef = getTransducerData(transducerID); 2067 2068 if (transducerRef) { 2069 NXEventData tabletData = {}; 2070 2071 tabletData.proximity.vendorID = getVendorID(); 2072 tabletData.proximity.tabletID = getProductID(); 2073 tabletData.proximity.pointerID = transducerID; 2074 tabletData.proximity.deviceID = transducerRef->deviceID; 2075 tabletData.proximity.vendorPointerType = transducerRef->type; 2076 tabletData.proximity.pointerSerialNumber = vendorTransducerSerialNumber; 2077 tabletData.proximity.uniqueID = vendorTransducerUniqueID; 2078 tabletData.proximity.capabilityMask = transducerRef->capabilities; 2079 tabletData.proximity.enterProximity = inRange; 2080 tabletData.proximity.pointerType = 2081 (invert && (transducerRef->type == NX_TABLET_POINTER_PEN)) ? 2082 NX_TABLET_POINTER_ERASER : NX_TABLET_POINTER_PEN; 2083 2084 _pointingNub->dispatchProximityEvent(&tabletData, timeStamp); 2085 } 2086 2087 NUB_UNLOCK; 2088 2089#endif /* !TARGET_OS_EMBEDDED */ 2090} 2091 2092bool IOHIDEventService::readyForReports() 2093{ 2094 return _readyForInputReports; 2095} 2096 2097//============================================================================== 2098// IOHIDEventService::getDeviceUsagePairs 2099//============================================================================== 2100OSMetaClassDefineReservedUsed(IOHIDEventService, 0); 2101OSArray * IOHIDEventService::getDeviceUsagePairs() 2102{ 2103 //RY: Correctly deal with kIOHIDDeviceUsagePairsKey 2104 OSArray * providerUsagePairs = (OSArray*)_provider->copyProperty(kIOHIDDeviceUsagePairsKey); 2105 2106 if ( OSDynamicCast(OSArray, providerUsagePairs) && ( providerUsagePairs != _deviceUsagePairs ) ) { 2107 setProperty(kIOHIDDeviceUsagePairsKey, providerUsagePairs); 2108 if ( _deviceUsagePairs ) 2109 _deviceUsagePairs->release(); 2110 2111 _deviceUsagePairs = providerUsagePairs; 2112 _deviceUsagePairs->retain(); 2113 } 2114#if TARGET_OS_EMBEDDED 2115 else if ( !_deviceUsagePairs ) { 2116 _deviceUsagePairs = OSArray::withCapacity(2); 2117 2118 if ( _deviceUsagePairs ) { 2119 OSDictionary * pair = OSDictionary::withCapacity(2); 2120 2121 if ( pair ) { 2122 OSNumber * number; 2123 2124 number = OSNumber::withNumber(getPrimaryUsagePage(), 32); 2125 if ( number ) { 2126 pair->setObject(kIOHIDDeviceUsagePageKey, number); 2127 number->release(); 2128 } 2129 2130 number = OSNumber::withNumber(getPrimaryUsage(), 32); 2131 if ( number ) { 2132 pair->setObject(kIOHIDDeviceUsageKey, number); 2133 number->release(); 2134 } 2135 2136 _deviceUsagePairs->setObject(pair); 2137 pair->release(); 2138 } 2139 } 2140 } 2141#endif 2142 OSSafeRelease(providerUsagePairs); 2143 2144 return _deviceUsagePairs; 2145} 2146 2147//============================================================================== 2148// IOHIDEventService::getReportInterval 2149//============================================================================== 2150OSMetaClassDefineReservedUsed(IOHIDEventService, 1); 2151UInt32 IOHIDEventService::getReportInterval() 2152{ 2153 UInt32 interval = 8000; // default to 8 milliseconds 2154 OSObject *object = copyProperty(kIOHIDReportIntervalKey, gIOServicePlane, kIORegistryIterateRecursively | kIORegistryIterateParents); 2155 if ( OSDynamicCast(OSNumber, object) ) 2156 interval = ((OSNumber*)object)->unsigned32BitValue(); 2157 OSSafeReleaseNULL(object); 2158 2159 return interval; 2160} 2161 2162#define kCenteredPointerMaxRelativeValue 8 2163#define GET_RELATIVE_VALUE_FROM_CENTERED(centered,relative) \ 2164 relative = (centered * kCenteredPointerMaxRelativeValue) >> 16;\ 2165 2166OSMetaClassDefineReservedUsed(IOHIDEventService, 2); 2167//============================================================================== 2168// IOHIDEventService::dispatchMultiAxisPointerEvent 2169//============================================================================== 2170void IOHIDEventService::dispatchMultiAxisPointerEvent( 2171 AbsoluteTime timeStamp, 2172 UInt32 buttonState, 2173 IOFixed x, 2174 IOFixed y, 2175 IOFixed z, 2176 IOFixed rX, 2177 IOFixed rY, 2178 IOFixed rZ, 2179 IOOptionBits options) 2180{ 2181 2182 bool validAxis = false; 2183 bool validRelative = false; 2184 bool validScroll = false; 2185 bool isZButton = false; 2186 UInt32 interval = 0; 2187 2188 if ( ! _readyForInputReports ) 2189 return; 2190 2191 validRelative = ( options & kMultiAxisOptionRotationForTranslation ) ? rX || rY || _multiAxis.rX || _multiAxis.rY : x || y || _multiAxis.x || _multiAxis.y; 2192 validScroll = rZ || _multiAxis.rZ; 2193 2194 validAxis = x || y || z || rX || rY || rZ || _multiAxis.x || _multiAxis.y || _multiAxis.z || _multiAxis.rX || _multiAxis.rY || _multiAxis.rZ; 2195 2196 if ( options & kMultiAxisOptionZForScroll ) { 2197 validScroll |= z || _multiAxis.z; 2198 } else if ( z > 0 ){ 2199 isZButton = true; 2200 buttonState |= (z>>16) & 1; 2201 } 2202 2203 validRelative |= buttonState != _multiAxis.buttonState; 2204 2205 if ( validAxis || validRelative || validScroll ) { 2206 2207 SInt32 dx = 0; 2208 SInt32 dy = 0; 2209 SInt32 sx = 0; 2210 SInt32 sy = 0; 2211 2212 if ( !isZButton && (options & kMultiAxisOptionRotationForTranslation) ) { 2213 GET_RELATIVE_VALUE_FROM_CENTERED(-rY, dx); 2214 GET_RELATIVE_VALUE_FROM_CENTERED(rX, dy); 2215 } else { 2216 GET_RELATIVE_VALUE_FROM_CENTERED(x, dx); 2217 GET_RELATIVE_VALUE_FROM_CENTERED(y, dy); 2218 } 2219 2220 GET_RELATIVE_VALUE_FROM_CENTERED(rZ, sy); 2221 2222 if ( options & kMultiAxisOptionZForScroll ) 2223 GET_RELATIVE_VALUE_FROM_CENTERED(z, sx); 2224 2225#if TARGET_OS_EMBEDDED 2226 IOHIDEvent * subEvent = IOHIDEvent::multiAxisPointerEvent(timeStamp, buttonState, x, y, z, rX, rY, rZ); 2227 if ( subEvent ) { 2228 2229 IOHIDEvent * event; 2230 2231 if ( validRelative || (!validRelative && !validScroll) ) { 2232 event = IOHIDEvent::relativePointerEvent(timeStamp, dx, dy, 0, buttonState); 2233 if ( event ) { 2234 2235 if ( subEvent ) { 2236 event->appendChild(subEvent); 2237 } 2238 2239 dispatchEvent(event); 2240 event->release(); 2241 } 2242 } 2243 2244 if ( validScroll ) { 2245 event = IOHIDEvent::scrollEvent(timeStamp, sx, sy, 0); 2246 if ( event ) { 2247 2248 if ( subEvent ) { 2249 event->appendChild(subEvent); 2250 } 2251 2252 dispatchEvent(event); 2253 event->release(); 2254 } 2255 } 2256 2257 subEvent->release(); 2258 } 2259#else 2260 dispatchRelativePointerEvent(timeStamp, dx, dy, buttonState, options); 2261 dispatchScrollWheelEvent(timeStamp, sy, sx, 0, options); 2262#endif 2263 2264 if ( (options & kIOHIDEventOptionIsRepeat) == 0 ) { 2265 _multiAxis.timer->cancelTimeout(); 2266 if ( validAxis ) 2267 interval = getReportInterval() + getReportInterval()/2; 2268 } else if ( validAxis ) { 2269 interval = getReportInterval(); 2270 } 2271 2272 if ( interval ) 2273 _multiAxis.timer->setTimeoutUS(interval); 2274 2275 } 2276 2277 _multiAxis.x = x; 2278 _multiAxis.y = y; 2279 _multiAxis.z = z; 2280 _multiAxis.rX = rX; 2281 _multiAxis.rY = rY; 2282 _multiAxis.rZ = rZ; 2283 _multiAxis.buttonState = buttonState; 2284 _multiAxis.options = options; 2285} 2286 2287//============================================================================== 2288// IOHIDEventService::dispatchDigitizerEventWithOrientation 2289//============================================================================== 2290void IOHIDEventService::dispatchDigitizerEventWithOrientation( 2291 AbsoluteTime timeStamp, 2292 DigitizerTransducerType type __unused, 2293 UInt32 transducerID, 2294 bool inRange, 2295 UInt32 buttonState, 2296 IOFixed x, 2297 IOFixed y, 2298 IOFixed z, 2299 IOFixed tipPressure, 2300 IOFixed auxPressure, 2301 IOFixed twist, 2302 DigitizerOrientationType orientationType, 2303 IOFixed * orientationParams, 2304 UInt32 orientationParamCount, 2305 IOOptionBits options) 2306{ 2307 IOHID_DEBUG(kIOHIDDebugCode_DispatchDigitizer, x, y, buttonState, options); 2308 2309 IOFixed params[5] = {}; 2310 bool touch = false; 2311 2312 if ( ! _readyForInputReports ) 2313 return; 2314 2315 if ( !inRange ) { 2316 buttonState = 0; 2317 tipPressure = 0; 2318 } 2319 2320 if ( orientationParams ) { 2321 orientationParamCount = min(5, orientationParamCount); 2322 2323 bcopy(orientationParams, params, sizeof(IOFixed) * orientationParamCount); 2324 } 2325 2326#if TARGET_OS_EMBEDDED 2327 IOHIDEvent * collectionEvent = NULL; 2328 IOHIDEvent * childEvent = NULL; 2329 SInt32 eventMask = 0; // what's changed 2330 UInt32 eventOptions = 0; 2331 2332 if ( options & kDigitizerInvert ) 2333 eventOptions |= kIOHIDTransducerInvert; 2334 2335 childEvent = IOHIDEvent::digitizerEvent(timeStamp, transducerID, type, inRange, buttonState, x, y, z, tipPressure, auxPressure, twist, eventOptions); 2336 require(childEvent, exit); 2337 2338 buttonState |= (tipPressure>>16) & 1; 2339 2340 if ( tipPressure ) 2341 touch |= 1; 2342 else 2343 touch |= buttonState & 1; 2344 2345 childEvent->setIntegerValue(kIOHIDEventFieldDigitizerTouch, touch); 2346 if (touch != _digitizer.touch) { 2347 eventMask |= kIOHIDDigitizerEventTouch; 2348 } 2349 2350 if (inRange != _digitizer.range) { 2351 eventMask |= kIOHIDDigitizerEventRange; 2352 2353 if ( inRange ) { 2354 _digitizer.x = x; 2355 _digitizer.y = y; 2356 eventMask |= kIOHIDDigitizerEventIdentity; 2357 } 2358 } 2359 2360 if (inRange && ( (_digitizer.x != x) || (_digitizer.y != y) || (_digitizer.z != z) ) ) { 2361 eventMask |= kIOHIDDigitizerEventPosition; 2362 } 2363 2364 2365 childEvent->setIntegerValue(kIOHIDEventFieldDigitizerEventMask, eventMask); 2366 2367 collectionEvent = IOHIDEvent::digitizerEvent(timeStamp, transducerID, type, inRange, buttonState, x, y, z, tipPressure, auxPressure, twist, eventOptions); 2368 require(collectionEvent, exit); 2369 2370 collectionEvent->setIntegerValue(kIOHIDEventFieldDigitizerCollection, TRUE); 2371 collectionEvent->setIntegerValue(kIOHIDEventFieldDigitizerRange, childEvent->getIntegerValue(kIOHIDEventFieldDigitizerRange)); 2372 collectionEvent->setIntegerValue(kIOHIDEventFieldDigitizerEventMask, childEvent->getIntegerValue(kIOHIDEventFieldDigitizerEventMask)); 2373 collectionEvent->setIntegerValue(kIOHIDEventFieldDigitizerTouch, childEvent->getIntegerValue(kIOHIDEventFieldDigitizerTouch)); 2374 2375 collectionEvent->appendChild(childEvent); 2376 2377 dispatchEvent(collectionEvent); 2378 2379exit: 2380 if ( collectionEvent ) 2381 collectionEvent->release(); 2382 2383 if ( childEvent ) 2384 childEvent->release(); 2385 2386#else 2387 2388 bool invert = options & kDigitizerInvert; 2389 2390 // Entering proximity 2391 if ( inRange && inRange != _digitizer.range ) { 2392 dispatchTabletProximityEvent(timeStamp, transducerID, inRange, invert); 2393 } 2394 2395 if ( inRange ) { 2396 Bounds bounds = {0, kMaxSystemAbsoluteRangeSigned, 0, kMaxSystemAbsoluteRangeSigned}; 2397 2398 SInt32 scaledX = ((SInt64)x * kMaxSystemAbsoluteRangeSigned) >> 16; 2399 SInt32 scaledY = ((SInt64)y * kMaxSystemAbsoluteRangeSigned) >> 16; 2400 SInt32 scaledZ = ((SInt64)z * kMaxSystemAbsoluteRangeSigned) >> 16; 2401 SInt32 scaledTP = ((SInt64)tipPressure * EV_MAXPRESSURE) >> 16; 2402 SInt32 scaledBP = ((SInt64)auxPressure * EV_MAXPRESSURE) >> 16; 2403 SInt32 scaledTiltX = (((SInt64)params[0] * kMaxSystemAbsoluteRangeSigned)/90) >> 16; 2404 SInt32 scaledTiltY = (((SInt64)params[1] * kMaxSystemAbsoluteRangeSigned)/90) >> 16; 2405 2406 if ( orientationType != kDigitizerOrientationTypeTilt ) 2407 bzero(params, sizeof(params)); 2408 2409 dispatchTabletPointerEvent(timeStamp, transducerID, scaledX, scaledY, scaledZ, &bounds, buttonState, scaledTP, 0, EV_MAXPRESSURE, scaledBP, 0, EV_MAXPRESSURE, scaledTiltX, scaledTiltY, twist>>10 /*10:6 fixed*/); 2410 2411 dispatchAbsolutePointerEvent(timeStamp, scaledX, scaledY, &bounds, buttonState, inRange, scaledTP, 0, EV_MAXPRESSURE); 2412 } 2413 2414 if ( !inRange && inRange != _digitizer.range ) { 2415 dispatchTabletProximityEvent(timeStamp, transducerID, inRange, invert); 2416 } 2417 2418 2419 2420#endif /* TARGET_OS_EMBEDDED */ 2421 2422 _digitizer.range = inRange; 2423 _digitizer.x = x; 2424 _digitizer.y = y; 2425 _digitizer.z = z; 2426 _digitizer.touch = touch; 2427 2428} 2429 2430//============================================================================== 2431// IOHIDEventService::dispatchDigitizerEvent 2432//============================================================================== 2433OSMetaClassDefineReservedUsed(IOHIDEventService, 3); 2434void IOHIDEventService::dispatchDigitizerEvent( 2435 AbsoluteTime timeStamp, 2436 UInt32 transducerID, 2437 DigitizerTransducerType type, 2438 bool inRange, 2439 UInt32 buttonState, 2440 IOFixed x, 2441 IOFixed y, 2442 IOFixed z, 2443 IOFixed tipPressure, 2444 IOFixed auxPressure, 2445 IOFixed twist, 2446 IOOptionBits options ) 2447{ 2448 dispatchDigitizerEventWithOrientation(timeStamp, transducerID, type, inRange, buttonState, x, y, z, tipPressure, auxPressure, twist, kDigitizerOrientationTypeTilt, NULL, 0, options); 2449} 2450 2451//============================================================================== 2452// IOHIDEventService::dispatchDigitizerEventWithTiltOrientation 2453//============================================================================== 2454OSMetaClassDefineReservedUsed(IOHIDEventService, 4); 2455void IOHIDEventService::dispatchDigitizerEventWithTiltOrientation( 2456 AbsoluteTime timeStamp, 2457 UInt32 transducerID, 2458 DigitizerTransducerType type, 2459 bool inRange, 2460 UInt32 buttonState, 2461 IOFixed x, 2462 IOFixed y, 2463 IOFixed z, 2464 IOFixed tipPressure, 2465 IOFixed auxPressure, 2466 IOFixed twist, 2467 IOFixed tiltX, 2468 IOFixed tiltY, 2469 IOOptionBits options) 2470{ 2471 IOFixed params[] = {tiltX, tiltY}; 2472 2473 dispatchDigitizerEventWithOrientation(timeStamp, transducerID, type, inRange, buttonState, x, y, z, tipPressure, auxPressure, twist, kDigitizerOrientationTypeTilt, params, sizeof(params)/sizeof(IOFixed), options); 2474} 2475 2476 2477//============================================================================== 2478// IOHIDEventService::dispatchDigitizerEventWithPolarOrientation 2479//============================================================================== 2480OSMetaClassDefineReservedUsed(IOHIDEventService, 5); 2481void IOHIDEventService::dispatchDigitizerEventWithPolarOrientation( 2482 AbsoluteTime timeStamp, 2483 UInt32 transducerID, 2484 DigitizerTransducerType type, 2485 bool inRange, 2486 UInt32 buttonState, 2487 IOFixed x, 2488 IOFixed y, 2489 IOFixed z, 2490 IOFixed tipPressure, 2491 IOFixed auxPressure, 2492 IOFixed twist, 2493 IOFixed altitude, 2494 IOFixed azimuth, 2495 IOOptionBits options) 2496{ 2497 IOFixed params[] = {altitude, azimuth}; 2498 2499 dispatchDigitizerEventWithOrientation(timeStamp, transducerID, type, inRange, buttonState, x, y, z, tipPressure, auxPressure, twist, kDigitizerOrientationTypePolar, params, sizeof(params)/sizeof(IOFixed), options); 2500} 2501 2502 2503#if TARGET_OS_EMBEDDED 2504void IOHIDEventService::close(IOService *forClient, IOOptionBits options) 2505{ 2506 _commandGate->runAction(OSMemberFunctionCast(IOCommandGate::Action, this, &IOHIDEventService::closeGated), forClient, (void*)options); 2507} 2508 2509void IOHIDEventService::closeGated(IOService *forClient, IOOptionBits options) 2510{ 2511 super::close(forClient, options); 2512} 2513 2514OSDefineMetaClassAndStructors(IOHIDClientData, OSObject) 2515 2516IOHIDClientData * IOHIDClientData::withClientInfo(IOService *client, void* context, void * action) 2517{ 2518 IOHIDClientData * data = new IOHIDClientData; 2519 2520 if (!data) { } 2521 else if (data->init()) { 2522 data->client = client; 2523 data->context = context; 2524 data->action = action; 2525 } else { 2526 data->release(); 2527 data = NULL; 2528 } 2529 2530 return data; 2531} 2532 2533//============================================================================== 2534// IOHIDEventService::open 2535//============================================================================== 2536OSMetaClassDefineReservedUsed(IOHIDEventService, 6); 2537bool IOHIDEventService::open( IOService * client, 2538 IOOptionBits options, 2539 void * context, 2540 Action action) 2541{ 2542 return _commandGate->runAction(OSMemberFunctionCast(IOCommandGate::Action, this, &IOHIDEventService::openGated), client, (void*)options, context, (void*)action); 2543} 2544 2545//============================================================================== 2546// IOHIDEventService::dispatchEvent 2547//============================================================================== 2548OSMetaClassDefineReservedUsed(IOHIDEventService, 7); 2549void IOHIDEventService::dispatchEvent(IOHIDEvent * event, IOOptionBits options) 2550{ 2551 OSCollectionIterator * iterator = OSCollectionIterator::withCollection(_clientDict); 2552 IOHIDClientData * clientData; 2553 OSObject * clientKey; 2554 IOService * client; 2555 void * context; 2556 Action action; 2557 2558 event->setSenderID(getRegistryEntryID()); 2559 2560 IOHID_DEBUG(kIOHIDDebugCode_DispatchHIDEvent, options, 0, 0, 0); 2561 2562 if ( !iterator ) 2563 return; 2564 2565 while ((clientKey = iterator->getNextObject())) { 2566 2567 clientData = OSDynamicCast(IOHIDClientData, _clientDict->getObject((const OSSymbol *)clientKey)); 2568 2569 if ( !clientData ) 2570 continue; 2571 2572 client = clientData->getClient(); 2573 context = clientData->getContext(); 2574 action = (Action)clientData->getAction(); 2575 2576 if ( action ) 2577 (*action)(client, this, context, event, options); 2578 } 2579 2580 iterator->release(); 2581 2582} 2583 2584//============================================================================== 2585// IOHIDEventService::getPrimaryUsagePage 2586//============================================================================== 2587OSMetaClassDefineReservedUsed(IOHIDEventService, 8); 2588UInt32 IOHIDEventService::getPrimaryUsagePage () 2589{ 2590 UInt32 primaryUsagePage = 0; 2591 OSArray * deviceUsagePairs = getDeviceUsagePairs(); 2592 2593 if ( deviceUsagePairs && deviceUsagePairs->getCount() ) { 2594 OSDictionary * pair = OSDynamicCast(OSDictionary, deviceUsagePairs->getObject(0)); 2595 2596 if ( pair ) { 2597 OSNumber * number = OSDynamicCast(OSNumber, pair->getObject(kIOHIDDeviceUsagePageKey)); 2598 2599 if ( number ) 2600 primaryUsagePage = number->unsigned32BitValue(); 2601 } 2602 } 2603 2604 return primaryUsagePage; 2605} 2606 2607//============================================================================== 2608// IOHIDEventService::getPrimaryUsage 2609//============================================================================== 2610OSMetaClassDefineReservedUsed(IOHIDEventService, 9); 2611UInt32 IOHIDEventService::getPrimaryUsage () 2612{ 2613 UInt32 primaryUsage = 0; 2614 OSArray * deviceUsagePairs = getDeviceUsagePairs(); 2615 2616 if ( deviceUsagePairs && deviceUsagePairs->getCount() ) { 2617 OSDictionary * pair = OSDynamicCast(OSDictionary, deviceUsagePairs->getObject(0)); 2618 2619 if ( pair ) { 2620 OSNumber * number = OSDynamicCast(OSNumber, pair->getObject(kIOHIDDeviceUsageKey)); 2621 2622 if ( number ) 2623 primaryUsage = number->unsigned32BitValue(); 2624 } 2625 } 2626 2627 return primaryUsage; 2628} 2629 2630//============================================================================== 2631// IOHIDEventService::copyEvent 2632//============================================================================== 2633OSMetaClassDefineReservedUsed(IOHIDEventService, 10); 2634IOHIDEvent * IOHIDEventService::copyEvent( 2635 IOHIDEventType type, 2636 IOHIDEvent * matching, 2637 IOOptionBits options) 2638{ 2639 return NULL; 2640} 2641 2642//============================================================================== 2643// IOHIDEventService::openGated 2644//============================================================================== 2645bool IOHIDEventService::openGated(IOService * client, 2646 IOOptionBits options, 2647 void * context, 2648 Action action) 2649{ 2650 IOHIDClientData * clientData = 2651 IOHIDClientData::withClientInfo(client, context, (void*)action); 2652 bool ret = false; 2653 2654 if ( clientData ) { 2655 if ( super::open(client, options, clientData) ) 2656 ret = true; 2657 clientData->release(); 2658 } 2659 2660 return ret; 2661} 2662 2663#else 2664 2665OSMetaClassDefineReservedUnused(IOHIDEventService, 6); 2666OSMetaClassDefineReservedUnused(IOHIDEventService, 7); 2667OSMetaClassDefineReservedUnused(IOHIDEventService, 8); 2668OSMetaClassDefineReservedUnused(IOHIDEventService, 9); 2669OSMetaClassDefineReservedUnused(IOHIDEventService, 10); 2670#endif /* TARGET_OS_EMBEDDED */ 2671OSMetaClassDefineReservedUnused(IOHIDEventService, 11); 2672OSMetaClassDefineReservedUnused(IOHIDEventService, 12); 2673OSMetaClassDefineReservedUnused(IOHIDEventService, 13); 2674OSMetaClassDefineReservedUnused(IOHIDEventService, 14); 2675OSMetaClassDefineReservedUnused(IOHIDEventService, 15); 2676OSMetaClassDefineReservedUnused(IOHIDEventService, 16); 2677OSMetaClassDefineReservedUnused(IOHIDEventService, 17); 2678OSMetaClassDefineReservedUnused(IOHIDEventService, 18); 2679OSMetaClassDefineReservedUnused(IOHIDEventService, 19); 2680OSMetaClassDefineReservedUnused(IOHIDEventService, 20); 2681OSMetaClassDefineReservedUnused(IOHIDEventService, 21); 2682OSMetaClassDefineReservedUnused(IOHIDEventService, 22); 2683OSMetaClassDefineReservedUnused(IOHIDEventService, 23); 2684OSMetaClassDefineReservedUnused(IOHIDEventService, 24); 2685OSMetaClassDefineReservedUnused(IOHIDEventService, 25); 2686OSMetaClassDefineReservedUnused(IOHIDEventService, 26); 2687OSMetaClassDefineReservedUnused(IOHIDEventService, 27); 2688OSMetaClassDefineReservedUnused(IOHIDEventService, 28); 2689OSMetaClassDefineReservedUnused(IOHIDEventService, 29); 2690OSMetaClassDefineReservedUnused(IOHIDEventService, 30); 2691OSMetaClassDefineReservedUnused(IOHIDEventService, 31); 2692 2693