I fail to understand your reasonment.
The notation Ctrl-@, Ctrl-[ etc. and also the ^@, ^[ representations,
are just convenient shorthands based on the ASCII chart map; there are
no reasons to have them linked to the US keyboard layout (which predates
ASCII by about one century).
For example, the same layout is used with EBCDIC machines; and on each
layout, being ASCII or EBCDIC, the character Ctrl-[ is got by pressing a
unshifted key (labelled Esc) which is far away from the actual [{ key.
> My guess is that mined was designed in a country using a keymap
> where @ is a normal key, rather than a Shifted key.
That is true, but I hear that computer people in Nederland prefer the US
layout to the official Dutch, because of the easier access to ] { }.
As a matter of fact, MINIX does not include the keymap for that keyboard
and the usage(8) man page explains that patches for this are not welcome
(seek for Dutch), although it might reflect Kees' personal opinion.
In fact, I am not even sure that keyboard layout was available (in
hardware, ie the key engravings) for the original PC with 83-key layout
which with Minix and mined was designed.
> That's why asking me to type Ctrl-@ is weird for me in the first
> place, I can only type Ctrl-Shift-2.
As I said, you should try Ctrl-2, without hitting the Shift key.
> I guess I would suggest to use Ctrl-[ for MA (MArk beginning of a
> block) rather than Ctrl-@.
I am not sure it would work (but I did not test either): ESC (the
character behind the Ctrl-[ combination) is used by the tty driver as
prefix for all the "extended keys" (including the function and the
movement keys), as stated in the ANSI X.40 standard and the traditional
terminal protocol used with *nix.
> Ctrl-[ seems to be mapped to the function I (Ignore this keystroke),
I read it mapped to ESC. What is mapped to I is the combination Ctrl-\,
which have two disadvantages:
* some non-US keyboard layout maps do not have the combination enabled
(but this is easy enough to solve);
* Ctrl-\ is traditionally associated on *nix to sending the QUIT signal
to the foreground task (see the tty(4) man page.)
Antoine
So here, we got the code for the key, and it would be NUL, right?
> escape = esc; /* Key is escaped? (true if added since the XT) */
> esc = 0;
>
> switch (ch) {
...snipping irrelevant cases...
> default: /* A normal key */
> if(!make)
> return -1;
> if(ch)
> return ch;
> {
> static char seen[2][NR_SCAN_CODES];
> int notseen = 0, ei;
> ei = escape ? 1 : 0;
/*there*/
> if(scode >= 0 && scode < NR_SCAN_CODES) {
> notseen = !seen[ei][scode];
> seen[ei][scode] = 1;
> } else {
> printf("tty: scode %d makes no sense\n", scode);
> }
> if(notseen) {
> printf("tty: ignoring unrecognized %s "
> "scancode 0x%x\n",
> escape ? "escaped" : "straight", scode);
> }
> }
> return -1;
> }
The problem is in that small snippet: as you see, when ch is 0, there
are no difference between "ignore this key" (which returns -1, at the
bottom) and "this generates NUL" (which ought to return 0), so the
latter case is dropped on the floor. :-(
The fix is up to you. Personnally, I went the hacky way, hardcoding the
mapping scancode 3 to NUL, inserting at /*there*/ something like
if( scode == 3 )
return '\0'; /* Ctrl+2 returns NUL */
else
(in my code, 3 is replaced by NUL_SCAN which I #defined around line 65,
but the idea is the same.)
> /* Key release, or a shift type key. */
> return(-1);
> }
> ----------------
>
> And I guess this is the realed keymap info from /trunk/src/drivers/tty/
> keymaps/us-std.src:
Yes, this is correct.
> /* 03 - '2' */ '2', '@', A('2'), A('2'), A('@'), C('@'),
>
> Well, many other keys have C('@'):
... but there, it rather means "ignore that key".
And yes, this is probably a bad design which tries to shoehorse all the
char value AND the error condition inside a char object, something which
is know to _always_ leave some orphaned character code... just that NUL
is a rather bad choice IMHO.
Now we are not constrained by the 640KB of the original PC, perhaps it
might be time to revise this? And while at it, perhaps using Unicode to
encode the characters, this would permit to undo the current link
between the keyboard mapping and the on-screen characters, at the cost
of some reverse mapping later in the stack, in map_key or make_break
At least, .keymap do have a magic number, so we can upgrade into a new
version without breaking everything...
> Well, I am not sure I understand why it did not entered the:
> switch (ch) {
> case CTRL: /* Left or right control key */
This is how works the IBM PC: it sends an interrupt at each key press,
known as 'make event'; and also at each key release ('break event');
when you hit Ctrl-2, you actually send four events (unordered):
* make for CTRL (code 0x28 or 0x36)
* make for 2 (code 3)
* break for 2 (code 0x83)
* break for CTRL (code 0xA8 or 0xB6, matching the first one)
The only event which is eventually delivered to the client is the
second, the others are swallowed by the make_break() function.
Hope it is clearer for you now.
Antoine