xkeycaps - graphically display and edit the X keyboard mapping
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
accepts all of the standard toolkit options, and also accepts
the following options:
- -keyboard keyboard-name or -kbd
- Specifies the type of keyboard to display. There are many different
computer keyboards in the world, and xkeycaps must know which one
you are using in order to function correctly. Case does not matter when
specifying a keyboard name.
If you're running on the console display of a Sun or HP, then
xkeycaps will interrogate the attached keyboard hardware directly
to determine what keyboard you're using. But if you're running remotely,
or on another type of machine, then you must specify a keyboard
- Lists the recognized values for the -keyboard option.
- -gutterwidth number or -gw number
- Specifies the number of pixels of space to leave between each key.
- -font fontname
- Specifies the font to use to display the keycaps.
The following standard X Toolkit command line arguments are commonly used with
- -display host:dpy
- This option specifies the X server to contact.
- -geometry geometry
- This option specifies the preferred size and position of the window.
- -bg color
- This option specifies the color to use for the background of the window.
The default is light gray.
- -fg color
- This option specifies the color to use for the foreground of the window.
The default is black.
- -bw number
- This option specifies the width in pixels of the border surrounding the
- -xrm resourcestring
- This option specifies a resource string to be used. This is especially
useful for setting resources that do not have separate command line
The 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
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:
- This displays the text printed on the physical key, and the keycode
generated by that key in hex, decimal, and octal.
- This displays the set of KeySyms that this key currently generates.
- This displays the ASCII equivalent of this key, taking into account the
current modifier keys which are down.
- this displays the modifier bits which this key generates. If a key
generates modifiers, it is a chord-key like Shift or
- Whether the X server claims that this key autorepeats. I say ``
claims'' because the OpenWindows X server is the only one I have
encountered for which this information is accurate. The per-key autorepeat
flag seems to be almost-universally ignored.
There are several buttons in the upper left corner of the window. They are:
- Exits the program.
- Select Keyboard
- Pops up a dialog box from which you can change which keyboard is
displayed. The left column lists the known types of keyboards, and the
right column lists the known layouts (mappings) of those keyboards.
- Type At Window
- After selecting this, you are asked to click on some other window. After
doing this, clicking on keys on the keyboard display will simulate key
events on the window you selected. Selecting the root window or the
xkeycaps window turns this off.
If you are using a window manager (for example, twm(1)) in which you
can lock the keyboard focus on a window and still click on other windows
without having the focus change, then you can accomplish the same thing
merely by focusing on another window and clicking on the keys in the
- Restore Default Map
- This command restores the keyboard to its default state. If you execute
this command while displaying a keyboard which is not the type of keyboard
you are really using, your keymap will be in a nonsensical state. There is
no way for xkeycaps to tell what keyboard you are using except by
taking your word for it, so don't lie.
- Write Output
- This command writes an xmodmap input file representing the current
state of the keyboard (including all of your changes) to a file in your
The file will be called .xmodmap-hostname, where
hostname is the name of the machine you're running on. It will warn
you if the file already exists.
It prompts you with a dialog box: you can either write an xmodmap
file representing the state of every key, or you can write a smaller file
which describes only the changes.
The idea is that in the appropriate startup script, you would add a line
xmodmap /.xmodmap-`uname -n`
in the appropriate init file, so that those keyboard modifications are made
each time you log in. (If you're not sure where this command should go,
ask your system administrator, as that tends to vary from site to
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
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
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
, click left on the Control
key, and then click on the
key. Click on Control
again to turn the control modifier off.
Typing a key on the real
keyboard simulates a
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
key, and click on the C
key in the window, a
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:
- Exchange Keys
- After selecting this menu item, you are asked to click on another key.
That key and the key on which you brought up the menu will be exchanged.
This changes the keyboard mapping immediately.
- Duplicate Key
- After selecting this menu item, you are asked to click on another key.
That key will be made a copy of the key on which you brought up the menu.
That is, the two keys will generate the same set of keysyms and modifiers.
This changes the keyboard mapping immediately.
- Disable Key
- The key on which you brought up the menu will be made to generate no
keysyms and no modifiers. This changes the keyboard mapping
- Restore Key To Default
- The key on which you brought up the menu will be restored to its default
state; no other key will be altered. This actually changes the current
- Edit KeySyms of Key
- This pops up the "Edit Key" window, which allows you to
arbitrarily change which keysyms and modifiers this key generates.
On the left side of the window is the list of the keysyms that this key
currently generates. (A key may generate up to eight keysyms; the
interpretation of these keysyms is described in the X protocol document,
and is summarized later in the KEYSYMS AND KEYCODES section of this
The second column is a multiple-choice list of the eight modifier bits that
this key may generate. For example, if you want a key to behave as a
``control'' key, you should select the Control modifier.
The third and fourth column (the scrolling lists) are for changing the
keysym associated with the key. When you select a keysym-position from the
first column, the character set and keysym will be displayed in the
scrolling lists. Clicking on a keysym in the ``KeySym'' column will
install that keysym in the highlighted slot in the first column.
To select a keysym from a different character set, click on the character
set name in the second column. (The Latin1 and Keyboard
character sets are the most commonly used.)
At the bottom of the window are three buttons: Undo, Abort,
and Ok. Clicking on Undo reverts the Edit Key window to the
current state of the key in question. Abort closes the Edit Key
window without making any changes. Ok closes the Edit Key window
and installs your changes (the current keyboard mapping is modified.)
To effectively edit your keyboard mapping, there are some terms you need to be
- This is a raw scan-code that is read from the keyboard; each physical key
on the keyboard has a different number associated with it; this mapping
cannot be changed (but that's ok.)
Generally, every keyboard has its own set of KeyCodes, which is why you will
probably need to have a different keymap for every system you use.
- This is a symbol which can be generated by a single press of one key on
the keyboard: for example, all letters, numbers, and punctuation are
keysyms, and so are more abstract things like ``shift'' and ``control''.
Each KeyCode (that is, key on the keyboard) is associated with certain
KeySyms. The KeySyms are what give the keys their semantics (and makes the
A key generate an A), not the KeyCodes.
Usually keys are associated with one or two keysyms, which correspond to the
symbols generated when the key is pressed, and when it is pressed while
the shift key is held down. There is a special case, which is that if the
key contains only one KeySym, and it is a letter, then the Shift key does
the obvious thing that one does to letters.
- Not to be confused with KeySyms, this refers to the text which is printed
on the physical keys: it is immutable (unless you repaint your
- This term refers to a set of two or more keys held down simultaniously (by
analogy with piano keyboards.) All but one of the keys will generally be
Modifier Keys. Sometimes Constellation is used to mean the same
- Modifier Key
- This is a key like shift or control, which is used to alter the
interpretation of other keys which are held down at the same time.
Generally, pressing a modifier key without also pressing a non-modifier
key does nothing.
A key is a modifier key if it has a Modifier KeySym on it. (More
specifically, if the KeyCode of that key is associated with a Modifier
- Modifier KeySym
- A KeySym is a modifier keysym if it has a Modifier Bit associated with it.
But, the rules are a little more complicated than that. It's easier to
describe by example:
For a key to behave as one expects a shift key to behave, the keycode should
have the Shift modifier bit set; and the key should generate one of the
keysyms Shift_L and Shift_R. If either of these is not true, the key will
not behave as a shift key.
Analogously, a control key must have the Control modifier set, and use one
of the keysyms Control_L or Control_R.
This implies that if you wanted to swap your shift and control keys, it
would not be enough to simply swap their modifier bits: you must swap
their keysyms as well. If you only swap the modifier bits, it might appear
to work at first, but other things would malfunction.
Keys like Meta (and Super, Hyper, etc.) are a bit more complicated (see
- Modifier Bit
- Modifier bits are attributes which certain keysyms can have. Some modifier
bits have predefined semantics: Shift, Lock, and Control. The remaining
modifier bits (Mod1 through Mod5) have semantics which are defined by the
keys with which they are associated.
That is, the Control modifier means Control if it is attached to Control_L
or Control_R, and is illegal elsewhere.
But Mod1 means Meta if it is attached to Meta_L or Meta_R; but it would mean
Alt if it were attached to Alt_L or Alt_R; or Hyper with Hyper_L or
Hyper_R; and so on. (It could not, however, be attached to Control_L,
since the Control modifier has already spoken for those keysyms.)
If you're thinking that this is all senselessly complicated... you're
The following is a more precise technical explanation of how keymapping works.
This description is from the X Protocol document, and is reprinted here for
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
. 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
, 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
. 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
modifiers are off.
The second KeySym is used when the Shift
modifier is on, or when the
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
, 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.
The 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
. Each modifier bit is
controlled by the state of a set of keys, and these sets are specified in a
table accessed by GetModifierMapping()
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
modifier should be interpreted as Caps Lock
according as the keycodes in its controlling set include
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
Scan the existing modifier mappings. If it finds a modifier that contains a
keycode whose set of keysyms includes XK_Meta_L
should use that modifier bit.
If there is no existing modifier controlled by XK_Meta_L
, 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
The above means that the Mod1
modifier does not necessarily mean
, although some applications (such as twm
) 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
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.
In 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.
Not 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
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
, followed by A
to produce the Aacute
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
library, which simulates the traditional Xt behavior. For
more info, read the commentary at the top of the file
Dead 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
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.
People 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
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
you hit F17:
xterm*VT100.Translations: #override \
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
It is also not possible to make a keyboard key behave as a mouse button.
Both 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
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
First, their default keymap has the Control
modifier attached to both the
key and the Multi_key
. This is completely crazy, because
not only is Multi_key
not a control key, it's not even a
key! It mustn't have any modifier bits attached to it at all.
Second, they attach Mod1
and also to Alt_R
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
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
; change the left Alt key to generate Alt_L
instead of Meta_L
; and delete the Hyper_R
keysym from the
If you have any pull with these vendors, I encourage you to encourage them to
get their act together.
understands all of the core resource names and classes as well
- *Keyboard.keyboard (class Keyboard)
- Which keyboard to display; this is the same as the -keyboard
command-line option. If this is not specified, the default keyboard is
guessed, based on the server's vendor identification string.
- *Keyboard.Keyboard.selectCursor (class
- The cursor to use when selecting a key or window with the mouse. The
default is the crosshair cursor.
- *Keyboard.Key.highlight (class
- The color to use to highlight a key when it is depressed. If this is the
same as the background color of the key, it is highlighted with a stipple
- *Keyboard.Key.keycapColor (class
- The color to paint the keycap string.
- *Keyboard.Key.keycodeColor (class
- The color to paint the keycode number.
- *Keyboard.Key.borderColor (class Color)
- The color of the box around each key.
- *Keyboard.Key.keycapFont (class Font)
- The font to use to draw the keycap string.
- *Keyboard.Key.keycodeFont (class Font)
- The font to use to draw the keycode number.
- *Keyboard.Key.borderWidth (class Int)
- The thickness of the box around each key.
- *Keyboard.Key.gutterWidth (class Int)
- How many pixels to leave between this key and it's neighbors to the right
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
keys to have wider borders, you could specify that with
It 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
- HighlightKey(condition, arg)
- This places the key in question in the highlighted state.
If no argument is passed to this action, then the key is determined
by the event which invoked this action. If this action is invoked by a
KeyPress or KeyRelease event, the key-widget is the key
corresponding to the key that the event represents. If it is a
ButtonPress, ButtonRelease, or PointerMotion event,
then the key-widget is the one under the mouse.
The argument may be one of the words mouse,
highlighted, or displayed, meaning the key under the mouse,
the key most recently highlighted, or the key currently being described in
the ``Info'' area at the top of the window, respectively.
The condition may be one of the words ifmod, unlessmod,
iftracking, unlesstracking, ifhighlighted, or
unlesshighlighted. If ifmod was specified and the key in
question (as determined by the argument or by the invoking event)
is not a modifier key, then this action is not executed. The
unlessmod condition is the opposite. The iftracking and
unlesstracking conditions allow you to do some actions only if (or
unless) the key is being ``tracked'' with the mouse (see below.) The
ifhighlighted and unlesshighlighted actions allow you to do
some things only if (or unless) the key in question is currently in the
- UnhighlightKey(condition, arg)
- This places the key in question in the unhighlighted state. Arguments are
- ToggleKey(condition, arg)
- This makes the key be highlighted if it is unhighlighted, or unhighlighted
if it is highlighted. Arguments are as above.
- SimulateKeyPress(condition, arg)
- This action makes a KeyPress event corresponding to the key be
synthesized on the focus window. Arguments are as above.
- SimulateKeyRelease(condition, arg)
- This action makes a KeyRelease event corresponding to the key be
synthesized on the focus window. Arguments are as above.
- TrackKey(condition, arg)
- This makes the key in question begin being ``tracked'', which means that
moving the mouse off of it will simulate a button-release action, and then
will simulate a button-press action on the key that the mouse has moved on
to. This action may only be invoked from a ButtonPress or
- UntrackKey(condition, arg)
- This makes the key in question no longer be ``tracked.''
- DescribeKey(condition, arg)
- This action causes the key and its bindings to be displayed in the
``Info'' section at the top of the window, if it is not already described
The default actions for the Keyboard
<Motion>: DescribeKey(mouse,unlessTracking) \n\
<KeyDown>: HighlightKey() \
<KeyUp>: UnhighlightKey() \
<Btn1Down>: HighlightKey(unlessMod) \
<Btn1Up>: UntrackKey(highlighted) \
<Btn3Down>: XawPositionSimpleMenu(keyMenu) \
If 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
to the <Btn1Down>
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
from the DescribeKey
action bound to <Motion>
If you don't want the modifier keys to toggle, then change the Button1
xkeycaps*Keyboard.actions: #override \
<Btn1Down>: HighlightKey() \
<Btn1Up>: UntrackKey(highlighted) \
Remember that these actions exist on the Keyboard
widget, not on the
widgets. If you add actions to the Key
widgets, things will
- to get the default host and display number.
- to get the name of a resource file that overrides the global resources
stored in the RESOURCE_MANAGER property.
- to get the location of the XKeysymDB file, which lists the
The latest version can always be found at http://www.jwz.org/xkeycaps/
Because this program has default colors that aren't "black" and
"white", the -rv
command-line option doesn't work. But the
% xkeycaps -fg white -bg black -bd white
will 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
keys will get ``stuck'' until they are pressed again.
(Don't go like that.)
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
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
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
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.
program still sucks. Since its ADD
directives take keysyms as arguments instead of keycodes, there are things
that you can do with XKeyCaps
that you can't represent in an
script (at least, not without great pain.)
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.
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.
Copyright © 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.
Jamie Zawinski <firstname.lastname@example.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
- Thanks to:
- Jonathan Abbey, Alon Albert, Vladimir Alexiev, David Arnold, David Axmark,
Ruediger Back, Pedro Bayon, Corne Beerse, Eric Benson, Christoph Berg,
Markus Berndt, Roger Binns, Stefan Bj|rnelund, email@example.com,
Mark Borges, Volker Bosch, Dave Brooks, Lorenzo M. Catucci, Michel
Catudal, Francois Regis Colin, John Coppens, Cesar Crusius, Bart Van
Cutsem, Matthew Davey, Christopher Davis, Albrecht Dress, Kristian Ejvind,
Michael Elbel, Joe English, Eric Fischer, Morgan Fletcher, Olivier
Galibert, Carson Gaspar, Andre Gerhard, Daniel Glastonbury, Christian F.
Goetze, Dan R. Greening, Edgar Greuter, John Gotts, Berthold Gunreben,
Jens Hafsteinsson, Adam Hamilton, Magnus Hammerin, Kenneth Harker, Ben
Harris, Mikael Hedin, Tom Ivar Helbekkmo, Mick Hellstrom, Neil Hendin,
Andre Heynatz, Mike Hicks, Alan Ho, Hide Horiuchi, Dirk Jablonowski, Alan
Jaffray, Anders Wegge Jakobsen, Chris Jones, Jorgen Jonsson, Peter Kaiser,
Heikki Kantola, Tufan Karadere, Benedikt Kessler, Philippe Kipfer, Edwin
Klement, John Knox, Haavard Kvaalen, Frederic Leguern, Simon Leinen,
Michael Lemke, Tor Lillqvist, Torbj|rn Lindgren, Tony Lindstrom, Richard
Lloyd, Ulric Longyear, Ulf Magnusson, Cliff Marcellus, John A. Martin, Tom
McConnell, Grant McDorman, Hein Meling, Jason Merrill, Aleksandar
Milivojevic, Manuel Moreno, Ken Nakata, Pekka Nikander, Todd Nix, Leif
Nixon, Christian Nybo, Antoni Pamies Olive, Edgar Bonet Orozco, Steven W.
Orr, Martin Ouwehand, Daniel Packman, John Palmieri, Chris Paulson-Ellis,
Eduardo Perez, Michael Piotrowski, Andrej Presern, Jeremy Prior, Dominique
Quatravaux, Matthias Rabe, Garst R. Reese, Peter Remmers, Todd Richmond,
Ken Rose, Pavel Rosendorf, Gael Roualland, Lucien Saviot, Johannes
Schmidt-Fischer, Andreas Schuch, Larry Schwimmer, Joe Siegrist, Jarrod
Smith, Tom Spindler, Robin Stephenson, Joerg Stippa, D. Stolte, A. A.
Stoorvogel, Juergen Stuber, Markus Stumpf, Jeffrey Templon, Jay Thorne,
Anthony Thyssen, Christoph Tietz, firstname.lastname@example.org, Juha Vainikka, Poonlap
Veeratanabutr, Ivo Vollrath, Gord Vreugdenhil, Ronan Waide, Jan Wedekind,
Bj|rn Wennberg, Mats Wichmann, Stephen Williams, Barry Warsaw, Steven
Winikoff, Carl Witty, Stephen Wray, Endre Witzoe, Kazutaka Yokota, Yair
Zadik, and Robert Zwickenpflug.