RWS@ZERMATT.LCS.MIT.EDU (Robert Scheifler) (11/04/87)
Date: Thu, 29 Oct 87 10:48:08 PST From: smarks@Sun.COM SYNOPSIS: The Sun X server didn't implement beeps or keyclicks. Autorepeat was too slow and caused screen flicker. [Sun internal bugs 7, 15, 48] DESCRIPTION: Autorepeat had an interaction with the screensaver that caused the screen to flicker. Autorepeat was also too slow, so it was made faster. Autorepeat and keyclick are now controllable by the ChangeKbdCtrl. There were also problems with keyboard translation and SunView; most of these are now fixed. Some lint fixes are also included. FIX: 2 files: server/ddx/sun/sun.h, server/ddx/sun/sunKbd.c *** /tmp/,RCSt1000661 Wed Nov 4 10:05:46 1987 --- server/ddx/sun/sun.h Wed Nov 4 09:50:08 1987 *************** *** 12,18 **** * software for any purpose. It is provided "as is" without * express or implied warranty. * ! * "$Header: sun.h,v 4.3 87/09/12 02:29:58 sun Exp $ SPRITE (Berkeley)" */ #ifndef _SUN_H_ #define _SUN_H_ --- 12,18 ---- * software for any purpose. It is provided "as is" without * express or implied warranty. * ! * "$Header: sun.h,v 4.4 87/11/04 09:49:53 rws Exp $ SPRITE (Berkeley)" */ #ifndef _SUN_H_ #define _SUN_H_ *************** *** 101,106 **** --- 101,109 ---- pointer devPrivate; /* Private to keyboard device */ Bool map_q; /* TRUE if fd has a mapped event queue */ int offset; /* to be added to device keycodes */ + KeybdCtrl *ctrl; /* Current control structure (for + * keyclick, bell duration, auto- + * repeat, etc.) */ } KbPrivRec, *KbPrivPtr; #define MIN_KEYCODE 8 /* necessary to avoid the mouse buttons */ *************** *** 247,252 **** --- 250,256 ---- extern Bool sunCursorLoc(); extern void sunRemoveCursor(); extern void sunRestoreCursor(); + extern void sunMoveCursor(); /* * Initialization *************** *** 273,282 **** extern int lastEventTime; /* Time (in ms.) of last event */ extern void SetTimeSinceLastInputEvent(); - extern void ErrorF(); ! #define AUTOREPEAT_INITIATE (300) /* milliseconds */ ! #define AUTOREPEAT_DELAY (100) /* milliseconds */ /* * We signal autorepeat events with the unique Firm_event * id AUTOREPEAT_EVENTID. --- 277,285 ---- extern int lastEventTime; /* Time (in ms.) of last event */ extern void SetTimeSinceLastInputEvent(); ! #define AUTOREPEAT_INITIATE (200) /* milliseconds */ ! #define AUTOREPEAT_DELAY (50) /* milliseconds */ /* * We signal autorepeat events with the unique Firm_event * id AUTOREPEAT_EVENTID. *************** *** 289,294 **** --- 292,315 ---- extern int autoRepeatKeyDown; /* TRUE if key down */ extern int autoRepeatReady; /* TRUE if time out */ extern int autoRepeatDebug; /* TRUE if debugging */ + extern struct timeval autoRepeatLastKeyDownTv; + extern struct timeval autoRepeatDeltaTv; + + #define tvminus(tv, tv1, tv2) /* tv = tv1 - tv2 */ \ + if ((tv1).tv_usec < (tv2).tv_usec) { \ + (tv1).tv_usec += 1000000; \ + (tv1).tv_sec -= 1; \ + } \ + (tv).tv_usec = (tv1).tv_usec - (tv2).tv_usec; \ + (tv).tv_sec = (tv1).tv_sec - (tv2).tv_sec; + + #define tvplus(tv, tv1, tv2) /* tv = tv1 + tv2 */ \ + (tv).tv_sec = (tv1).tv_sec + (tv2).tv_sec; \ + (tv).tv_usec = (tv1).tv_usec + (tv2).tv_usec; \ + if ((tv).tv_usec > 1000000) { \ + (tv).tv_usec -= 1000000; \ + (tv).tv_sec += 1; \ + } /* * Sun specific extensions: *** /tmp/,RCSt1000672 Wed Nov 4 10:07:02 1987 --- server/ddx/sun/sunKbd.c Wed Nov 4 09:53:22 1987 *************** *** 45,51 **** #ifndef lint static char sccsid[] = "%W %G Copyright 1987 Sun Micro"; #endif ! #define NEED_EVENTS #include "sun.h" #include <stdio.h> --- 45,52 ---- #ifndef lint static char sccsid[] = "%W %G Copyright 1987 Sun Micro"; #endif ! ! #define NEED_EVENTS #include "sun.h" #include <stdio.h> *************** *** 53,60 **** #include "keysym.h" #include "inputstr.h" - extern CARD16 keyModifiersList[]; - typedef struct { int trans; /* Original translation form */ } SunKbPrivRec, *SunKbPrivPtr; --- 54,59 ---- *************** *** 61,66 **** --- 60,66 ---- extern CARD8 *sunModMap[]; extern KeySymsRec sunKeySyms[]; + extern CARD16 keyModifiersList[]; static void sunBell(); static void sunKbdCtrl(); *************** *** 71,94 **** int autoRepeatDebug = 0; int autoRepeatReady; static int autoRepeatFirst; ! static struct timeval autoRepeatLastKeyDownTv; ! static struct timeval autoRepeatDeltaTv; ! #define tvminus(tv, tv1, tv2) /* tv = tv1 - tv2 */ \ ! if ((tv1).tv_usec < (tv2).tv_usec) { \ ! (tv1).tv_usec += 1000000; \ ! (tv1).tv_sec -= 1; \ ! } \ ! (tv).tv_usec = (tv1).tv_usec - (tv2).tv_usec; \ ! (tv).tv_sec = (tv1).tv_sec - (tv2).tv_sec; ! #define tvplus(tv, tv1, tv2) /* tv = tv1 + tv2 */ \ ! (tv).tv_sec = (tv1).tv_sec + (tv2).tv_sec; \ ! (tv).tv_usec = (tv1).tv_usec + (tv2).tv_usec; \ ! if ((tv).tv_usec > 1000000) { \ ! (tv).tv_usec -= 1000000; \ ! (tv).tv_sec += 1; \ ! } - static SunKbPrivRec sunKbPriv; static KbPrivRec sysKbPriv = { -1, /* Type of keyboard */ --- 71,80 ---- int autoRepeatDebug = 0; int autoRepeatReady; static int autoRepeatFirst; ! struct timeval autoRepeatLastKeyDownTv; ! struct timeval autoRepeatDeltaTv; ! static KeybdCtrl sysKbCtrl; static SunKbPrivRec sunKbPriv; static KbPrivRec sysKbPriv = { -1, /* Type of keyboard */ *************** *** 100,105 **** --- 86,92 ---- (pointer)&sunKbPriv, /* Private to keyboard device */ (Bool)0, /* Mapped queue */ 0, /* offset for device keycodes */ + &sysKbCtrl, /* Initial full duration = .25 sec. */ }; /*- *************** *** 121,126 **** --- 108,114 ---- * *----------------------------------------------------------------------- */ + #define TR_UNDEFINED (TR_NONE-1) int sunKbdProc (pKeyboard, what) DevicePtr pKeyboard; /* Keyboard to manipulate */ *************** *** 128,133 **** --- 116,122 ---- { KbPrivPtr pPriv; register int kbdFd; + static int deviceOffKbdState = TR_UNDEFINED; switch (what) { case DEVICE_INIT: *************** *** 172,179 **** * itself which couldn't be filled in before. */ pKeyboard->devicePrivate = (pointer)&sysKbPriv; - pKeyboard->on = FALSE; /* * ensure that the keycodes on the wire are >= MIN_KEYCODE */ --- 161,170 ---- * itself which couldn't be filled in before. */ pKeyboard->devicePrivate = (pointer)&sysKbPriv; pKeyboard->on = FALSE; + sysKbCtrl = defaultKeyboardControl; + sysKbPriv.ctrl = &sysKbCtrl; + /* * ensure that the keycodes on the wire are >= MIN_KEYCODE */ *************** *** 195,203 **** case DEVICE_ON: if (sunUseSunWindows()) { #ifdef SUN_WINDOWS ! if (! sunSetUpKbdSunWin(windowFd, TRUE, pKeyboard)) { FatalError("Can't set up keyboard\n"); } AddEnabledDevice(windowFd); #endif SUN_WINDOWS } --- 186,208 ---- case DEVICE_ON: if (sunUseSunWindows()) { #ifdef SUN_WINDOWS ! if (! sunSetUpKbdSunWin(windowFd, TRUE)) { FatalError("Can't set up keyboard\n"); } + /* + * Don't tamper with keyboard translation here + * unless this is a server reset. If server + * is reset then set translation to that saved + * when DEVICE_CLOSE was executed. + * Translation is set/reset upon receipt of + * KBD_USE/KBD_DONE input events (sunIo.c) + */ + if (deviceOffKbdState != TR_UNDEFINED) { + if (sunChangeKbdTranslation(pKeyboard, + deviceOffKbdState == TR_UNTRANS_EVENT) < 0) { + FatalError("Can't set (SW) keyboard translation\n"); + } + } AddEnabledDevice(windowFd); #endif SUN_WINDOWS } *************** *** 222,230 **** case DEVICE_OFF: if (sunUseSunWindows()) { #ifdef SUN_WINDOWS ! if (! sunSetUpKbdSunWin(windowFd, FALSE, pKeyboard)) { FatalError("Can't close keyboard\n"); } RemoveEnabledDevice(windowFd); #endif SUN_WINDOWS } --- 227,257 ---- case DEVICE_OFF: if (sunUseSunWindows()) { #ifdef SUN_WINDOWS ! /* ! * Save current translation state in case of server ! * reset. Used above when DEVICE_ON is executed. ! */ ! if ((kbdFd = open("/dev/kbd", O_RDONLY, 0)) < 0) { ! Error("DEVICE_OFF: Can't open kbd\n"); ! goto badkbd; ! } ! if (ioctl(kbdFd, KIOCGTRANS, &deviceOffKbdState) < 0) { ! Error("Can't save keyboard state\n"); ! } ! (void) close(kbdFd); ! ! badkbd: ! if (! sunSetUpKbdSunWin(windowFd, FALSE)) { FatalError("Can't close keyboard\n"); } + + /* + * Restore SunWindows translation. + */ + if (sunChangeKbdTranslation(pKeyboard,FALSE) < 0) { + FatalError("Can't reset keyboard translation\n"); + } + RemoveEnabledDevice(windowFd); #endif SUN_WINDOWS } *************** *** 231,237 **** else { pPriv = (KbPrivPtr)pKeyboard->devicePrivate; kbdFd = pPriv->fd; ! /* * Restore original keyboard directness and translation. */ --- 258,264 ---- else { pPriv = (KbPrivPtr)pKeyboard->devicePrivate; kbdFd = pPriv->fd; ! /* * Restore original keyboard directness and translation. */ *************** *** 253,259 **** * Ring the terminal/keyboard bell * * Results: ! * None. * * Side Effects: * None, really... --- 280,287 ---- * Ring the terminal/keyboard bell * * Results: ! * Ring the keyboard bell for an amount of time proportional to ! * "loudness." * * Side Effects: * None, really... *************** *** 265,271 **** int loudness; /* Percentage of full volume */ DevicePtr pKeyboard; /* Keyboard to ring */ { ! /* no can do, for now */ } /*- --- 293,338 ---- int loudness; /* Percentage of full volume */ DevicePtr pKeyboard; /* Keyboard to ring */ { ! KbPrivPtr pPriv = (KbPrivPtr) pKeyboard->devicePrivate; ! int kbdCmd; /* Command to give keyboard */ ! int kbdOpenedHere; ! ! if (loudness == 0) { ! return; ! } ! ! kbdOpenedHere = ( pPriv->fd < 0 ); ! if ( kbdOpenedHere ) { ! pPriv->fd = open("/dev/kbd", O_RDWR, 0); ! if (pPriv->fd < 0) { ! ErrorF("sunBell: can't open keyboard"); ! return; ! } ! } ! ! kbdCmd = KBD_CMD_BELL; ! if (ioctl (pPriv->fd, KIOCCMD, &kbdCmd) < 0) { ! ErrorF ("Failed to activate bell"); ! goto bad; ! } ! ! /* ! * Leave the bell on for a while == duration (ms) proportional to ! * loudness desired with a 10 thrown in to convert from ms to usecs. ! */ ! usleep (pPriv->ctrl->bell_duration * 1000); ! ! kbdCmd = KBD_CMD_NOBELL; ! if (ioctl (pPriv->fd, KIOCCMD, &kbdCmd) < 0) { ! ErrorF ("Failed to deactivate bell"); ! goto bad; ! } ! ! bad: ! if ( kbdOpenedHere ) { ! (void) close(pPriv->fd); ! pPriv->fd = -1; ! } } /*- *************** *** 282,291 **** *----------------------------------------------------------------------- */ static void ! sunKbdCtrl (pKeyboard) DevicePtr pKeyboard; /* Keyboard to alter */ { ! /* can only change key click on sun 3 keyboards, so what's the use? */ } /*- --- 349,383 ---- *----------------------------------------------------------------------- */ static void ! sunKbdCtrl (pKeyboard, ctrl) DevicePtr pKeyboard; /* Keyboard to alter */ + KeybdCtrl *ctrl; { ! KbPrivPtr pPriv = (KbPrivPtr) pKeyboard->devicePrivate; ! int kbdClickCmd = ctrl->click ? KBD_CMD_CLICK : KBD_CMD_NOCLICK; ! int kbdOpenedHere; ! ! kbdOpenedHere = ( pPriv->fd < 0 ); ! if ( kbdOpenedHere ) { ! pPriv->fd = open("/dev/kbd", O_WRONLY, 0); ! if (pPriv->fd < 0) { ! ErrorF("sunKbdCtrl: can't open keyboard"); ! return; ! } ! } ! ! if (ioctl (pPriv->fd, KIOCCMD, &kbdClickCmd) < 0) { ! ErrorF("Failed to set keyclick"); ! goto bad; ! } ! ! *pPriv->ctrl = *ctrl; ! ! bad: ! if ( kbdOpenedHere ) { ! (void) close(pPriv->fd); ! pPriv->fd = -1; ! } } /*- *************** *** 329,335 **** *pNumEvents = nBytes / sizeof (Firm_event); } ! if (autoRepeatKeyDown && autoRepeatReady && *pNumEvents == 0) { *pNumEvents = 1; /* Fake the event */ evBuf[0].id = AUTOREPEAT_EVENTID; /* Flags autoRepeat event */ if (autoRepeatDebug) --- 421,428 ---- *pNumEvents = nBytes / sizeof (Firm_event); } ! if (autoRepeatKeyDown && autoRepeatReady && ! pPriv->ctrl->autoRepeat == AutoRepeatModeOn && *pNumEvents == 0) { *pNumEvents = 1; /* Fake the event */ evBuf[0].id = AUTOREPEAT_EVENTID; /* Flags autoRepeat event */ if (autoRepeatDebug) *************** *** 366,378 **** --- 459,478 ---- { xEvent xE; PtrPrivPtr ptrPriv; + KbPrivPtr pPriv; int delta; static xEvent autoRepeatEvent; BYTE key; + CARD16 keyModifiers; ptrPriv = (PtrPrivPtr) LookupPointerDevice()->devicePrivate; if (autoRepeatKeyDown && fe->id == AUTOREPEAT_EVENTID) { + pPriv = (KbPrivPtr) pKeyboard->devicePrivate; + if (pPriv->ctrl->autoRepeat != AutoRepeatModeOn) { + autoRepeatKeyDown = 0; + return; + } /* * Generate auto repeat event. XXX one for now. * Update time & pointer location of saved KeyPress event. *************** *** 381,389 **** ErrorF("sunKbdProcessEvent: autoRepeatKeyDown = %d\n", autoRepeatKeyDown); ! delta = TVTOMILLI(autoRepeatDeltaTv) / 2; ! if (autoRepeatFirst == TRUE) ! autoRepeatFirst = FALSE; /* * Fake a key up event and a key down event --- 481,488 ---- ErrorF("sunKbdProcessEvent: autoRepeatKeyDown = %d\n", autoRepeatKeyDown); ! delta = TVTOMILLI(autoRepeatDeltaTv); ! autoRepeatFirst = FALSE; /* * Fake a key up event and a key down event *************** *** 395,401 **** autoRepeatEvent.u.u.type = KeyRelease; (* pKeyboard->processInputProc) (&autoRepeatEvent, pKeyboard); - autoRepeatEvent.u.keyButtonPointer.time += delta; autoRepeatEvent.u.u.type = KeyPress; (* pKeyboard->processInputProc) (&autoRepeatEvent, pKeyboard); --- 494,499 ---- *************** *** 407,414 **** } key = (fe->id & 0x7F) + sysKbPriv.offset; ! if (!keyModifiersList[key]) ! { /* * Kill AutoRepeater on any real non-modifier Kbd event. */ --- 505,511 ---- } key = (fe->id & 0x7F) + sysKbPriv.offset; ! if ((keyModifiers = keyModifiersList[key]) == 0) { /* * Kill AutoRepeater on any real non-modifier Kbd event. */ *************** *** 423,430 **** xE.u.u.type = ((fe->value == VKEY_UP) ? KeyRelease : KeyPress); xE.u.u.detail = key; ! if (keyModifiersList[key] & LockMask) ! { if (xE.u.u.type == KeyRelease) return; /* this assumes autorepeat is not desired */ if (((DeviceIntPtr)pKeyboard)->down[key >> 3] & (1 << (key & 7))) --- 520,526 ---- xE.u.u.type = ((fe->value == VKEY_UP) ? KeyRelease : KeyPress); xE.u.u.detail = key; ! if (keyModifiers & LockMask) { if (xE.u.u.type == KeyRelease) return; /* this assumes autorepeat is not desired */ if (((DeviceIntPtr)pKeyboard)->down[key >> 3] & (1 << (key & 7))) *************** *** 431,438 **** xE.u.u.type = KeyRelease; } ! if ((fe->value == VKEY_DOWN) && !keyModifiersList[key]) ! { /* turn on AutoRepeater */ if (autoRepeatDebug) ErrorF("sunKbdProcessEvent: VKEY_DOWN\n"); autoRepeatEvent = xE; --- 527,534 ---- xE.u.u.type = KeyRelease; } ! if ((xE.u.u.type == KeyPress) && (keyModifiers == 0)) { ! /* initialize new AutoRepeater event & mark AutoRepeater on */ if (autoRepeatDebug) ErrorF("sunKbdProcessEvent: VKEY_DOWN\n"); autoRepeatEvent = xE; *************** *** 483,495 **** KbPrivPtr pPriv; int kbdFd; int tmp; ! int KbdOpenedHere; pPriv = (KbPrivPtr)pKeyboard->devicePrivate; kbdFd = pPriv->fd; ! KbdOpenedHere = ( kbdFd < 0 ); ! if ( KbdOpenedHere ) { kbdFd = open("/dev/kbd", O_RDONLY, 0); if ( kbdFd < 0 ) { Error( "sunChangeKbdTranslation: Can't open keyboard" ); --- 579,591 ---- KbPrivPtr pPriv; int kbdFd; int tmp; ! int kbdOpenedHere; pPriv = (KbPrivPtr)pKeyboard->devicePrivate; kbdFd = pPriv->fd; ! kbdOpenedHere = ( kbdFd < 0 ); ! if ( kbdOpenedHere ) { kbdFd = open("/dev/kbd", O_RDONLY, 0); if ( kbdFd < 0 ) { Error( "sunChangeKbdTranslation: Can't open keyboard" ); *************** *** 512,517 **** --- 608,614 ---- } tmp = TR_UNTRANS_EVENT; if (ioctl (kbdFd, KIOCTRANS, &tmp) < 0) { + ErrorF("sunChangeKbdTranslation: kbdFd=%d\n",kbdFd); Error ("Setting keyboard translation"); goto bad; } *************** *** 529,545 **** (void)ioctl (kbdFd, KIOCTRANS, &tmp); } ! if ( KbdOpenedHere ) (void) close( kbdFd ); return(0); bad: ! if ( KbdOpenedHere ) (void) close( kbdFd ); ! return( -1 ); } - #ifdef SUN_WINDOWS /*- --- 626,641 ---- (void)ioctl (kbdFd, KIOCTRANS, &tmp); } ! if ( kbdOpenedHere ) (void) close( kbdFd ); return(0); bad: ! if ( kbdOpenedHere && kbdFd >= 0 ) (void) close( kbdFd ); ! return(-1); } #ifdef SUN_WINDOWS /*- *************** *** 548,554 **** --- 644,653 ---- * Change which events the kernel will pass through as keyboard * events. * + * Does NOT affect keyboard translation. + * * Results: + * Inputevent mask modified. * * Side Effects: * *************** *** 556,565 **** */ Bool ! sunSetUpKbdSunWin(windowFd, onoff, pKeyboard) int windowFd; Bool onoff; - DeviceRec *pKeyboard; { struct inputmask inputMask; static struct inputmask oldInputMask; --- 655,663 ---- */ Bool ! sunSetUpKbdSunWin(windowFd, onoff) int windowFd; Bool onoff; { struct inputmask inputMask; static struct inputmask oldInputMask; *************** *** 595,621 **** } win_set_kbd_mask(windowFd, &inputMask); - - /* - * Set the keyboard into "direct" mode and turn on - * event translation. - */ - #ifdef notdef - if (sunChangeKbdTranslation(pKeyboard,TRUE) < 0) { - FatalError("Can't set keyboard translation\n"); - } - #endif notdef } else { win_set_kbd_mask(windowFd, &oldInputMask); - - /* - * Restore original keyboard directness and translation. - */ - if (sunChangeKbdTranslation(pKeyboard,FALSE) < 0) { - FatalError("Can't reset keyboard translation\n"); - } - } return (TRUE); } --- 693,701 ---- *************** *** 662,667 **** --- 742,749 ---- return (TRUE); } + static KeybdCtrl *pKbdCtrl = (KeybdCtrl *) 0; + /*ARGSUSED*/ void sunBlockHandler(nscreen, pbdata, pptv, pReadmask) *************** *** 670,689 **** struct timeval **pptv; pointer pReadmask; { ! static struct timeval artv; /* autorepeat timeval */ ! static sec1 = 0; /* tmp for patching */ ! static sec2 = AUTOREPEAT_INITIATE; ! static sec3 = AUTOREPEAT_DELAY; if (!autoRepeatKeyDown) return; ! artv.tv_sec = sec1; if (autoRepeatFirst == TRUE) ! artv.tv_usec = 1000 * sec2; else ! artv.tv_usec = 1000 * sec3; *pptv = &artv; if (autoRepeatDebug) ErrorF("sunBlockHandler(%d,%d): \n", artv.tv_sec, artv.tv_usec); } --- 752,774 ---- struct timeval **pptv; pointer pReadmask; { ! static struct timeval artv = { 0, 0 }; /* autorepeat timeval */ if (!autoRepeatKeyDown) return; ! if (pKbdCtrl == (KeybdCtrl *) 0) ! pKbdCtrl = ((KbPrivPtr) LookupKeyboardDevice()->devicePrivate)->ctrl; ! ! if (pKbdCtrl->autoRepeat != AutoRepeatModeOn) ! return; ! if (autoRepeatFirst == TRUE) ! artv.tv_usec = 1000 * AUTOREPEAT_INITIATE; else ! artv.tv_usec = 1000 * AUTOREPEAT_DELAY; *pptv = &artv; + if (autoRepeatDebug) ErrorF("sunBlockHandler(%d,%d): \n", artv.tv_sec, artv.tv_usec); } *************** *** 701,706 **** --- 786,797 ---- if (autoRepeatDebug) ErrorF("sunWakeupHandler(ar=%d, err=%d):\n", autoRepeatKeyDown, err); + if (pKbdCtrl == (KeybdCtrl *) 0) + pKbdCtrl = ((KbPrivPtr) LookupKeyboardDevice()->devicePrivate)->ctrl; + + if (pKbdCtrl->autoRepeat != AutoRepeatModeOn) + return; + if (autoRepeatKeyDown) { gettimeofday(&tv, (struct timezone *) NULL); tvminus(autoRepeatDeltaTv, tv, autoRepeatLastKeyDownTv); *************** *** 716,719 **** ProcessInputEvents(); autoRepeatReady = 0; } - --- 807,809 ----