[comp.windows.x] Xlib NumLock Modifier implementation

mikep@sco.COM (Mike Patnode) (02/18/91)

Due to the length of the PC/AT Keyboard proposal, I've decided to post
the NumLock implementation separately.  Hopefully it will get more
attention and comments this way.   The complete PC/AT Keyboard document 
will follow this posting.  The ANSI X Protocol committee is being 
approached with this proposal. 

Three quick notes.

1. Mode Switch is no longer being used for Num Lock.  Too many European 
   X servers are already using Mode Switch for their 3rd and 4th key
   engravings.  A solution was needed that did not break any existing
   server mappings.

2. I'm not set on Mod2 for NumLock, but in order for this to work we are
   going to have to break down and assign some existing modifier to the 
   Num Lock key.  Mod2 is already being used for NumLock by ISC and AT&T.
   NCD uses Mod5.

3. There is a bug in Xt which causes default translations to be
   exclusive.  Setting a new modifier bit will some cause translations 
   not to be activated.  THIS IS A BUG! See page 347 of Asente & Swick 
   for a detailed explanation.


       3.  Lock	Keys


       3.1  Previous Implementations

       Many different approaches have been taken to attempt to deal
       with the	Num Lock key.  The most	common approach	has been to
       simply ignore the functionality,	since no implementation	is
       suggested by the	Protocol.  Some	servers	send both a Key
       Press and Release event while others only send the Press
       event, followed by the Release event on the second press.
       Most servers do turn on the LED associated with the key,	but
       very few	actually change	the keyboard mapping.  Some simple
       implementations set a modifier bit when the key is locked.
       A Num Lock standard must	adhere to the existing X protocol
       as much as possible, and	not break existing applications	and
       server implementations when avoidable.


       3.2  Num	Lock Modifier

       The most	obvious	implementation of the Num Lock key is to
       follow the example set by the Caps Lock key.  The alphabetic
       keysyms,	which are arbitrarily defined in
       lib/X/XKeyBind.c:XConvertCase(),	are treated special by the
       protocol.  In short, XConvertCase() is called whenever a
       alphabetic keysym needs to be converted to lower	case. The
       keysyms are left	capitalized if the appropriate modifier	bit
       is set.	This is	implemented in lib/X/XKeyBind.c:XTranslateKey().

       The Num Lock key	should be treated the exact same way, but
       with the keymap table being used for conversions.  By
       assigning Num Lock to a modifier	bit known by Xlib, a simple
       change can be made to lib/X/XKeyBind.c:XTranslateKey() to
       support Num Lock	functionality.	In the context diff below,
       a simple	macro has been defined to identify a keypad key.
       Note that only the numeric engravings need be checked.
       Before any other	modifier translation takes place, the
       Is_KP_Keysym() check is made.  If the Num Lock modifier bit
       is set, the second column of the	keymap table is	returned.
       If the Shift modifier bit is set	as well, the first column
       is used.	 Note that a Shift by itself will simply acess the
       second column.

____________________________________________________________________________
*** /a/X11R4/mit/lib/X/XKeyBind.c       Mon Dec 11 16:09:42 1989
--- XKeyBind.c  Sat Feb 16 22:20:56 1991
***************
*** 17,22 ****
--- 17,28 ----
#define AllMods (ShiftMask|LockMask|ControlMask|
		Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)

+ #define NumLockMask Mod2Mask
+
+ /* Watch the multiple evaluation */
+ #define Is_KP_Keysym(k) ((((k)>= XK_KP_0) && ((k) <= XK_KP_9)) || 
+				    ((k) == XK_KP_Decimal))
+
 static	ComputeMaskFromKeytrans();
 static	int Initialize();
 static	void XConvertCase();
***************
*** 276,282 ****
	  syms += 2;
	  per -= 2;
      }
!     if(!(modifiers & ShiftMask) &&
	      (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) {
	  if ((per == 1) || (syms[1] == NoSymbol))
	      XConvertCase(dpy, syms[0], keysym_return, &usym);
--- 281,289 ----
	  syms += 2;
	  per -= 2;
      }
!     if((modifiers & NumLockMask) && (per > 1)	&& Is_KP_Keysym(syms[1])) {
!         *keysym_return = (modifiers & ShiftMask)? syms[0] : syms[1];
!     } else if (!(modifiers & ShiftMask) &&
              (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) {
      if ((per == 1) || (syms[1] == NoSymbol))
	      XConvertCase(dpy, syms[0], keysym_return, &usym);
____________________________________________________________________________

       If there are no KP_ keysyms in the second column of the 
       mapkey table (IE: The keyboard does not use NumLock) 
       Mod2 will have no effect on the keyboard binding.


       3.3  Server Changes

       Three changes also need to be applied to	the server to
       complete	the Num	Lock key functionality.	 These are
       necessary for the above implementation and are somewhat
       obvious.

	  o The	server should only send	a Press	event when Num Lock
	    is toggled on, and only send a Release event when the
	    key	is toggled off.

	  o If an LED labeled "Num Lock" exists	on the keyboard, it
	    should be turned on	and off	in accordance with the
	    status of the key.

	  o The	XK_Num_Lock keysym shall be defined as Mod2.


Please send/post your comments, or even call me if you like.

mp
-- 
Mike Patnode					The Santa Cruz Operation 
Software Engineer				400 Encinal Street
{ucscc,uunet}!sco!mikep	 mikep@sco.COM  	P.O. Box 1900
(408) 458-1422                                  Santa Cruz, CA 95061