10f66f451Sopenharmony_ci/* demo_scankey.c - collate incoming ansi escape sequences.
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2015 Rob Landley <rob@landley.net>
40f66f451Sopenharmony_ci *
50f66f451Sopenharmony_ci * TODO sigwinch
60f66f451Sopenharmony_ci
70f66f451Sopenharmony_ciUSE_DEMO_SCANKEY(NEWTOY(demo_scankey, 0, TOYFLAG_BIN))
80f66f451Sopenharmony_ci
90f66f451Sopenharmony_ciconfig DEMO_SCANKEY
100f66f451Sopenharmony_ci  bool "demo_scankey"
110f66f451Sopenharmony_ci  default n
120f66f451Sopenharmony_ci  help
130f66f451Sopenharmony_ci    usage: demo_scankey
140f66f451Sopenharmony_ci
150f66f451Sopenharmony_ci    Move a letter around the screen. Hit ESC to exit.
160f66f451Sopenharmony_ci*/
170f66f451Sopenharmony_ci
180f66f451Sopenharmony_ci#define FOR_demo_scankey
190f66f451Sopenharmony_ci#include "toys.h"
200f66f451Sopenharmony_ci
210f66f451Sopenharmony_civoid demo_scankey_main(void)
220f66f451Sopenharmony_ci{
230f66f451Sopenharmony_ci  time_t t[2];
240f66f451Sopenharmony_ci  unsigned width, height, tick;
250f66f451Sopenharmony_ci  char c = 'X', scratch[16];
260f66f451Sopenharmony_ci  int key, x, y;
270f66f451Sopenharmony_ci
280f66f451Sopenharmony_ci  t[0] = t[1] = x = tick = 0;
290f66f451Sopenharmony_ci  memset(scratch, 0, 16);
300f66f451Sopenharmony_ci  y = 1;
310f66f451Sopenharmony_ci
320f66f451Sopenharmony_ci  sigatexit(tty_sigreset);  // Make ctrl-c restore tty
330f66f451Sopenharmony_ci  tty_esc("?25l");          // hide cursor
340f66f451Sopenharmony_ci  tty_esc("0m");            // reset color to default
350f66f451Sopenharmony_ci  tty_esc("2J");            // Clear screen
360f66f451Sopenharmony_ci  xset_terminal(1, 1, 0, 0); // Raw mode
370f66f451Sopenharmony_ci
380f66f451Sopenharmony_ci  for (;;) {
390f66f451Sopenharmony_ci    tty_jump(x, y);
400f66f451Sopenharmony_ci    xputc(c);
410f66f451Sopenharmony_ci    t[1&++tick] = time(0);
420f66f451Sopenharmony_ci    if (t[0] != t[1]) terminal_probesize(&width, &height);
430f66f451Sopenharmony_ci    // Don't block first time through, to force header print
440f66f451Sopenharmony_ci    key = scan_key_getsize(scratch, -1*!!t[0], &width, &height);
450f66f451Sopenharmony_ci    tty_jump(0, 0);
460f66f451Sopenharmony_ci    printf("ESC to exit: ");
470f66f451Sopenharmony_ci    // Print unknown escape sequence
480f66f451Sopenharmony_ci    if (*scratch) {
490f66f451Sopenharmony_ci      printf("key=[ESC");
500f66f451Sopenharmony_ci      // Fetch rest of sequence after deviation, time gap determines end
510f66f451Sopenharmony_ci      while (0<(key = scan_key_getsize(scratch, 0, &width, &height)))
520f66f451Sopenharmony_ci        printf("%c", key);
530f66f451Sopenharmony_ci      printf("] ");
540f66f451Sopenharmony_ci    } else printf("key=%d ", key);
550f66f451Sopenharmony_ci    printf("x=%d y=%d width=%d height=%d\033[K", x, y, width, height);
560f66f451Sopenharmony_ci    fflush(0);
570f66f451Sopenharmony_ci
580f66f451Sopenharmony_ci    if (key == -2) continue;
590f66f451Sopenharmony_ci    if (key <= ' ') break;
600f66f451Sopenharmony_ci    if (key>=256) {
610f66f451Sopenharmony_ci      tty_jump(x, y);
620f66f451Sopenharmony_ci      xputc(' ');
630f66f451Sopenharmony_ci
640f66f451Sopenharmony_ci      key -= 256;
650f66f451Sopenharmony_ci      if (key==KEY_UP) y--;
660f66f451Sopenharmony_ci      else if (key==KEY_DOWN) y++;
670f66f451Sopenharmony_ci      else if (key==KEY_RIGHT) x++;
680f66f451Sopenharmony_ci      else if (key==KEY_LEFT) x--;
690f66f451Sopenharmony_ci      else if (key==KEY_PGUP) y = 0;
700f66f451Sopenharmony_ci      else if (key==KEY_PGDN) y = 999;
710f66f451Sopenharmony_ci      else if (key==KEY_HOME) x = 0;
720f66f451Sopenharmony_ci      else if (key==KEY_END) x = 999;
730f66f451Sopenharmony_ci      if (y<1) y = 1;
740f66f451Sopenharmony_ci      if (y>=height) y = height-1;
750f66f451Sopenharmony_ci      if (x<0) x = 0;
760f66f451Sopenharmony_ci      if (x>=width) x = width-1;
770f66f451Sopenharmony_ci    } else c = key;
780f66f451Sopenharmony_ci  }
790f66f451Sopenharmony_ci  tty_reset();
800f66f451Sopenharmony_ci}
81