[Toybox] [PATCH] scan_key: support more terminals.

Rob Landley rob at landley.net
Sat Mar 23 16:11:39 PDT 2019


On 3/23/19 2:44 PM, enh via Toybox wrote:
> Although we can get away with ignoring termcap/terminfo on the output
> side by restricting ourselves to generally-supported escape sequences,

There's documentation on this, by the way:

http://man7.org/linux/man-pages/man4/console_codes.4.html

I have a note on my todo list to look at this one especially:

      ESC [ ? 1 h
              DECCKM (default off): When set, the cursor keys send an ESC O
              prefix, rather than ESC [.

  $ echo -e '\e[?1h'
  $ sleep 10
  ^[OA^[OA^[OA^C

I probably want to add '\e[?1l' to my setup code...

> the input side is trickier because we need to support the sequences sent
> by common terminals. Luckily, this isn't is as bad as it sounds because
> only Home/End commonly differ. But it does mean we need a slightly
> different implementation to deal with the many-to-one mapping.

What _were_ the other sequences for home/end? Looks like it was just \eO instead
of \e[ prefixes?

> Since we can't use TAGGED_ARRAY for this (without inflicting pain on all
> the callers)

Or adding a redirect field that says "this is actually this other one".

Long ago I pondered a "list of strings that can generate this key" but the hard
part is that the numeric semicolon syntax is arbitrarily extensible (just like
with color changes the other way, ala ls.c:

    if (flags & FLAG_color) {
      color = color_from_mode(st->st_mode);
      if (color) printf("\033[%d;%dm", color>>8, color&255);
    }

Most _mostly_ it's just pairs that seem to be reported? (But not always. I think
I blogged about this years and years ago, back when I was working out how to fix

  http://lists.busybox.net/pipermail/busybox/2008-October/067397.html

And the FUN part is that function keys are reporting... inconsistent weirdness.
Shift F1 in the terminal is \e[25~ and shift F2 is 26, but then it goes 28 29 31
32 33 34 (skipping 27 and 30 but _not_ 33), and then refuses to report shift F9
or higher at all. (Wheee!)

Oh, and here's the ctrl-shift function key sequence in an xfce terminal, F1
through F12:

^[O1;6P^[O1;6Q^[O1;6R^[O1;6S^[[15;6~^[[17;6~^[[18;6~^[[19;6~^[[20;6~^[[23;6~^[[24;6~

(It decided that ctrl-shift-F10 should pop up a menu so I didn't get that one,
but that's plenty crazy right there. First 4 start with the non-current escape
sequence, which at least lets me distinguish the R response from a cursor probe
response. Then it's more like the Linux text mode one except I don't get
_anything_ for ctrl-shift-function keys in there...)

> I've also switched to OR-ing in the modifier keys, so we
> have (say) KEY_UP|KEY_SHIFT rather than a separate KEY_SUP. This also
> generalizes better should we ever need to support multiple modifiers at
> once.

I've pondered doing something like that and waited for a user to show up. :)

Especially since such a user might be able to do a "survey of available inputs",
although now that terminal programs are less of a thing that's probably mostly
"ssh from mac, bsd, and putty". (In theory the various terminal window programs
for gnome/kde/xfce are also a varying source of inputs, but they all seem to
_mostly_ copy linux text mode?)

The real problem is to _get_ a survey of all the keys I have to boot into an
xterm with no window manager, because otherwise half of the key chords are
intercepted. (Did you know that ctrl-alt-cursor key switches desktops in the
desktop switcher?) Which means I have to install a bunch of terminal programs,
rip them out of their desktop context and boot them directly under /usr/bin/X,
try all the keys and record the results, and hopefully work out patterns.

And yes I asked Rich Felker, who wrote a terminal program of his own long ago
(http://git.musl-libc.org/cgit/uuterm/) if he had useful resources, and he
didn't. :(

There's a lot of complexity in this that the current parser is unaware of, and I
would love to improve it it, but I'd probaby want to _start_ with not having
esc[ repeated at the start of most sequences that could _also_ produce escO
under the right circumstances. (Except above, collision between function key and
position report, it _is_ meaninful in some circumstances! Grrr...)

> To reduce the number of #defines, I've also switched from KEY_F1,
> KEY_F2, and so on to KEY_FN+1, KEY_FN+2, and so on. This isn't obviously
> necessary, and easily undone if we'd rather have move #defines in return
> for slightly more natural naming.

I'd like to work out what the design should _be_. And it's stayed on the todo
list this long because that's nontrivial.

> To enable all this, I've inverted scan_key and scan_key_getsize so that
> scan_key_getsize is now the underlying function, and we don't waste all
> the top bits encoding width and height between scan_key and
> scan_key_getsize.

As long as we don't _send_ the probe when we don't mean to, life is good.

> Tested by pressing Home and End in hexedit in all of the terminals
> available to me.

For regression testing, can I get a list of what those terminals _are_?

Rob



More information about the Toybox mailing list