Home
       term.c - iomenu - interactive terminal-based selection menu
  HTML git clone git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
   DIR LICENSE
       ---
       term.c (1806B)
       ---
            1 #include "term.h"
            2 #include <ctype.h>
            3 #include <stdint.h>
            4 #include <stdio.h>
            5 #include <string.h>
            6 #include <sys/ioctl.h>
            7 #include <termios.h>
            8 #include "compat.h"
            9 #include "utf8.h"
           10 
           11 struct term term;
           12 
           13 static int
           14 term_codepoint_width(uint32_t codepoint, int pos)
           15 {
           16         if (codepoint == '\t')
           17                 return 8 - pos % 8;
           18         return wcwidth(codepoint);
           19 }
           20 
           21 int
           22 term_at_width(char const *s, int width, int pos)
           23 {
           24         char const *beg = s;
           25 
           26         for (uint32_t state = 0, codepoint; *s != '\0'; s++) {
           27                 if (utf8_decode(&state, &codepoint, *s) == UTF8_ACCEPT) {
           28                         pos += term_codepoint_width(codepoint, pos);
           29                         if (pos > width)
           30                                 break;
           31                 }
           32         }
           33         return s - beg;
           34 }
           35 
           36 int
           37 term_raw_on(int fd)
           38 {
           39         static char *seq = "\x1b[s\x1b[?1049h\x1b[H";
           40         struct termios termios;
           41         ssize_t len = strlen(seq);
           42 
           43         if (write(fd, seq, len) < len)
           44                 return -1;
           45 
           46         memset(&termios, 0, sizeof termios);
           47         if (tcgetattr(fd, &term.termios) < 0)
           48                 return -1;
           49         memcpy(&termios, &term.termios, sizeof termios);
           50 
           51         termios.c_lflag &= ~(ICANON | ECHO | IEXTEN | IGNBRK | ISIG);
           52         if (tcsetattr(fd, TCSANOW, &termios) == -1)
           53                 return -1;
           54         return 0;
           55 }
           56 
           57 int
           58 term_raw_off(int fd)
           59 {
           60         static char *seq = "\x1b[2J\x1b[u\033[?1049l";
           61         ssize_t len = strlen(seq);
           62 
           63         if (tcsetattr(fd, TCSANOW, &term.termios) < 0)
           64                 return -1;
           65         if (write(fd, seq, len) < len)
           66                 return -1;
           67         return 0;
           68 }
           69 
           70 int
           71 term_get_key(FILE *fp)
           72 {
           73         int key, num;
           74 
           75         key = fgetc(fp);
           76 top:
           77         switch (key) {
           78         case EOF:
           79                 return -1;
           80         case TERM_KEY_ALT('['):
           81                 key = getc(fp);
           82                 if (key == EOF)
           83                         return -1;
           84 
           85                 for (num = 0; isdigit(key);) {
           86                         num *= 10;
           87                         num += key - '0';
           88 
           89                         key = fgetc(fp);
           90                         if (key == EOF)
           91                                 return -1;
           92                 }
           93 
           94                 key = TERM_KEY_CSI(key, num);
           95 
           96                 goto top;
           97         case TERM_KEY_ESC:
           98                 key = getc(fp);
           99                 if (key == EOF)
          100                         return -1;
          101                 key = TERM_KEY_ALT(key);
          102                 goto top;
          103         default:
          104                 return key;
          105         }
          106 }