xref: /netbsd-src/external/bsd/less/dist/lesstest/term.c (revision e4a6e799a67c2028562d75b4e61407b22434aa36)
1*e4a6e799Ssimonb #include <string.h>
2*e4a6e799Ssimonb #include <fcntl.h>
3*e4a6e799Ssimonb #include <termios.h>
4*e4a6e799Ssimonb #include <termcap.h>
5*e4a6e799Ssimonb #include <sys/ioctl.h>
6*e4a6e799Ssimonb #include "lesstest.h"
7*e4a6e799Ssimonb 
8*e4a6e799Ssimonb TermInfo terminfo;
9*e4a6e799Ssimonb 
set_termio_flags(struct termios * s)10*e4a6e799Ssimonb static void set_termio_flags(struct termios* s) {
11*e4a6e799Ssimonb 	s->c_lflag &= ~(0
12*e4a6e799Ssimonb #ifdef ICANON
13*e4a6e799Ssimonb 		| ICANON
14*e4a6e799Ssimonb #endif
15*e4a6e799Ssimonb #ifdef ECHO
16*e4a6e799Ssimonb 		| ECHO
17*e4a6e799Ssimonb #endif
18*e4a6e799Ssimonb #ifdef ECHOE
19*e4a6e799Ssimonb 		| ECHOE
20*e4a6e799Ssimonb #endif
21*e4a6e799Ssimonb #ifdef ECHOK
22*e4a6e799Ssimonb 		| ECHOK
23*e4a6e799Ssimonb #endif
24*e4a6e799Ssimonb #if ECHONL
25*e4a6e799Ssimonb 		| ECHONL
26*e4a6e799Ssimonb #endif
27*e4a6e799Ssimonb 	);
28*e4a6e799Ssimonb 
29*e4a6e799Ssimonb 	s->c_oflag |= (0
30*e4a6e799Ssimonb #ifdef OXTABS
31*e4a6e799Ssimonb 		| OXTABS
32*e4a6e799Ssimonb #else
33*e4a6e799Ssimonb #ifdef TAB3
34*e4a6e799Ssimonb 		| TAB3
35*e4a6e799Ssimonb #else
36*e4a6e799Ssimonb #ifdef XTABS
37*e4a6e799Ssimonb 		| XTABS
38*e4a6e799Ssimonb #endif
39*e4a6e799Ssimonb #endif
40*e4a6e799Ssimonb #endif
41*e4a6e799Ssimonb #ifdef OPOST
42*e4a6e799Ssimonb 		| OPOST
43*e4a6e799Ssimonb #endif
44*e4a6e799Ssimonb #ifdef ONLCR
45*e4a6e799Ssimonb 		| ONLCR
46*e4a6e799Ssimonb #endif
47*e4a6e799Ssimonb 	);
48*e4a6e799Ssimonb 
49*e4a6e799Ssimonb 	s->c_oflag &= ~(0
50*e4a6e799Ssimonb #ifdef ONOEOT
51*e4a6e799Ssimonb 		| ONOEOT
52*e4a6e799Ssimonb #endif
53*e4a6e799Ssimonb #ifdef OCRNL
54*e4a6e799Ssimonb 		| OCRNL
55*e4a6e799Ssimonb #endif
56*e4a6e799Ssimonb #ifdef ONOCR
57*e4a6e799Ssimonb 		| ONOCR
58*e4a6e799Ssimonb #endif
59*e4a6e799Ssimonb #ifdef ONLRET
60*e4a6e799Ssimonb 		| ONLRET
61*e4a6e799Ssimonb #endif
62*e4a6e799Ssimonb 	);
63*e4a6e799Ssimonb }
64*e4a6e799Ssimonb 
65*e4a6e799Ssimonb // Enable or disable raw mode on the given tty.
raw_mode(int tty,int on)66*e4a6e799Ssimonb void raw_mode(int tty, int on) {
67*e4a6e799Ssimonb 	struct termios s;
68*e4a6e799Ssimonb 	static struct termios save_term;
69*e4a6e799Ssimonb 	if (!on) {
70*e4a6e799Ssimonb 		s = save_term;
71*e4a6e799Ssimonb 	} else {
72*e4a6e799Ssimonb 		tcgetattr(tty, &s);
73*e4a6e799Ssimonb 		save_term = s;
74*e4a6e799Ssimonb 		set_termio_flags(&s);
75*e4a6e799Ssimonb 		s.c_cc[VMIN] = 1;
76*e4a6e799Ssimonb 		s.c_cc[VTIME] = 0;
77*e4a6e799Ssimonb 	}
78*e4a6e799Ssimonb 	tcsetattr(tty, TCSADRAIN, &s);
79*e4a6e799Ssimonb }
80*e4a6e799Ssimonb 
81*e4a6e799Ssimonb // Initialize the enter & exit capabilities for a given terminal mode.
setup_mode(char * enter_cap,char * exit_cap,char ** enter_str,char ** exit_str,char ** spp)82*e4a6e799Ssimonb static void setup_mode(char* enter_cap, char* exit_cap, char** enter_str, char** exit_str, char** spp) {
83*e4a6e799Ssimonb 	*enter_str = tgetstr(enter_cap, spp);
84*e4a6e799Ssimonb 	if (*enter_str == NULL) *enter_str = "";
85*e4a6e799Ssimonb 	*exit_str = tgetstr(exit_cap, spp);
86*e4a6e799Ssimonb 	if (*exit_str == NULL) *exit_str = tgetstr("me", spp);
87*e4a6e799Ssimonb 	if (*exit_str == NULL) *exit_str = "";
88*e4a6e799Ssimonb }
89*e4a6e799Ssimonb 
ltgetstr(char * id,char ** area)90*e4a6e799Ssimonb static char* ltgetstr(char* id, char** area) {
91*e4a6e799Ssimonb 	char* str = tgetstr(id, area);
92*e4a6e799Ssimonb 	if (str == NULL) str = "";
93*e4a6e799Ssimonb 	return str;
94*e4a6e799Ssimonb }
95*e4a6e799Ssimonb 
96*e4a6e799Ssimonb // Initialize the terminfo struct with info about the terminal $TERM.
setup_term(void)97*e4a6e799Ssimonb int setup_term(void) {
98*e4a6e799Ssimonb 	static char termbuf[4096];
99*e4a6e799Ssimonb 	static char sbuf[4096];
100*e4a6e799Ssimonb 	char* term = getenv("TERM");
101*e4a6e799Ssimonb 	if (term == NULL) term = "dumb";
102*e4a6e799Ssimonb 	if (tgetent(termbuf, term) <= 0) {
103*e4a6e799Ssimonb 		fprintf(stderr, "cannot setup terminal %s\n", term);
104*e4a6e799Ssimonb 		return 0;
105*e4a6e799Ssimonb 	}
106*e4a6e799Ssimonb 	char* sp = sbuf;
107*e4a6e799Ssimonb 	setup_mode("so", "se", &terminfo.enter_standout, &terminfo.exit_standout, &sp);
108*e4a6e799Ssimonb 	setup_mode("us", "ue", &terminfo.enter_underline, &terminfo.exit_underline, &sp);
109*e4a6e799Ssimonb 	setup_mode("md", "me", &terminfo.enter_bold, &terminfo.exit_bold, &sp);
110*e4a6e799Ssimonb 	setup_mode("mb", "me", &terminfo.enter_blink, &terminfo.exit_blink, &sp);
111*e4a6e799Ssimonb 
112*e4a6e799Ssimonb 	char* bs = ltgetstr("kb", &sp);
113*e4a6e799Ssimonb 	terminfo.backspace_key = (strlen(bs) == 1) ? *bs : '\b';
114*e4a6e799Ssimonb 	terminfo.cursor_move = ltgetstr("cm", &sp);
115*e4a6e799Ssimonb 	terminfo.clear_screen = ltgetstr("cl", &sp);
116*e4a6e799Ssimonb 	terminfo.init_term = ltgetstr("ti", &sp);
117*e4a6e799Ssimonb 	terminfo.deinit_term = ltgetstr("te", &sp);
118*e4a6e799Ssimonb 	terminfo.enter_keypad = ltgetstr("ks", &sp);
119*e4a6e799Ssimonb 	terminfo.exit_keypad = ltgetstr("ke", &sp);
120*e4a6e799Ssimonb 	terminfo.key_right = ltgetstr("kr", &sp);
121*e4a6e799Ssimonb 	terminfo.key_left = ltgetstr("kl", &sp);
122*e4a6e799Ssimonb 	terminfo.key_up = ltgetstr("ku", &sp);
123*e4a6e799Ssimonb 	terminfo.key_down = ltgetstr("kd", &sp);
124*e4a6e799Ssimonb 	terminfo.key_home = ltgetstr("kh", &sp);
125*e4a6e799Ssimonb 	terminfo.key_end = ltgetstr("@7", &sp);
126*e4a6e799Ssimonb 	return 1;
127*e4a6e799Ssimonb }
128