diff options
Diffstat (limited to 'lesstest/term.c')
-rw-r--r-- | lesstest/term.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/lesstest/term.c b/lesstest/term.c new file mode 100644 index 000000000000..1e2e5a3ab64b --- /dev/null +++ b/lesstest/term.c @@ -0,0 +1,127 @@ +#include <string.h> +#include <fcntl.h> +#include <termios.h> +#include <termcap.h> +#include <sys/ioctl.h> +#include "lesstest.h" + +TermInfo terminfo; + +static void set_termio_flags(struct termios* s) { + s->c_lflag &= ~(0 +#ifdef ICANON + | ICANON +#endif +#ifdef ECHO + | ECHO +#endif +#ifdef ECHOE + | ECHOE +#endif +#ifdef ECHOK + | ECHOK +#endif +#if ECHONL + | ECHONL +#endif + ); + + s->c_oflag |= (0 +#ifdef OXTABS + | OXTABS +#else +#ifdef TAB3 + | TAB3 +#else +#ifdef XTABS + | XTABS +#endif +#endif +#endif +#ifdef OPOST + | OPOST +#endif +#ifdef ONLCR + | ONLCR +#endif + ); + + s->c_oflag &= ~(0 +#ifdef ONOEOT + | ONOEOT +#endif +#ifdef OCRNL + | OCRNL +#endif +#ifdef ONOCR + | ONOCR +#endif +#ifdef ONLRET + | ONLRET +#endif + ); +} + +// Enable or disable raw mode on the given tty. +void raw_mode(int tty, int on) { + struct termios s; + static struct termios save_term; + if (!on) { + s = save_term; + } else { + tcgetattr(tty, &s); + save_term = s; + set_termio_flags(&s); + s.c_cc[VMIN] = 1; + s.c_cc[VTIME] = 0; + } + tcsetattr(tty, TCSADRAIN, &s); +} + +// Initialize the enter & exit capabilities for a given terminal mode. +static void setup_mode(char* enter_cap, char* exit_cap, char** enter_str, char** exit_str, char** spp) { + *enter_str = tgetstr(enter_cap, spp); + if (*enter_str == NULL) *enter_str = ""; + *exit_str = tgetstr(exit_cap, spp); + if (*exit_str == NULL) *exit_str = tgetstr("me", spp); + if (*exit_str == NULL) *exit_str = ""; +} + +static char* ltgetstr(char* id, char** area) { + char* str = tgetstr(id, area); + if (str == NULL) str = ""; + return str; +} + +// Initialize the terminfo struct with info about the terminal $TERM. +int setup_term(void) { + static char termbuf[4096]; + static char sbuf[4096]; + char* term = getenv("TERM"); + if (term == NULL) term = "dumb"; + if (tgetent(termbuf, term) <= 0) { + fprintf(stderr, "cannot setup terminal %s\n", term); + return 0; + } + char* sp = sbuf; + setup_mode("so", "se", &terminfo.enter_standout, &terminfo.exit_standout, &sp); + setup_mode("us", "ue", &terminfo.enter_underline, &terminfo.exit_underline, &sp); + setup_mode("md", "me", &terminfo.enter_bold, &terminfo.exit_bold, &sp); + setup_mode("mb", "me", &terminfo.enter_blink, &terminfo.exit_blink, &sp); + + char* bs = ltgetstr("kb", &sp); + terminfo.backspace_key = (strlen(bs) == 1) ? *bs : '\b'; + terminfo.cursor_move = ltgetstr("cm", &sp); + terminfo.clear_screen = ltgetstr("cl", &sp); + terminfo.init_term = ltgetstr("ti", &sp); + terminfo.deinit_term = ltgetstr("te", &sp); + terminfo.enter_keypad = ltgetstr("ks", &sp); + terminfo.exit_keypad = ltgetstr("ke", &sp); + terminfo.key_right = ltgetstr("kr", &sp); + terminfo.key_left = ltgetstr("kl", &sp); + terminfo.key_up = ltgetstr("ku", &sp); + terminfo.key_down = ltgetstr("kd", &sp); + terminfo.key_home = ltgetstr("kh", &sp); + terminfo.key_end = ltgetstr("@7", &sp); + return 1; +} |