diff options
author | Rob Landley <rob@landley.net> | 2016-01-07 14:34:47 -0600 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2016-01-07 14:34:47 -0600 |
commit | efb309d4cdb2f4c3926b0550d9dc1661c1e4a091 (patch) | |
tree | aee8bfabdaf7ecf20d0ad54f97df9f3bb1ca840e /lib | |
parent | d3a435e53c94ec25b4ae5fa2614f49ef8884e08a (diff) | |
download | toybox-efb309d4cdb2f4c3926b0550d9dc1661c1e4a091.tar.gz |
Make scan_key() specify timeout in miliseconds, split out terminal_probesize(),
add function key definitions and shift/ctrl/alt cursor keys.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/interestingtimes.c | 56 | ||||
-rw-r--r-- | lib/lib.h | 5 |
2 files changed, 34 insertions, 27 deletions
diff --git a/lib/interestingtimes.c b/lib/interestingtimes.c index 612d9d6e..70fd4f9b 100644 --- a/lib/interestingtimes.c +++ b/lib/interestingtimes.c @@ -46,31 +46,28 @@ int terminal_size(unsigned *xx, unsigned *yy) return x || y; } -// Wrapper that parses results from ANSI probe. If block|2 query size and -// send ANSI probe if we can't. (Probe queries xterm size through -// serial connection, when local TTY doesn't know and only remote end knows.) -// Otherwise acts like scan_key() -int scan_key_getsize(char *scratch, int block, unsigned *xx, unsigned *yy) +// Query terminal size, sending ANSI probe if necesary. (Probe queries xterm +// size through serial connection, when local TTY doesn't know but remote does.) +// Returns 0 if ANSI probe sent, 1 if size determined from tty or environment + +int terminal_probesize(unsigned *xx, unsigned *yy) { - int key; + if (terminal_size(xx, yy) && (!xx || *xx) && (!yy || *yy)) return 1; - if (block&2) { - struct pollfd pfd; + // Send probe: bookmark cursor position, jump to bottom right, + // query position, return cursor to bookmarked position. + xprintf("\e[s\e[999C\e[999B\e[6n\e[u"); - if (terminal_size(xx, yy)) { - if (!(block&1)) return -2; - } else { - // Send probe: bookmark cursor position, jump to bottom right, - // query position, return cursor to bookmarked position. - xprintf("\e[s\e[999C\e[999B\e[6n\e[u"); + return 0; +} - // Wait up to a quarter second for a result - memset(&pfd, 0, sizeof(struct pollfd)); - pfd.events = POLLIN; - xpoll(&pfd, 0, 250); - } - } - while (512&(key = scan_key(scratch, block&1))) { +// Wrapper that parses results from ANSI probe to update screensize. +// Otherwise acts like scan_key() +int scan_key_getsize(char *scratch, int miliwait, unsigned *xx, unsigned *yy) +{ + int key; + + while (512&(key = scan_key(scratch, miliwait))) { if (key<0) break; if (xx) *xx = (key>>10)&1023; if (yy) *yy = (key>>20)&1023; @@ -120,20 +117,27 @@ struct scan_key_list { {"UP", "\033[A"}, {"DOWN", "\033[B"}, {"RIGHT", "\033[C"}, {"LEFT", "\033[D"}, {"PGUP", "\033[5~"}, {"PGDN", "\033[6~"}, {"HOME", "\033OH"}, {"END", "\033OF"}, {"INSERT", "\033[2~"}, + + {"F1", "\033OP"}, {"F2", "\033OQ"}, {"F3", "\033OR"}, {"F4", "\033OS"}, + {"F5", "\033[15~"}, {"F6", "\033[17~"}, {"F7", "\033[18~"}, + {"F8", "\033[19~"}, {"F9", "\033[20~"}, + {"SUP", "\033[1;2A"}, {"AUP", "\033[1;3A"}, {"CUP", "\033[1;5A"}, {"SDOWN", "\033[1;2B"}, {"ADOWN", "\033[1;3B"}, {"CDOWN", "\033[1;5B"}, {"SRIGHT", "\033[1;2C"}, {"ARIGHT", "\033[1;3C"}, {"CRIGHT", "\033[1;5C"}, - {"SLEFT", "\033[1;2D"}, {"ALEFT", "\033[1;3D"}, {"CLEFT", "\033[1;5D"} + {"SLEFT", "\033[1;2D"}, {"ALEFT", "\033[1;3D"}, {"CLEFT", "\033[1;5D"}, + {"SF1", "\033O1;2P"}, {"AF1", "\033O1;3P"}, {"CF1", "\033[1;5P"} ); // Scan stdin for a keypress, parsing known escape sequences +// Blocks for miliwait miliseconds, none 0, forever if -1 // Returns: 0-255=literal, -1=EOF, -2=NONE, 256-...=index into scan_key_list // >512 is x<<9+y<<21 // scratch space is necessary because last char of !seq could start new seq // Zero out first byte of scratch before first call to scan_key // block=0 allows fetching multiple characters before updating display -int scan_key(char *scratch, int block) +int scan_key(char *scratch, int miliwait) { struct pollfd pfd; int maybe, i, j; @@ -151,7 +155,8 @@ int scan_key(char *scratch, int block) // Check for return from terminal size probe memset(pos, 0, 6*sizeof(int)); - sscanf(scratch+1, "\033%n[%n%3u%n,%n%3u%nR%n", pos, pos+1, &y, + scratch[(1+*scratch)&15] = 0; + sscanf(scratch+1, "\033%n[%n%3u%n;%n%3u%nR%n", pos, pos+1, &y, pos+2, pos+3, &x, pos+4, pos+5); if (pos[5]) { // Recognized X/Y position, consume and return @@ -180,7 +185,8 @@ int scan_key(char *scratch, int block) // Need more data to decide // 30 miliseconds is about the gap between characters at 300 baud - if (maybe || !block) if (!xpoll(&pfd, 1, 30*maybe)) break; + if (maybe || miliwait != -1) + if (!xpoll(&pfd, 1, maybe ? 30 : miliwait)) break; // Read 1 byte so we don't overshoot sequence match. (We can deviate // and fail to match, but match consumes entire buffer.) @@ -221,9 +221,10 @@ int draw_rstr(char *start, int width, int (*escout)(FILE *out, wchar_t wc)); // interestingtimes.c int xgettty(void); int terminal_size(unsigned *xx, unsigned *yy); -int scan_key_getsize(char *scratch, int block, unsigned *xx, unsigned *yy); +int terminal_probesize(unsigned *xx, unsigned *yy); +int scan_key_getsize(char *scratch, int miliwait, unsigned *xx, unsigned *yy); int set_terminal(int fd, int raw, struct termios *old); -int scan_key(char *scratch, int block); +int scan_key(char *scratch, int miliwait); void tty_esc(char *s); void tty_jump(int x, int y); void tty_reset(void); |