[comp.windows.x] X11 fix #44, server/ddx/sun duo, Sun beeps, keyclicks, and autorepeat

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