[comp.windows.x] LED's on Sun's type 4 Keyboard - solution

x-window@uni-paderborn.de (X-Window Betreuung) (04/19/91)

Here are some patches to the Xsun server to allow it to make use of
the CapsLock, Compose and NumLock LED's on the Type 4 Keyboard (say,
SparcStation). I've tested them with SunOS 4.1.1, I'm not sure whether
they work with SunOS 4.0.3 or not. 

The CapsLock LED is bound to the Lock Modifier, i.e. when you press
the CapsLock Key, the LED lights up, when you press it again, the LED
is darkened (sorry for bad english). The same is done with the NumLock
Key and NumLock LED resp. Well not quite the same, for the NumLock LED
is bound to the mod5 Modifier key and NumLock is bound to mod5. I've
made the mod5 modifier a toggle modifier too. The Compose LED is bound
to mod3, which is bound to Multi_key by default. On a german keyboard
you should bind it to Mode_switch, too (and Mode_switch should be on
keycode 26).

Now here we go. Hope it's useful. Comments are welcome.
( cd to mit/server/ddx/sun to apply the patch)

Regards, Swen

-----8< if you cut here, you will probably damage your screen >8------

*** sunKbd.c.orig	Mon Oct  8 16:19:03 1990
--- sunKbd.c	Fri Apr 19 10:46:25 1991
***************
*** 79,84 ****
--- 79,88 ----
  struct timeval    autoRepeatDeltaTv;
  static KeybdCtrl  sysKbCtrl;
  
+ static void SetLockLED();
+ static void SetComposeLED();
+ static void SetNumLED();
+ 
  static SunKbPrivRec	sunKbPriv;  
  static KbPrivRec  	sysKbPriv = {
      -1,				/* Type of keyboard */
***************
*** 140,146 ****
   * matter since no 386i has ever been shipped with a type 3 keyboard.
   */
  #ifndef i386
! #define TYPE4KEYBOARDOVERRIDE
  #endif
  	    if (sysKbPriv.fd >= 0) {
  		kbdFd = sysKbPriv.fd;
--- 144,151 ----
   * matter since no 386i has ever been shipped with a type 3 keyboard.
   */
  #ifndef i386
! /* #define TYPE4KEYBOARDOVERRIDE */
! /* this is not needed with SunOS 4.1.1 */
  #endif
  	    if (sysKbPriv.fd >= 0) {
  		kbdFd = sysKbPriv.fd;
***************
*** 561,570 ****
      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)) {
  	/* initialize new AutoRepeater event & mark AutoRepeater on */
  	if (autoRepeatDebug)
--- 566,618 ----
      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;
+ 	    SetLockLED(FALSE);
+ 	}
+ 	else
+ 	    SetLockLED(TRUE);
      }
  
+ /*
+  * The following is a hack to make mod5 a toggle-key. This should usually
+  * be bound on the Num_Lock key. The Num_Lock led shows the current state
+  * of the mod5-Key, if any. Bind Num_Lock to mod5 as follows:
+  *           xmodmap -e 'clear mod5' -e 'add mod5 = Num_Lock'
+  */
+     if (keyModifiers & Mod5Mask)
+       {
+ 	if (xE.u.u.type == KeyRelease)
+ 	  return;
+ 	if (BitIsOn(((DeviceIntPtr)pKeyboard)->key->down, key))
+ 	  {
+ 	    xE.u.u.type = KeyRelease;
+ 	    SetNumLED(FALSE);
+ 	  }
+ 	else
+ 	  {
+ 	    SetNumLED(TRUE);
+ 	  }
+       }
+     
+ /* 
+  * A hack for the Mode_switch key, provided it is bound
+  * to Mod3 (for the national characterset)
+  * The Compose-led lights up when mod3 is pressed. On the german keyboard
+  * Mode_switch is usually AltGraph, which is keycode 26. You should remap the
+  * keyboard as follows:
+  *
+  * xmodmap -e 'keycode 26 = Mode_switch' -e 'clear mod3' -e 'add mod3 = Mode_switch'
+  *
+  */
+     if (keyModifiers & Mod3Mask)
+       {
+ 	if (xE.u.u.type == KeyRelease)
+ 	  SetComposeLED(FALSE);
+ 	else
+ 	  SetComposeLED(TRUE);
+       }
+     
      if ((xE.u.u.type == KeyPress) && (keyModifiers == 0)) {
  	/* initialize new AutoRepeater event & mark AutoRepeater on */
  	if (autoRepeatDebug)
***************
*** 872,875 ****
--- 920,1037 ----
      if (autoRepeatReady)
  	ProcessInputEvents();
      autoRepeatReady = 0;
+ }
+ 
+ static void
+ SetLockLED(on)
+      Bool on;
+ {
+   char leds = 0;
+ 
+   if (sysKbPriv.type != KB_SUN4) /* No LED's on other keyboards */
+     return;
+ 
+   if (sysKbPriv.fd < 0)		/* kbd not opened yet, do nothing */
+     return;
+ 
+   if (ioctl(sysKbPriv.fd, KIOCGLED, &leds) < 0)
+     {
+     ErrorF("Failed to get leds");
+     return;
+   }
+   
+   if (on)
+     {
+       leds |= LED_CAPS_LOCK;
+       if (ioctl(sysKbPriv.fd, KIOCSLED, &leds) < 0)
+ 	{
+ 	  ErrorF("Failed to set leds");
+ 	  return;
+ 	}
+     }
+   else 
+     {
+       leds &= ~LED_CAPS_LOCK;
+       if (ioctl(sysKbPriv.fd, KIOCSLED, &leds) < 0)
+ 	{
+ 	  ErrorF("Failed to set leds");
+ 	  return;
+ 	}
+     }
+ }
+ 
+ static void
+ SetComposeLED(on)
+      Bool on;
+ {
+   char leds = 0;
+ 
+   if (sysKbPriv.type != KB_SUN4) /* No LED's on other keyboards */
+     return;
+ 
+   if (sysKbPriv.fd < 0)		/* kbd not opened yet, do nothing */
+     return;
+ 
+   if (ioctl(sysKbPriv.fd, KIOCGLED, &leds) < 0)
+     {
+     ErrorF("Failed to get leds");
+     return;
+   }
+   
+   if (on)
+     {
+       leds |= LED_COMPOSE;
+       if (ioctl(sysKbPriv.fd, KIOCSLED, &leds) < 0)
+ 	{
+ 	  ErrorF("Failed to set leds");
+ 	  return;
+ 	}
+     }
+   else 
+     {
+       leds &= ~LED_COMPOSE;
+       if (ioctl(sysKbPriv.fd, KIOCSLED, &leds) < 0)
+ 	{
+ 	  ErrorF("Failed to set leds");
+ 	  return;
+ 	}
+     }
+ }
+ 
+ static void
+ SetNumLED(on)
+      Bool on;
+ {
+   char leds = 0;
+ 
+   if (sysKbPriv.type != KB_SUN4) /* No LED's on other keyboards */
+     return;
+ 
+   if (sysKbPriv.fd < 0)		/* kbd not opened yet, do nothing */
+     return;
+ 
+   if (ioctl(sysKbPriv.fd, KIOCGLED, &leds) < 0)
+     {
+     ErrorF("Failed to get leds");
+     return;
+   }
+   
+   if (on)
+     {
+       leds |= LED_NUM_LOCK;
+       if (ioctl(sysKbPriv.fd, KIOCSLED, &leds) < 0)
+ 	{
+ 	  ErrorF("Failed to set leds");
+ 	  return;
+ 	}
+     }
+   else 
+     {
+       leds &= ~LED_NUM_LOCK;
+       if (ioctl(sysKbPriv.fd, KIOCSLED, &leds) < 0)
+ 	{
+ 	  ErrorF("Failed to set leds");
+ 	  return;
+ 	}
+     }
  }
*** sunKeyMap.c.orig	Mon Oct  8 16:19:03 1990
--- sunKeyMap.c	Fri Apr 19 10:50:19 1991
***************
*** 480,485 ****
--- 480,487 ----
  #define	sH	(ShiftMask)
  #define	lK	(LockMask)
  #define	mT	(Mod1Mask)
+ #define	mK	(Mod3Mask)	/* Used for Multi_key and Mode_switch */
+ #define	nL	(Mod5Mask)	/* Used for the Num_Lock key */
  static CARD8 type2modmap[MAP_LENGTH] = {
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 00-0f */
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 10-1f */
***************
*** 523,531 ****
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 10-1f */
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 20-2f */
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 30-3f */
!     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 40-4f */
      0,  0,  0,  cT, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 50-5f */
!     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  sH, 0,  0,  0,  0,  0, /* 60-6f */
      0,  0,  0,  0,  0,  sH, 0,  0,  0,  0,  0,  0,  0,  0,  lK, mT,/* 70-7f */
      0,  mT, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 80-8f */
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 90-9f */
--- 525,533 ----
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 10-1f */
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 20-2f */
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 30-3f */
!     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  mK, 0,  0,  0,  0,  0, /* 40-4f */
      0,  0,  0,  cT, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 50-5f */
!     0,  0,  0,  0,  0,  0,  0,  0,  0,  nL, sH, 0,  0,  0,  0,  0, /* 60-6f */
      0,  0,  0,  0,  0,  sH, 0,  0,  0,  0,  0,  0,  0,  0,  lK, mT,/* 70-7f */
      0,  mT, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 80-8f */
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 90-9f */


-----8< if you cut here, you will probably damage your screen >8------
--

---->  Swen Thuemmler  *  X-Betreuung  *  <swen@uni-paderborn.de>  <----