1/* 2 * 3 * @APPLE_LICENSE_HEADER_START@ 4 * 5 * Copyright (c) 1999-2003 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 <IOKit/IOLib.h> 26 27#include "IOHIDKeyboardDevice.h" 28 29typedef struct GenericLEDKeyboardDescriptor { 30 //05 01: Usage Page (Generic Desktop) 31 UInt8 devUsagePageOp; 32 UInt8 devUsagePageNum; 33 //09 06: Usage (Keyboard) 34 UInt8 devUsageOp; 35 UInt8 devUsageNum; 36 //A1 01: Collection (Application) 37 UInt8 appCollectionOp; 38 UInt8 appCollectionNum; 39 //05 07: Usage Page (Key Codes) 40 UInt8 modUsagePageOp; 41 UInt8 modUsagePageNum; 42 //19 e0: Usage Minimum...... (224) 43 UInt8 modUsageMinOp; 44 UInt8 modUsageMinNum; 45 //29 e7: Usage Maximum...... (231) 46 UInt8 modUsageMaxOp; 47 UInt8 modUsageMaxNum; 48 //15 00: Logical Minimum.... (0) 49 UInt8 modLogMinOp; 50 UInt8 modLogMinNum; 51 //25 01: Logical Maximum.... (1) 52 UInt8 modLogMaxOp; 53 UInt8 modLogMaxNum; 54 //95 01: Report Count....... (1) 55 UInt8 modRptCountOp; 56 UInt8 modRptCountNum; 57 //75 08: Report Size........ (8) 58 UInt8 modRptSizeOp; 59 UInt8 modRptSizeNum; 60 //81 02: Input (Data) 61 UInt8 modInputOp; 62 UInt8 modInputNum; 63 64 //95 01: Report Count....... (1) 65 UInt8 rsrvCountOp; 66 UInt8 rsrvCountNum; 67 //75 08: Report Size........ (8) 68 UInt8 rsrvSizeOp; 69 UInt8 rsrvSizeNum; 70 //81 01: Input (Constant) 71 UInt8 rsrvInputOp; 72 UInt8 rsrvInputNum; 73 74 75 //95 02: Report Count....... (2) 76 UInt8 ledRptCountOp; 77 UInt8 ledRptCountNum; 78 //75 01: Report Size........ (1) 79 UInt8 ledRptSizeOp; 80 UInt8 ledRptSizeNum; 81 //05 08: Usage Page (LEDs) 82 UInt8 ledUsagePageOp; 83 UInt8 ledUsagePageNum; 84 //19 01: Usage Minimum...... (1) 85 UInt8 ledUsageMinOp; 86 UInt8 ledUsageMinNum; 87 //29 02: Usage Maximum...... (2) 88 UInt8 ledUsageMaxOp; 89 UInt8 ledUsageMaxNum; 90 //91 02: Output (Data) 91 UInt8 ledInputOp; 92 UInt8 ledInputNum; 93 94 //95 01: Report Count....... (1) 95 UInt8 fillRptCountOp; 96 UInt8 fillRptCountNum; 97 //75 03: Report Size........ (3) 98 UInt8 fillRptSizeOp; 99 UInt8 fillRptSizeNum; 100 //91 01: Output (Constant) 101 UInt8 fillInputOp; 102 UInt8 fillInputNum; 103 104 105 //95 06: Report Count....... (6) 106 UInt8 keyRptCountOp; 107 UInt8 keyRptCountNum; 108 //75 08: Report Size........ (8) 109 UInt8 keyRptSizeOp; 110 UInt8 keyRptSizeNum; 111 //15 00: Logical Minimum.... (0) 112 UInt8 keyLogMinOp; 113 UInt8 keyLogMinNum; 114 //26 ff 00: Logical Maximum.... (255) 115 UInt8 keyLogMaxOp; 116 UInt16 keyLogMaxNum; 117 //05 07: Usage Page (Key Codes) 118 UInt8 keyUsagePageOp; 119 UInt8 keyUsagePageNum; 120 //19 00: Usage Minimum...... (0) 121 UInt8 keyUsageMinOp; 122 UInt8 keyUsageMinNum; 123 //29 ff: Usage Maximum...... (255) 124 UInt8 keyUsageMaxOp; 125 UInt8 keyUsageMaxNum; 126 //81 00: Input (Array) 127 UInt8 keyInputOp; 128 UInt8 keyInputNum; 129 130 //C0: End Collection 131 UInt8 appCollectionEnd; 132} GenericLEDKeyboardDescriptor; 133 134struct GenericKeyboardDescriptor { 135 //05 01: Usage Page (Generic Desktop) 136 UInt8 devUsagePageOp; 137 UInt8 devUsagePageNum; 138 //09 06: Usage (Keyboard) 139 UInt8 devUsageOp; 140 UInt8 devUsageNum; 141 //A1 01: Collection (Application) 142 UInt8 appCollectionOp; 143 UInt8 appCollectionNum; 144 //05 07: Usage Page (Key Codes) 145 UInt8 modUsagePageOp; 146 UInt8 modUsagePageNum; 147 //19 e0: Usage Minimum...... (224) 148 UInt8 modUsageMinOp; 149 UInt8 modUsageMinNum; 150 //29 e7: Usage Maximum...... (231) 151 UInt8 modUsageMaxOp; 152 UInt8 modUsageMaxNum; 153 //15 00: Logical Minimum.... (0) 154 UInt8 modLogMinOp; 155 UInt8 modLogMinNum; 156 //25 01: Logical Maximum.... (1) 157 UInt8 modLogMaxOp; 158 UInt8 modLogMaxNum; 159 //95 01: Report Count....... (1) 160 UInt8 modRptCountOp; 161 UInt8 modRptCountNum; 162 //75 08: Report Size........ (8) 163 UInt8 modRptSizeOp; 164 UInt8 modRptSizeNum; 165 //81 02: Input (Data) 166 UInt8 modInputOp; 167 UInt8 modInputNum; 168 169 //95 01: Report Count....... (1) 170 UInt8 rsrvCountOp; 171 UInt8 rsrvCountNum; 172 //75 08: Report Size........ (8) 173 UInt8 rsrvSizeOp; 174 UInt8 rsrvSizeNum; 175 //81 01: Input (Constant) 176 UInt8 rsrvInputOp; 177 UInt8 rsrvInputNum; 178 179 180 //95 02: Report Count....... (2) 181 UInt8 ledRptCountOp; 182 UInt8 ledRptCountNum; 183 //75 01: Report Size........ (1) 184 UInt8 ledRptSizeOp; 185 UInt8 ledRptSizeNum; 186 //05 08: Usage Page (LEDs) 187 UInt8 ledUsagePageOp; 188 UInt8 ledUsagePageNum; 189 //19 01: Usage Minimum...... (1) 190 UInt8 ledUsageMinOp; 191 UInt8 ledUsageMinNum; 192 //29 02: Usage Maximum...... (2) 193 UInt8 ledUsageMaxOp; 194 UInt8 ledUsageMaxNum; 195 //91 02: Output (Data) 196 UInt8 ledInputOp; 197 UInt8 ledInputNum; 198 199 //95 01: Report Count....... (1) 200 UInt8 fillRptCountOp; 201 UInt8 fillRptCountNum; 202 //75 03: Report Size........ (3) 203 UInt8 fillRptSizeOp; 204 UInt8 fillRptSizeNum; 205 //91 01: Output (Constant) 206 UInt8 fillInputOp; 207 UInt8 fillInputNum; 208 209 210 //95 06: Report Count....... (6) 211 UInt8 keyRptCountOp; 212 UInt8 keyRptCountNum; 213 //75 08: Report Size........ (8) 214 UInt8 keyRptSizeOp; 215 UInt8 keyRptSizeNum; 216 //15 00: Logical Minimum.... (0) 217 UInt8 keyLogMinOp; 218 UInt8 keyLogMinNum; 219 //26 ff 00: Logical Maximum.... (255) 220 UInt8 keyLogMaxOp; 221 UInt16 keyLogMaxNum; 222 //05 07: Usage Page (Key Codes) 223 UInt8 keyUsagePageOp; 224 UInt8 keyUsagePageNum; 225 //19 00: Usage Minimum...... (0) 226 UInt8 keyUsageMinOp; 227 UInt8 keyUsageMinNum; 228 //29 ff: Usage Maximum...... (255) 229 UInt8 keyUsageMaxOp; 230 UInt8 keyUsageMaxNum; 231 //81 00: Input (Array) 232 UInt8 keyInputOp; 233 UInt8 keyInputNum; 234 235 //C0: End Collection 236 UInt8 appCollectionEnd; 237} GenericKeyboardDescriptor; 238 239typedef struct GenericKeyboardRpt { 240 UInt8 modifiers; 241 UInt8 reserved; 242 UInt8 keys[6]; 243} GenericKeyboardRpt; 244 245static UInt8 gGenLEDKeyboardDesc[] = { 246 0x05, 0x01, 247 0x09, 0x06, 248 0xA1, 0x01, 249 0x05, 0x07, 250 0x19, 0xe0, 251 0x29, 0xe7, 252 0x15, 0x00, 253 0x25, 0x01, 254 0x75, 0x01, 255 0x95, 0x08, 256 0x81, 0x02, 257 0x95, 0x01, 258 0x75, 0x08, 259 0x81, 0x01, 260 261 0x95, 0x02, 262 0x75, 0x01, 263 0x05, 0x08, 264 0x19, 0x01, 265 0x29, 0x02, 266 0x91, 0x02, 267 0x95, 0x01, 268 0x75, 0x06, 269 0x91, 0x01, 270 271 0x95, 0x06, 272 0x75, 0x08, 273 0x15, 0x00, 274 0x26, 0xff, 0x00, 275 0x05, 0x07, 276 0x19, 0x00, 277 0x29, 0xff, 278 0x81, 0x00, 279 0xC0 280}; 281 282static UInt8 gGenKeyboardDesc[] = { 283 0x05, 0x01, 284 0x09, 0x06, 285 0xA1, 0x01, 286 0x05, 0x07, 287 0x19, 0xe0, 288 0x29, 0xe7, 289 0x15, 0x00, 290 0x25, 0x01, 291 0x75, 0x01, 292 0x95, 0x08, 293 0x81, 0x02, 294 0x95, 0x01, 295 0x75, 0x08, 296 0x81, 0x01, 297 298 0x95, 0x06, 299 0x75, 0x08, 300 0x15, 0x00, 301 0x26, 0xff, 0x00, 302 0x05, 0x07, 303 0x19, 0x00, 304 0x29, 0xff, 305 0x81, 0x00, 306 0xC0 307}; 308 309extern unsigned int hid_adb_2_usb_keymap[]; //In Cosmo_USB2ADB.cpp 310 311#define super IOHIDDeviceShim 312 313OSDefineMetaClassAndStructors( IOHIDKeyboardDevice, IOHIDDeviceShim ) 314 315 316IOHIDKeyboardDevice * 317IOHIDKeyboardDevice::newKeyboardDeviceAndStart(IOService * owner, UInt32 location) 318{ 319 IOService * provider = owner; 320 321 while ( NULL != (provider = provider->getProvider()) ) 322 { 323 if(OSDynamicCast(IOHIDDevice, provider) || OSDynamicCast(IOHIDevice, provider)) 324 return 0; 325 } 326 327 328 IOHIDKeyboardDevice * device = new IOHIDKeyboardDevice; 329 330 if (device) 331 { 332 if ( device->initWithLocation(location) && device->attach(owner) ) 333 { 334 if (!device->start(owner)) 335 { 336 device->detach(owner); 337 device->release(); 338 device = 0; 339 } 340 } 341 else 342 { 343 device->release(); 344 device = 0; 345 } 346 } 347 348 return device; 349} 350 351 352bool IOHIDKeyboardDevice::initWithLocation( UInt32 location ) 353{ 354 if (!super::initWithLocation(location)) 355 return false; 356 357 _report = 0; 358 _cachedLEDState = 0; 359 _inputReportOnly = true; 360 361 return true; 362} 363 364void IOHIDKeyboardDevice::free() 365{ 366 if (_report) _report->release(); 367 368 super::free(); 369} 370 371bool IOHIDKeyboardDevice::handleStart( IOService * provider ) 372{ 373 if (!super::handleStart(provider)) 374 return false; 375 376 if ( (_keyboard = OSDynamicCast(IOHIKeyboard, provider)) ) 377 { 378 _inputReportOnly = ((transport() == kIOHIDTransportADB) && (_keyboard->deviceType() >= 0xc3)); 379 _cachedLEDState = _keyboard->getLEDStatus() & 0x3; 380 } 381 382 _report = IOBufferMemoryDescriptor::withCapacity( 383 sizeof(GenericKeyboardRpt), kIODirectionNone, true); 384 385 bzero(_report->getBytesNoCopy(), sizeof(GenericKeyboardRpt)); 386 387 return (_report) ? true : false; 388} 389 390IOReturn IOHIDKeyboardDevice::newReportDescriptor( 391 IOMemoryDescriptor ** descriptor ) const 392{ 393 void * desc; 394 UInt8 * descBytes; 395 UInt8 descSize; 396 397 if (!descriptor) 398 return kIOReturnBadArgument; 399 400 if (_inputReportOnly) 401 { 402 descSize = sizeof(GenericKeyboardDescriptor); 403 descBytes = gGenKeyboardDesc; 404 } 405 else 406 { 407 descSize = sizeof(GenericLEDKeyboardDescriptor); 408 descBytes = gGenLEDKeyboardDesc; 409 } 410 411 *descriptor = IOBufferMemoryDescriptor::withCapacity( 412 descSize, 413 kIODirectionNone, 414 true); 415 416 if (! *descriptor) 417 return kIOReturnNoMemory; 418 419 desc = ((IOBufferMemoryDescriptor *)(*descriptor))->getBytesNoCopy(); 420 bcopy(descBytes, desc, descSize); 421 422 return kIOReturnSuccess; 423} 424 425IOReturn IOHIDKeyboardDevice::getReport(IOMemoryDescriptor *report, 426 IOHIDReportType reportType, 427 IOOptionBits options __unused ) 428{ 429 if (!report) 430 return kIOReturnError; 431 432 if ( reportType != kIOHIDReportTypeInput) 433 return kIOReturnUnsupported; 434 435 report->writeBytes(0, _report->getBytesNoCopy(), min(report->getLength(), _report->getLength())); 436 return kIOReturnSuccess; 437} 438 439IOReturn IOHIDKeyboardDevice::setReport(IOMemoryDescriptor * report, 440 IOHIDReportType reportType __unused, 441 IOOptionBits options ) 442{ 443 UInt8 ledState; 444 UInt8 mask; 445 446 if ((options & 0xff) || (_inputReportOnly) || !_keyboard) 447 return kIOReturnError; 448 449 report->readBytes( 0, (void *)&ledState, sizeof(UInt8) ); 450 451 mask = (1 << (kHIDUsage_LED_NumLock - 1)); 452 if ( (ledState & mask) && !(_cachedLEDState & mask) ) 453 { 454 _keyboard->setNumLockFeedback(true); 455 } 456 else if ( !(ledState & mask) && (_cachedLEDState & mask) ) 457 { 458 _keyboard->setNumLockFeedback(false); 459 } 460 461 mask = (1 << (kHIDUsage_LED_CapsLock - 1)); 462 if ( (ledState & mask) && !(_cachedLEDState & mask) ) 463 { 464 _keyboard->setAlphaLockFeedback(true); 465 } 466 else if ( !(ledState & mask) && (_cachedLEDState & mask) ) 467 { 468 _keyboard->setAlphaLockFeedback(false); 469 } 470 471 _cachedLEDState = ledState; 472 473 return kIOReturnSuccess; 474} 475 476void IOHIDKeyboardDevice::setCapsLockLEDElement(bool state) 477{ 478 UInt8 mask = (1 << (kHIDUsage_LED_CapsLock-1)); 479 480 if (_inputReportOnly) 481 return; 482 483 if (state) 484 _cachedLEDState |= mask; 485 486 else 487 _cachedLEDState &= ~mask; 488 489 *(UInt8 *)(_report->getBytesNoCopy()) = _cachedLEDState; 490 491 handleReport(_report, kIOHIDReportTypeOutput); 492} 493 494void IOHIDKeyboardDevice::setNumLockLEDElement(bool state) 495{ 496 UInt8 mask = (1 << (kHIDUsage_LED_NumLock-1)); 497 498 if (_inputReportOnly) 499 return; 500 501 if (state) 502 _cachedLEDState |= mask; 503 504 else 505 _cachedLEDState &= ~mask; 506 507 *(UInt8 *)(_report->getBytesNoCopy()) = _cachedLEDState; 508 509 handleReport(_report, kIOHIDReportTypeOutput); 510} 511 512#define SET_MODIFIER_BIT(bitField, key, down) \ 513 if (down) {bitField |= (1 << (key - 0xe0));} \ 514 else {bitField &= ~(1 << (key - 0xe0));} 515 516void IOHIDKeyboardDevice::postKeyboardEvent(UInt8 key, bool keyDown) 517{ 518 GenericKeyboardRpt *report = (GenericKeyboardRpt *)_report->getBytesNoCopy(); 519 UInt8 usbKey; 520 521 if (!report) 522 return; 523 524 // Convert ADB scan code to USB 525 if (! (usbKey = hid_adb_2_usb_keymap[key])) 526 return; 527 528 // Check if modifier 529 if ((usbKey >= 0xe0) && (usbKey <= 0xe7)) 530 { 531 SET_MODIFIER_BIT(report->modifiers, usbKey, keyDown); 532 } 533 else 534 { 535 for (int i=0; i<6; i++) 536 { 537 if (report->keys[i] == usbKey) 538 { 539 if (keyDown) return; 540 541 for (int j=i; j<5; j++) 542 report->keys[j] = report->keys[j+1]; 543 544 report->keys[5] = 0; 545 break; 546 } 547 548 else if ((report->keys[i] == 0) && keyDown) 549 { 550 report->keys[i] = usbKey; 551 break; 552 } 553 } 554 } 555 556 handleReport(_report); 557} 558 559enum { 560 kUSB_LEFT_CONTROL_BIT = 0x01, 561 kUSB_LEFT_SHIFT_BIT = 0x02, 562 kUSB_LEFT_ALT_BIT = 0x04, 563 kUSB_LEFT_FLOWER_BIT = 0x08, 564 565 kUSB_RIGHT_CONTROL_BIT = 0x10, 566 kUSB_RIGHT_SHIFT_BIT = 0x20, 567 kUSB_RIGHT_ALT_BIT = 0x040, 568 kUSB_RIGHT_FLOWER_BIT = 0x80 569}; 570 571void IOHIDKeyboardDevice::postFlagKeyboardEvent(UInt32 flags) 572{ 573 GenericKeyboardRpt *report = (GenericKeyboardRpt *)_report->getBytesNoCopy(); 574 UInt32 flagDelta = (flags ^ _lastFlags); 575 576 if (!flagDelta) 577 return; 578 579 report->modifiers = 0; 580 _lastFlags = flags; 581 582 if ( flagDelta & 0x0000ffff ) 583 { 584 if( flags & NX_DEVICELSHIFTKEYMASK ) 585 report->modifiers |= kUSB_LEFT_SHIFT_BIT; 586 if( flags & NX_DEVICELCTLKEYMASK ) 587 report->modifiers |= kUSB_LEFT_CONTROL_BIT; 588 if( flags & NX_DEVICELALTKEYMASK ) 589 report->modifiers |= kUSB_LEFT_ALT_BIT; 590 if( flags & NX_DEVICELCMDKEYMASK ) 591 report->modifiers |= kUSB_LEFT_FLOWER_BIT; 592 593 if( flags & NX_DEVICERSHIFTKEYMASK ) 594 report->modifiers |= kUSB_RIGHT_SHIFT_BIT; 595 if( flags & NX_DEVICERCTLKEYMASK ) 596 report->modifiers |= kUSB_RIGHT_CONTROL_BIT; 597 if( flags & NX_DEVICERALTKEYMASK ) 598 report->modifiers |= kUSB_RIGHT_ALT_BIT; 599 if( flags & NX_DEVICERCMDKEYMASK ) 600 report->modifiers |= kUSB_RIGHT_FLOWER_BIT; 601 } 602 else if ( flagDelta & 0xffff0000 ) 603 { 604 if( flags & NX_SHIFTMASK ) 605 report->modifiers |= kUSB_LEFT_SHIFT_BIT; 606 if( flags & NX_CONTROLMASK ) 607 report->modifiers |= kUSB_LEFT_CONTROL_BIT; 608 if( flags & NX_ALTERNATEMASK ) 609 report->modifiers |= kUSB_LEFT_ALT_BIT; 610 if( flags & NX_COMMANDMASK ) 611 report->modifiers |= kUSB_LEFT_FLOWER_BIT; 612 } 613 614 if ( flagDelta & NX_ALPHASHIFTMASK ) 615 { 616 postKeyboardEvent(0x39, flags & NX_ALPHASHIFTMASK); 617 return; 618 } 619 620 handleReport(_report); 621} 622 623OSString * IOHIDKeyboardDevice::newProductString() const 624{ 625 OSString * string = 0; 626 627 if ( !(string = super::newProductString()) ) 628 string = OSString::withCString("Virtual Keyboard"); 629 630 return string; 631} 632