Please note, that this page doesn't cover the XKEYBOARD extension.
(If you are using the text console or a video text terminal: This is not covered here. Their mechanisms for configuring/typing special characters are very system specific. Numerous modern Unix flavours support this for their console [setkeys(1)/loadkeys(1)/dumpkeys(1), etc]. Video text terminals might have a special built-in "compose" mechanism, probably to be activated by a built-in menu system in advance.)
The following doesn't concern only 8bit "special characters"
but all those characters which you can't find literally on your caps.
On some national keyboards even some important
ASCII characters are missing, e.g., {, [, ], }, @, \, |, ~
.
This page contains latin1 (western europe 8-bit) characters for illustration. Your browser/font might not display them.
(By the way, using the Euro Symbol is on-topic, in Europe. Then you need latin9.)
A good explanation of the X11 keyboard model is in the xkeycaps(1) manual. (Probably, for now, there's enough information in here, to at least start without having read it.)
If you use the XKB-extension (in contrast to me, because i am using an X11R5 at the time of this writing), i.e. if xdpyinfo(1) shows "XKEYBOARD" in the extension section, and if you try to solve special problems with it, mainly getting it running at all, then the following might not be useful. But still see more documentation and system specific problems for some hints about configuring XFree86 (where problems with XKB usually occur). Nevertheless, the plain xmodmap way described in here always works (although it might mean some work in the worst case).
Content:
Before you start with keymapping,
There are at least five ways to type special characters:
But before you start looking at the keymapping in X11, confirm the following:
Illustration for a west european user (Latin-1 aka ISO8859-1)
$ xlsfonts -fn '*-iso8859-1' $ xfd -fn '8x13-iso8859-1' $ xterm -fn '8x13-iso8859-1' $ perl -e 'for$i(160..255){printf"%c%c",$i,($i%16==15)?10:32}'(the last command is just one way to print the valid eight bit characters as simple test)
Most of the really simply named fonts should be iso8859-1, you would only need "8x13", instead of "8x13-iso8859-1".
Footnote:
However, in rare cases, confirmation with xfd(1) is necessary,
because a few X11 standard fonts wrongly only contain ASCII,
although they're even labeled iso8859-1. Examples (older X11R5, from
the "misc-fixed-medium-*" family) are 5x8
,
6x9
, 6x10
, 6x12
.
See more details.
If you're using standard sized fixed fonts, you are not likely to
run into this problem--but as stumbling over it is very annoying then,
i mention the problem.
See also Jukka Korpela's page about characters and encoding.
Some shells, e.g. bash(1), tcsh(1), and on some systems, even some terminalemulators like dtterm(1) and aixterm(1) initialize themselves according to your locale settings. (If you can't properly set up bash via the locale, search the manpage in the section 'Readline Variables' about 'meta' for a workaround.)
Many applications also pay attention to your locale settings, but shell and terminalemulator are really crucial about this.
'Re: "ASCII"
> 127'
in comp.unix.misc, Apr/01.)
KeyPress event, serial 15, synthetic NO, window 0x4400001, root 0x29, subw 0x0, time 1444453669, (112,112), root:(121,362), state 0x00, keycode ... (keysym 0xe4, adiaeresis), same_screen YES, XLookupString gives 1 characters: "ä"
Note, that the symbolic name (the KeySym name)
usually is a long term identifier, and not the character itself
(the only exceptions are the alphanumerical characters from the plain
ASCII alphabet). So, in this example, the KeySym
name is adiaeresis instead of ä
(a-umlaut).
There are three requirements to make AltGr work:
As an illustration:
xev(1) reports the AltGr-cap to have the keycode 20 for me, but this number will very likely differ for you.
$ xmodmap -e 'keycode 20 = Mode_switch"
$ xmodmap -e 'clear mod3' $ xmodmap -e 'add mod3 = Mode_switch'...and the result looks like the following, when looking at it with xmodmap(1). (Don't bother about the other lines of mine, except the following fact: don't "mix" keysyms with different purpose in a single line):
$ xmodmap shift Shift_L (0x6a), Shift_R (0x75) lock Caps_Lock (0x1e) control Control_L (0x53) mod1 Meta_L (0x7f) mod2 Alt_R (0x81) mod3 Mode_switch (0x14) mod4 mod5 Num_Lock (0x69)
xmodmap -e 'keycode 84 = a A adiaeresis Adiaeresis'...the cap 'A' most likely will be a different keycode number on your keyboard.
(By the way, the '0x14' in parentheses behind Mode_switch is just the hexadecimal value of my Keycode for this cap.)
I arbitrarily associated Mode_switch with "mod3", but you can use any modifier (from mod1 to mod5), which is still free (i.e. not mapped with anything different already). Well, in practice, you shouldn't use mod1, as some programs wrongly (hardcoded) expect this one to be associated with Meta.
See some
hints on xmodmap
file for more background, and what programs to use to make all this easier,
if you still have problems.
(BTW, there's a detailed instruction from Helmut Richter at http://www.lrz-muenchen.de/services/software/x11/xmodmap_en/ for making heavy use of Mode_switch for ISO8859-1.)
Now, if you hold AltGraph and press 'a', while xev(1) is running, it should look like the following, only the emphasized parts are important:
KeyPress event, serial 15, synthetic NO, window 0x5000001, root 0x29, subw 0x0, time 2948632304, (126,89), root:(344,392), state 0x0, keycode 20 (keysym 0xff7e, Mode_switch), same_screen YES, XLookupString gives 0 characters: "" KeyPress event, serial 15, synthetic NO, window 0x5000001, root 0x29, subw 0x0, time 2948633524, (126,89), root:(344,392), state 0x20, keycode 84 (keysym 0xe4, adiaeresis), same_screen YES, XLookupString gives 1 characters: "ä"
(again: the keycode will certainly vary if you don't use the same keyboard like me)
You don't have to verify the following - it's just for your interest:
'0x20' (from the state field) is hexadecimal and means '32'.
If you enumerate the logical modifiers above [shift, lock, control,
mod1, mod2, ...] with powers of 2 [1, 2, 4, 8, etc.] you'll
see that 'mod3' is decimal 32, hexadecimal 20. In X11, the logical
modifier settings are just stored as a bit-field internally.
If you have mapped it onto another modifier
from Mod1-Mod5, then this value will be according.
(One could also patch xev to report modifiers in a human readable way - but it's not really useful, just handy and convenient. xkeycaps(1) will do it out of the box, and xmodmap(1) tells you the mapping of all in one.)
(For two XFree86-3 specialities: Danish-HOWTO, "Getting the AltGr key to work under X11")
The KeySym name, which you'll need for the mapping, is Multi_key
(hint: you press several keys in a row).
An example is hitting Multi_key, afterwards 'O'
and finally '/' [slash], which results in 'Ø'
[Oslash].
Originally (X11R5) , this mechanism works "Xserver-internally" and thus you don't need to map it as a logical modifier.
Basically, you only need to map a free cap:
$ xmodmap -e 'keycode ... = Multi_key'...or if you have none: map a combination, i.e. adding it to Mode_switch (or Control_R):
$ xmodmap -e 'keycode ... = Mode_switch Multi_key'
If the compose-mechanism is not working for you:
Because of the last point, it's not really possible to debug this with xev(1), as it doesn't support the compose mechanism. (But you certainly can confirm, that "Multi_key" is properly configured!)
If it works for you, see a list of possible combinations of keys and their 'compose'-result. They are rather easy to remember, but you have to type a lot.
This is another, automatic way of composing. dead means that the actual generation of the character is delayed until you have pressed a second cap: until then the key seems "dead".
This method allows you to compose every (allowed) accented character by just typing the according dead_accent first and the according base character afterwards.
As example: <dead_grave> and then <a> results in 'à'. Unfortunately there are different implementations among X11R5 vs. R6 and MIT vs XFree86. See also the following pages (not always Linux specific at all).
Just as an example: various dead_characters from MIT(/Solaris) X11R6 with a possible resulting latin1 character.
dead_grave + a = à dead_acute + a = á dead_circumflex + a = â dead_cedilla + c = ç dead_tilde + n = ñ dead_diaeresis + o = öNote: On Solaris2.5[.1] the according KeySym-names (as Sun extension) are not included in /usr/openwin/include/X11/keysymdef.h but - with different names - in /usr/openwin/lib/X11/XKeysymDB:
SunFA_Grave SunFA_Acute SunFA_Circum SunFA_Cedilla SunFA_Tilde SunFA_Diaeresis
XTerm.VT100.translations: #override \ :@Alt_L<Key>a: string("ä") \n\ :@Alt_L<Key>comma: string("«") \n\ :@Alt_L<Key>m: string("µ") \n\ :@Alt_L<Key>c: string("©") \n\
~/.inputrc"
ASCII: | | ! | " | # | $ | % | & | ' | | ( | ) | * | + | , | - | . | / | | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | 8 | 9 | : | ; | < | = | > | ? | | @ | A | B | C | D | E | F | G | | H | I | J | K | L | M | N | O | | P | Q | R | S | T | U | V | W | | X | Y | Z | [ | \ | ] | ^ | _ | | ` | a | b | c | d | e | f | g | | h | i | j | k | l | m | n | o | | p | q | r | s | t | u | v | w | | x | y | z | { | | | } | ~ |del| (literal ISO8859-1 characters following, your browser might not display them) With "Meta": | | ¡ | ¢ | £ | ¤ | ¥ | ¦ | § | | ¨ | © | ª | « | ¬ | | ® | ¯ | | ° | ± | ² | ³ | ´ | µ | ¶ | · | | ¸ | ¹ | º | » | ¼ | ½ | ¾ | ¿ | | À | Á | Â | Ã | Ä | Å | Æ | Ç | | È | É | Ê | Ë | Ì | Í | Î | Ï | | Ð | Ñ | Ò | Ó | Ô | Õ | Ö | × | | Ø | Ù | Ú | Û | Ü | Ý | Þ | ß | | à | á | â | ã | ä | å | æ | ç | | è | é | ê | ë | ì | í | î | ï | | ð | ñ | ò | ó | ô | õ | ö | ÷ | | ø | ù | ú | û | ü | ý | þ | ÿ |
Both tables originate from Solaris, /usr/pub/iso.
To switch off this behaviour in xterm(1) (because it's the default), you need to have "XTerm.eightBitInput: False" in your X11 Resources. (Don't worry, it doesn't affect typing 8-bit charactes with the other, correct mechanisms.)
Then, xterm(1) converts <Meta-key> to <ESC><key>,
which is also useful, if you use emacs-like bindings somewhere.
(Even in a shell, bash: "Meta-b/f" then means "move a word backward/forward".)
The advantage of xmodmap(1): it comes with the X11 core and you'll will be able to help yourself practically always. In particular, it also works, if your XKB extension is running.
The disadvantages are:
xmodmap -pke
", you have to do hand work for
the modifier mapping, as xmodmap(1) doesn't know an option
to output this in a way it can re-read it again.
Well, in the worst case, all you need to do is
clear shift clear lock clear control clear mod1 clear mod2 clear mod3 clear mod4 clear mod5 [...] (mapping all the keycodes) add shift = Shift_L Shift_R add control = Control_L (perhaps also Control_R) add lock = Caps_Lock add mod1 = [...[ (usually Meta_L / Meta_R) add mod2 = [...] (e.g. Mode_switch) add mod3 = [...] (e.g. Num_Lock) add mod4 = [...] (e.g. Alt_L / Alt_R) add mod5 = [...]
On Solaris, you don't need to do that, but can use xmakemap(1) to generate a really complete keymap.
See also some hints for xmodmap with a lot of comments about all this. (It's hardly readable, but should be pretty informative for the interested.)
When using a german keyboard: by default, both "Alt_R" and "Mode_switch" are likely associated with the same logical X11 modifier. This is very bad, because they must not be mixed. Typing e.g. '@' (via "AltGr/Mode_switch-Q") then closes the window in some applications (via "Alt/Meta-Q").
As alternative suggestion: map the lower row from left to right
with:
Meta_L (mod1) / Alt_L (mod2) / [Space] / Mode_switch aka AltGR
(mod3) / Meta_R (mod1) / Multi_key aka Compose
If the keycodes from left to right are
148 / 34 / [Space] / 66 / 149 / 150:
clear mod1 clear mod2 clear mod3 keycode 148 = Meta_L keycode 34 = Alt_L keycode 66 = Mode_switch keycode 149 = Meta_R keycode 150 = Multi_key add mod1 = Meta_L Meta_R add mod2 = Alt_L add mod3 = Mode_switch add mod4 = Num_Lock
As far as i know this is also a useful mapping for Meta and Alt if you're using (x)emacs which distinguishes them. So they should be associated with different modifiers.
If you want more help than xmodmap(1) to debug and remap this yourself, but don't have xev(1) installed, then compile it yourself.
...parts of it are actually rather interesting and easy to read.
$ xdpyinfo | grep XKEYBOARD
The proper solution ("what symbolic link exactly is still lacking?" or alike) will depend on your distribution, what you are having already and how you've gotten there. See various hints to get an idea; the fastest and most direct way is just strace(1)ing your Xserver, finding out where it's actually searching.
You definitely should search with google ( http://groups.google.com/advanced_group_search with "xfree 4 keyboard" or alike) in the appropriate usenet groups (for X11 or your OS).