|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this 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 OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. ! 26: * ! 27: * EventSrcPCKeyoard.m - PC Keyboard EventSrc subclass implementation ! 28: * ! 29: * HISTORY ! 30: * 10 Sep 1992 Joe Pasqua ! 31: * Created. ! 32: * 5 Nov, 1993 ! 33: * Modified for Hppa ! 34: * 15 Dec 1993 ! 35: * Modified for 712 ! 36: * 23 Mar 1997 ! 37: * Modified for PPC ! 38: */ ! 39: ! 40: // TO DO: ! 41: // ! 42: // NOTES: ! 43: // * We override methods in the EventSrcExported protocol so that we can ! 44: // intercept messages used to control who owns us. This gives us ! 45: // an opportunity to acquire/release the PCKeyboard device we want to own. ! 46: // * In the current system the EventDriver instance is always the owner ! 47: // of this EventSrc. In the future the km driver and the EventDriver might ! 48: // both be potential owners. ! 49: // * The device dependent portion of the event flags are set by this module ! 50: // before the flags are passed up to our owner. There are a couple of notes ! 51: // on this. First, the PC keyboard has no key labelled "Command", therefore ! 52: // the NX_NEXT[RL]CMDKEYMASK flag bits will never be set. Conversely, the ! 53: // PC keyboard has both a left and a right Control key. When either key is ! 54: // pressed we set the NX_NEXTCTLKEYMASK mask. The code processing events ! 55: // must determine which one it was by looking at the code that is generated. ! 56: // * To find things that need to be fixed, search for FIX, to find questions ! 57: // to be resolved, search for ASK, to find stuff that still needs to be ! 58: // done, search for TO DO. ! 59: // ! 60: ! 61: #import <driverkit/generalFuncs.h> ! 62: #import <machkit/NXLock.h> ! 63: #import <driverkit/KeyMap.h> ! 64: #import <bsd/dev/evsio.h> ! 65: #import <bsd/dev/ppc/event.h> ! 66: #import <bsd/dev/ppc/PPCKeymap.c> // The default keymapping string ! 67: #import <bsd/dev/ppc/EventSrcPCKeyboard.h> ! 68: #import <bsd/dev/ppc/PCKeyboardDefs.h> ! 69: #import <bsd/dev/ppc/PPCKeyboardPriv.h> ! 70: ! 71: // Private variables that are global to the module: ! 72: static EventSrcPCKeyboard *instance = (EventSrcPCKeyboard *)0; ! 73: ! 74: // Forward declarations ! 75: static void autoRepeatCallout( void *data ); ! 76: unsigned int wserver_on=0; ! 77: ! 78: //Make sure USB exists ! 79: id usb_UIM_object = 0; ! 80: ! 81: // FIXME: Nasty hack to reinit mouse on server startup ! 82: #include "PPCMouse.h" ! 83: extern PPCMouse *_my_Mouse; ! 84: ! 85: @implementation EventSrcPCKeyboard ! 86: ! 87: // ! 88: // BEGIN: Utility Procedures ! 89: // ! 90: static void nsecs_to_packed_ns(ns_time_t *nsecs, unsigned int *pnsecs) ! 91: { ! 92: _NX_packed_time_t data; ! 93: int i; ! 94: ! 95: data.tval = *nsecs; // nsecs to ns_time_t ! 96: for ( i = 0; i < EVS_PACKED_TIME_SIZE; ++i ) ! 97: pnsecs[i] = data.itval[i]; ! 98: } ! 99: ! 100: static void packed_nsecs_to_nsecs(unsigned int *pnsecs, ns_time_t *nsecs) ! 101: { ! 102: _NX_packed_time_t data; ! 103: int i; ! 104: ! 105: for ( i = 0; i < EVS_PACKED_TIME_SIZE; ++i ) ! 106: data.itval[i] = pnsecs[i]; ! 107: *nsecs = data.tval; ! 108: } ! 109: // ! 110: // END: Utility Procedures ! 111: // ! 112: ! 113: ! 114: // ! 115: // BEGIN: Implementation of Private EventSrcPCKeyoard methods ! 116: // ! 117: - resetKeyboard ! 118: // Description: Reset the keymapping to the default value and reconfigure ! 119: // the keyboards. ! 120: { ! 121: [deviceLock lock]; ! 122: if ( keyMap != nil ) ! 123: [keyMap free]; ! 124: // Set up default keymapping. ! 125: ! 126: keyMap = [[KeyMap alloc] initFromKeyMapping:PPCDefaultKeymap ! 127: length:sizeof PPCDefaultKeymap ! 128: canFree:NO]; ! 129: ! 130: [keyMap setDelegate:self]; ! 131: keyRepeat = EV_DEFAULTKEYREPEAT; ! 132: initialKeyRepeat = EV_DEFAULTINITIALREPEAT; ! 133: [deviceLock unlock]; ! 134: return self; ! 135: } ! 136: ! 137: - scheduleAutoRepeat ! 138: // Description: Schedule a procedure to be called when a timeout has expired ! 139: // so that we can generate a repeated key. ! 140: // Preconditions: ! 141: // * deviceLock should be held on entry ! 142: { ! 143: if ( calloutPending == YES ) ! 144: { ! 145: ns_untimeout( (func)autoRepeatCallout, (void *)self ); ! 146: calloutPending = NO; ! 147: } ! 148: if ( downRepeatTime > 0ULL ) ! 149: { ! 150: ns_abstimeout( ! 151: (func)autoRepeatCallout, ! 152: (void *)self, ! 153: downRepeatTime, ! 154: CALLOUT_PRI_THREAD ); ! 155: calloutPending = YES; ! 156: } ! 157: return self; ! 158: } ! 159: ! 160: - autoRepeat ! 161: // Description: Repeat the currently pressed key and schedule ourselves ! 162: // to be called again after another interval elapses. ! 163: // Preconditions: ! 164: // * Should only be executed on callout thread ! 165: // * deviceLock should be unlocked on entry. ! 166: { ! 167: ns_time_t ns; ! 168: ! 169: IOGetTimestamp(&ns); ! 170: [deviceLock lock]; ! 171: if ( calloutPending == NO ) ! 172: { ! 173: [deviceLock unlock]; ! 174: return self; ! 175: } ! 176: calloutPending = NO; ! 177: isRepeat = YES; ! 178: ! 179: if ( downRepeatTime > 0ULL && downRepeatTime <= ns ) ! 180: { ! 181: // Device is due to generate a repeat ! 182: lastEventTime = ns; ! 183: [keyMap doKeyboardEvent:codeToRepeat ! 184: direction:YES ! 185: keyBits:keyState]; ! 186: downRepeatTime += keyRepeat; ! 187: } ! 188: ! 189: isRepeat = NO; ! 190: [self scheduleAutoRepeat]; ! 191: [deviceLock unlock]; ! 192: return self; ! 193: } ! 194: ! 195: static void autoRepeatCallout( void *data ) ! 196: // Description: Callout used to enter Obj-C autoRepeat code from NS timer ! 197: // callout. This proc was set as a callback in scheduleAutoRepeat. ! 198: { ! 199: EventSrcPCKeyboard *kbd = (EventSrcPCKeyboard *)data; ! 200: [kbd autoRepeat]; ! 201: } ! 202: ! 203: ! 204: - setRepeat:(unsigned)eventType forCode:(unsigned)keyCode ! 205: // Description: Set up or tear dow key repeat operations. The method ! 206: // that locks deviceLock is a bit higher on the call stack. ! 207: // This method is invoked as a side effect of our own ! 208: // invocation of [keyMap doKeyboardEvent]. ! 209: // Preconditions: ! 210: // * deviceLock should be held upon entry. ! 211: { ! 212: if ( isRepeat == NO ) // make sure we're not already repeating ! 213: { ! 214: if (eventType == NX_KEYDOWN) // Start repeat ! 215: { ! 216: // Set this key to repeat (push out last key if present) ! 217: downRepeatTime = initialKeyRepeat + lastEventTime; ! 218: codeToRepeat = keyCode; ! 219: // reschedule key repeat event here ! 220: [self scheduleAutoRepeat]; ! 221: } ! 222: else if (eventType == NX_KEYUP) // End repeat ! 223: { ! 224: /* Remove from downKey */ ! 225: if (codeToRepeat == keyCode) ! 226: { ! 227: downRepeatTime = 0ULL; ! 228: codeToRepeat = -1; ! 229: [self scheduleAutoRepeat]; ! 230: } ! 231: } ! 232: } ! 233: return self; ! 234: } ! 235: ! 236: - initKeyboard ! 237: // Description: Perform setup work needed to find and configure our ! 238: // PCKeyboard device. We have to tell it to send events to us. ! 239: { ! 240: IOReturn drtn; ! 241: ! 242: ! 243: drtn = IOGetObjectForDeviceName("PPCKeyboard0", &kbdDevice); ! 244: if(drtn) { ! 245: IOLog("initKeyboard: Can't find PPCKeyboard0 (%s)\n", ! 246: [self stringFromReturn:drtn]); ! 247: return nil; ! 248: } ! 249: return self; ! 250: } ! 251: // ! 252: // END: Implementation of Private EventSrcPCKeyoard methods ! 253: // ! 254: ! 255: ! 256: // ! 257: // BEGIN: Implementation of the KeyMapDelegate protocol ! 258: // ! 259: - keyboardEvent:(int)eventType ! 260: flags:(unsigned)flags ! 261: keyCode:(unsigned)keyCode ! 262: charCode:(unsigned)charCode ! 263: charSet:(unsigned)charSet ! 264: originalCharCode:(unsigned)origCharCode ! 265: originalCharSet:(unsigned)origCharSet ! 266: // Description: We use this notification to set up our keyRepeat timer ! 267: // and to pass along the event to our owner. In the current ! 268: // implementation this is always the EventDriver. In the future, ! 269: // the km driver may be another potential owner. This method ! 270: // will be called while the KeyMap object is processing ! 271: // the key code we've sent it using doKeyboardEvent. ! 272: { ! 273: [[self owner] keyboardEvent :eventType ! 274: flags:(flags | deviceDependentFlags) ! 275: keyCode:keyCode ! 276: charCode:charCode ! 277: charSet:charSet ! 278: originalCharCode:origCharCode ! 279: originalCharSet:origCharSet ! 280: repeat:isRepeat ! 281: atTime:lastEventTime]; ! 282: ! 283: // Set up key repeat operations here. ! 284: return [self setRepeat:eventType forCode:keyCode]; ! 285: } ! 286: ! 287: - keyboardSpecialEvent:(unsigned)eventType ! 288: flags:(unsigned)flags ! 289: keyCode:(unsigned)keyCode ! 290: specialty:(unsigned)flavor ! 291: // Description: See the description for keyboardEvent. ! 292: { ! 293: [[self owner] keyboardSpecialEvent:eventType ! 294: flags:(flags | deviceDependentFlags) ! 295: keyCode :keyCode ! 296: specialty:flavor ! 297: atTime:lastEventTime]; ! 298: ! 299: // Set up key repeat operations here. ! 300: if (flavor != NX_KEYTYPE_CAPS_LOCK) ! 301: return [self setRepeat:eventType forCode:keyCode]; ! 302: } ! 303: ! 304: - updateEventFlags:(unsigned)flags ! 305: // Description: Process non-event-generating flag changes. Simply pass this ! 306: // along to our owner. ! 307: { ! 308: return [[self owner] updateEventFlags:flags]; ! 309: } ! 310: ! 311: - (unsigned)eventFlags ! 312: // Description: Return global event flags In this world, there is only ! 313: // one keyboard device so device flags == global flags. ! 314: { ! 315: return eventFlags; ! 316: } ! 317: ! 318: - (unsigned)deviceFlags ! 319: // Description: Return per-device event flags. In this world, there is only ! 320: // one keyboard device so device flags == global flags. ! 321: { ! 322: return eventFlags; ! 323: } ! 324: ! 325: - setDeviceFlags:(unsigned)flags ! 326: // Description: Set device event flags. In this world, there is only ! 327: // one keyboard device so device flags == global flags. ! 328: { ! 329: eventFlags = flags; ! 330: return self; ! 331: } ! 332: ! 333: - (BOOL)alphaLock ! 334: // Description: Return current alpha-lock state. This is a state tracking ! 335: // callback used by the KeyMap object. ! 336: { ! 337: return alphaLock; ! 338: } ! 339: ! 340: - setAlphaLock:(BOOL)val ! 341: // Description: Set current alpha-lock state This is a state tracking ! 342: // callback used by the KeyMap object. ! 343: { ! 344: alphaLock = val; ! 345: [kbdDevice setAlphaLockFeedback:val]; ! 346: return self; ! 347: } ! 348: ! 349: - (BOOL)charKeyActive ! 350: // Description: Return YES If a character generating key down This is a state ! 351: // tracking callback used by the KeyMap object. ! 352: { ! 353: return charKeyActive; ! 354: } ! 355: ! 356: - setCharKeyActive:(BOOL)val ! 357: // Description: Note whether a char generating key is down. This is a state ! 358: // tracking callback used by the KeyMap object. ! 359: { ! 360: charKeyActive = val; ! 361: return self; ! 362: } ! 363: // ! 364: // END: Implementation of the KeyMapDelegate protocol ! 365: // ! 366: ! 367: ! 368: // ! 369: // BEGIN: Implementation of PCKeyboardImported protocol ! 370: // ! 371: - (void)dispatchKeyboardEvent:(PCKeyboardEvent *)event ! 372: // Description: This method is the heart of event dispatching. The underlying ! 373: // PCKeyboard object invokes this method with each event. We then ! 374: // get the event xlated and dispatched using a keyMap instance. ! 375: // The event structure passed in by reference should not be freed. ! 376: { ! 377: unsigned keyMask; ! 378: ! 379: lastEventTime = event->timeStamp; ! 380: ! 381: switch (event->keyCode) { ! 382: case ADBK_SHIFT: keyMask = NX_NEXTLSHIFTKEYMASK; break; ! 383: case ADBK_SHIFT_R: keyMask = NX_NEXTRSHIFTKEYMASK; break; ! 384: case ADBK_OPTION: keyMask = NX_NEXTLALTKEYMASK; break; ! 385: case ADBK_OPTION_R: keyMask = NX_NEXTRALTKEYMASK; break; ! 386: case ADBK_CONTROL: keyMask = NX_NEXTCTLKEYMASK; break; ! 387: case ADBK_CONTROL_R: keyMask = NX_NEXTCTLKEYMASK; break; ! 388: default: keyMask = 0; break; ! 389: } ! 390: ! 391: if (event->goingDown) ! 392: deviceDependentFlags |= keyMask; ! 393: else ! 394: deviceDependentFlags &= ~keyMask; ! 395: ! 396: [deviceLock lock]; ! 397: ! 398: if( (event->keyCode == ADBK_CAPSLOCK)) { // Send a capslock toggle ! 399: if( event->goingDown != alphaLock ) { ! 400: [keyMap doKeyboardEvent:ADBK_CAPSLOCK ! 401: direction:YES ! 402: keyBits:keyState]; ! 403: [keyMap doKeyboardEvent:ADBK_CAPSLOCK ! 404: direction:NO ! 405: keyBits:keyState]; ! 406: } ! 407: } else { ! 408: [keyMap doKeyboardEvent:event->keyCode ! 409: direction:event->goingDown ! 410: keyBits:keyState]; ! 411: } ! 412: [deviceLock unlock]; ! 413: } ! 414: ! 415: - (IOReturn)relinquishOwnershipRequest : device ! 416: { ! 417: IOReturn r; ! 418: ! 419: [[self ownerLock] lock]; ! 420: if ( [self owner] == nil ) ! 421: { ! 422: ownDevice = NO; ! 423: r = IO_R_SUCCESS; ! 424: } ! 425: else ! 426: r = IO_R_BUSY; ! 427: ! 428: [[self ownerLock] unlock]; ! 429: return r; ! 430: } ! 431: ! 432: - (IOReturn)canBecomeOwner : device ! 433: { ! 434: IOReturn drtn; ! 435: drtn = [device becomeOwner: self]; ! 436: if(drtn) ! 437: { ! 438: IOLog("%s: becomeOwner of %s failed (%s)\n", ! 439: [self name], ! 440: [device name], ! 441: [self stringFromReturn:drtn]); ! 442: } ! 443: else ! 444: { ! 445: ownDevice = YES; ! 446: } ! 447: return( drtn); ! 448: } ! 449: // ! 450: // END: Implementation of PCKeyboardImported protocol ! 451: // ! 452: ! 453: ! 454: // ! 455: // BEGIN: Implementation of Exported EventSrcPCKeyoard methods ! 456: // ! 457: - init ! 458: // Description: Initialize an EventSrcPCKeyboard ! 459: { ! 460: [deviceLock lock]; ! 461: [super init]; ! 462: if ( keyMap != nil ) ! 463: [keyMap free]; ! 464: // Set up default keymapping ! 465: ! 466: keyMap = [[KeyMap alloc] initFromKeyMapping:PPCDefaultKeymap ! 467: length:sizeof PPCDefaultKeymap ! 468: canFree:NO]; ! 469: ! 470: [keyMap setDelegate:self]; ! 471: [self initKeyboard]; ! 472: keyRepeat = EV_DEFAULTKEYREPEAT; ! 473: initialKeyRepeat = EV_DEFAULTINITIALREPEAT; ! 474: [deviceLock unlock]; ! 475: return self; ! 476: } ! 477: ! 478: + probe ! 479: // Description: This is our factory method. It is the IODevice probe ! 480: // routine for psuedo drivers. ! 481: { ! 482: if ( instance != nil ) ! 483: return instance; ! 484: ! 485: instance = [self alloc]; ! 486: ! 487: instance->deviceLock = [NXLock new]; ! 488: [instance setName:"EventSrcPCKeyboard0"]; ! 489: [instance setDeviceKind:"EventSrcPCKeyboard"]; ! 490: ! 491: if ( [instance init] == nil ) ! 492: [instance free]; // No devices. Go away ! 493: return instance; ! 494: } ! 495: ! 496: - free ! 497: // Description: Go Away. Be careful when freeing the lock. ! 498: { ! 499: id lock; ! 500: ! 501: lock = deviceLock; ! 502: [lock lock]; ! 503: instance = nil; ! 504: deviceLock = nil; ! 505: if ( keyMap != nil ) ! 506: [keyMap free]; ! 507: // Release keyboard device, so we won't get any more events ! 508: if ( kbdDevice != nil ) ! 509: [kbdDevice relinquishOwnership:self]; ! 510: [lock unlock]; ! 511: [lock free]; ! 512: return [super free]; ! 513: } ! 514: ! 515: - (IOReturn)getIntValues:(unsigned *)parameterArray ! 516: forParameter:(IOParameterName)parameterName ! 517: count:(unsigned int *)count ! 518: { ! 519: IOReturn r = IO_R_INVALID_ARG; ! 520: NXEventSystemDevice *dp; ! 521: unsigned maxCount = *count; ! 522: unsigned *returnedCount = count; ! 523: ! 524: if ( strcmp( parameterName, EVSIOCKR ) == 0 ) // Current Key Repeat ! 525: { ! 526: if ( maxCount >= EVSIOCKR_SIZE ) ! 527: { ! 528: *returnedCount = EVSIOCKR_SIZE; ! 529: [deviceLock lock]; ! 530: nsecs_to_packed_ns( ! 531: &initialKeyRepeat, ¶meterArray[EVSIOCKR_INITIAL]); ! 532: nsecs_to_packed_ns( ! 533: &keyRepeat, ¶meterArray[EVSIOCKR_BETWEEN]); ! 534: [deviceLock unlock]; ! 535: r = IO_R_SUCCESS; ! 536: } ! 537: } ! 538: else if ( strcmp( parameterName, EVSIOCKML ) == 0 ) // Current Keymap len. ! 539: { ! 540: if ( maxCount >= EVSIOCKML_SIZE ) ! 541: { ! 542: *returnedCount = EVSIOCKML_SIZE; ! 543: [deviceLock lock]; ! 544: if ( keyMap == nil ) ! 545: parameterArray[0] = 0; ! 546: else ! 547: parameterArray[0] = [keyMap keyMappingLength]; ! 548: [deviceLock unlock]; ! 549: r = IO_R_SUCCESS; ! 550: } ! 551: } ! 552: else if ( strcmp( parameterName, EVSIOINFO ) == 0 ) // Device info ! 553: { ! 554: dp = (NXEventSystemDevice *)¶meterArray[0]; ! 555: *returnedCount = 0; ! 556: // No need to lock device since we're not even reading the structure. ! 557: dp->interface = [kbdDevice interfaceId]; ! 558: dp->dev_type = NX_EVS_DEVICE_TYPE_KEYBOARD; ! 559: dp->interface_addr = 0; ! 560: dp->id = [kbdDevice handlerId]; //Right now ID is for ADB keyboard ! 561: //This line shows up very late in bootup, around time LOGIN is happening on screen ! 562: // I think this may be the code that maps international key maps. A.W. 12/21/98 ! 563: // Now I will call USB method to retrieve USB keyboard attached, if any. The ! 564: // USB method will return the same 16 + ADB ID that is in the various .keyboard ! 565: // files in /System/Library/Keyboards/* ! 566: ! 567: if (usb_UIM_object != 0) ! 568: { ! 569: int adb_id; ! 570: ! 571: adb_id = [usb_UIM_object getADBKeyboardID]; ! 572: if (adb_id != 0) ! 573: { ! 574: dp->id = adb_id; //converted from USB land ! 575: //kprintf("ADB: keyboard converted from USB is %d decimal\n", adb_id); ! 576: } ! 577: } ! 578: ! 579: ! 580: *returnedCount = sizeof(NXEventSystemDevice) / sizeof(int); ! 581: r = IO_R_SUCCESS; ! 582: } ! 583: else if ( strcmp( parameterName, EVSIOGKEYS ) == 0 ) // Key state ! 584: { ! 585: if( maxCount == EVK_NUNITS) { ! 586: [deviceLock lock]; ! 587: bcopy( &keyState, parameterArray, EVK_NUNITS * sizeof( int)); ! 588: [deviceLock unlock]; ! 589: r = IO_R_SUCCESS; ! 590: } ! 591: } ! 592: else ! 593: { ! 594: r = [super getIntValues:parameterArray ! 595: forParameter:parameterName ! 596: count:count]; ! 597: if (r == IO_R_UNSUPPORTED) ! 598: r = IO_R_INVALID_ARG; ! 599: } ! 600: return r; ! 601: } ! 602: ! 603: - (IOReturn)getCharValues:(unsigned char *)parameterArray ! 604: forParameter:(IOParameterName)parameterName ! 605: count:(unsigned int *)count ! 606: { ! 607: IOReturn r = IO_R_INVALID_ARG; ! 608: int cnt; ! 609: unsigned maxCount = *count; ! 610: unsigned *returnedCount = count; ! 611: ! 612: if ( strcmp( parameterName, EVSIOCKM ) == 0 ) // Current KeyMap ! 613: { ! 614: [deviceLock lock]; ! 615: if ( keyMap != nil ) ! 616: { ! 617: cnt = [keyMap keyMappingLength]; ! 618: cnt = (cnt < maxCount) ? cnt : maxCount; ! 619: *returnedCount = cnt; ! 620: bcopy( [keyMap keyMapping:(int *)0], parameterArray, cnt ); ! 621: r = IO_R_SUCCESS; ! 622: } ! 623: else ! 624: r = IO_R_NOT_ATTACHED; ! 625: [deviceLock unlock]; ! 626: } ! 627: else ! 628: { ! 629: r = [super getCharValues:parameterArray ! 630: forParameter:parameterName ! 631: count:count]; ! 632: if (r == IO_R_UNSUPPORTED) ! 633: r = IO_R_INVALID_ARG; ! 634: } ! 635: return r; ! 636: } ! 637: ! 638: - (IOReturn)setIntValues:(unsigned *)parameterArray ! 639: forParameter:(IOParameterName)parameterName ! 640: count:(unsigned int)count ! 641: { ! 642: IOReturn r = IO_R_INVALID_ARG; ! 643: ! 644: if ( strcmp( parameterName, EVSIOSKR ) == 0 ) // Set Key Repeat ! 645: { ! 646: if ( count == EVSIOSKR_SIZE ) ! 647: { ! 648: [deviceLock lock]; ! 649: packed_nsecs_to_nsecs(parameterArray, &keyRepeat); ! 650: if ( keyRepeat < EV_MINKEYREPEAT ) ! 651: keyRepeat = EV_MINKEYREPEAT; ! 652: [deviceLock unlock]; ! 653: r = IO_R_SUCCESS; ! 654: } ! 655: } ! 656: else if ( strcmp( parameterName, EVSIOSIKR ) == 0 ) // Set Init Key Repeat ! 657: { ! 658: if ( count == EVSIOSIKR_SIZE ) ! 659: { ! 660: [deviceLock lock]; ! 661: packed_nsecs_to_nsecs(parameterArray, &initialKeyRepeat); ! 662: if ( initialKeyRepeat < EV_MINKEYREPEAT ) ! 663: initialKeyRepeat = EV_MINKEYREPEAT; ! 664: [deviceLock unlock]; ! 665: r = IO_R_SUCCESS; ! 666: } ! 667: } ! 668: else if ( strcmp( parameterName, EVSIORKBD ) == 0 ) // Reset keyboard ! 669: { ! 670: [self resetKeyboard]; ! 671: r = IO_R_SUCCESS; ! 672: } ! 673: else ! 674: { ! 675: r = [super setIntValues:parameterArray ! 676: forParameter:parameterName ! 677: count : count]; ! 678: if (r == IO_R_UNSUPPORTED) ! 679: r = IO_R_INVALID_ARG; ! 680: } ! 681: return r; ! 682: } ! 683: ! 684: - (IOReturn)setCharValues:(unsigned char *)parameterArray ! 685: forParameter:(IOParameterName)parameterName ! 686: count:(unsigned int)count ! 687: { ! 688: IOReturn r = IO_R_INVALID_ARG; ! 689: unsigned char *map; ! 690: id oldMap; ! 691: ! 692: if ( strcmp( parameterName, EVSIOSKM ) == 0 ) // Set KeyMap ! 693: { ! 694: map = (unsigned char *)IOMalloc( count ); ! 695: bcopy( parameterArray, map, count ); ! 696: [deviceLock lock]; ! 697: oldMap = keyMap; ! 698: keyMap = [[KeyMap alloc] initFromKeyMapping:map ! 699: length:count ! 700: canFree:YES]; ! 701: if ( keyMap != nil ) ! 702: { ! 703: if ( oldMap != nil ) ! 704: [oldMap free]; ! 705: [keyMap setDelegate:self]; ! 706: r = IO_R_SUCCESS; ! 707: } ! 708: else ! 709: { ! 710: keyMap = oldMap; ! 711: r = IO_R_INVALID_ARG; ! 712: } ! 713: [deviceLock unlock]; ! 714: } ! 715: else ! 716: { ! 717: r = [super setCharValues:parameterArray ! 718: forParameter:parameterName ! 719: count : count]; ! 720: if (r == IO_R_UNSUPPORTED) ! 721: r = IO_R_INVALID_ARG; ! 722: } ! 723: return r; ! 724: } ! 725: // ! 726: // END: Implementation of Exported EventSrcPCKeyoard methods ! 727: // ! 728: ! 729: ! 730: ! 731: // ! 732: // BEGIN: Implementation of EventSrcExported protocol ! 733: // ! 734: // ! 735: - (IOReturn)relinquishOwnership:(id)client ! 736: { ! 737: IOReturn r; ! 738: ! 739: // kill autorepeat task ! 740: downRepeatTime = 0ULL; ! 741: codeToRepeat = -1; ! 742: [self scheduleAutoRepeat]; ! 743: // clear modifiers to avoid stuck keys ! 744: [self setAlphaLock:NO]; ! 745: [[self owner] updateEventFlags:0]; ! 746: deviceDependentFlags = 0; ! 747: eventFlags = 0; ! 748: bzero( keyState, sizeof( kbdBitVector)); ! 749: ! 750: r = [super relinquishOwnership:client]; ! 751: [[self ownerLock] lock]; ! 752: // If nobody took over this EventSrc, release attached keyboards ! 753: wserver_on = 0; ! 754: if ( r == IO_R_SUCCESS && [self owner] == nil ) ! 755: { ! 756: if ( [kbdDevice relinquishOwnership:self] == IO_R_SUCCESS ) ! 757: ownDevice = NO; ! 758: } ! 759: [[self ownerLock] unlock]; ! 760: return r; ! 761: } ! 762: ! 763: - (IOReturn) becomeOwner:(id)client ! 764: { ! 765: IOReturn r; ! 766: ! 767: r = [super becomeOwner:client]; ! 768: [[self ownerLock] lock]; ! 769: if ( r == IO_R_SUCCESS && ownDevice == NO ) ! 770: { ! 771: if ( [kbdDevice becomeOwner:self] == IO_R_SUCCESS ) ! 772: { ! 773: ownDevice = YES; ! 774: wserver_on = 1; ! 775: // FIXME: Nasty hack to reinit mouse on server startup ! 776: [_my_Mouse mouseInit]; ! 777: } ! 778: else if ( [kbdDevice desireOwnership:self] != IO_R_SUCCESS ) ! 779: { ! 780: [super relinquishOwnership:client]; ! 781: r = IO_R_BUSY; ! 782: } ! 783: } ! 784: [[self ownerLock] unlock]; ! 785: return r; ! 786: } ! 787: // ! 788: // END: Implementation of EventSrcExported protocol ! 789: // ! 790: ! 791: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.