Newsgroups: comp.windows.x
Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!think.com!snorkelwacker.mit.edu!bloom-beacon!dont-send-mail-to-path-lines
From: mouse@lightning.mcrcim.mcgill.EDU (der Mouse)
Subject: Re:  How do I remap the keyboard?
Message-ID: <9105021454.AA18784@lightning.McRCIM.McGill.EDU>
Sender: daemon@athena.mit.edu (Mr Background)
Organization: The Internet
Date: 2 May 91 14:54:33 GMT
Lines: 128

>>> We have an application that needs to redefine the keys on the
>>> keyboard to be different from the default.  It is obvious that X
>>> contains support for this;

> First, one thing I suspected is true:  The keycode->keysym mapping
> seems to be done in the server, so changes there are global to the
> [server].

Close.  It is stored on the server, but interpreted by the client.
However, changing the server's stored state sends events to all
clients, and all (or close enough as no difference) clients do the
right thing with this event, so it amounts to the same thing.

> The question about defining shift-comma and shift-dot got answered by
> several people:
> 	xmodmap keysym comma = comma less
> 	xmodmap keysym period = period greater
> or
> 	xmodmap -e 'keysym comma = comma less' -e 'keysym period = period greater'
> if you want to save a bit of cpu time.  I'd tried lots of guesses as
> to what xmodmap's syntax was, and never guessed this.  I also can't
> quite correlate this with what xmodmap's manual page describes as its
> syntax.  I mean, why are "comma" and "period" replicated on both
> sides of the '='?

Because you still want , on the , key (to pick the comma key).  What
"keysym comma = comma less" says is "find the keycode that maps to the
keysym `comma' and change it to map to `comma' unshifted and `less'
shifted".  Observant readers will notice that I glibly said "...the
keycode that maps to...", when there may in fact be more than one.  I
don't offhand know what xmodmap does in this case; I suspect it uses
the lowest (or perhaps highest) such keycode.

> How does it know that I'm telling it to change shift-comma, say,
> rather that just comma or ctrl-comma or meta-comma or ...?

Because that's the convention for interpreting the columns of the
keycode-to-keysym mapping.

Each keycode is mapped to a list of keysyms.  These are considered as a
two-dimensional array, with missing keysyms filled in according to
rules which are complicated enough to be confusing if I gave them here
in their entirety, but I do need to say that if the second keysym in a
list is missing or is NoSymbol, it is considered to be a copy of the
first keysym in the list.  The convention is that the first column (ie,
the first keysym in the list) is used when the key is pressed unshifted
and the second column (ie, the second keysym in the list) is used when
the key is pressed shifted.  (CapsLock and ShiftLock modify this in
reasonable ways; for details see the protocol document.)

Thus, "keysym comma = comma less" says that the key that used to map to
the keysym "comma" is to be mapped to "comma" unshifted and "less"
shifted.

There is no similar coherent standard for the Control and Meta
modifiers.  (Strictly speaking, there is no Meta modifier; the closest
thing there is is something like "any modifier bit bound to a keycode
which is bound to a Meta_L or Meta_R keysym".)  Thus, if you want to
change control-comma or meta-comma, you're at the mercy of the client
in question; I believe xterm provides reasonable support for this sort
of remapping.

> One of the first things was to discover that when the xterm manual
> page says "The xterm application reads the .Xdefaults file during
> startup ..." it is lying through its teeth.  I wasted a couple of
> hours modifying .Xdefaults, and nothing I did had any effect
> whatsoever on new xterms.  I became suspicious, did a "ls -lu
> .Xdefaults", started a new xterm, and repeated the "ls -lu", and
> verified that the access time hadn't changed.  So xterm doesn't open
> .Xdefaults at all.  A bit more experimenting verified that if I kill
> X off and restart it, xterm then uses the contents of .Xdefaults.
> Thus .Xdefaults is cached inside the X server, and xterm gets the
> info from there.

Close.  xterm reads the RESOURCE_MANAGER property from the server and
uses that; I think if no such property has been set up it then goes to
your .Xdefaults.

When you start X, your startup script probably do something like
"xrdb -load < .Xdefaults".  This loads the .Xdefaults file into the
RESOURCE_MANAGER property, which is why restarting X cleared things up.

> 	xterm*Translations: #override \
> 		<Key>F1   : string("You touched F1") \n\
> 		...

> [...].  So far so good.  Well, not really, since this strikes me as
> incredibly bizarre syntax.  I mean, why the '#' before the
> "override"?  Why the "\n\" at the end of the lines?

I have no idea.  The translation manager is one of the weirdest things
I've seen.  It really makes no sense to me to toss it all into one
resource; this makes it hard to configure....

I would much prefer something like

xterm*Translations.F1: string("You touched F1")
xterm*Translations.Help: string("You touched Help")

but adding modifier bits to this makes it difficult.  The proposed Xlib
routine to search for all completions of a given partial resource would
allow this to be fixed....

> Also, I'm blocked at what might be the most critical point:  The
> above definitions define strings consisting only of printable ASCII
> characters.  I need to get things like ESC and CR and NUL into the
> strings.

I believe this can be done.  I'm not certain of the syntax, but I think
you want to skip the double quotes and use hex, something like

<Key>F1: string(0x1b) string("<-ESC CR->") string(0x0d)

> Another possibility:  Some of our important applications involve
> running tip inside the window talking out a port to a DOS system that
> is running pcanywhere, so what we need is to send IBM PC/DOS escape
> sequences down the line.  It occurs to me that one solution would be
> a window that is specifically an emulation of a DOS keyboard/display.

You could probably take mterm and drop another emulation module into
it.  (mterm is my terminal emulator; adding a new emulation type is
intended to be fairly easy.  You can get it by ftp from 132.206.1.1 in
X/mterm.src/ or by mail from me.)

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu
