|
NAMExkeycaps - graphically display and edit the X keyboard mappingSYNOPSISxkeycaps [-toolkitoption ...] [-option ...]DESCRIPTIONThe xkeycaps program displays a keyboard. Moving the mouse over a key describes the keysyms and modifiers that that key generates. Clicking left on a key simulates a KeyPress event. Clicking right on a key brings up a menu of operations, including a command to change the keysyms that the key generates. This program is, in part, a graphical front-end to xmodmap(1).OPTIONSxkeycaps accepts all of the standard toolkit options, and also accepts the following options:
X OPTIONSThe following standard X Toolkit command line arguments are commonly used with xkeycaps:
DISPLAYThe bottom part of the window is a drawing of a keyboard. In the top left of each key is printed the string which actually appears on the surface of the key. In the bottom right of the key is the (hexadecimal) keycode that this key generates.At the top of the screen are several lines of text describing the key under the mouse (or the most recently typed key.) These lines are:
COMMANDSThere are several buttons in the upper left corner of the window. They are:
Clicking left on a key simulates a KeyPress event. Releasing the button simulates a KeyRelease event. If you click left on a key and move the mouse while the button is down, KeyPress and KeyRelease events will be simulated on every key you move the mouse over. Think of the mouse as your finger: if you drag the mouse over several keys, they will go down and up in turn. Clicking left on a key which is associated with modifier bits (such as Shift or Control) causes that key to ``lock'' down. Clicking left again releases the key. In this way, you can generate key-chords with the mouse: to generate Control-C, click left on the Control key, and then click on the C key. Click on Control again to turn the control modifier off. Typing a key on the real keyboard simulates a KeyPress/KeyRelease event pair in the same way that clicking on a key does. You can also combine mouse and keyboard input: for example, if you use the mouse to select the Shift key, and type a character, the event that is simulated will have the Shift modifier set. And if you hold down the real Control key, and click on the C key in the window, a Control-C event will be generated. (Assuming, that is, that your window manager does not intercept control-left-button for its own purposes.) Clicking right on a key pops up a menu of commands for the given key. They are:
KEYSYMS AND KEYCODESTo effectively edit your keyboard mapping, there are some terms you need to be familiar with:
X PROTOCOL DOCUMENT ON KEYMAPSThe following is a more precise technical explanation of how keymapping works. This description is from the X Protocol document, and is reprinted here for your convenience:A list of KeySyms is associated with each KeyCode. If
that list (ignoring trailing NoSymbol entries) is a single KeySym
``K'', then the list is treated as if it were the list ``K NoSymbol K
NoSymbol''. If the list (ignoring trailing NoSymbol entries) is a
pair of KeySyms ``K1 K2'', then the list is treated as if it were the list
``K1 K2 K1 K2''. If the list (ignoring trailing NoSymbol
entries) is a triple of KeySyms ``K1 K2 K3'', then the list is treated
as if it were the list ``K1 K2 K3 NoSymbol''.
The first four elements of the list are split into two groups of KeySyms. Group 1 contains the first and second KeySyms, Group 2 contains third and fourth KeySyms. Within each group, if the second element of the group is NoSymbol, then the group should be treated as if the second element were the same as the first element, except when the first element is an alphabetic KeySym ``K'' for which both lowercase and uppercase forms are defined. In that case, the group should be treated as if the first element were the lowercase form of ``K'' and the second element were the uppercase form of ``K''. The standard rules for obtaining a KeySym from a KeyPress event make use of only the Group 1 and Group 2 KeySyms; no interpretation of other KeySyms in the list is given here. (That is, the last four KeySyms are unused.) Which group to use is determined by modifier state. Switching between groups is controlled by the KeySym named Mode_switch. By attaching that KeySym to some KeyCode and attaching that KeyCode to any one of the modifiers Mod1 through Mod5. This modifier is called the ``group modifier''. For any KeyCode, Group 1 is used when the group modifier is off, and Group 2 is used when the group modifier is on. Within a group, which KeySym to use is also determined by modifier state. The first KeySym is used when the Shift and Lock modifiers are off. The second KeySym is used when the Shift modifier is on, or when the Lock modifier is on and the second KeySym is uppercase alphabetic, or when the Lock modifier is on and is interpreted as ShiftLock. Otherwise, when the Lock modifier is on and is interpreted as CapsLock, the state of the Shift modifier is applied first to select a KeySym, but if that KeySym is lowercase alphabetic, then the corresponding uppercase KeySym is used instead. ICCCM ON THE MODIFIER MAPPINGThe following is a more precise technical explanation of how modifier keys are interpreted. This description is from the Inter-Client Communications Conventions Manual, and is reprinted here for your convenience:X11 supports 8 modifier bits, of which 3 are pre-assigned
to Shift, Lock and Control. Each modifier bit is
controlled by the state of a set of keys, and these sets are specified in a
table accessed by GetModifierMapping() and SetModifierMapping().
A client needing to use one of the pre-assigned modifiers should assume that the modifier table has been set up correctly to control these modifiers. The Lock modifier should be interpreted as Caps Lock or Shift Lock according as the keycodes in its controlling set include XK_Caps_Lock or XK_Shift_Lock. Clients should determine the meaning of a modifier bit from the keysyms being used to control it. A client needing to use an extra modifier, for example Meta, should: Scan the existing modifier mappings. If it finds a modifier that contains a keycode whose set of keysyms includes XK_Meta_L or XK_Meta_R, it should use that modifier bit. If there is no existing modifier controlled by XK_Meta_L or XK_Meta_R, it should select an unused modifier bit (one with an empty controlling set) and: If there is a keycode with XL_Meta_L in its set of keysyms, add that keycode to the set for the chosen modifier, then if there is a keycode with XL_Meta_R in its set of keysyms, add that keycode to the set for the chosen modifier, then if the controlling set is still empty, interact with the user to select one or more keys to be Meta. If there are no unused modifier bits, ask the user to take corrective action. The above means that the Mod1 modifier does not necessarily mean Meta, although some applications (such as twm and emacs 18) assume that. Any of the five unassigned modifier bits could mean Meta; what matters is that a modifier bit is generated by a keycode which is bound to the keysym Meta_L or Meta_R. Therefore, if you want to make a ``meta'' key, the right way is to make the keycode in question generate both a Meta keysym, and some previously-unassigned modifier bit. THE MODE_SWITCH KEYSYMIn case the above didn't make sense, what the Mode_switch keysym does is, basically, act as an additional kind of shift key. If you have four keysyms attached to the A key, then those four keysyms will be accessed by the chords: A; Shift-A, Mode_Switch-A; and Mode_Switch-Shift-A, respectively.Like any Modifier Key, for Mode_switch to function, it must have a modifier bit attached to it. So, select one of the bits Mod1 through Mod5 (whichever is unused) and attach that to the Mode_switch key. THE MULTI_KEY KEYSYMNot to be confused with Mode_switch, Multi_key allows the input of multiple character sequences that represent a single character (keysym.) A more traditional name for this keysym might have been Compose.The Multi_key keysym is not a modifier keysym. That is, for it to function properly, it should not have any modifier bits associated with it. This is because it is not a ``chording'' key: you do not hold it down along with other keys. Rather, you press Multi_key, then release it, then press and release another key, and the two together yield a new character. For example, one traditional binding would be for Multi_key, followed by single-quote, followed by A to produce the Aacute keysym. Not all vendors support the use of the Multi_key keysym; in particular, Digital, Sun, and HP support it, but the X Consortium does not. (The reason for this, I am told, is that ``Compose'' sequences are considered obsolete; the party line is that you should be using Input Methods to do this.) Whether Multi_key works is a property of the Xt library (not the X server) so it's possible that on a single system, Multi_key might work with some applications and not others (depending on how those applications were compiled and linked.) If you use Lucid Emacs or XEmacs, then you can take advantage of Multi_key sequences even if your version of Xt doesn't support it, by loading the x-compose library, which simulates the traditional Xt behavior. For more info, read the commentary at the top of the file "/usr/local/lib/xemacs-*/lisp/x11/x-compose.el". DEAD KEYSYMSDead keys work similarly Multi_key, but they are two-keystroke commands instead of three. For example, pressing the Dead_tilde key, releasing it, then pressing the A key would generate the single keysym Atilde. (They are called ``dead'' keys because they do not, by themselves, insert characters, but instead modify the following character typed. But HP likes to call them ``mute'' instead of ``dead,'' no doubt to avoid frightening the children.)Again, these are not supported by all versions of the Xt library (but can be simulated by XEmacs.) Also note that different vendors have different names for the dead keysyms. For example: depending on your vendor, X server version, and the phase of the moon, you might find that the name of ``dead-tilde'' is Dead_Tilde, Dtilde, SunFA_Tilde, SunXK_FA_Tilde, DXK_tilde, DXK_tilde_accent, hpmute_asciitilde, hpXK_mute_asciitilde, or even XK_mute_asciitilde. It's a mess! You'll have to just try it and see what works, if anything. THINGS YOU CAN'T DOPeople often ask if xkeycaps or xmodmap can be used to make one key generate a sequence of characters. Unfortunately, no: you can't do this sort of thing by manipulating the server's keymaps. The X keyboard model just doesn't work that way.The way to do such things is to set translation resources on particular widgets. It has to be done on an application-by-application basis. For example, here's how you would convince xterm(1) to insert the string next when you hit F17: xterm*VT100.Translations: #override \ <Key>F17: string("next")Other applications may have different mechanisms for accomplishing the same thing, and some applications might not support it at all. Check the relevant man pages for specifics. Likewise, you can't convince one key to generate another key with modifiers (for example, you can't make F1 behave like Ctrl-A except by using translations, as above.) It is also not possible to make a keyboard key behave as a mouse button. LOSER VENDORSBoth HP and S.u.S.E. ship their systems with broken keyboard settings by default. They really should know better, but they don't.As explained above, it is undefined behavior for one modifier bit to be shared between two keys with dissimilar semantics. By default, HP uses Mod1 for both Meta and Mode_switch. This means that it's impossible for a program to tell the difference between, for example, Meta-X and Mode_switch-X. So, to repair this mess, you need to give the Mode_switch key a different modifier bit (mod2, for example.) Or, you could just remove it from the keymap entirely. S.u.S.E. Linux is even more screwed up than HP: whereas HP's default keymap contains only one bug, S.u.S.E.'s default map contains three completely different errors! First, their default keymap has the Control modifier attached to both the Control key and the Multi_key. This is completely crazy, because not only is Multi_key not a control key, it's not even a chording key! It mustn't have any modifier bits attached to it at all. Second, they attach Mod1 to Meta_L and also to Alt_R. Some people think that ``meta'' and ``alt'' are synonyms, but the fact is that the X Window System does not agree. Those are distinct keys. It's possible to have both ``meta'' and ``alt'' keys on the keyboard at the same time, and to have programs interpret them distinctly. But of course only if they don't bogusly share the same modifier bit, making the interpretation of that bit be ambiguous. Third, they attach Mod5 to both Scroll_Lock and to Hyper_R, which is wrong for reasons that should by now be obvious. The easiest way to fix your S.u.S.E. configuration is to: remove control from Multi_key; change the left Alt key to generate Alt_L instead of Meta_L; and delete the Hyper_R keysym from the keyboard. If you have any pull with these vendors, I encourage you to encourage them to get their act together. X RESOURCESXKeyCaps understands all of the core resource names and classes as well as:
The class of each key widget is ``Key,'' as you see above. The name of each key is the string(s) printed on its face. So if you wanted (for example) the Shift keys to have wider borders, you could specify that with xkeycaps*Keyboard.Shift.borderWidth: 2 ACTIONSIt is possible to rebind the actions which happen when a key or mouse button is pressed or released. These actions are available on the Keyboard widget:
The default actions for the Keyboard widget are: <Motion>: DescribeKey(mouse,unlessTracking) \n\ \ <KeyDown>: HighlightKey() \ DescribeKey(unlessMod) \ DescribeKey(displayed) \ SimulateKeyPress() \n\ \ <KeyUp>: UnhighlightKey() \ DescribeKey(displayed) \ SimulateKeyRelease() \n\ \ <Btn1Down>: HighlightKey(unlessMod) \ ToggleKey(ifMod) \ TrackKey(unlessMod) \ SimulateKeyPress(ifHighlighted) \ SimulateKeyRelease(unlessHighlighted) \n\ \ <Btn1Up>: UntrackKey(highlighted) \ SimulateKeyRelease(highlighted,unlessMod) \ UnhighlightKey(highlighted,unlessMod) \n\ \ <Btn3Down>: XawPositionSimpleMenu(keyMenu) \ MenuPopup(keyMenu) \nIf you don't want a key to be described each time the mouse moves over it, you can remove the <Motion> action. In that case, you should probably add DescribeKey() to the <Btn1Down> and <KeyDown> actions. If you want the key under the mouse to be described even while the mouse is moving with a button down, then remove the unlessTracking parameter from the DescribeKey action bound to <Motion>. If you don't want the modifier keys to toggle, then change the Button1 actions to xkeycaps*Keyboard.actions: #override \ <Btn1Down>: HighlightKey() \ TrackKey(unlessmod) \ SimulateKeyPress() \n\ <Btn1Up>: UntrackKey(highlighted) \ SimulateKeyRelease(highlighted) \ UnhighlightKey(highlighted) \nRemember that these actions exist on the Keyboard widget, not on the Key widgets. If you add actions to the Key widgets, things will malfunction. ENVIRONMENT
UPGRADESThe latest version can always be found at http://www.jwz.org/xkeycaps/SEE ALSOX(1), xmodmap(1), xset(1), xdpyinfo(1)BUGSBecause this program has default colors that aren't "black" and "white", the -rv command-line option doesn't work. But the incantation% xkeycaps -fg white -bg black -bd whitewill do what you want on a monochrome screen. The NeXT default map is believed to be incorrect; someone with access to a NeXT will need to debug this. There is no portable way to be sure what keyboard is being used; this means it will often not default to the correct one, and if the user makes changes to the keymap while displaying a keyboard which is not the right one, very bad things can happen. If you depress more than a dozen keys at a time, many X servers get confused, and don't transmit enough KeyRelease events; the result of this is that the xkeycaps keys will get ``stuck'' until they are pressed again. (Don't go like that.) The AutoRepeat flag is apparently useless on all X servers except the OpenWindows one (I've never seen another server that didn't ignore it.) You don't get to select from the set of Vendor keysyms (those keysyms which are defined in the XKeysymDB file) unless you're running X11r5 or newer. NCD's non-US keyboards do not use the standard R4/R5 mechanism for attaching more than two keysyms to one key; instead of simply having three or four keysyms attached to the keycode in question, the Compose key changes the actual keycode of the key (it turns its high bit on.) The xkeycaps program doesn't really understand this. Someone from NCD support told me that in future releases they will do things the R4/R5 way instead of the way they do things now, so hacking xkeycaps to understand the current behavior is probably not worth the effort. The Type at Window command doesn't seem to work on the WreckStation version of XTerm. I assume some variation of the normal XTerm's Allow SendEvents command is necessary. If you can't select anything from the right-button popup menu, it might be because you have NumLock or CapsLock down. I'm not sure how to fix this, it seems to be some dumb Xt thing. If the popup menu is always greyed out, or doesn't correspond to the key that you clicked on, it might be because you're running xswarm, an old version of xautolock, or some other program that antisocially interferes with event-propagation. (Don't go like that.) Because of the nonlinear way in which this program uses XLookupString, there's no sensible way for it to do compose processing, and show you the results of ``dead'' key or Multi_key sequences. It needs to know about more keyboard types (and no doubt always will...) L-shaped keys aren't drawn accurately. We should use the Shape extension for that. In addition to displaying the ASCII version of the given character, it should display the corresponding character in the character set (Latin2, Kana, Greek, etc.) This would require having fonts for all of those character sets, though, and as far as I can tell, they don't all come standard. When running on a Sun and talking to an OpenWindows server, we should parse the appropriate file from $OPENWINHOME/etc/keytables/ to determine the default keymap. No doubt there are system-specific ways of doing this in other environments as well. The HP C compiler complains about "invalid pointer initialization" in the header files. This is a bug in that compiler, not in xkeycaps. This compiler bug goes away if you invoke HP's cc with the the -Aa (ANSI) option. The xmodmap program still sucks. Since its ADD and REMOVE directives take keysyms as arguments instead of keycodes, there are things that you can do with XKeyCaps that you can't represent in an xmodmap script (at least, not without great pain.) The xmodmap program has no commands for changing the autorepeat status of keys, so that information is not written in the output. Perhaps we could write out an appropriate xset command instead. (For example, to turn on autorepeat on PgUp (which happens to have key code 103) on Solaris, you would do: "xset r 103".) Some versions of OpenWound use a nonstandard mechanism for specifying which keys have toggle (lock-like) behavior (whereas most other X servers base this behavior on the keysym: if Caps_Lock or Shift_Lock is generated, the key locks, otherwise it does not.) XKeyCaps doesn't know how to change the lock status on these servers. This is because I don't know how, either. If you know what system calls are necessary to hack this behavior, tell me. The XKB interface of X11R6 looks to provide most of the information which xkeycaps needs to know, but I haven't had time to investigate this yet. COPYRIGHTCopyright © 1991-1999 by Jamie Zawinski. Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. No representations are made about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.AUTHORJamie Zawinski <jwz@jwz.org>, 10-nov-91.Please send me any changes you make! Especially new keyboards. The strength of this program lies in the fact that it knows about so many different keyboards, thanks to the hundreds contributions I've received over the years. If you have to make your own modifications, please do your part! Send the changes back to me so that I can incorporate them into a future release.
Visit the GSP FreeBSD Man Page Interface. |