[comp.unix.internals] MIT Sparc X server and keyboard indicators

dsamperi@Citicorp.COM (Dominick Samperi) (04/24/91)

The Sun Sparc X server that is included on the MIT X Windows
tape does not handle the keyboard indicator lights properly.
For example, pressing the CAPS LOCK key does not cause the
appropriate indicator light to be turned on. The program
mit/server/ddx/sun/kbd_mode can be used to enable the indicator
lights (by specifying the -a option), but this disables ALL
keys that do not have indicator lights! The -u option will
reenable these keys, but disable the indicator lights. (We
are using Sparc 1+'s and Sparc 2's.)

We have applied all 18 of the standard MIT patches, but these
do not appear to address the problem. I guess the real problem
is that the server code from Sun is not supported, in particular,
it has not been modified to deal with the newer Sparc keyboards.

Has anyone found a solution to this problem? Thanks in advance.

-- 
Dominick Samperi -- Citicorp
dsamperi@Citicorp.COM
uunet!ccorp!dsamperi

subbarao@phoenix.Princeton.EDU (Kartik Subbarao) (04/24/91)

In article <1991Apr23.191004.16381@Citicorp.COM> dsamperi@Citicorp.COM (Dominick Samperi) writes:
>The Sun Sparc X server that is included on the MIT X Windows
>tape does not handle the keyboard indicator lights properly.
>For example, pressing the CAPS LOCK key does not cause the
>appropriate indicator light to be turned on. 

Yeah, this is a true bummer. Just Another bug in X11R4, oh well.
>
>We have applied all 18 of the standard MIT patches, but these
>do not appear to address the problem. I guess the real problem
>is that the server code from Sun is not supported, in particular,
>it has not been modified to deal with the newer Sparc keyboards.
>
>Has anyone found a solution to this problem? Thanks in advance.

I complained about the same thing (and other things as well) and was given
the good piece of advice to use the openwindows server instead of X. Note that 
you can still run all X - clients (i.e, tvtwm, xrn, xclock, ...), and they
even run faster. The fonts even look nicer (IMHO). To do this, you need to
put "xnews" in place of "Xsun" in your .xserverrc.

But I too am open to suggestions. Is there anyone that has gotten big old X
to behave on suns?

			-Kartik


still runlll
--
internet# rm `df | tail +2 | awk '{ printf "%s/quotas\n",$6}'`

subbarao@phoenix.Princeton.EDU -| Internet
kartik@silvertone.Princeton.EDU (NeXT mail)  
SUBBARAO@PUCC.BITNET			          - Bitnet

viktor@shearson.com (Viktor Dukhovni) (04/25/91)

	The patch below provides for X11R4 the following Sun features

	1)  The ability to run "overview -w xinit" on top of sunview
	and use Meta-L2 to iconise the X-server,  click on the icon
	to return to X

	2)  Arbitrary bell files (XSUNBELLFILE in the environ)
	you need to copy /usr/demo/SOUND/multimedia to /usr/include/multimedia

	3)  Support for NumLock

	4)  Support for NumLock and CapsLock LEDs under 4.1 or higher
	(does not work under 4.0)

	5)  Fixes a small memory leak in the validation routines.

	6)  reduces optinal features in server from:
! #define ExtensionDefines -DSHAPE -DMITSHM -DMULTIBUFFER -DMITMISC
	    to
! #define ExtensionDefines -DMULTIBUFFER
	You may not want this,  but my X server was big enough already.



	Works for me.  No other guarantees.  Not endorsed by my company.
	Enjoy!  No flames please if it breaks your server.

*** /tmp/,RCSt1a01932	Wed Apr 24 22:11:44 1991
--- ./server/ddx/mi/mivaltree.c	Tue Oct  2 20:30:54 1990
***************
*** 642,647 ****
--- 642,648 ----
  	    if (pWin->valdata) {
  		(* pScreen->RegionEmpty)(&pWin->clipList);
  		(* pScreen->RegionEmpty)(&pWin->borderClip);
+ 		xfree(pWin->valdata) ;
  		pWin->valdata = (ValidatePtr)NULL;
  	    }
  	}
*** /tmp/,RCSt1a01935	Wed Apr 24 22:11:45 1991
--- ./server/ddx/sun/sunKbd.c	Tue Oct 23 14:15:44 1990
***************
*** 48,53 ****
--- 48,57 ----
  
  
  #define NEED_EVENTS
+ #ifdef SUN_AUDIO_FILE
+ #include <multimedia/libaudio.h>
+ #include <multimedia/audio_device.h>
+ #endif
  #include "sun.h"
  #include <stdio.h>
  #include "Xproto.h"
***************
*** 55,61 ****
  #include "inputstr.h"
  
  typedef struct {
!     int	    	  trans;          	/* Original translation form */
  } SunKbPrivRec, *SunKbPrivPtr;
  
  extern CARD8 *sunModMap[];
--- 59,71 ----
  #include "inputstr.h"
  
  typedef struct {
!     int		trans;		/* Original translation form */
! #ifdef SUN_AUDIO_FILE
!     int		audio_fd;	/* /dev/audio fd */
!     int		sound_fd;	/* fd of sound file */
!     struct stat	sound_stat;	/* stat info of sound file */
!     Bool	using_audio;	/* true if using /dev/audio else normal bell */
! #endif
  } SunKbPrivRec, *SunKbPrivPtr;
  
  extern CARD8 *sunModMap[];
***************
*** 93,98 ****
--- 103,169 ----
      &sysKbCtrl,			/* Initial full duration = .25 sec. */
  };
  
+ /* XXX:  Must be a clean way of not hardwiring these! */
+ #define KB_SUN4_CODE_MASK	0x7F
+ #define KB_SUN4_MAX_CODE	0x7F
+ #define KB_SUN4_NUM_LOCK_KCODE	(0x61+MIN_KEYCODE)
+ #define KB_SUN4_CAPS_LOCK_KCODE	(0x76+MIN_KEYCODE)
+ 
+ #ifdef SUN_NUMLOCK
+ /*
+  * The following table is the list of scancodes for keys affected by
+  * the numlock switch.  The order MUST match the order of simulated
+  * numlock keys defined at the end of the keymap in sunKeyMap.c
+  */
+ static char		numlock_keys[] = {
+     0x2d, 0x2e, 0x2f, 0x32, 0x44, 0x45, 0x46, 0x47, 0x5a,
+     0x5b, 0x5c, 0x5d, 0x5e, 0x70, 0x71, 0x72, 0x7d, 0x00
+ };
+ #endif
+ 
+ #ifdef SUN_LED_SUPPORT
+ /*
+  * set_kbd_led
+  */
+ static void
+ set_kbd_led (pKeyboard, flag, mask)
+ DevicePtr	pKeyboard;
+ Bool		flag;
+ long		mask;
+ {
+     KbPrivPtr		kbp = (KbPrivPtr) pKeyboard->devicePrivate;
+     int 		kbdOpenedHere;
+     char		led;
+     bool		old;
+ 
+ 
+     kbdOpenedHere = ( kbp->fd < 0 );
+     if ( kbdOpenedHere ) {
+ 	kbp->fd = open("/dev/kbd", O_RDWR, 0);
+ 	if (kbp->fd < 0) {
+ 	    ErrorF("set_numlock_flag: can't open keyboard");
+ 	    return;
+ 	}
+     }	
+  
+     (void) ioctl (kbp->fd, KIOCGLED, &led);
+     old = ((led & mask) == mask);
+ 
+     if (flag != old) {
+ 	if (flag)
+ 	    led |= mask;
+ 	else
+ 	    led &= ~mask;
+ 	(void) ioctl (kbp->fd, KIOCSLED, &led);
+     }
+ 
+     if ( kbdOpenedHere ) {
+ 	(void) close(kbp->fd);
+ 	kbp->fd = -1;
+     }
+ }
+ #endif
+ 
  /*-
   *-----------------------------------------------------------------------
   * sunKbdProc --
***************
*** 167,173 ****
                          perror( "ioctl KIOCGETKEY" );
  			FatalError("Can't KIOCGETKEY on fd %d\n", kbdFd);
                      }
!                     if (key.kio_entry != HOLE)
                          sysKbPriv.type = KB_SUN4;
                  }
  #endif
--- 238,244 ----
                          perror( "ioctl KIOCGETKEY" );
  			FatalError("Can't KIOCGETKEY on fd %d\n", kbdFd);
                      }
!                     if ( ((long)key.kio_entry) != HOLE)
                          sysKbPriv.type = KB_SUN4;
                  }
  #endif
***************
*** 208,213 ****
--- 279,292 ----
  		sunKeySyms[sysKbPriv.type].maxKeyCode += offset;
  		sysKbPriv.offset = offset;
  	    }
+ #ifdef SUN_LED_SUPPORT
+ 	    if (sysKbPriv.type == KB_SUN4)
+ 		set_kbd_led (pKeyboard, FALSE, ~0L);
+ #endif
+ #ifdef SUN_AUDIO_FILE
+ 	    sunKbPriv.audio_fd = sunKbPriv.sound_fd = -1;
+ 	    sunKbPriv.using_audio = FALSE;
+ #endif
  	    InitKeyboardDeviceStruct(
  		    pKeyboard,
  		    &(sunKeySyms[sysKbPriv.type]),
***************
*** 229,234 ****
--- 308,314 ----
  		 * when DEVICE_CLOSE was executed.
  		 * Translation is set/reset upon receipt of
  		 * KBD_USE/KBD_DONE input events (sunIo.c)
+ 		 * Or When Meta-L2 suspends the server.
  		 */
  		if (deviceOffKbdState != TR_UNDEFINED) {
  		    if (sunChangeKbdTranslation(pKeyboard,
***************
*** 235,240 ****
--- 315,333 ----
  				deviceOffKbdState == TR_UNTRANS_EVENT) < 0) {
  			FatalError("Can't set (SW) keyboard translation\n");
  		    }
+ 
+ #ifdef SUN_LED_SUPPORT
+ 		    if (sysKbPriv.type == KB_SUN4) {
+ 			set_kbd_led (pKeyboard, FALSE, ~0L) ;
+ 			/* Set LEDs to match Logical state */
+ 			if (BitIsOn(((DeviceIntPtr)pKeyboard)->key->down,
+ 				    KB_SUN4_NUM_LOCK_KCODE))
+ 			    set_kbd_led (pKeyboard, TRUE, LED_NUM_LOCK) ;
+ 			if (BitIsOn(((DeviceIntPtr)pKeyboard)->key->down, 
+ 				    KB_SUN4_CAPS_LOCK_KCODE))
+ 			    set_kbd_led (pKeyboard, TRUE, LED_CAPS_LOCK) ;
+ 		    }
+ #endif
  		}
  		AddEnabledDevice(windowFd);
  #endif SUN_WINDOWS
***************
*** 254,259 ****
--- 347,354 ----
  		AddEnabledDevice(kbdFd);
  	    }
  	    pKeyboard->on = TRUE;
+ 	    /* Enable Processing in sunWakeupHandler */
+ 	    autoRepeatReady = 1;
  	    break;
  
  	case DEVICE_CLOSE:
***************
*** 326,335 ****
      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;
      }
--- 421,516 ----
      int	    	  loudness;	    /* Percentage of full volume */
      DevicePtr	  pKeyboard;	    /* Keyboard to ring */
  {
!     KbPrivPtr		pPriv = (KbPrivPtr) pKeyboard->devicePrivate;
!     SunKbPrivPtr	psPriv = (SunKbPrivPtr) pPriv->devPrivate;
!     int			kbdCmd;   	    /* Command to give keyboard */
!     int			kbdOpenedHere; 
! 
! 
! #ifdef SUN_AUDIO_FILE
! #define savecopy(dst,src) \
! 	((dst=(src)), dst = (dst ? strcpy(malloc(strlen(dst)+1),dst) : NULL))
! 
!     extern char *	getenv() ;
! 
!     static Audio_hdr	dev_hdr, sound_hdr;
!     double		gain;
!     struct stat		st;
!     char		buf[1024];
!     int			nr;
!     static char *	audio_file = NULL;
! 
!     if (psPriv->using_audio) {
! 
! 	/* open the /dev/audio device */
! 	if (psPriv->audio_fd < 0) {
! 	    if ((psPriv->audio_fd = open ("/dev/audio",
! 					  O_WRONLY | O_NDELAY)) < 0) {
! 		if (errno != EBUSY)	/* hard error, don't retry later */
! 		    psPriv->using_audio = FALSE;	
! 		goto use_kybd_bell;
! 	    }
! 	}
! 
! 	if (audio_get_play_config(psPriv->audio_fd,&dev_hdr) != AUDIO_SUCCESS) {
! 	    /* not an audio device */
! 	    (void) close (psPriv->audio_fd);
! 	    psPriv->audio_fd = -1;
! 	    psPriv->using_audio = FALSE;
! 	    goto use_kybd_bell;
! 	}
! 
! 	/* open the sound file */
! 	if (psPriv->sound_fd < 0) {
! reopen_sound:
! 	    if ( !audio_file && !savecopy(audio_file,getenv(SUN_AUDIO_FILE)) ||
! 	         (psPriv->sound_fd = open (audio_file, O_RDONLY, 0)) < 0 ) {
! 		/* can't open, try again later (maybe too expensive?) */
! 		psPriv->sound_fd = -1;
! 		goto use_kybd_bell;
! 	    }
! 	    (void) fstat(psPriv->sound_fd, &(psPriv->sound_stat));
! 	}
! 	else {	/* stat the file to see if it may have changed */
! 	    if (stat (audio_file, &st) == -1) {
! 		(void) close (psPriv->sound_fd);
! 		psPriv->sound_fd = -1;
! 		goto use_kybd_bell;
! 	    }
! 	    if (st.st_mtime != psPriv->sound_stat.st_mtime) {
! 		(void) close (psPriv->sound_fd);	/* changed, go reopen */
! 		goto reopen_sound;
! 	    }
! 	}
! 	
! 	/* set the volume */
! 	gain = ((double) loudness) / 100.0;
! 	(void) audio_set_play_gain (psPriv->audio_fd, &gain);	/* ignore errors */
! 	
! 	/* process the audio file header */
! 	(void) lseek (psPriv->sound_fd, 0L, 0);
! 	if (audio_read_filehdr (psPriv->sound_fd, &sound_hdr, (char *) 0, 0) != AUDIO_SUCCESS)
! 	    goto use_kybd_bell;
! 	if (audio_cmp_hdr (&dev_hdr, &sound_hdr) != 0) {
! 	    if (audio_drain (psPriv->audio_fd, FALSE) != AUDIO_SUCCESS)
! 		goto use_kybd_bell;
! 	    if (audio_set_play_config (psPriv->audio_fd, &sound_hdr) != AUDIO_SUCCESS)
! 		goto use_kybd_bell;
! 	}
! 
! 	/* write the sound */
! 	while ((nr = read (psPriv->sound_fd, buf, sizeof (buf))) >= 0) {
! 	    if (nr == 0)
! 		break;
! 	    (void) write (psPriv->audio_fd, buf, nr);
! 	}
! 
! 	return;
!     }
! 
! use_kybd_bell:
! #endif
! 
      if (loudness == 0) {
   	return;
      }
***************
*** 386,394 ****
      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 ) {
--- 567,579 ----
      DevicePtr	  pKeyboard;	    /* Keyboard to alter */
      KeybdCtrl     *ctrl;
  {
!     KbPrivPtr		pPriv = (KbPrivPtr) pKeyboard->devicePrivate;
!     SunKbPrivPtr	psPriv = (SunKbPrivPtr) ((KbPrivPtr)pKeyboard->devicePrivate)->devPrivate;
!     int			kbdClickCmd = ctrl->click ? KBD_CMD_CLICK : KBD_CMD_NOCLICK;
!     int			kbdOpenedHere;
! #ifdef SUN_AUDIO_FILE
!     int			kbdBellPitch = ctrl->bell_pitch;
! #endif
  
      kbdOpenedHere = ( pPriv->fd < 0 );
      if ( kbdOpenedHere ) {
***************
*** 403,408 ****
--- 588,606 ----
   	ErrorF("Failed to set keyclick");
  	goto bad;
      }
+ 
+ #ifdef SUN_AUDIO_FILE
+     if (!kbdOpenedHere && kbdBellPitch == 0) {	/* 0 pitch means release /dev/audio, use bell */
+ 	if (psPriv->audio_fd >= 0) {
+ 	    (void) audio_drain (psPriv->audio_fd, FALSE);
+ 	    (void) close (psPriv->audio_fd);
+ 	    psPriv->audio_fd = -1;
+ 	}
+ 	psPriv->using_audio = FALSE;
+     }
+     else
+ 	psPriv->using_audio = TRUE;
+ #endif
   
      *pPriv->ctrl = *ctrl;
  
***************
*** 443,449 ****
      static Firm_event	evBuf[MAXEVENTS];   /* Buffer for Firm_events */
  
      pPriv = (KbPrivPtr) pKeyboard->devicePrivate;
!     nBytes = read (pPriv->fd, evBuf, sizeof(evBuf));
  
      if (nBytes < 0) {
  	if (errno == EWOULDBLOCK) {
--- 641,650 ----
      static Firm_event	evBuf[MAXEVENTS];   /* Buffer for Firm_events */
  
      pPriv = (KbPrivPtr) pKeyboard->devicePrivate;
!     if (pKeyboard->on)
! 	nBytes = read (pPriv->fd, evBuf, sizeof(evBuf));
!     else
! 	nBytes = 0;
  
      if (nBytes < 0) {
  	if (errno == EWOULDBLOCK) {
***************
*** 501,508 ****
      BYTE		key;
      CARD8		keyModifiers;
  
      if (autoRepeatKeyDown && fe->id == AUTOREPEAT_EVENTID) {
- 	pPriv = (KbPrivPtr) pKeyboard->devicePrivate;
  	if (pPriv->ctrl->autoRepeat != AutoRepeatModeOn) {
  		autoRepeatKeyDown = 0;
  		return;
--- 702,709 ----
      BYTE		key;
      CARD8		keyModifiers;
  
+     pPriv = (KbPrivPtr) pKeyboard->devicePrivate;
      if (autoRepeatKeyDown && fe->id == AUTOREPEAT_EVENTID) {
  	if (pPriv->ctrl->autoRepeat != AutoRepeatModeOn) {
  		autoRepeatKeyDown = 0;
  		return;
***************
*** 539,545 ****
  	return;
      }
  
!     key = (fe->id & 0x7F) + sysKbPriv.offset;
      keyModifiers = ((DeviceIntPtr)pKeyboard)->key->modifierMap[key];
      if (autoRepeatKeyDown && (keyModifiers == 0) &&
  	((fe->value == VKEY_DOWN) || (key == autoRepeatEvent.u.u.detail))) {
--- 740,765 ----
  	return;
      }
  
! 
! #ifdef SUN_NUMLOCK
!     if (pPriv->type == KB_SUN4) {
! 	char	*cp, *index ();
! 
! 	key = fe->id & KB_SUN4_CODE_MASK;
! 	if (BitIsOn(((DeviceIntPtr)pKeyboard)->key->down, 
! 	    KB_SUN4_NUM_LOCK_KCODE) &&
! 	    (cp = index (numlock_keys, key)) != NULL)
! 	    fe->id = KB_SUN4_MAX_CODE + 1 + (cp - numlock_keys);
! 	else
! 	    fe->id &= KB_SUN4_CODE_MASK;
!     }
!     else
! 	fe->id &= KB_SUN4_CODE_MASK;
!     key = fe->id + sysKbPriv.offset;
! #else
!     key = (fe->id & KB_SUN4_CODE_MASK) + sysKbPriv.offset;
! #endif
! 
      keyModifiers = ((DeviceIntPtr)pKeyboard)->key->modifierMap[key];
      if (autoRepeatKeyDown && (keyModifiers == 0) &&
  	((fe->value == VKEY_DOWN) || (key == autoRepeatEvent.u.u.detail))) {
***************
*** 558,568 ****
      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 (BitIsOn(((DeviceIntPtr)pKeyboard)->key->down, key))
! 	    xE.u.u.type = KeyRelease;
      }
  
      if ((xE.u.u.type == KeyPress) && (keyModifiers == 0)) {
--- 778,807 ----
      xE.u.u.type = ((fe->value == VKEY_UP) ? KeyRelease : KeyPress);
      xE.u.u.detail = key;
  
! #ifndef SUN_NUMLOCK
!     if (keyModifiers & LockMask)
! #else
!     if (keyModifiers & LockMask ||
! 	pPriv->type == KB_SUN4 && key == KB_SUN4_NUM_LOCK_KCODE)
! #endif
!     {
! #ifdef SUN_LED_SUPPORT
! 	int ledmask = (keyModifiers & LockMask) ? LED_CAPS_LOCK : LED_NUM_LOCK;
! #endif
! 	if (xE.u.u.type == KeyRelease ||
! 	    BitIsOn(((DeviceIntPtr)pKeyboard)->key->down, key)) {
! 	    if ( xE.u.u.type == KeyRelease )
! 		return;
! 	    else
! 		xE.u.u.type = KeyRelease;
! #ifdef SUN_LED_SUPPORT
! 	    if ( pPriv->type == KB_SUN4 )
! 		    set_kbd_led(pKeyboard, FALSE, ledmask) ;
! 	} else {
! 	    if ( pPriv->type == KB_SUN4 )
! 		set_kbd_led (pKeyboard, TRUE, ledmask);
! #endif
! 	}
      }
  
      if ((xE.u.u.type == KeyPress) && (keyModifiers == 0)) {
***************
*** 621,626 ****
--- 860,866 ----
      int		kbdOpenedHere;
  
      static struct timeval lastChngKbdTransTv;
+     static int firsttime = 1;
      struct timeval tv;
      struct timeval lastChngKbdDeltaTv;
      int lastChngKbdDelta;
***************
*** 629,639 ****
       * Workaround for SS1 serial driver kernel bug when KIOCTRANS ioctl()s
       * occur too closely together in time.
       */
      gettimeofday(&tv, (struct timezone *) NULL);
!     tvminus(lastChngKbdDeltaTv, tv, lastChngKbdTransTv);
!     lastChngKbdDelta = TVTOMILLI(lastChngKbdDeltaTv);
      if (lastChngKbdDelta < 750) {
  	struct timeval wait;
  
  	/*
           * We need to guarantee at least 750 milliseconds between
--- 869,890 ----
       * Workaround for SS1 serial driver kernel bug when KIOCTRANS ioctl()s
       * occur too closely together in time.
       */
+     /*
+      * Is this still needed ???  What OS Versions???
+      */
+ #ifdef KIOCTRANS_HACK
      gettimeofday(&tv, (struct timezone *) NULL);
!     if (firsttime) {
! 	lastChngKbdTransTv = tv;
! 	lastChngKbdDelta   = 0;
! 	firsttime = 0;
!     } else {
! 	tvminus(lastChngKbdDeltaTv, tv, lastChngKbdTransTv);
! 	lastChngKbdDelta = TVTOMILLI(lastChngKbdDeltaTv);
!     }
      if (lastChngKbdDelta < 750) {
  	struct timeval wait;
+ 	int    mask = sigmask(SIGIO);       
  
  	/*
           * We need to guarantee at least 750 milliseconds between
***************
*** 641,650 ****
  	 */
  	wait.tv_sec = 0;
  	wait.tv_usec = (750L - lastChngKbdDelta) * 1000L;
!         (void) select(0, (int *)0, (int *)0, (int *)0, &wait);
          gettimeofday(&tv, (struct timezone *) NULL);
      }
      lastChngKbdTransTv = tv;
      
  
      pPriv = (KbPrivPtr)pKeyboard->devicePrivate;
--- 892,905 ----
  	 */
  	wait.tv_sec = 0;
  	wait.tv_usec = (750L - lastChngKbdDelta) * 1000L;
! 
! 	mask = sigblock(mask) ;
!         (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &wait);
! 	(void) sigsetmask(mask) ;
          gettimeofday(&tv, (struct timezone *) NULL);
      }
      lastChngKbdTransTv = tv;
+ #endif
      
  
      pPriv = (KbPrivPtr)pKeyboard->devicePrivate;
***************
*** 792,802 ****
--- 1047,1078 ----
      register struct inputevent *se;
  {   
      Firm_event	fe;
+     int		loc;
+     static	Meta_On, Meta_hold;
  
      fe.time = event_time(se);
      fe.id = event_id(se);
      fe.value = (event_is_up(se) ? VKEY_UP : VKEY_DOWN);
  
+     if (fe.id > 0) {
+ 	loc = (fe.id - 1) * sunKeySyms[sysKbPriv.type].mapWidth;
+ 
+ 	if( sunKeySyms[sysKbPriv.type].map[loc] == XK_Meta_L ||
+ 	   sunKeySyms[sysKbPriv.type].map[loc] == XK_Meta_R ) /* Meta */
+ 	{
+ 		Meta_hold = fe.id;
+ 		Meta_On = (fe.value == VKEY_DOWN);
+ 	}
+ 	if( sunKeySyms[sysKbPriv.type].map[loc] == XK_L2 ) /* L2 */
+ 	{
+ 		if( fe.value == VKEY_DOWN && Meta_On )
+ 		{
+ 			stopme();
+ 			fe.id = Meta_hold;
+ 			fe.value = VKEY_UP;
+ 		}
+ 	}
+     }
      sunKbdProcessEvent (pKeyboard, &fe);
  }
  #endif SUN_WINDOWS
*** /tmp/,RCSt1a01938	Wed Apr 24 22:11:46 1991
--- ./server/ddx/sun/sun.h	Tue Oct 23 14:14:59 1990
***************
*** 248,259 ****
  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; \
--- 248,259 ----
  extern struct timeval autoRepeatDeltaTv;
  
  #define tvminus(tv, tv1, tv2)	/* tv = tv1 - tv2 */ \
  		(tv).tv_usec = (tv1).tv_usec - (tv2).tv_usec; \
! 		(tv).tv_sec = (tv1).tv_sec - (tv2).tv_sec; \
! 		if ((tv).tv_usec < 0) { \
! 			(tv).tv_usec += 1000000; \
! 			(tv).tv_sec -= 1; \
! 		}
  
  #define tvplus(tv, tv1, tv2)	/* tv = tv1 + tv2 */ \
  		(tv).tv_sec = (tv1).tv_sec + (tv2).tv_sec; \
*** /tmp/,RCSt1a01941	Wed Apr 24 22:11:47 1991
--- ./server/ddx/sun/sunKeyMap.c	Tue Oct 23 14:16:28 1990
***************
*** 350,356 ****
          XK_F7,          NoSymbol,               /* 0x10 */
          XK_F8,          NoSymbol,               /* 0x11 */
          XK_F9,          NoSymbol,               /* 0x12 */
! 	XK_Alt_L,	NoSymbol,		/* 0x13 */
          NoSymbol,       NoSymbol,               /* 0x14 */
          XK_R1,          XK_Pause,               /* 0x15 */
          XK_R2,          NoSymbol,               /* 0x16 */
--- 350,356 ----
          XK_F7,          NoSymbol,               /* 0x10 */
          XK_F8,          NoSymbol,               /* 0x11 */
          XK_F9,          NoSymbol,               /* 0x12 */
!         XK_Alt_L,       NoSymbol,               /* 0x13 */
          NoSymbol,       NoSymbol,               /* 0x14 */
          XK_R1,          XK_Pause,               /* 0x15 */
          XK_R2,          NoSymbol,               /* 0x16 */
***************
*** 376,384 ****
          XK_quoteleft,   XK_asciitilde,          /* 0x2a */
          XK_BackSpace,   NoSymbol,               /* 0x2b */
          NoSymbol,       NoSymbol,               /* 0x2c */
!         XK_R4,          XK_KP_Equal,		/* 0x2d */
!         XK_R5,          XK_KP_Divide,		/* 0x2e */
!         XK_R6,          XK_KP_Multiply,		/* 0x2f */
          NoSymbol,       NoSymbol,               /* 0x30 */
          XK_L5,          NoSymbol,               /* 0x31 */
          XK_Delete,      XK_KP_Decimal,          /* 0x32 */
--- 376,384 ----
          XK_quoteleft,   XK_asciitilde,          /* 0x2a */
          XK_BackSpace,   NoSymbol,               /* 0x2b */
          NoSymbol,       NoSymbol,               /* 0x2c */
!         XK_R4,          XK_KP_Equal,            /* 0x2d */
!         XK_R5,          XK_KP_Divide,           /* 0x2e */
!         XK_R6,          XK_KP_Multiply,         /* 0x2f */
          NoSymbol,       NoSymbol,               /* 0x30 */
          XK_L5,          NoSymbol,               /* 0x31 */
          XK_Delete,      XK_KP_Decimal,          /* 0x32 */
***************
*** 425,431 ****
          XK_Left,        XK_KP_4,                /* 0x5b */
          XK_R11,         XK_KP_5,                /* 0x5c */
          XK_Right,       XK_KP_6,                /* 0x5d */
!         XK_Insert,       XK_KP_0,                /* 0x5e */
          XK_L9,          NoSymbol,               /* 0x5f */
          NoSymbol,       NoSymbol,               /* 0x60 */
          XK_L10,         NoSymbol,               /* 0x61 */
--- 425,431 ----
          XK_Left,        XK_KP_4,                /* 0x5b */
          XK_R11,         XK_KP_5,                /* 0x5c */
          XK_Right,       XK_KP_6,                /* 0x5d */
!         XK_Insert,      XK_KP_0,                /* 0x5e */
          XK_L9,          NoSymbol,               /* 0x5f */
          NoSymbol,       NoSymbol,               /* 0x60 */
          XK_L10,         NoSymbol,               /* 0x61 */
***************
*** 459,464 ****
--- 459,486 ----
          XK_KP_Add,      XK_KP_Add,              /* 0x7d */
          NoSymbol,       NoSymbol,               /* 0x7e */
          NoSymbol,       NoSymbol,               /* 0x7f */
+ #ifdef SUN_NUMLOCK
+         /* these entries are faked scan codes for keys that are affected
+          * by the numlock key.  The order must match the table in sunKbd.c
+          */
+         XK_KP_Equal,    XK_R4,                  /* 0x2d => 0x80 */
+         XK_KP_Divide,   XK_R5,                  /* 0x2e => 0x81 */
+         XK_KP_Multiply, XK_R6,                  /* 0x2f => 0x82 */
+         XK_KP_Decimal,  NoSymbol,               /* 0x32 => 0x83 */
+         XK_KP_7,        XK_R7,                  /* 0x44 => 0x84 */
+         XK_KP_8,        XK_R8,                  /* 0x45 => 0x85 */
+         XK_KP_9,        XK_R9,                  /* 0x46 => 0x86 */
+         XK_KP_Subtract, NoSymbol,               /* 0x47 => 0x87 */
+         XK_KP_Enter,    NoSymbol,               /* 0x5a => 0x88 */
+         XK_KP_4,        XK_R10,                 /* 0x5b => 0x89 */
+         XK_KP_5,        XK_R11,                 /* 0x5c => 0x8a */
+         XK_KP_6,        XK_R12,                 /* 0x5d => 0x8b */
+         XK_KP_0,        NoSymbol,               /* 0x5e => 0x8c */
+         XK_KP_1,        XK_R13,                 /* 0x70 => 0x8d */
+         XK_KP_2,        XK_R14,                 /* 0x71 => 0x8e */
+         XK_KP_3,        XK_R15,                 /* 0x72 => 0x8f */
+         XK_KP_Add,      NoSymbol,               /* 0x7d => 0x90 */
+ #endif
  };
  
  
***************
*** 473,479 ****
--- 495,505 ----
  #endif
      Sun2Map,		1,	0x7a,	2,
      Sun3Map,		1,	0x7a,	2,
+ #ifdef SUN_NUMLOCK
+     Sun4Map,		1,	0x90,	2,
+ #else
      Sun4Map,		1,	0x7d,	2,
+ #endif
  };
  
  #define	cT	(ControlMask)
*** /tmp/,RCSt1a01944	Wed Apr 24 22:11:48 1991
--- ./server/ddx/sun/sunInit.c	Tue Oct 23 14:15:36 1990
***************
*** 689,691 ****
--- 689,786 ----
  
      return (fd);
  }
+ 
+ /*
+  * stopme - stop window for suntools
+  */
+ #ifdef	SUN_WINDOWS
+ #include    "validate.h"
+ #include    "windowstr.h"
+ #include    "dix.h"
+ extern WindowPtr *WindowTable;
+ 
+ stopme()
+ {
+     DevicePtr	pKbd;
+     int		i;
+     void	ExposeEveryone();
+ 
+     if( !sunUseSunWindows())
+ 	return;
+ 
+     /*
+      * on our way out -- shut down keyboard and mouse
+      * and remove the window
+      */
+     pKbd = LookupKeyboardDevice();
+     sunKbdProc(pKbd,  DEVICE_OFF);
+     sunMouseProc(pKbd, DEVICE_OFF);
+     win_remove(windowFd);
+ 
+     sunNonBlockConsoleOff((char *)0) ;
+     kill(0, SIGSTOP);
+ 
+     /*
+      * we're back, restore the window, and turn on the
+      * keyboard and mouse
+      * reset nonblocking mode on stderr.
+      */
+     i = fcntl(2, F_GETFL, 0);
+     if (i >= 0)
+         i = fcntl(2, F_SETFL, i | FNDELAY);
+     if (i < 0) {
+         perror("fcntl");
+         ErrorF("InitOutput: can't put stderr in non-block mode\n");
+     }
+     win_insert(windowFd);
+     sunMouseProc(pKbd, DEVICE_ON);
+     sunKbdProc(pKbd, DEVICE_ON);
+ 
+ 
+     /*
+      * refresh all screens
+      */
+     for( i = 0; i < screenInfo.numScreens; )
+         ExposeEveryone(WindowTable[i++]);
+ }
+ 
+ /*
+  * Cause a repaint of area slightly larger than window 
+  * by covering with temp window, and destroying the latter.  
+  * Shamelessly copied from the TileScreenSaver() code in dix/window.c
+  */
+ static void
+ ExposeEveryone(pWin)
+     WindowPtr pWin;
+ {
+     int       result;
+     XID       attributes[2];
+     Mask      mask = CWBackPixmap|CWOverrideRedirect;
+     WindowPtr tempWin;		
+     ScreenPtr pScreen = pWin->drawable.pScreen ;
+     Window    wid     = pWin->drawable.id;
+     
+ 
+ #define FUDGE 32
+ 
+     attributes[0] = None;
+     attributes[1] = xTrue;
+     tempWin = 
+ 	 CreateWindow(FakeClientID(0), pWin,
+ 	      (short)-FUDGE, (short)-FUDGE,
+ 	      (unsigned short)(pScreen->width + FUDGE),
+ 	      (unsigned short)(pScreen->height + FUDGE),
+ 	      0, InputOutput, mask, attributes, 0, serverClient,
+ 	      wVisual(pWin), &result);
+ 
+     if (!tempWin)
+ 	return;
+ 
+     if (!AddResource(tempWin->drawable.id, RT_WINDOW, (pointer)tempWin))
+ 	return;
+ 
+     MapWindow(tempWin, serverClient);
+     FreeResource(tempWin->drawable.id,RT_NONE) ;
+     DeleteWindow(tempWin,serverClient) ;
+ }
+ #endif	SUN_WINDOWS
*** /tmp/,RCSt1a01947	Wed Apr 24 22:11:48 1991
--- ./server/Imakefile	Mon Sep 24 15:15:44 1990
***************
*** 230,235 ****
--- 230,238 ----
  #if defined(UseSunWindowsInServer) && UseSunWindowsInServer
  SUNWINDOWSLIBS = -lsunwindow -lpixrect
  #endif
+ #if defined(UseSunAudioInServer) && UseSunAudioInServer
+ SUNAUDIOLIBS = -laudio
+ #endif
  #define need_dix
  #define need_ddx_snf
  #define need_ddx_mi
***************
*** 240,246 ****
  SUNDIRS = dix ddx/snf ddx/mi ddx/mfb ddx/cfb ddx/sun os/4.2bsd
  SUNOBJS = ddx/sun/sunInit.o $(FONTUTIL)
  SUNLIBS = $(SUN) $(CFB) $(DIX) $(BSD) $(SNF) $(MFB) $(MI) $(EXTENSIONS)
! SUNSYSLIBS = $(SYSLIBS) $(SUNWINDOWSLIBS)
  XsunDIRS = $(SUNDIRS)
  
  ServerTarget(Xsun,$(EXTDIR) $(FONTUTILDIR) $(SUNDIRS),$(SUNOBJS),$(SUNLIBS),$(SUNSYSLIBS))
--- 243,249 ----
  SUNDIRS = dix ddx/snf ddx/mi ddx/mfb ddx/cfb ddx/sun os/4.2bsd
  SUNOBJS = ddx/sun/sunInit.o $(FONTUTIL)
  SUNLIBS = $(SUN) $(CFB) $(DIX) $(BSD) $(SNF) $(MFB) $(MI) $(EXTENSIONS)
! SUNSYSLIBS = $(SUNAUDIOLIBS) $(SYSLIBS) $(SUNWINDOWSLIBS)
  XsunDIRS = $(SUNDIRS)
  
  ServerTarget(Xsun,$(EXTDIR) $(FONTUTILDIR) $(SUNDIRS),$(SUNOBJS),$(SUNLIBS),$(SUNSYSLIBS))
*** /tmp/,RCSt1a01950	Wed Apr 24 22:11:49 1991
--- ./clients/xinit/Imakefile	Mon Oct  1 17:18:13 1990
***************
*** 1,4 ****
--- 1,8 ----
+ #ifdef SunArchitecture
+         DEFINES = SunWindowsDefines ConnectionFlags -DBINDIR=\"$(BINDIR)\"
+ #else
          DEFINES = ConnectionFlags -DBINDIR=\"$(BINDIR)\"
+ #endif
          DEPLIBS = $(DEPXMULIB) $(DEPXLIB)
  LOCAL_LIBRARIES = $(XMULIB) $(XLIB)
            SRCS1 = xinit.c 
*** /tmp/,RCSt1a01953	Wed Apr 24 22:11:49 1991
--- ./clients/xinit/xinit.c	Sun Oct  7 03:31:52 1990
***************
*** 141,146 ****
--- 141,150 ----
      return;
  }
  
+ #ifdef sun
+ static char	*under_sunview;
+ #endif
+ 
  main(argc, argv)
  int argc;
  register char **argv;
***************
*** 175,181 ****
  		 * that means SunWindows isn't running, so we should pass 
  		 * the -C flag to xterm so that it sets up a console.
  		 */
! 		if ( getenv("WINDOW_PARENT") == NULL )
  		    *cptr++ = "-C";
  #endif /* sun */
  	} else {
--- 179,185 ----
  		 * that means SunWindows isn't running, so we should pass 
  		 * the -C flag to xterm so that it sets up a console.
  		 */
! 		if ( (under_sunview=getenv("WINDOW_PARENT")) == NULL )
  		    *cptr++ = "-C";
  #endif /* sun */
  	} else {
***************
*** 290,298 ****
  	signal(SIGUSR1, sigUsr1);
  	if ((serverpid = startServer(server)) > 0
  	 && (clientpid = startClient(client)) > 0) {
! 		pid = -1;
! 		while (pid != clientpid && pid != serverpid)
  			pid = wait(NULL);
  	}
  	signal(SIGQUIT, SIG_IGN);
  	signal(SIGINT, SIG_IGN);
--- 294,315 ----
  	signal(SIGUSR1, sigUsr1);
  	if ((serverpid = startServer(server)) > 0
  	 && (clientpid = startClient(client)) > 0) {
! #ifndef SUN_WINDOWS
! 		for (pid = -1;  pid != clientpid && pid != serverpid;)
  			pid = wait(NULL);
+ #else
+ 		for(pid=-1; pid != clientpid && pid != serverpid;) 
+ 		{
+ 			pid = wait3(&status, WUNTRACED, NULL) ;
+ 			if ( under_sunview && pid == serverpid )
+ 				if (WIFSTOPPED(status)) {
+ 					(void)sigblock(SIGCHLD) ;
+ 					(void)kill(0,SIGSTOP) ;
+ 					(void)kill(serverpid,SIGCONT) ;
+ 					pid = -1;
+ 				}
+ 		}
+ #endif
  	}
  	signal(SIGQUIT, SIG_IGN);
  	signal(SIGINT, SIG_IGN);
*** /tmp/,RCSt1a01956	Wed Apr 24 22:11:50 1991
--- ./config/sun.cf	Mon Oct 15 21:42:41 1990
***************
*** 10,18 ****
  #define OSMinorVersion    1
  #define HasSaberC	  NO		/* for machines that have it */
  #define HasNdbm		  YES
! #define XsunServer 	  Xsun
  
! #define HasGcc 		  NO  	/* VERY USEFUL for server on Sun3 */
  
  #define SystemV           NO
  #define HasPutenv YES
--- 10,24 ----
  #define OSMinorVersion    1
  #define HasSaberC	  NO		/* for machines that have it */
  #define HasNdbm		  YES
! #define XsunServer	  Xsun
! #define ManPath		  /usr/local/man
! #define ManSuffix	  1
  
! #ifdef sparc
! #define HasGcc NO
! #else
! #define HasGcc YES 	/* VERY USEFUL for server on Sun3 */
! #endif
  
  #define SystemV           NO
  #define HasPutenv YES
***************
*** 42,47 ****
--- 48,54 ----
  
  /* you may find one or both of these options useful on your system */
  /* #define DefaultCCOptions -f68881 -pipe */
+ #define DefaultCCOptions -pipe
  
  #define LibraryCCOptions /* don't want special floating point */
  #define LibraryDefines  /**/
***************
*** 53,59 ****
--- 60,70 ----
  
  #if OSMajorVersion == 3 && OSMinorVersion <= 2
  #define OptimizedCDebugFlags /* as nothing */
+ #else
+ #ifdef SparcArchitecture
+ #define OptimizedCDebugFlags	-O4
  #endif
+ #endif
  
  #define UseSunWindowsInServer	YES	/* link in SunWindows support? */
  
***************
*** 63,68 ****
--- 74,106 ----
  #define SunWindowsDefines /* as nothing */
  #endif
  
+ #define UseSunAudioInServer	YES
+ #define UseSunNumlock		YES	/* enable numlock support on type4 kbds? */
+ 
+ #if UseSunNumlock
+ #if OSMajorVersion >= 4 && OSMinorVersion >= 1
+ #define SunNumlockDefines	-DSUN_NUMLOCK -DSUN_LED_SUPPORT
+ #else
+ #define SunNumlockDefines	-DSUN_NUMLOCK
+ #endif
+ #else
+ #define SunNumlockDefines	/* as nothing */
+ #endif
+ 
+ #if UseSunAudioInServer
+ #if OSMajorVersion >= 4 && OSMinorVersion >= 1
+ #define UseSunAudioInServer	YES	/* use /dev/audio for bell? */
+ #else
+ #define UseSunAudioInServer	NO
+ #endif
+ #endif
+ 
+ #if UseSunAudioInServer
+ #define SunAudioDefines -DSUN_AUDIO_FILE=\"XSUNBELLFILE\"
+ #else
+ #define SunAudioDefines	/* as nothing */
+ #endif
+ 
  /* define this as you like for server compilation */
  #if OSMajorVersion >= 4 || defined(SparcArchitecture)
  #define AllocateLocalDefines -DINCLUDE_ALLOCA_H
***************
*** 70,78 ****
  #define AllocateLocalDefines /**/
  #endif
  
! #define ExtensionDefines -DSHAPE -DMITSHM -DMULTIBUFFER -DMITMISC
  
! #define ServerDefines -DXDMCP SunWindowsDefines ExtensionDefines AllocateLocalDefines
  
  #if OSMajorVersion >= 4 && OSMinorVersion >= 0
  #define SetTtyGroup YES
--- 108,116 ----
  #define AllocateLocalDefines /**/
  #endif
  
! #define ExtensionDefines -DMULTIBUFFER
  
! #define ServerDefines -DXDMCP SunNumlockDefines SunWindowsDefines SunAudioDefines ExtensionDefines AllocateLocalDefines
  
  #if OSMajorVersion >= 4 && OSMinorVersion >= 0
  #define SetTtyGroup YES

--
        Viktor Dukhovni <viktor@shearson.com>       : ARPA
                <...!uunet!shearson.com!viktor>     : UUCP
        388 Greenwich St., 11th floor, NY, NY 10013 : US-Post
                +1-(212)-464-3793                   : VOICE

guy@auspex.auspex.com (Guy Harris) (04/26/91)

>>For example, pressing the CAPS LOCK key does not cause the
>>appropriate indicator light to be turned on. 
>
>Yeah, this is a true bummer. Just Another bug in X11R4, oh well.

Bug?  It'd have been a little difficult to "fix" that "bug", given that
when X11R4 came out, SunOS 4.1 wasn't out yet, which means that the
keyboard driver (except possibly on the 386i) didn't support the "ioctl"
call to turn the LEDs on and off.

>I complained about the same thing (and other things as well) and was given
>the good piece of advice to use the openwindows server instead of X.

I suspect the OW server doesn't run the indicator lights when run under
SunOS 4.0[.x]; if it does, I'll be *extremely* surprised (unless OW
comes with a modified version of the keyboard driver).