|
|
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.