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