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 * 24-Jan-01 bubba Don't auto-repeat on Power Key. This prevents infinite power key 25 * events from being generated when this key is hit on ADB keyboards. 26 */ 27 28#include <AssertMacros.h> 29#include <IOKit/IOLib.h> 30#include <IOKit/IOLocks.h> 31#include <IOKit/hidsystem/IOHIKeyboardMapper.h> 32#include <IOKit/hidsystem/IOLLEvent.h> 33#include <IOKit/hidsystem/IOHIDParameter.h> 34#include "IOKit/hidsystem/IOHIDSystem.h" 35#include "IOKit/hidsystem/IOHIKeyboard.h" 36#include "IOHIDKeyboardDevice.h" 37#include "IOHIDFamilyTrace.h" 38#include "IOHIDSecurePromptClient.h" 39#include "ev_private.h" 40 41//************************************************************************ 42// KeyboardReserved 43// 44// RY: The following was added because the IOHIKeyboard class doesn't have 45// a reserved field defined. Essentially what this does is create a 46// static dictionary that stores OSData objects for each keyboard. These 47// OSData objects will be added and removed as each keyboard enters and 48// leaves the system. 49 50struct KeyboardReserved 51{ 52 IOHIKeyboard * service; 53 thread_call_t repeat_thread_call; 54 bool dispatchEventCalled; 55 bool isSeized; 56 bool repeatMode; 57 bool hasSecurePrompt; 58 IOService * openClient; 59 IOHIDKeyboardDevice * keyboardNub; 60}; 61 62static OSArray *gKeyboardReservedArray = OSArray::withCapacity(4); 63IOLock *gKeyboardReservedArrayLock = IOLockAlloc(); 64 65static KeyboardReserved * GetKeyboardReservedStructEventForService(IOHIKeyboard *service, UInt32 * index = 0) 66{ 67 KeyboardReserved * retVal = 0; 68 if (gKeyboardReservedArray) { 69 OSCollectionIterator * iterator = 0; 70 iterator = OSCollectionIterator::withCollection(gKeyboardReservedArray); 71 if (iterator) { 72 bool done = false; 73 while (!done) { 74 OSObject * obj = 0; 75 IOLockLock(gKeyboardReservedArrayLock); 76 while (!done && (NULL != (obj = iterator->getNextObject()))) { 77 obj->retain(); 78 IOLockUnlock(gKeyboardReservedArrayLock); 79 80 OSData * data = OSDynamicCast(OSData, obj); 81 if (data) { 82 retVal = (KeyboardReserved *)data->getBytesNoCopy(); 83 if (retVal && (retVal->service == service)) { 84 if (index) 85 *index = gKeyboardReservedArray->getNextIndexOfObject(obj, 0); 86 done = true; 87 } 88 else { 89 retVal = 0; 90 } 91 } 92 IOLockLock(gKeyboardReservedArrayLock); 93 } 94 IOLockUnlock(gKeyboardReservedArrayLock); 95 if (iterator->isValid()) { 96 done = true; 97 } 98 else { 99 iterator->reset(); 100 } 101 } 102 iterator->release(); 103 } 104 } 105 return retVal; 106} 107 108static void AppendNewKeyboardReservedStructForService(IOHIKeyboard *service) 109{ 110 KeyboardReserved temp; 111 OSData * data = 0; 112 113 if (gKeyboardReservedArray) 114 { 115 bzero(&temp, sizeof(KeyboardReserved)); 116 temp.repeatMode = true; 117 temp.service = service; 118 data = OSData::withBytes(&temp, sizeof(KeyboardReserved)); 119 IOLockLock(gKeyboardReservedArrayLock); 120 gKeyboardReservedArray->setObject(data); 121 IOLockUnlock(gKeyboardReservedArrayLock); 122 data->release(); 123 } 124} 125 126static void RemoveKeyboardReservedStructForService(IOHIKeyboard *service) 127{ 128 UInt32 index = 0; 129 130 if (gKeyboardReservedArray && GetKeyboardReservedStructEventForService(service, &index) ) 131 { 132 IOLockLock(gKeyboardReservedArrayLock); 133 gKeyboardReservedArray->removeObject(index); 134 IOLockUnlock(gKeyboardReservedArrayLock); 135 } 136} 137 138//************************************************************************ 139 140#define super IOHIDevice 141OSDefineMetaClassAndStructors(IOHIKeyboard, IOHIDevice); 142 143bool IOHIKeyboard::init(OSDictionary * properties) 144{ 145 if (!super::init(properties)) return false; 146 147 /* 148 * Initialize minimal state. 149 */ 150 151 _deviceLock = IOLockAlloc(); 152 _keyMap = 0; 153 _keyStateSize = 4*((maxKeyCodes()+(EVK_BITS_PER_UNIT-1))/EVK_BITS_PER_UNIT); 154 _keyState = (UInt32 *) IOMalloc(_keyStateSize); 155 _codeToRepeat = (unsigned)-1; 156 157 _keyboardEventTarget = 0; 158 _keyboardEventAction = 0; 159 _keyboardSpecialEventTarget = 0; 160 _keyboardSpecialEventAction = 0; 161 _updateEventFlagsTarget = 0; 162 _updateEventFlagsAction = 0; 163 164 if (!_deviceLock || !_keyState) return false; 165 166 bzero(_keyState, _keyStateSize); 167 168 return true; 169} 170 171bool IOHIKeyboard::start(IOService * provider) 172{ 173 if (!super::start(provider)) return false; 174 175 /* 176 * IOHIKeyboard serves both as a service and a nub (we lead a double 177 * life). Register ourselves as a nub to kick off matching. 178 */ 179 180 AppendNewKeyboardReservedStructForService(this); 181 KeyboardReserved * tempReservedStruct = GetKeyboardReservedStructEventForService(this); 182 183 if (tempReservedStruct) 184 { 185 tempReservedStruct->repeat_thread_call = thread_call_allocate(_autoRepeat, this); 186 } 187 188 registerService(kIOServiceAsynchronous); 189 190 return true; 191} 192 193void IOHIKeyboard::stop(IOService * provider) 194{ 195 super::stop(provider); 196 197 KeyboardReserved *tempReservedStruct = GetKeyboardReservedStructEventForService(this); 198 199 if (tempReservedStruct) { 200 thread_call_cancel(tempReservedStruct->repeat_thread_call); 201 thread_call_free(tempReservedStruct->repeat_thread_call); 202 tempReservedStruct->repeat_thread_call = NULL; 203 204 if ( tempReservedStruct->keyboardNub ) 205 tempReservedStruct->keyboardNub->release(); 206 tempReservedStruct->keyboardNub = NULL; 207 208 if ( tempReservedStruct->hasSecurePrompt ) 209 tempReservedStruct->hasSecurePrompt = false; 210 211 RemoveKeyboardReservedStructForService(this); 212 } 213} 214 215void IOHIKeyboard::free() 216// Description: Go Away. Be careful when freeing the lock. 217{ 218 IOLock * lock = NULL; 219 220 if ( _deviceLock ) 221 { 222 lock = _deviceLock; 223 IOLockLock( lock); 224 _deviceLock = NULL; 225 } 226 227 if ( _keyMap ) { 228 _keyMap->release(); 229 _keyMap = 0; 230 } 231 232 if( _keyState ) 233 IOFree( _keyState, _keyStateSize); 234 235 // RY: MENTAL NOTE Do this last 236 if ( lock ) 237 { 238 IOLockUnlock( lock); 239 IOLockFree( lock); 240 } 241 242 super::free(); 243} 244 245IOHIDKind IOHIKeyboard::hidKind() 246{ 247 return kHIKeyboardDevice; 248} 249 250bool IOHIKeyboard::updateProperties( void ) 251{ 252 bool ok; 253 254 ok = setProperty( kIOHIDKeyMappingKey, _keyMap ); 255 256 return( ok & super::updateProperties() ); 257} 258 259IOReturn IOHIKeyboard::setParamProperties( OSDictionary * dict ) 260{ 261 OSData * data = NULL; 262 OSNumber * number = NULL; 263 IOReturn err = kIOReturnSuccess; 264 IOReturn err2 = kIOReturnSuccess; 265 unsigned char * map = NULL; 266 IOHIKeyboardMapper * oldMap = NULL; 267 bool updated = false; 268 UInt64 nano; 269 270 if( dict->getObject(kIOHIDResetKeyboardKey)) 271 resetKeyboard(); 272 273 IOLockLock( _deviceLock); 274 275 if ((number = OSDynamicCast(OSNumber, 276 dict->getObject(kIOHIDKeyRepeatKey))) || 277 (data = OSDynamicCast(OSData, 278 dict->getObject(kIOHIDKeyRepeatKey)))) 279 { 280 nano = (number) ? number->unsigned64BitValue() : *((UInt64 *) (data->getBytesNoCopy())); 281 282 if( nano < EV_MINKEYREPEAT) 283 nano = EV_MINKEYREPEAT; 284 nanoseconds_to_absolutetime(nano, &_keyRepeat); 285 updated = true; 286 } 287 288 if ((number = OSDynamicCast(OSNumber, 289 dict->getObject(kIOHIDInitialKeyRepeatKey))) || 290 (data = OSDynamicCast(OSData, 291 dict->getObject(kIOHIDInitialKeyRepeatKey)))) 292 { 293 nano = (number) ? number->unsigned64BitValue() : *((UInt64 *) (data->getBytesNoCopy())); 294 295 if( nano < EV_MINKEYREPEAT) 296 nano = EV_MINKEYREPEAT; 297 nanoseconds_to_absolutetime(nano, &_initialKeyRepeat); 298 updated = true; 299 } 300 301 if( (data = OSDynamicCast( OSData, dict->getObject(kIOHIDKeyMappingKey)))) 302 { 303 304 map = (unsigned char *)IOMalloc( data->getLength() ); 305 bcopy( data->getBytesNoCopy(), map, data->getLength() ); 306 oldMap = _keyMap; 307 _keyMap = IOHIKeyboardMapper::keyboardMapper(this, map, data->getLength(), true); 308 309 if (_keyMap) 310 { 311 // point the new keymap to the IOHIDSystem, so it can set properties in it 312 _keyMap->setKeyboardTarget((IOService *) _keyboardEventTarget); 313 314 if (oldMap) 315 oldMap->release(); 316 updated = true; 317 } 318 else 319 { 320 _keyMap = oldMap; 321 err = kIOReturnBadArgument; 322 } 323 } 324 if (NULL != (number = OSDynamicCast(OSNumber, dict->getObject(kIOHIDSubinterfaceIDKey)))) 325 { 326 if (!OSDynamicCast(OSNumber, getProperty(kIOHIDOriginalSubinterfaceIDKey))) { 327 // no original key 328 OSNumber *original = (OSNumber*)copyProperty(kIOHIDSubinterfaceIDKey); 329 if (OSDynamicCast(OSNumber, original)) { 330 setProperty(kIOHIDOriginalSubinterfaceIDKey, original); 331 } 332 OSSafeReleaseNULL(original); 333 } 334 _deviceType = number->unsigned32BitValue(); 335 updated = true; 336 } 337 338 // give the keymap a chance to update to new properties 339 if (_keyMap) 340 err2 = _keyMap->setParamProperties(dict); 341 342 IOLockUnlock( _deviceLock); 343 344 if( updated ) 345 updateProperties(); 346 347 // we can only return one error 348 if (err == kIOReturnSuccess) 349 err = err2; 350 351 return( err == kIOReturnSuccess ) ? super::setParamProperties(dict) : err; 352} 353 354// RY: Override IORegistryEntry::setProperties(). This was removed earlier 355// in Leopard, but turns out that won't work as the linker will not end up 356// doing the right thing and travese the super class to resolve the symbol. 357IOReturn IOHIKeyboard::setProperties( OSObject * properties ) 358{ 359 return super::setProperties(properties); 360} 361 362 363 364bool IOHIKeyboard::resetKeyboard() 365// Description: Reset the keymapping to the default value and reconfigure 366// the keyboards. 367{ 368 const unsigned char *defaultKeymap; 369 UInt32 defaultKeymapLength; 370 371 IOLockLock( _deviceLock); 372 373 if ( _keyMap ) { 374 _keyMap->release(); 375 _keyMap = 0; 376 } 377 378 // Set up default keymapping. 379 defaultKeymap = defaultKeymapOfLength(&defaultKeymapLength); 380 381 _keyMap = IOHIKeyboardMapper::keyboardMapper( this, 382 defaultKeymap, 383 defaultKeymapLength, 384 false ); 385 386 if (_keyMap) 387 { 388 // point the new keymap to the IOHIDSystem, so it can set properties in it 389 _keyMap->setKeyboardTarget((IOService *) _keyboardEventTarget); 390 391 clock_interval_to_absolutetime_interval( EV_DEFAULTKEYREPEAT, 392 kNanosecondScale, &_keyRepeat); 393 clock_interval_to_absolutetime_interval( EV_DEFAULTINITIALREPEAT, 394 kNanosecondScale, &_initialKeyRepeat); 395 } 396 397 updateProperties(); 398 399 _interfaceType = interfaceID(); 400 _deviceType = deviceType(); 401 _guid = getGUID(); 402 403 if (getProperty("HIDKeyboardKeysDefined")) 404 { 405 KeyboardReserved * reservedStruct = GetKeyboardReservedStructEventForService(this); 406 407 if ( reservedStruct && !reservedStruct->keyboardNub) 408 reservedStruct->keyboardNub = IOHIDKeyboardDevice::newKeyboardDeviceAndStart(this); 409 } 410 411 IOLockUnlock( _deviceLock); 412 return (_keyMap) ? true : false; 413} 414 415void IOHIKeyboard::scheduleAutoRepeat() 416// Description: Schedule a procedure to be called when a timeout has expired 417// so that we can generate a repeated key. 418// Preconditions: 419// * _deviceLock should be held on entry 420{ 421 KeyboardReserved *tempReservedStruct = GetKeyboardReservedStructEventForService(this); 422 423 if ( _calloutPending == true ) 424 { 425 if (tempReservedStruct) { 426 thread_call_cancel(tempReservedStruct->repeat_thread_call); 427 } 428 _calloutPending = false; 429 } 430 if ( AbsoluteTime_to_scalar(&_downRepeatTime) ) 431 { 432 AbsoluteTime deadline; 433 clock_absolutetime_interval_to_deadline(_downRepeatTime, &deadline); 434 if (tempReservedStruct) { 435 IOHID_DEBUG(kIOHIDDebugCode_KeyboardCapsThreadTrigger, this, __OSAbsoluteTime(deadline), tempReservedStruct->repeat_thread_call, 0); 436 thread_call_enter_delayed(tempReservedStruct->repeat_thread_call, deadline); 437 } 438 _calloutPending = true; 439 } 440} 441 442void IOHIKeyboard::_autoRepeat(thread_call_param_t arg, 443 thread_call_param_t) /* thread_call_func_t */ 444{ 445 IOHIKeyboard *self = (IOHIKeyboard *) arg; 446 IOHID_DEBUG(kIOHIDDebugCode_KeyboardCapsThreadActive, self, self ? self->_codeToRepeat : 0, 0, 0); 447 self->autoRepeat(); 448} 449 450void IOHIKeyboard::autoRepeat() 451// Description: Repeat the currently pressed key and schedule ourselves 452// to be called again after another interval elapses. 453// Preconditions: 454// * Should only be executed on callout thread 455// * _deviceLock should be unlocked on entry. 456{ 457 KeyboardReserved *tempReservedStruct = GetKeyboardReservedStructEventForService(this); 458 459 IOLockLock( _deviceLock); 460 if (( _calloutPending == false ) || 461 ((tempReservedStruct) && tempReservedStruct->dispatchEventCalled )) 462 { 463 IOLockUnlock( _deviceLock); 464 return; 465 } 466 _calloutPending = false; 467 _isRepeat = true; 468 469 if (tempReservedStruct) tempReservedStruct->dispatchEventCalled = true; 470 471 if ( AbsoluteTime_to_scalar(&_downRepeatTime) ) 472 { 473 // Device is due to generate a repeat 474 // <rdar://problem/7415196> 475 if (postSecureKey(_codeToRepeat, true)) { 476 // do nothing 477 } 478 else if (_keyMap) { 479 _keyMap->translateKeyCode(_codeToRepeat, 480 true, /* direction */ 481 _keyState /* keyBits */); 482 } 483 _downRepeatTime = _keyRepeat; 484 } 485 486 if (tempReservedStruct) tempReservedStruct->dispatchEventCalled = false; 487 488 _isRepeat = false; 489 scheduleAutoRepeat(); 490 IOLockUnlock( _deviceLock); 491} 492 493void IOHIKeyboard::setRepeat(unsigned eventType, unsigned keyCode) 494// Description: Set up or tear down key repeat operations. The method 495// that locks _deviceLock is a bit higher on the call stack. 496// This method is invoked as a side effect of our own 497// invocation of _keyMap->translateKeyCode(). 498// Preconditions: 499// * _deviceLock should be held upon entry. 500{ 501 KeyboardReserved *tempReservedStruct; 502 503 if ( _isRepeat == false ) // make sure we're not already repeating 504 { 505 tempReservedStruct = GetKeyboardReservedStructEventForService(this); 506 507 if ((eventType == NX_KEYDOWN) && 508 (tempReservedStruct && (tempReservedStruct->repeatMode == true))) // Start repeat 509 { 510 // Set this key to repeat (push out last key if present) 511 _downRepeatTime = _initialKeyRepeat; // + _lastEventTime; 512 _codeToRepeat = keyCode; 513 // reschedule key repeat event here 514 scheduleAutoRepeat(); 515 } 516 else if (((eventType == NX_KEYUP) && (_codeToRepeat == keyCode)) || 517 (tempReservedStruct && (tempReservedStruct->repeatMode == false))) // End repeat 518 { 519 AbsoluteTime_to_scalar(&_downRepeatTime) = 0; 520 _codeToRepeat = (unsigned)-1; 521 scheduleAutoRepeat(); 522 } 523 } 524} 525 526void IOHIKeyboard::setRepeatMode(bool repeat) 527{ 528 KeyboardReserved *tempReservedStruct = GetKeyboardReservedStructEventForService(this); 529 530 IOLockLock( _deviceLock); 531 if (tempReservedStruct) 532 { 533 tempReservedStruct->repeatMode = repeat; 534 } 535 IOLockUnlock( _deviceLock); 536} 537 538 539// 540// BEGIN: Implementation of the methods required by IOHIKeyboardMapper. 541// 542 543void IOHIKeyboard::keyboardEvent(unsigned eventType, 544 /* flags */ unsigned flags, 545 /* keyCode */ unsigned keyCode, 546 /* charCode */ unsigned charCode, 547 /* charSet */ unsigned charSet, 548 /* originalCharCode */ unsigned origCharCode, 549 /* originalCharSet */ unsigned origCharSet) 550// Description: We use this notification to set up our _keyRepeat timer 551// and to pass along the event to our owner. This method 552// will be called while the KeyMap object is processing 553// the key code we've sent it using deliverKey. 554{ 555 KeyboardReserved *tempReservedStruct = GetKeyboardReservedStructEventForService(this); 556 bool relock = false; 557 558 if (tempReservedStruct && tempReservedStruct->dispatchEventCalled) 559 { 560 relock = true; 561 IOLockUnlock(_deviceLock); 562 } 563 564 UInt16 usage = 0; 565 UInt16 usagePage = 0; 566 unsigned modifiedOrigCharCode = origCharCode; 567 unsigned modifiedOrigCharSet = origCharSet; 568 unsigned modifiedFlags = flags; 569 570 if ((origCharCode < 0xffff) && (origCharSet < 0xffff)) { 571 getLastPageAndUsage(usagePage, usage); 572 573 if (usage || usagePage) { 574 modifiedOrigCharCode |= usage << 16; 575 modifiedOrigCharSet |= usagePage << 16; 576 modifiedFlags |= NX_HIGHCODE_ENCODING_MASK; 577 } 578 } 579 else { 580 IOLog("IOHIKeyboard::keyboardEvent original code/set unusually large %02x:%02x\n", origCharCode, origCharSet); 581 } 582 583 _keyboardEvent( this, 584 eventType, 585 /* flags */ modifiedFlags, 586 /* keyCode */ keyCode, 587 /* charCode */ charCode, 588 /* charSet */ charSet, 589 /* originalCharCode */ modifiedOrigCharCode, 590 /* originalCharSet */ modifiedOrigCharSet, 591 /* keyboardType */ _deviceType, 592 /* repeat */ _isRepeat, 593 /* atTime */ _lastEventTime); 594 595 if (relock) 596 { 597 IOLockLock(_deviceLock); 598 } 599 600 601 if( keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_CAPS_LOCK) || 602 keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_NUM_LOCK) || 603 keyCode == _keyMap->getParsedSpecialKey(NX_POWER_KEY) || 604 keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_MUTE) || 605 keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_PLAY) || 606 keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_EJECT) || 607 keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_VIDMIRROR) || 608 keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_ILLUMINATION_TOGGLE)) 609 { 610 //Don't repeat caps lock on ADB/USB. 0x39 is default ADB code. 611 // We are here because KeyCaps needs to see 0x39 as a real key, 612 // not just another modifier bit. 613 614 if (_interfaceType == NX_EVS_DEVICE_INTERFACE_ADB) 615 { 616 return; 617 } 618 } 619 620 // Set up key repeat operations here. 621 setRepeat(eventType, keyCode); 622} 623 624void IOHIKeyboard::keyboardSpecialEvent(unsigned eventType, 625 /* flags */ unsigned flags, 626 /* keyCode */ unsigned keyCode, 627 /* specialty */ unsigned flavor) 628// Description: See the description for keyboardEvent. 629{ 630 KeyboardReserved *tempReservedStruct = GetKeyboardReservedStructEventForService(this); 631 bool relock = false; 632 633 if (tempReservedStruct && tempReservedStruct->dispatchEventCalled) 634 { 635 relock = true; 636 IOLockUnlock(_deviceLock); 637 } 638 639 _keyboardSpecialEvent(this, 640 eventType, 641 /* flags */ flags, 642 /* keyCode */ keyCode, 643 /* specialty */ flavor, 644 /* guid */ _guid, 645 /* repeat */ _isRepeat, 646 /* atTime */ _lastEventTime); 647 648 if (relock) 649 { 650 IOLockLock(_deviceLock); 651 } 652 653 // Set up key repeat operations here. 654 // Don't repeat capslock, numlock, power key, mute key, play key, 655 // eject key, vidmirror key, illumination toggle key. 656 if( keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_CAPS_LOCK) || 657 keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_NUM_LOCK) || 658 keyCode == _keyMap->getParsedSpecialKey(NX_POWER_KEY) || 659 keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_MUTE) || 660 keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_PLAY) || 661 keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_EJECT) || 662 keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_VIDMIRROR) || 663 keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_ILLUMINATION_TOGGLE)) 664 { 665 return; 666 } 667 668 // Set up key repeat operations here. 669 setRepeat(eventType, keyCode); 670} 671 672void IOHIKeyboard::updateEventFlags(unsigned flags) 673// Description: Process non-event-generating flag changes. Simply pass this 674// along to our owner. 675{ 676 KeyboardReserved *tempReservedStruct = GetKeyboardReservedStructEventForService(this); 677 bool relock = false; 678 679 if (tempReservedStruct && tempReservedStruct->dispatchEventCalled) 680 { 681 relock = true; 682 IOLockUnlock(_deviceLock); 683 } 684 685 _updateEventFlags(this, flags); 686 687 if (relock) 688 { 689 IOLockLock(_deviceLock); 690 } 691} 692 693unsigned IOHIKeyboard::eventFlags() 694// Description: Return global event flags In this world, there is only 695// one keyboard device so device flags == global flags. 696{ 697 return _eventFlags; 698} 699 700unsigned IOHIKeyboard::deviceFlags() 701// Description: Return per-device event flags. In this world, there is only 702// one keyboard device so device flags == global flags. 703{ 704 return _eventFlags; 705} 706 707void IOHIKeyboard::setDeviceFlags(unsigned flags) 708// Description: Set device event flags. In this world, there is only 709// one keyboard device so device flags == global flags. 710{ 711 if (_eventFlags != flags) { 712 _eventFlags = flags; 713 714 // RY: On Modifier change, we should 715 // reset the auto repeat timer 716 AbsoluteTime_to_scalar(&_downRepeatTime) = 0; 717 _codeToRepeat = (unsigned)-1; 718 scheduleAutoRepeat(); 719 } 720} 721 722bool IOHIKeyboard::alphaLock() 723// Description: Return current alpha-lock state. This is a state tracking 724// callback used by the KeyMap object. 725{ 726 return _alphaLock; 727} 728 729void IOHIKeyboard::setAlphaLock(bool val) 730// Description: Set current alpha-lock state This is a state tracking 731// callback used by the KeyMap object. 732{ 733 _alphaLock = val; 734 setAlphaLockFeedback(val); 735 736 KeyboardReserved *tempReservedStruct = GetKeyboardReservedStructEventForService(this); 737 738 if (tempReservedStruct && tempReservedStruct->keyboardNub ) 739 tempReservedStruct->keyboardNub->setCapsLockLEDElement(val); 740 741} 742 743bool IOHIKeyboard::numLock() 744{ 745 return _numLock; 746} 747 748void IOHIKeyboard::setNumLock(bool val) 749{ 750 _numLock = val; 751 752 setNumLockFeedback(val); 753 754 KeyboardReserved *tempReservedStruct = GetKeyboardReservedStructEventForService(this); 755 756 if (tempReservedStruct && tempReservedStruct->keyboardNub ) 757 tempReservedStruct->keyboardNub->setNumLockLEDElement(val); 758 759} 760 761bool IOHIKeyboard::charKeyActive() 762// Description: Return true If a character generating key down This is a state 763// tracking callback used by the KeyMap object. 764{ 765 return _charKeyActive; 766} 767 768void IOHIKeyboard::setCharKeyActive(bool val) 769// Description: Note whether a char generating key is down. This is a state 770// tracking callback used by the KeyMap object. 771{ 772 _charKeyActive = val; 773} 774// 775// END: Implementation of the methods required by IOHIKeyboardMapper. 776// 777 778void IOHIKeyboard::dispatchKeyboardEvent(unsigned int keyCode, 779 /* direction */ bool goingDown, 780 /* timeStamp */ AbsoluteTime time) 781// Description: This method is the heart of event dispatching. The overlying 782// subclass invokes this method with each event. We then 783// get the event xlated and dispatched using a _keyMap instance. 784// The event structure passed in by reference should not be freed. 785{ 786 IOHIKeyboardMapper * theKeyMap; 787 KeyboardReserved *tempReservedStruct = GetKeyboardReservedStructEventForService(this); 788 789 IOLockLock( _deviceLock); 790 791 _lastEventTime = time; 792 793 // <rdar://problem/7415196> 794 if (postSecureKey(keyCode, goingDown)) { 795 IOLockUnlock( _deviceLock); 796 return; 797 } 798 799 if (tempReservedStruct) 800 { 801 if (tempReservedStruct->keyboardNub) 802 { 803 // Post the event to the HID Manager 804 tempReservedStruct->keyboardNub->postKeyboardEvent(keyCode, goingDown); 805 } 806 807 if (tempReservedStruct->isSeized) 808 { 809 IOLockUnlock( _deviceLock); 810 return; 811 } 812 813 tempReservedStruct->dispatchEventCalled = true; 814 } 815 816 if (_keyMap) _keyMap->translateKeyCode(keyCode, 817 /* direction */ goingDown, 818 /* keyBits */ _keyState); 819 820 // remember the keymap while we hold the lock 821 theKeyMap = _keyMap; 822 823 if (tempReservedStruct) tempReservedStruct->dispatchEventCalled = false; 824 825 IOLockUnlock( _deviceLock); 826 827 // outside the lock (because of possible recursion), give the 828 // keymap a chance to do some post processing 829 // since it is possible we will be entered reentrantly and 830 // release the keymap, we will add a retain here. 831 if (theKeyMap) 832 { 833 theKeyMap->retain(); 834 theKeyMap->keyEventPostProcess(); 835 theKeyMap->release(); 836 } 837} 838 839const unsigned char * IOHIKeyboard::defaultKeymapOfLength(UInt32 * length) 840{ 841 *length = 0; 842 return NULL; 843} 844 845void IOHIKeyboard::setAlphaLockFeedback(bool /* val */) 846{ 847 return; 848} 849 850void IOHIKeyboard::setNumLockFeedback(bool /* val */) 851{ 852 return; 853} 854 855UInt32 IOHIKeyboard::maxKeyCodes() 856{ 857 return( NX_NUMKEYCODES ); 858} 859 860bool IOHIKeyboard:: doesKeyLock ( unsigned key __unused) 861{ 862 return false; 863} 864 865unsigned IOHIKeyboard:: getLEDStatus () 866{ 867 return 0; 868} 869 870 871bool IOHIKeyboard::open(IOService * client, 872 IOOptionBits options, 873 KeyboardEventAction keAction, 874 KeyboardSpecialEventAction kseAction, 875 UpdateEventFlagsAction uefAction) 876{ 877 if ( (!_keyMap) && (!resetKeyboard())) return false; 878 879 if (client == this) { 880 KeyboardReserved *tempReservedStruct; 881 tempReservedStruct = GetKeyboardReservedStructEventForService(this); 882 883 return super::open((tempReservedStruct) ? tempReservedStruct->openClient : 0, options); 884 } 885 886 return open(client, 887 options, 888 0, 889 (KeyboardEventCallback)keAction, 890 (KeyboardSpecialEventCallback)kseAction, 891 (UpdateEventFlagsCallback)uefAction); 892} 893 894bool IOHIKeyboard::open( 895 IOService * client, 896 IOOptionBits options, 897 void * /*refcon*/, 898 KeyboardEventCallback keCallback, 899 KeyboardSpecialEventCallback kseCallback, 900 UpdateEventFlagsCallback uefCallback) 901{ 902 if (client == this) return true; 903 904 KeyboardReserved *tempReservedStruct; 905 tempReservedStruct = GetKeyboardReservedStructEventForService(this); 906 907 if (tempReservedStruct) tempReservedStruct->openClient = client; 908 909 bool returnValue = open(this, options, 910 (KeyboardEventAction)_keyboardEvent, 911 (KeyboardSpecialEventAction)_keyboardSpecialEvent, 912 (UpdateEventFlagsAction)_updateEventFlags); 913 914 if (!returnValue) 915 return false; 916 917 // point the new keymap to the IOHIDSystem, so it can set properties in it 918 // this handles the case where although resetKeyboard is called above, 919 // _keyboardEventTarget is as yet unset, so zero is passed 920 if (_keyMap) 921 _keyMap->setKeyboardTarget(client); 922 923 // Note: client object is already retained by superclass' open() 924 _keyboardEventTarget = client; 925 _keyboardEventAction = (KeyboardEventAction)keCallback; 926 _keyboardSpecialEventTarget = client; 927 _keyboardSpecialEventAction = (KeyboardSpecialEventAction)kseCallback; 928 _updateEventFlagsTarget = client; 929 _updateEventFlagsAction = (UpdateEventFlagsAction)uefCallback; 930 931 return true; 932} 933 934void IOHIKeyboard::close(IOService * client, IOOptionBits) 935{ 936 // kill autorepeat task 937 // do this before we issue keyup for any other keys 938 // that are down. 939 AbsoluteTime ts; 940 clock_get_uptime(&ts); 941 if (_codeToRepeat != ((unsigned)-1)) 942 dispatchKeyboardEvent(_codeToRepeat, false, ts); 943 944 // now get rid of any other keys that might be down 945 UInt32 i, maxKeys = maxKeyCodes(); 946 for (i=0; i<maxKeys; i++) 947 if ( EVK_IS_KEYDOWN(i,_keyState) ) 948 dispatchKeyboardEvent(i, false, ts); 949 950 // continue to issue zero'ed out flags changed events 951 // just in case any of the flag bits were manually set 952 _updateEventFlags(this, 0); 953 954 _keyboardSpecialEvent( this, 955 NX_SYSDEFINED, 956 0, 957 NX_NOSPECIALKEY, 958 NX_SUBTYPE_STICKYKEYS_RELEASE, 959 _guid, 960 0, 961 _lastEventTime); 962 963 bzero(_keyState, _keyStateSize); 964 965 _keyboardEventAction = NULL; 966 _keyboardEventTarget = 0; 967 _keyboardSpecialEventAction = NULL; 968 _keyboardSpecialEventTarget = 0; 969 _updateEventFlagsAction = NULL; 970 _updateEventFlagsTarget = 0; 971 972 super::close(client); 973} 974 975IOReturn IOHIKeyboard::message( UInt32 type, IOService * provider, 976 void * argument) 977{ 978 IOReturn ret = kIOReturnSuccess; 979 980 switch(type) 981 { 982 case kIOHIDSystem508MouseClickMessage: 983 case kIOHIDSystem508SpecialKeyDownMessage: 984 if (_keyMap) 985 ret = _keyMap->message(type, this); 986 break; 987 988 case kIOHIDSystemDeviceSeizeRequestMessage: 989 if (OSDynamicCast(IOHIDDevice, provider)) 990 { 991 KeyboardReserved *tempReservedStruct = GetKeyboardReservedStructEventForService(this); 992 993 if (tempReservedStruct) { 994 tempReservedStruct->isSeized = (bool)argument; 995 } 996 } 997 break; 998 999 case IOHIDSecurePromptClient::gatheringMessage: 1000 { 1001 if (argument) { 1002 // Only do things if someone is turning ON gathering. 1003 AbsoluteTime ts; 1004 clock_get_uptime(&ts); 1005 1006 // kill any pending repeat 1007 if (_codeToRepeat != ((unsigned)-1)) 1008 dispatchKeyboardEvent(_codeToRepeat, false, ts); 1009 1010 // now get rid of any other keys that might be down 1011 UInt32 i, maxKeys = maxKeyCodes(); 1012 for (i=0; i<maxKeys; i++) 1013 if ( EVK_IS_KEYDOWN(i,_keyState) ) 1014 dispatchKeyboardEvent(i, false, ts); 1015 1016 // continue to issue zero'ed out flags changed events 1017 // just in case any of the flag bits were manually set 1018 _updateEventFlags(this, 0); 1019 1020 _keyboardSpecialEvent( this, 1021 NX_SYSDEFINED, 1022 0, 1023 NX_NOSPECIALKEY, 1024 NX_SUBTYPE_STICKYKEYS_RELEASE, 1025 _guid, 1026 0, 1027 _lastEventTime); 1028 1029 // Now, disable gathering on all other secure clients 1030 if (provider) { 1031 OSIterator *itr = getClientIterator(); 1032 if (itr) { 1033 IOHIDSecurePromptClient *client = NULL; 1034 do { 1035 client = IOHIDSecurePromptClient::nextForIterator(itr); 1036 if (client && (client != provider) && client->gathering()) { 1037 client->setGathering(0); 1038 } 1039 } 1040 while(client); 1041 itr->release(); 1042 } 1043 } 1044 } 1045 } 1046 1047 default: 1048 ret = super::message(type, provider, argument); 1049 break; 1050 } 1051 1052 return ret; 1053} 1054 1055void IOHIKeyboard::_keyboardEvent( IOHIKeyboard * self, 1056 unsigned eventType, 1057 /* flags */ unsigned flags, 1058 /* keyCode */ unsigned key, 1059 /* charCode */ unsigned charCode, 1060 /* charSet */ unsigned charSet, 1061 /* originalCharCode */ unsigned origCharCode, 1062 /* originalCharSet */ unsigned origCharSet, 1063 /* keyboardType */ unsigned keyboardType, 1064 /* repeat */ bool repeat, 1065 /* atTime */ AbsoluteTime ts) 1066{ 1067 if (!self || !self->_keyboardEventAction || !self->_keyboardEventTarget) { 1068 // nothing to be done 1069 } 1070 else { 1071 // this is skanky 1072 KeyboardEventCallback keCallback = (KeyboardEventCallback)self->_keyboardEventAction; 1073 1074 (*keCallback)(self->_keyboardEventTarget, 1075 eventType, 1076 flags, 1077 key, 1078 charCode, 1079 charSet, 1080 origCharCode, 1081 origCharSet, 1082 keyboardType, 1083 repeat, 1084 ts, 1085 self, 1086 0); 1087 } 1088} 1089 1090void IOHIKeyboard::_keyboardSpecialEvent( 1091 IOHIKeyboard * self, 1092 unsigned eventType, 1093 /* flags */ unsigned flags, 1094 /* keyCode */ unsigned key, 1095 /* specialty */ unsigned flavor, 1096 /* guid */ UInt64 guid, 1097 /* repeat */ bool repeat, 1098 /* atTime */ AbsoluteTime ts) 1099{ 1100 if (!self || !self->_keyboardSpecialEventAction || !self->_keyboardEventTarget) { 1101 // nothing to be done 1102 } 1103 else { 1104 // this is skanky 1105 KeyboardSpecialEventCallback kseCallback = (KeyboardSpecialEventCallback)self->_keyboardSpecialEventAction; 1106 1107 (*kseCallback)(self->_keyboardEventTarget, 1108 eventType, 1109 flags, 1110 key, 1111 flavor, 1112 guid, 1113 repeat, 1114 ts, 1115 self, 1116 0); 1117 } 1118} 1119 1120void IOHIKeyboard::_updateEventFlags( IOHIKeyboard * self, 1121 unsigned flags) 1122{ 1123 if (!self || !self->_keyboardSpecialEventAction || !self->_keyboardEventTarget) { 1124 // nothing to be done 1125 } 1126 else { 1127 // this is skanky 1128 UpdateEventFlagsCallback uefCallback = (UpdateEventFlagsCallback)self->_updateEventFlagsAction; 1129 1130 (*uefCallback)(self->_updateEventFlagsTarget, 1131 flags, 1132 self, 1133 0); 1134 } 1135} 1136 1137/******************************************************************************/ 1138IOReturn IOHIKeyboard::newUserClient(task_t owningTask, 1139 void * security_id, 1140 UInt32 type, 1141 OSDictionary * properties, 1142 IOUserClient ** handler ) 1143{ 1144 if ( type == IOHIDSecurePromptClient::clientID ) { 1145 IOWorkLoop *loop = getWorkLoop(); 1146 IOReturn result = kIOReturnNotReady; 1147 1148 if ( loop ) { 1149 result = loop->runAction( OSMemberFunctionCast( IOWorkLoop::Action, this, &IOHIKeyboard::newUserClientGated ), 1150 this, owningTask, security_id, NULL, handler ); 1151 } 1152 else { 1153 IOLog( "IOHIDDevice::newUserClient failed to get a workloop\n" ); 1154 } 1155 1156 return result; 1157 } 1158 1159 return super::newUserClient( owningTask, security_id, type, properties, handler ); 1160} 1161 1162/******************************************************************************/ 1163static bool IOHIKeyboard_attachSecurePromptClient_Callback(void * target, 1164 void * refCon __unused, 1165 IOService * newService, 1166 IONotifier * notifier __unused ) 1167{ 1168 IOHIDSecurePromptClient *client = (IOHIDSecurePromptClient*)target; 1169 IOHIKeyboard *keyboard = OSDynamicCast(IOHIKeyboard, newService); 1170 1171 require(client, improper_call); 1172 require(keyboard, improper_call); 1173 1174 require(!client->dead(), invalid_client); 1175 1176 return client->attach(keyboard); 1177 1178invalid_client: 1179improper_call: 1180 return false; 1181} 1182 1183/******************************************************************************/ 1184IOReturn IOHIKeyboard::newUserClientGated(task_t owningTask, 1185 void * security_id, 1186 OSDictionary * properties, 1187 IOUserClient ** handler ) 1188{ 1189 IOHIDSecurePromptClient * client = new IOHIDSecurePromptClient; 1190 1191 if ( !client->initWithTask( owningTask, security_id, 0, properties ) ) { 1192 client->release(); 1193 return kIOReturnBadArgument; 1194 } 1195 1196 if ( !client->start( this ) ) { 1197 client->detach( this ); 1198 client->release(); 1199 return kIOReturnInternalError; 1200 } 1201 1202 *handler = client; 1203 1204// vtn3 TODO: tell client to guess table 1205 1206 // This user client must be attached to all keyboards 1207 OSDictionary *match = IOService::serviceMatching(kIOHIKeyboardClass); 1208 1209 IONotifier *notifier = IOService::addMatchingNotification(gIOPublishNotification, 1210 match, 1211 IOHIKeyboard_attachSecurePromptClient_Callback, 1212 client); 1213 client->setNotifier(notifier); 1214 match->release(); 1215 notifier->release(); 1216 1217 return kIOReturnSuccess; 1218} 1219 1220/******************************************************************************/ 1221bool IOHIKeyboard:: 1222postSecureKey(UInt8 key, bool down) 1223{ 1224 KeyboardReserved *reservedStruct = GetKeyboardReservedStructEventForService(this); 1225 bool posted = false; 1226 if (reservedStruct && reservedStruct->hasSecurePrompt) { 1227 IOHIDSecurePromptClient *client = NULL; 1228 OSIterator *itr = getClientIterator(); 1229 if (itr) { 1230 do { 1231 client = IOHIDSecurePromptClient::nextForIterator(itr); 1232 if (client && client->gathering()) { 1233 IOReturn result = client->postKey(key, down); 1234 client = NULL; 1235 if (result == kIOReturnSuccess) { 1236 // event was posted internally. needs suppression. 1237 posted = true; 1238 } 1239 } 1240 } 1241 while(client); 1242 itr->release(); 1243 } 1244 } 1245 return posted; 1246} 1247 1248/******************************************************************************/ 1249bool IOHIKeyboard:: 1250attachToChild(IORegistryEntry * child, 1251 const IORegistryPlane * plane ) 1252{ 1253 IOHIDSecurePromptClient *secureClient = OSDynamicCast(IOHIDSecurePromptClient, child); 1254 if (secureClient) { 1255 KeyboardReserved *reservedStruct = GetKeyboardReservedStructEventForService(this); 1256 if (reservedStruct) { 1257 reservedStruct->hasSecurePrompt = true; 1258 } 1259 } 1260 return super::attachToChild(child, plane); 1261} 1262 1263/******************************************************************************/ 1264void IOHIKeyboard:: 1265detachFromChild(IORegistryEntry * child, 1266 const IORegistryPlane * plane ) 1267{ 1268 IOHIDSecurePromptClient *secureClient = OSDynamicCast(IOHIDSecurePromptClient, child); 1269 1270 super::detachFromChild(child, plane); 1271 1272 if (secureClient) { 1273 KeyboardReserved *reservedStruct = GetKeyboardReservedStructEventForService(this); 1274 if (reservedStruct && reservedStruct->hasSecurePrompt) { 1275 OSIterator *itr = getClientIterator(); 1276 if (itr) { 1277 if (NULL == IOHIDSecurePromptClient::nextForIterator(itr)) { 1278 reservedStruct->hasSecurePrompt = false; 1279 } 1280 itr->release(); 1281 } 1282 } 1283 } 1284} 1285 1286/******************************************************************************/ 1287void IOHIKeyboard::clearLastPageAndUsage() 1288{ 1289 if (!_lastUsagePage && !_lastUsage) 1290 IOLog("IOHIKeyboard::clearLastPageAndUsage called when not set %02x:%02x\n", _lastUsagePage, _lastUsage); 1291 _lastUsagePage = 0; 1292 _lastUsage = 0; 1293} 1294 1295/******************************************************************************/ 1296void IOHIKeyboard::setLastPageAndUsage(UInt16 usagePage, UInt16 usage) 1297{ 1298 if (_lastUsagePage || _lastUsage) 1299 IOLog("IOHIKeyboard::setLastPageAndUsage called when already set %02x:%02x\n", _lastUsagePage, _lastUsage); 1300 _lastUsagePage = usagePage; 1301 _lastUsage = usage; 1302} 1303 1304/******************************************************************************/ 1305void IOHIKeyboard::getLastPageAndUsage(UInt16 &usagePage, UInt16 &usage) 1306{ 1307 usagePage = _lastUsagePage; 1308 usage = _lastUsage; 1309} 1310 1311/******************************************************************************/ 1312