[comp.windows.x] How do I remap the keyboard?

lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) (04/08/91)

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; it is equally obvious that I'm not making sufficient sense of
TFM to actually do it, so...

Two simple examples should suffice.  Suppose, firstly, that I wanted to
make this keyboard's command and period keys behave like they do on most
ASNI terminals:  shift+comma is '<' and shift+period is '>'.  How would
I do it?  It seems that xmodmap should be able to do this, but damned if
I can figure out the -e '...' expression to actually accomplish it.  The
result of the command 
	xmodmap -pk | egrep 'comma|period|less|greater'
on this system is:
    201         0x003c (less)   0x003e (greater)
    232         0x002c (comma)  0x002c (comma)
    237         0x002e (period) 0x002e (period)
What I'd like to do, I guess, is somehow copy the definitions for keycode
201 to the second columns of keycodes 232 and 237.  I've experimented with
lots of calls of xmodmap, but have gotten mostly error messages, and no
changes to any of these definitions.  Does anyone know how to do it?

Another example is redefining a function key.  Again, it is obvious that
the intention was that I be able to do it; it is equally obvious that I'm
not sufficiently intelligent to decrypt the descriptions in the manuals.
An example here is that the key labeled "F5" sends the keycode 90, which
is mapped onto keysym 0xffc2=F5.  When I run a program and type an F5 at
it, what it receives is the character string:
	1B 5B 31 35 7E
which is "\e[15~" in another notation.  Suppose I wanted the F5 key to give
the sequence "\e5F", or:
	1B 35 46
in hex.  How would I go about telling X that this is what I want?  Or is this
translation even done by X?  I mean, xev tells me that the keysym F5 has an
XLookupString that is 0 characters long, so maybe X isn't even doing it, but
in that case, who might it be, and how do I make a deal with them?

It sure seems that there oughta be some examples lying about, but I have
had no success in finding them...

barry@medicus.com (Barrelda Q. Nammowitz) (04/10/91)

In article <21867@shlump.nac.dec.com> lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) writes:
>[.....]..
>Another example is redefining a function key.  Again, it is obvious that
>the intention was that I be able to do it; it is equally obvious that I'm
>not sufficiently intelligent to decrypt the descriptions in the manuals.
>An example here is that the key labeled "F5" sends the keycode 90, which
>is mapped onto keysym 0xffc2=F5.  When I run a program and type an F5 at
>it, what it receives is the character string:
>	1B 5B 31 35 7E
>which is "\e[15~" in another notation.  Suppose I wanted the F5 key to give
>the sequence "\e5F", or:
>	1B 35 46
>in hex.  How would I go about telling X that this is what I want?  Or is this
>translation even done by X?  I mean, xev tells me that the keysym F5 has an
>XLookupString that is 0 characters long, so maybe X isn't even doing it, but
>in that case, who might it be, and how do I make a deal with them?
>
>It sure seems that there oughta be some examples lying about, but I have
>had no success in finding them...

I needed to do a similar thing for an application that we write here.
I redefine the function keys and arrow keys in my resource file, in 
this case my .Xdefaults file.  For my particular purpose the
key remapping is done for the xterm that my application runs in.

*xterm*translations: #override <Key>F1: string("^AOP") \n\
                               <Key>F2: string("^AOQ") \n\
                               <Key>F3: string("^AOR") \n\
                               <Key>F4: string("^AOS") \n\
                               <Key>F5: string("^AOT") \n\
                               <Key>F6: string("^AOU") \n\
                               <Key>F7: string("^AOV") \n\
                               <Key>F8: string("^AOW") \n\
                               <Key>F9: string("^AOX") \n\
                               <Key>F10: string("^AOY") \n\
                               <Key>F11: string("^B") \n\
                               <Key>F12: string("^E") \n\
                               <Key>Up: string("^A[A") \n\
                               <Key>Down: string("^A[B") \n\
                               <Key>Right: string("^A[C") \n\
                               <Key>Left: string("^A[D")


Hope this helps.

	--barry


------------------------------------------------------------------------------
Barry  Namm                                        Medicus Systems Corporation
barry@medicus.com                                        Clinical Data Systems
{uunet,sun!rtech,unisoft}!medicus!barry                    Alameda, California

mouse@lightning.mcrcim.mcgill.EDU (der Mouse) (04/11/91)

> 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;

After a fashion.  The X protocol contains support for remapping the
keyboard in the sense of changing the mapping between physical keys
("keycodes") and logical keys ("keysyms").  Xt, and some (most? all?)
clients that use it, has/have support for mapping (logical) keys to
mostly-arbitrary actions.

> Two simple examples should suffice.  Suppose, firstly, that I wanted
> to make this keyboard's command and period keys behave like they do
> on most ASNI terminals:  shift+comma is '<' and shift+period is '>'.

You mean they don't already? :-)

> How would I do it?  It seems that xmodmap should be able to do this,
> but damned if I can figure out the -e '...' expression to actually
> accomplish it.  The result of the command
> 	xmodmap -pk | egrep 'comma|period|less|greater'
> on this system is:
>     201         0x003c (less)   0x003e (greater)
>     232         0x002c (comma)  0x002c (comma)
>     237         0x002e (period) 0x002e (period)

This is the sort of thing that is well-supported.

xmodmap - << EOF
keysym comma = comma less
keysym period = period greater
EOF

or I believe the following is equivalent

xmodmap -e 'keysym comma = comma less' -e 'keysym period = period greater'

You may want to do something with the </> key as well.  (Let me guess:
you have a DEC keyboard. :-)

> Another example is redefining a function key.  [...]  An example here
> is that the key labeled "F5" sends the keycode 90, which is mapped
> onto keysym 0xffc2=F5.

You're ahead of the pack here.  Most people confused by X keyboard
handling wouldn't even understand that last sentence :-)

> When I run a program and type an F5 at it, what it receives is the
> character string:
> 	1B 5B 31 35 7E
> which is "\e[15~" in another notation.

When you type F5, what happens depends on the (X) client it's being
typed at.  When you say "run a program and type an F5 at it", I assume
you are running a non-X-aware program from within a terminal emulator
window.  In that case, the mapping from keysym F5 to the string you
gave is being performed by the terminal emulator, and to change it you
have to coax the terminal emulator into doing what you want.  This may
be anywhere from easy to impossible, depending on how customizable it
is.  xterm, for example, makes it fairly easy; the example in the FAQ
is

----------------------------------------------------------------------
Subject: 62)  How do I remap the keys on my keyboard to produce a string?

	There is no method of arranging for a particular string to be
produced when you press a particular key. The xmodmap client, which is useful 
for moving your CTRL and ESC keys to useful places, just rearranges keys and 
does not do "macro expansion."
	Some clients, including xterm and several X-based editors, accept
a translation resource such as:
	xterm*VT100.Translations: #override \
		<Key>F1: string("setenv DISPLAY unix:0")
which permits the shorthand F1 to be pressed to reset the display locally
within an xterm.  However, this doesn't work across all clients.
	Window managers, which could provide this facility, do not yet; nor
has a special "remapper" client been made available.

----------------------------------------------------------------------

Since you appear to be on a DEC machine, you may have to contend with
dxterm.  I would hope that dxterm has something similar; if you're
lucky, it will be identical.  Experiment and/or check the documentation
(or just chuck dxterm and use xterm instead).

					der Mouse

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

lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) (04/11/91)

In article <1991Apr9.172338.10501@medicus.com> barry@medicus.com (Barrelda Q. Nammowitz) writes:
>
>I needed to do a similar thing for an application that we write here.
>I redefine the function keys and arrow keys in my resource file, in 
>this case my .Xdefaults file.  For my particular purpose the
>key remapping is done for the xterm that my application runs in.
>
>*xterm*translations: #override <Key>F1: string("^AOP") \n\
>                               ...
>                               <Key>Left: string("^A[D")
>
>
>Hope this helps.

Not yet; I've tried a couple of variants, such as:
*xterm*translations: #override <Key>F13: string("You touched F13") \n\
							   <Key>F14: string("You touched F14")

After adding this to .Xdefaults and saving it, I start up an xterm, in which 
I run my hd program (much like "od -xc" but vertical so it's more readable).
The result when I type an F14 and a CR at it is:

	: hd
		0:_[26~_
		0:153370
		  BB26EA
This is the old "\e[26~" that was there before; nothing whatsoever has been
changed.  What I'd expect with the above definitions is:
		0:You touc hed F13_
		0:56727676 66624330
		  9F504F53 8540613A

What am I doing wrong?  Is there something I need to do other than write
a new .Xdefaults?  Is it perhaps getting a cached version from the server
instead of reading it from $HOME/.Xdefaults?  Am I wasting my time?

Also, it'd be nice if I didn't have to edit .Xdefaults to do this.  After
all, there are likely to be different applications running inside different
windows; they may well need to different mappings.  One of our applications
wants to talk to a DOS system, and it should send the function-key codes
that the IBM keyboard sends, else the DOS programs won't recognize them.
Other applications are talking to other systems remotely, and they need to
respond to the F* keys by sending whatever the remote system expects.  

In general,it seems that a mapping like this sort of needs to be per-window.  
The XLookupString() routine seems like it should somehow be involved, but
TFM doesn't seem to say anything coherent on the subject...

aw@jello.bae.bellcore.com (Andrew Wason) (04/13/91)

In article <22036@shlump.nac.dec.com>, lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) writes:
>Not yet; I've tried a couple of variants, such as:
>*xterm*translations: #override <Key>F13: string("You touched F13") \n\
>				   <Key>F14: string("You touched F14")
>
>After adding this to .Xdefaults and saving it, I start up an xterm, in which 
> [...]
>This is the old "\e[26~" that was there before; nothing whatsoever has been
>changed.
> [...]
>What am I doing wrong?  Is there something I need to do other than write
>a new .Xdefaults?  Is it perhaps getting a cached version from the server
>instead of reading it from $HOME/.Xdefaults?  Am I wasting my time?

Are you sure your xterm is named "xterm"?  Try using XTerm*translations
(class instead of name) and see if that works.

>Also, it'd be nice if I didn't have to edit .Xdefaults to do this.  After
>all, there are likely to be different applications running inside different
>windows; they may well need to different mappings.  One of our applications
>wants to talk to a DOS system, and it should send the function-key codes
>that the IBM keyboard sends, else the DOS programs won't recognize them.
>Other applications are talking to other systems remotely, and they need to
>respond to the F* keys by sending whatever the remote system expects.  


You can run each xterm with a different name and specify resources
specific to each name.
e.g.

  xterm -name larry&
  xterm -name curly&

  larry*translations: ...
  curly*translations: ...

Even better, xterm supports dynamically defining new translation
tables.  You can set up default translations which allow you to
switch between different tables at runtime.  See the man page.

Andrew

_______________________________________________________________________________

Andrew Wason                                       Bell Communications Research
aw@bae.bellcore.com                                Piscataway, NJ
bellcore!bae!aw

bschoen@well.sf.ca.us (Brook Schoenfield) (04/16/91)

>> 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;
>
>After a fashion.  The X protocol contains support for remapping the
>keyboard in the sense of changing the mapping between physical keys
>("keycodes") and logical keys ("keysyms").  Xt, and some (most? all?)
>clients that use it, has/have support for mapping (logical) keys to
>mostly-arbitrary actions.
>

YOu don't say whether you want to programmatically change the key
bindings for this one application (i.e., by coding in the app), or
get some trickery to rebind while running this application or
if you want to change the mappings for the server.

Der Mouse is right on for the last case, and actually has the answer
for the second case (though you will need to ln a different name for
xterm and set your translations for that. Xterm can be told to run
a program on its command line, thus making a very clean entry and
exit into a non x program).

However, if its the first case: you want to code an app to rebind
keysyms: that is a bit more complicated.  There is some excellent
sample code for this in Oliver Jones' book, Programming X Windows.

Beware that you must rebind each modifier grouping that a particular
key may experience separately: for instance, if you want an unshifted
'.' to reamin that when the numlock is down, you'll have to rebind
both the unshifted case and the numlock case: this leads to alot of
rebindings when you have to change large parts of a keyboard.

-- 


Brook Schoenfield
bschoen@well.sf.ca.us

lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) (04/19/91)

Hi again.  Some days ago I wrote:
>>> 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;

My mailbox soon filled up with  a lot of messages of the form "If you learn
anything on the topic, please tell me, too."  So here's what I know now
(including quite a few further admissions of ignorance ;-)...

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 display (or
to however many displays a given server is running).  Meanwhile, the
keysym->string mapping is done inside the application (actually inside
the X library inside the application in most cases), so changes there
are on a per-window (well, actually per-instance-of-the-X-library) basis.
This is all fine, but it helps to know how it works.

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 '='?
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 ...?  What the @#$@# *is*
the syntax of this little beastie?

Meanwhile, on the keysym->string translation, several people pointed me
at the appropriate clause in the FAQ files.  In reading it, it quickly
became obvious why grep hadn't found it for me; I would have never guessed
the terminology, and I can hardly recognize the entry as an answer to my
question.  But with the hint that it was the answer, I did a whole lot
of experimenting.  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.  This also explains why
xterm is to incredibly slow when started across a SLIP link; the entire
.Xdefaults file is stuffed across the link for every xterm.  A line
monitor verifies this; you can see the data flow by.  Sigh.

But I did stumble across another hint that you can say:
	setenv XENVIRONMENT foo
and when xterm starts up, it will read foo as a resource file.  I tried
this, and guess what?  It actually works as advertised.  I created a foo
file with contents like:
	xterm*scrollBar: true
	xterm*Translations: #override \
		<Key>F1   : string("You touched F1") \n\
		...
		<Key>KP_0 : string("You touched KP_0") \n\
		...
		<Key>KP_F2: string("KP_F2\\n") \n\
		...
		<Key>Help : string("You touched Help")
and ran an xterm.  Inside that xterm, the keys generated the strings that
you see above.  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?  Where is this explained?

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.  So far,
all my attempts have failed.  I tried putting them literally into the
quoted strings; I get off-the-wall error messages from xterm and the
keys don't get redefined at all.  I tried all sorts of escape sequences
such as "\n", "\013", "#0A", , and "^J", and none of them generate the 
bits I want.  They just toss out the backslashes and produce the printable 
chars inside the quotes.

Does anyone have any idea what the incantations might be to include an
arbitrary (preferably hex or octal) 8-bit byte into these strings?  Should
I perhaps hunt down the source code for xterm and analyze it?  Should I
just toss up my hands and write my own filter that reads keysyms and writes
what I tell it?  It sure seems that the folks who wrote xterm had this 
in mind, and it'd be a real waste to do it over again, but it's starting
to look like figuring out how it works will turn out to take more time 
than it would have to write my own program...

BTW, if there are any DECcies lurking hereabouts, it'd be interesting to
hear how this might be done in a dxterm.  Most of our intended applications
involve Ultrix workstations, and since dxterm has all these bells and
whistles to configure it like just about anything, it seems that there 
just might be a way to get dxterm to do it if xterm won't.

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.  I've seen these
running on Sun and AIX systems, but we want to run them on things like
Ultrix and OSF workstations.  This is a DECstation 3100, for instance.
Is there any chance of such a DOS-window program for such systems?

This is getting to be too many issues for a single article, so...

clive@x.co.uk (Clive Feather) (05/02/91)

In article <22171@shlump.nac.dec.com> lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) writes:
> The question about defining shift-comma and shift-dot got answered by
> several people:
>	xmodmap keysym comma = comma less
>	xmodmap keysym period = period greater
> 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 '='?
> 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 ...?  What the @#$@# *is*
> the syntax of this little beastie?

On the left hand side of the equals, you are telling it to change the
key with a comma on it. This is a convenience for the user; the
"correct" way to do this is to say "keycode 123 = ...". However, it
isn't obvious what the number of the key is, and it will differ from
keyboard to keyboard. So xmodmap offers to look it up for you. Any
symbol on the key will do: on my keyboard, "keysym 4 = ..." and
"keysym dollar = ..." are equivalent.

On the right hand side, you are listing the symbols that you want to
pretend are painted on the key. The rules for this are:

  symbol 1: unshifted key            (comma/period in your example)
  symbol 2: shifted key              (less/greater in your example)
  symbol 3: grouped key              (see below)
  symbol 4: shifted and grouped key
  symbols 5 onwards: no standard interpretation

The "group" key is a modifier (like shift or control) used to select
alternate key definitions (for example, for an English/Cyrillic
keyboard, or for APL). Rather than fixing "group" to a specific key
(such as meta), it is the key which is a modifier key (use xmodmap -pm
to look at this) and which has "ModeSwitch" as one of its keysyms.

> 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.  This also explains why
> xterm is to incredibly slow when started across a SLIP link; the entire
> .Xdefaults file is stuffed across the link for every xterm.  A line
> monitor verifies this; you can see the data flow by.  Sigh.

This behaviour is caused because you are running xrdb(1) from your
start-up file. This loads a copy of .Xdefaults on the server, in such a
way that XOpenDisplay (the Xlib function) will see it and copy it into
the application data space when opening the display. Xterm then sees that
this has been done, and uses it instead of .Xdefaults. There are good
reasons for this feature which I won't go into, but if you're using
SLIP, then you want to disable it. Just remove the xrdb command from you
start-up file.

My copy of the xterm(1) manual entry (R4)does not mention .Xdefaults at
all.  Have a look at the section RESOURCES in the X(1) manual entry,
which goes into this, mentioning xrdb(1). You should read the whole
X(1) manual entry before using X.

The appres(1) program might be of use to you, as well.

>	xterm*scrollBar: true
>	xterm*Translations: #override \
>		<Key>F1   : string("You touched F1") \n\
>		...
>		<Key>KP_0 : string("You touched KP_0") \n\
>		...
>		<Key>KP_F2: string("KP_F2\\n") \n\
>		...
>		<Key>Help : string("You touched Help")
[...]
> 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?  Where is this explained?

The \n puts a newline character into the *resource* entry, which causes
the *translation* manager to see the end of one line, and the start of
the next. The final backslash escapes out the newline for the *resource*
manager, so that it doesn't see the <Key> lines as each being a new
resource definition. The # is placed before the override to indicate
that this is *not* a normal translation line: the translation table can
begin directly with (say) "<Key>" (of course, the presence or absence of
#override affects the semantics). You might just as well ask why C
requires a # before "define", or Bourne shell a $ before a variable
name.

Translation tables are explained in an appendix to the Xt Toolkit
Intrinsics manual. There probably ought to be a pointer in X(1). File a
bug report with the Consortium.

> 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.  So far,
> all my attempts have failed.  I tried putting them literally into the
> quoted strings; I get off-the-wall error messages from xterm and the
> keys don't get redefined at all.  I tried all sorts of escape sequences
> such as "\n", "\013", "#0A", , and "^J", and none of them generate the 
> bits I want.  They just toss out the backslashes and produce the printable 
> chars inside the quotes.

Try:

    <Key>Help : string("You are an")string(0x0d)string(0x0a)string(Idiot!)

You can have any number of actions (the things that look like function
calls) on the right hand side. There is an example of this in the
xterm(1) manual entry, just before the heading OTHER FEATURES.
-- 
Clive D.W. Feather     | IXI Limited         | If you lie to the compiler,
clive@x.co.uk          | 62-74 Burleigh St.  | it will get its revenge.
Phone: +44 223 462 131 | Cambridge   CB1 1OJ |   - Henry Spencer
(USA: 1 800 XDESK 57)  | United Kingdom      |

mouse@lightning.mcrcim.mcgill.EDU (der Mouse) (05/02/91)

>>> 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

lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) (05/08/91)

In article <May91.080207.6043@x.co.uk> clive@x.co.uk (Clive D.W. Feather) writes:
|In article <22171@shlump.nac.dec.com> lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) writes:
|> 		...  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.  This also explains why
|> xterm is to incredibly slow when started across a SLIP link; the entire
|> .Xdefaults file is stuffed across the link for every xterm.  A line
|> monitor verifies this; you can see the data flow by.  Sigh.
|
|This behaviour is caused because you are running xrdb(1) from your
|start-up file.

No, I'm not; grep can't find the string "rdb" in any $HOME/.* file.  It
also fails to find it in /etc/ttys (where the server is started on this
Ultrix system).  It also can't be found in any file in /usr/lib/X11 or 
any subdirectory.  If there is a call of xrdb somewhere, it is hidden
so well that I've been unable to find it.  Perhaps when I go home I'll
leave behind a find that scans every file in all the disks...

|	... This loads a copy of .Xdefaults on the server, in such a
|way that XOpenDisplay (the Xlib function) will see it and copy it into
|the application data space when opening the display. Xterm then sees that
|this has been done, and uses it instead of .Xdefaults. There are good
|reasons for this feature which I won't go into, but if you're using
|SLIP, then you want to disable it. Just remove the xrdb command from you
|start-up file.

OK, so any hints as to how to find the sucker so I can disable it?

|Try:
|
|    <Key>Help : string("You are an")string(0x0d)string(0x0a)string(Idiot!)

Actuall, I prefer:
    <Key>Help : string(0x0D)\
		string(0x0D)string(0x0A)\
		string("You are beyond help!")\
		string(0x0d)string(0x0A)\
		string(0x0d)string(0x0A)

Thanks to everyone for the examples.  We actually have some DOS applications
running quite well from inside an xterm now.  The major remaining problem is
deciphering why we sometimes get '3' instead of '|' from pcanywhere, but this
is probably not anything that xterm can help us with.

Now to write up a sensible summary...

mouse@lightning.mcrcim.mcgill.EDU (der Mouse) (05/09/91)

>> This behaviour is caused because you are running xrdb(1) from your
>> start-up file.

> No, I'm not; grep can't find the string "rdb" in any $HOME/.* file.
> [...it doesn't seem to be anywhere else, either...]

Odd.  When you're running X, what does "xrdb -query" produce?  If it
produces something, xrdb is getting run *somewhere* along the
line...and if not, your problem is much more mysterious.

					der Mouse

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

kent@Xerox.com (Chris Kent) (05/09/91)

Since you're posting from a DEC site, and since I seem to remember that netrix is an Ultrix machine, I bet you're running the DEC session manager. One of the first things that it does when it starts up is run xrdb on your .Xdefaults.

That's why you couldn't find it anywhere else.

-- 
Chris Kent		Xerox PARC CSL			Palo Alto, CA USA
kent@arisia.xerox.com	xerox!kent			+1.415.494.4821

lan_csse@netrix.nac.dec.com (CSSE LAN Test Account) (05/14/91)

In article <1991May9.005015.26856@parc.xerox.com> kent@Xerox.com (Chris Kent) writes:
> Since you're posting from a DEC site, and since I seem to remember that 
> netrix is an Ultrix machine, I bet you're running the DEC session manager. 
> One of the first things that it does when it starts up is run xrdb on your 
> .Xdefaults.

You lose; pay up! (;-)  True, netrix is an Ultrix machine, but this is an
rlogin session from another machine.  This machine is also Ultrix, but I'm
running mwm (Motif), not dxwm.  My other machine is running uwm, and I'm
having fun trying to get mwm to match the feechurz (and user-friendliness)
of uwm.  There's not a dxwm in sight (we all hate it :-).

>That's why you couldn't find it anywhere else.

So why do uwm and mwm do it?  Can I get them to stop?  Also, what I'd 
really like to do is:  We have two machines that have just set up a new
SLIP link.  Their owners started up X however they felt like, and they
likely don't even understand much about how it works.  One of them wants
to start up xterm on machine $A with the DISPLAY set to $B:0 across the
SLIP link.  How can I tell the xterm to ignore *whatever* the remote
X server tells it, and read a local resources file?  The intent is to
eliminate the huge pile of resource messages that get stuffed through
the 9600-bps pinhole, so they can perhaps start in 10-20 seconds rather
that the 1-2 minutes that it now takes.  I can easily link xterm to other 
names or embed it within a script; packaging it for users is no problem.
But what to put in the package isn't at all obvious.

More generally, we have an assortment of applications that are essentially
unusable across a slow network, because the startup time is so slow that
the users have forgotten what they were doing by the time the window pops
up.  SLIP isn't the only problem; we have some multi-gatewayed (T1) links 
that are even slower than 9600-bps SLIP, and it'd be nice if they could be 
made minimally usable.  We've sort of assumed that it was hopeless, and that 
our graphics applications (even the most trivial) are unusable across them.  
If we're wrong, we'd love to be told just exactly how wrong we are, possibly 
with some demos of our wrongheadedness...