From: brendan@cygnus.com (Brendan Kehoe)
Newsgroups: comp.sys.sun.misc
Subject: Re: NumLock on Suns under X11R5 [was: Re: OW3 and Xterm]
Date: 3 Sep 92 23:48:31 GMT
	<1992Sep3.220153.5623@u.washington.edu>
Reply-To: brendan@cygnus.com
Followup-To: comp.sys.sun.misc
Organization: Cygnus Support, Palo Alto, CA
In-reply-to: fhl@milton.u.washington.edu's message of 3 Sep 92 22:01:53 GMT

fhl@milton.u.washington.edu (Dean Pentcheff) writes:

   OK, bonehead question #49: how do I get the NumLock key to work at
   all under X?  

I used this:

From jll40@duts.ccc.amdahl.com Fri Nov  1 08:26:11 1991
Date: Mon, 21 Oct 91 09:32 PDT
From: jll40@duts.ccc.amdahl.com (Jonathan L Lemon)
To: brendan@cs.widener.edu
Subject: Re: Enabling NumLock & the keypad on Suns under R5
Newsgroups: comp.windows.x
Organization: Amdahl Corporation, Sunnyvale CA
Cc: 

This is a slightly modified version of the patch for R5 that I posted 
earlier.  Since it uses the 'dead' slots in the scan table, it is 8-bit
clean.  It also allows you to 'relocate' the num-lock/compose keys elsewhere
on the keyboard.  In addition, the server will never see the mod4/mod5
modifier keys at all.
--
Jonathan

================================================================================

The following is a patch which for the sun4 server, which makes use of
the NumLock and Compose LEDS, as well as the mod4 and mod5 modifiers.

Within Amdahl, we run quite a few 3270 emulators, and have some people who
like to use the keypad for cursor motion, and others who prefer to use it for
the 3270 PF keys.  Unfortunately, there is no way to automatically toggle
between the two methods without starting a new emulator.

What this patch does is use the "mod4" modifier to toggle the NumLock LED on
the keyboard, and remap all the keys on the keypad from R4 on down to a new
scan code.  This in effect, implements a second "virtual" keypad for which you 
can switch back and forth.  By default, the mod4 modifier is bound to NumLock
and the default keymappings for the "virtual keypad" are the number keys.
Both of these can be changed via xmodmap.

To make the patch complete, the "mod5" modifier toggles the Compose LED, and
remaps the top row of keys (R1, R2, R3, NumLock) to new scancodes as well.
This allows complete customization of the entire keypad.  By default, the 
mod5 modifier is bound to the Multi_key KeySym (Compose on the keyboard), and
can also be changed with xmodmap.

One side effect of this patch is that the mod4/mod5 modifiers are rendered
effectively unusable for anything else (real minor loss, IMHO).  Also, 
completely clearing the modifier keys will result in no difference from
the original server.

To change the default keysymbol mapping, just edit the SunKeyMap.c file 
before building.  I have only made a half-hearted attempt to map the new
keypad to useful symbols, since most people will just re-map them via xmodmap
anyway.

To apply this patch, use the following instructions:
	1. 'cd' to the mit/server/ddx/sun directory
	2. feed this patch to 'patch'.
	3. Add the following line to the server/ddx/sun/Imakefile:

		DEFINES = -DSUN_NUMLOCK

	4. 'cd' to the mit/server directory.
	5. make Makefiles	(this updates the mit/server/ddx/sun makefile)	
	6. make

The concept (and portions of code) were taken from a similar patch for the R4
server, written by Robert Viduya.

Please send any problems/comments/etc to me.
--
Jonathan Lemon						jlemon@pswd.amdahl.com
Diagnostics Development, Amdahl Corp.
#include <std.disclaimer>

----------------------------------- cut here -----------------------------------

*** sunKbd.c.good	Wed Sep 11 13:05:04 1991
--- sunKbd.c	Wed Oct 16 09:09:22 1991
***************
*** 92,97 ****
--- 92,128 ----
      0,				/* lock state */
  };
  
+ #ifdef SUN_NUMLOCK
+ 
+ #define COMPOSE_LED		0x01
+ #define SCROLL_LOCK_LED		0x02
+ #define NUMLOCK_LED		0x04
+ 
+ /* The following table is a list of scancodes for keys affected by the numlock
+  * switch.  Their remapped keycode corresponds with scan_keys.
+  */
+ static char numlock_keys[] = {
+   0x2d, 0x2e, 0x2f, 0x44, 0x45, 0x46, 0x5b, 0x5c, 0x5d,
+   0x70, 0x71, 0x72, 0x47, 0x7d, 0x5a, 0x32, 0x5e, 0x00
+ };
+ 
+ static char compose_keys[] = {
+   0x15, 0x16, 0x17, 0x62, 0x00
+ };
+ 
+ /* This table is a list of all (originally) unused scancodes on a sun-4
+  * keyboard.  The entries in the table above will re-map to these scancodes.
+  */
+ static char numlock_scan_keys[] = {
+   0x02, 0x04, 0x0d, 0x0f, 0x14, 0x18, 0x1b, 0x1c, 0x2c,
+   0x30, 0x34, 0x4a, 0x4b, 0x60, 0x73, 0x74, 0x75, 0x00
+ };
+ 
+ static char compose_scan_keys[] = {
+   0x7b, 0x7c, 0x7e, 0x7f, 0x00
+ };
+ #endif
+ 
  /*-
   *-----------------------------------------------------------------------
   * sunKbdProc --
***************
*** 476,481 ****
--- 507,528 ----
      sunKbdSetLights (pKeyboard);
  }
  
+ #ifdef SUN_NUMLOCK
+ sunKbdModLight (pKeyboard, on, led)
+     DevicePtr	pKeyboard;
+     Bool	on;
+ {
+     KbPrivPtr	pPriv = (KbPrivPtr) pKeyboard->devicePrivate;
+     KeybdCtrl	ctrl;
+ 
+     if(on)
+       pPriv->ctrl->leds |= led;
+     else
+       pPriv->ctrl->leds &= ~led;
+     sunKbdSetLights (pKeyboard);
+ }
+ #endif
+ 
  /*-
   *-----------------------------------------------------------------------
   * sunKbdGetEvents --
***************
*** 551,557 ****
      BYTE		key;
      CARD8		keyModifiers;
  
!     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))) {
--- 598,623 ----
      BYTE		key;
      CARD8		keyModifiers;
  
!     key = fe->id & 0x7F;
! 
! #ifdef SUN_NUMLOCK
!     {
!     char *cp, *index();
! 
!     pPriv = (KbPrivPtr)pKeyboard->devicePrivate;
! 
!     if((pPriv->ctrl->leds & COMPOSE_LED) &&
!        ((cp = index(compose_keys, key)) != (char *)NULL))
!       fe->id = compose_scan_keys[(cp - compose_keys)];
! 
!     if((pPriv->ctrl->leds & NUMLOCK_LED) &&
!        ((cp = index(numlock_keys, key)) != (char *)NULL))
!       fe->id = numlock_scan_keys[(cp - numlock_keys)];
!     }
!     key = fe->id & 0x7F;
! #endif
! 
!     key += sysKbPriv.offset;
      keyModifiers = ((DeviceIntPtr)pKeyboard)->key->modifierMap[key];
      if (autoRepeatKeyDown && (keyModifiers == 0) &&
  	((fe->value == VKEY_DOWN) || (key == autoRepeatEvent.u.u.detail))) {
***************
*** 572,577 ****
--- 638,661 ----
  	    xE.u.u.type = KeyRelease;
  	sunKbdLockLight (pKeyboard, xE.u.u.type == KeyPress);
      }
+ 
+ #ifdef SUN_NUMLOCK
+     if (keyModifiers & Mod5Mask) {
+ 	if (xE.u.u.type == KeyRelease)
+ 	    return; /* this assumes autorepeat is not desired */
+ 	sunKbdModLight (pKeyboard, !(pPriv->ctrl->leds & COMPOSE_LED),
+ 				COMPOSE_LED);
+ 	return; /* this assumes that we never want to see this key */
+     }
+ 
+     if (keyModifiers & Mod4Mask) {
+ 	if (xE.u.u.type == KeyRelease)
+ 	    return; /* this assumes autorepeat is not desired */
+ 	sunKbdModLight (pKeyboard, !(pPriv->ctrl->leds & NUMLOCK_LED),
+ 				NUMLOCK_LED);
+ 	return; /* this assumes that we never want to see this key */
+     }
+ #endif
  
      if ((xE.u.u.type == KeyPress) && (keyModifiers == 0)) {
  	/* initialize new AutoRepeater event & mark AutoRepeater on */
*** sunKeyMap.c	Wed Sep 11 13:05:13 1991
--- sunKeyMap.c.good	Wed Sep 11 13:00:16 1991
***************
*** 333,341 ****
  
  static KeySym Sun4Map[] = {
          XK_L1,          NoSymbol,               /* 0x01 */
!         NoSymbol,       NoSymbol,               /* 0x02 */
          XK_L2,          NoSymbol,               /* 0x03 */
!         NoSymbol,       NoSymbol,               /* 0x4 */
          XK_F1,          NoSymbol,               /* 0x5 */
          XK_F2,          NoSymbol,               /* 0x6 */
          XK_F10,         NoSymbol,               /* 0x7 */
--- 333,341 ----
  
  static KeySym Sun4Map[] = {
          XK_L1,          NoSymbol,               /* 0x01 */
!         NoSymbol,       NoSymbol,               /* 0x02 */	/* R4 */
          XK_L2,          NoSymbol,               /* 0x03 */
!         NoSymbol,       NoSymbol,               /* 0x4 */	/* R5 */
          XK_F1,          NoSymbol,               /* 0x5 */
          XK_F2,          NoSymbol,               /* 0x6 */
          XK_F10,         NoSymbol,               /* 0x7 */
***************
*** 344,365 ****
          XK_F4,          NoSymbol,               /* 0xa */
          XK_F12,         NoSymbol,               /* 0xb */
          XK_F5,          NoSymbol,               /* 0xc */
!         NoSymbol,       NoSymbol,               /* 0xd */
          XK_F6,          NoSymbol,               /* 0xe */
!         NoSymbol,       NoSymbol,               /* 0xf */
          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 */
          XK_R3,          NoSymbol,               /* 0x17 */
!         NoSymbol,       NoSymbol,               /* 0x18 */
          XK_L3,          NoSymbol,               /* 0x19 */
          XK_L4,          NoSymbol,               /* 0x1a */
!         NoSymbol,       NoSymbol,               /* 0x1b */
!         NoSymbol,       NoSymbol,               /* 0x1c */
          XK_Escape,      NoSymbol,               /* 0x1d */
          XK_1,           XK_exclam,              /* 0x1e */
          XK_2,           XK_at,                  /* 0x1f */
--- 344,365 ----
          XK_F4,          NoSymbol,               /* 0xa */
          XK_F12,         NoSymbol,               /* 0xb */
          XK_F5,          NoSymbol,               /* 0xc */
!         NoSymbol,       NoSymbol,               /* 0xd */	/* R6 */
          XK_F6,          NoSymbol,               /* 0xe */
!         XK_KP_7,        NoSymbol,               /* 0xf */	/* R7 */
          XK_F7,          NoSymbol,               /* 0x10 */
          XK_F8,          NoSymbol,               /* 0x11 */
          XK_F9,          NoSymbol,               /* 0x12 */
  	XK_Alt_L,	NoSymbol,		/* 0x13 */
!         XK_KP_8,        NoSymbol,               /* 0x14 */	/* R8 */
          XK_R1,          XK_Pause,               /* 0x15 */
          XK_R2,          NoSymbol,               /* 0x16 */
          XK_R3,          NoSymbol,               /* 0x17 */
!         XK_KP_9,        NoSymbol,               /* 0x18 */	/* R9 */
          XK_L3,          NoSymbol,               /* 0x19 */
          XK_L4,          NoSymbol,               /* 0x1a */
!         XK_KP_4,        NoSymbol,               /* 0x1b */	/* R10 */
!         XK_KP_5,        NoSymbol,               /* 0x1c */	/* R11 */
          XK_Escape,      NoSymbol,               /* 0x1d */
          XK_1,           XK_exclam,              /* 0x1e */
          XK_2,           XK_at,                  /* 0x1f */
***************
*** 375,389 ****
          XK_equal,       XK_plus,                /* 0x29 */
          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 */
          XK_L6,          NoSymbol,               /* 0x33 */
!         NoSymbol,       NoSymbol,               /* 0x34 */
          XK_Tab,         NoSymbol,               /* 0x35 */
          XK_Q,           NoSymbol,               /* 0x36 */
          XK_W,           NoSymbol,               /* 0x37 */
--- 375,389 ----
          XK_equal,       XK_plus,                /* 0x29 */
          XK_quoteleft,   XK_asciitilde,          /* 0x2a */
          XK_BackSpace,   NoSymbol,               /* 0x2b */
!         XK_KP_6,        NoSymbol,               /* 0x2c */	/* R12 */
          XK_R4,          XK_KP_Equal,		/* 0x2d */
          XK_R5,          XK_KP_Divide,		/* 0x2e */
          XK_R6,          XK_KP_Multiply,		/* 0x2f */
!         XK_KP_1,        NoSymbol,               /* 0x30 */	/* R13 */
          XK_L5,          NoSymbol,               /* 0x31 */
          XK_Delete,      XK_KP_Decimal,          /* 0x32 */
          XK_L6,          NoSymbol,               /* 0x33 */
!         XK_KP_2,        NoSymbol,               /* 0x34 */	/* R14 */
          XK_Tab,         NoSymbol,               /* 0x35 */
          XK_Q,           NoSymbol,               /* 0x36 */
          XK_W,           NoSymbol,               /* 0x37 */
***************
*** 405,412 ****
          XK_KP_Subtract, XK_KP_Subtract,         /* 0x47 */
          XK_L7,          NoSymbol,               /* 0x48 */
          XK_L8,          NoSymbol,               /* 0x49 */
!         NoSymbol,       NoSymbol,               /* 0x4a */
!         NoSymbol,       NoSymbol,               /* 0x4b */
          XK_Control_L,   NoSymbol,               /* 0x4c */
          XK_A,           NoSymbol,               /* 0x4d */
          XK_S,           NoSymbol,               /* 0x4e */
--- 405,412 ----
          XK_KP_Subtract, XK_KP_Subtract,         /* 0x47 */
          XK_L7,          NoSymbol,               /* 0x48 */
          XK_L8,          NoSymbol,               /* 0x49 */
!         XK_KP_3,        NoSymbol,               /* 0x4a */	/* R15 */
!         NoSymbol,       NoSymbol,               /* 0x4b */	/* minus */
          XK_Control_L,   NoSymbol,               /* 0x4c */
          XK_A,           NoSymbol,               /* 0x4d */
          XK_S,           NoSymbol,               /* 0x4e */
***************
*** 427,433 ****
          XK_Right,       XK_KP_6,                /* 0x5d */
          XK_Insert,       XK_KP_0,                /* 0x5e */
          XK_L9,          NoSymbol,               /* 0x5f */
!         NoSymbol,       NoSymbol,               /* 0x60 */
          XK_L10,         NoSymbol,               /* 0x61 */
          XK_Num_Lock,    XK_Num_Lock,            /* 0x62 */
          XK_Shift_L,     NoSymbol,               /* 0x63 */
--- 427,433 ----
          XK_Right,       XK_KP_6,                /* 0x5d */
          XK_Insert,       XK_KP_0,                /* 0x5e */
          XK_L9,          NoSymbol,               /* 0x5f */
!         NoSymbol,       NoSymbol,               /* 0x60 */	/* plus */
          XK_L10,         NoSymbol,               /* 0x61 */
          XK_Num_Lock,    XK_Num_Lock,            /* 0x62 */
          XK_Shift_L,     NoSymbol,               /* 0x63 */
***************
*** 446,464 ****
          XK_R13,         XK_KP_1,                /* 0x70 */
          XK_Down,        XK_KP_2,                /* 0x71 */
          XK_R15,         XK_KP_3,                /* 0x72 */
!         NoSymbol,       NoSymbol,               /* 0x73 */
!         NoSymbol,       NoSymbol,               /* 0x74 */
!         NoSymbol,       NoSymbol,               /* 0x75 */
          XK_Help,        XK_Help,                /* 0x76 */
          XK_Caps_Lock,   NoSymbol,               /* 0x77 */
          XK_Meta_L,      NoSymbol,               /* 0x78 */
          XK_space,       NoSymbol,               /* 0x79 */
          XK_Meta_R,      NoSymbol,               /* 0x7a */
!         NoSymbol,       NoSymbol,               /* 0x7b */
!         NoSymbol,       NoSymbol,               /* 0x7c */
          XK_KP_Add,      XK_KP_Add,              /* 0x7d */
!         NoSymbol,       NoSymbol,               /* 0x7e */
!         NoSymbol,       NoSymbol,               /* 0x7f */
  };
  
  
--- 446,464 ----
          XK_R13,         XK_KP_1,                /* 0x70 */
          XK_Down,        XK_KP_2,                /* 0x71 */
          XK_R15,         XK_KP_3,                /* 0x72 */
!         NoSymbol,       NoSymbol,               /* 0x73 */	/* Enter */
!         NoSymbol,       NoSymbol,               /* 0x74 */	/* Del */
!         NoSymbol,       NoSymbol,               /* 0x75 */	/* Ins */
          XK_Help,        XK_Help,                /* 0x76 */
          XK_Caps_Lock,   NoSymbol,               /* 0x77 */
          XK_Meta_L,      NoSymbol,               /* 0x78 */
          XK_space,       NoSymbol,               /* 0x79 */
          XK_Meta_R,      NoSymbol,               /* 0x7a */
!         NoSymbol,       NoSymbol,               /* 0x7b */	/* R1 */
!         NoSymbol,       NoSymbol,               /* 0x7c */	/* R2 */
          XK_KP_Add,      XK_KP_Add,              /* 0x7d */
!         NoSymbol,       NoSymbol,               /* 0x7e */	/* R3 */
!         NoSymbol,       NoSymbol,               /* 0x7f */	/* numlock */
  };
  
  
***************
*** 480,485 ****
--- 480,487 ----
  #define	sH	(ShiftMask)
  #define	lK	(LockMask)
  #define	mT	(Mod1Mask)
+ #define	nL	(Mod4Mask)
+ #define	mK	(Mod5Mask)
  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 */


--
Brendan Kehoe                                               brendan@cygnus.com
Cygnus Support, Palo Alto, CA                                  +1 415 322 3811
                       Oooh! A handsome stranger! And me, without my shoes on.
                                     --The Princess, The Emperor's New Clothes
Newsgroups: comp.sys.sun.misc