3c45eb28521765a65c238ff77a4d3a8cd0485731
[mmh] / uip / termsbr.c
1 /*
2 ** termsbr.c -- termcap support
3 **
4 ** This code is Copyright (c) 2002, by the authors of nmh.  See the
5 ** COPYRIGHT file in the root directory of the nmh distribution for
6 ** complete copyright information.
7 */
8
9 #include <h/mh.h>
10
11 #ifdef HAVE_TERMIOS_H
12 # include <termios.h>
13 #else
14 # ifdef HAVE_TERMIO_H
15 #  include <termio.h>
16 # else
17 #  include <sgtty.h>
18 # endif
19 #endif
20
21 #ifdef HAVE_TERMCAP_H
22 # include <termcap.h>
23 #endif
24
25 /* <sys/ioctl.h> is need anyway for ioctl()
26 #ifdef GWINSZ_IN_SYS_IOCTL
27 */
28 # include <sys/ioctl.h>
29 /*
30 #endif
31 */
32
33 #ifdef WINSIZE_IN_PTEM
34 # include <sys/stream.h>
35 # include <sys/ptem.h>
36 #endif
37
38 #if BUFSIZ<2048
39 # define TXTSIZ 2048
40 #else
41 # define TXTSIZ BUFSIZ
42 #endif
43
44 /*
45 ** These variables are sometimes defined in,
46 ** and needed by the termcap library.
47 */
48 #ifdef HAVE_OSPEED
49 # ifdef MUST_DEFINE_OSPEED
50 extern short ospeed;
51 extern char PC;
52 # endif
53 #else
54 short ospeed;
55 char PC;
56 #endif
57
58 static long speedcode;
59
60 static int initLI = 0;
61 static int initCO = 0;
62
63 static int HC = 0;       /* are we on a hardcopy terminal? */
64 static int LI = 40;      /* number of lines */
65 static int CO = 80;      /* number of colums */
66 static char *CL = NULL;  /* termcap string to clear screen */
67 static char *SE = NULL;  /* termcap string to end standout mode   */
68 static char *SO = NULL;  /* termcap string to begin standout mode */
69
70 static char termcap[TXTSIZ];
71
72
73 static void
74 read_termcap(void)
75 {
76         char *bp, *cp;
77         char *term;
78
79 #ifndef TGETENT_ACCEPTS_NULL
80         char termbuf[TXTSIZ];
81 #endif
82
83 #ifdef HAVE_TERMIOS_H
84         struct termios tio;
85 #else
86 # ifdef HAVE_TERMIO_H
87         struct termio tio;
88 # else
89         struct sgttyb tio;
90 # endif
91 #endif
92
93         static int inited = 0;
94
95         if (inited++)
96                 return;
97
98         if (!(term = getenv("TERM")))
99                 return;
100
101 /*
102 ** If possible, we let tgetent allocate its own termcap buffer
103 */
104 #ifdef TGETENT_ACCEPTS_NULL
105         if (tgetent(NULL, term) != TGETENT_SUCCESS)
106                 return;
107 #else
108         if (tgetent(termbuf, term) != TGETENT_SUCCESS)
109                 return;
110 #endif
111
112 #ifdef HAVE_TERMIOS_H
113         speedcode = cfgetospeed(&tio);
114 #else
115 # ifdef HAVE_TERMIO_H
116         speedcode = ioctl(fileno(stdout), TCGETA, &tio) != NOTOK ?
117                         tio.c_cflag & CBAUD : 0;
118 # else
119         speedcode = ioctl(fileno(stdout), TIOCGETP, (char *) &tio) != NOTOK ?
120                         tio.sg_ospeed : 0;
121 # endif
122 #endif
123
124         HC = tgetflag("hc");
125
126         if (!initCO && (CO = tgetnum("co")) <= 0)
127                 CO = 80;
128         if (!initLI && (LI = tgetnum("li")) <= 0)
129                 LI = 24;
130
131         cp = termcap;
132         CL = tgetstr("cl", &cp);
133         if ((bp = tgetstr("pc", &cp)))
134                 PC = *bp;
135         if (tgetnum("sg") <= 0) {
136                 SE = tgetstr("se", &cp);
137                 SO = tgetstr("so", &cp);
138         }
139 }
140
141
142 int
143 sc_width(void)
144 {
145 #ifdef TIOCGWINSZ
146         struct winsize win;
147         int width;
148
149         if (ioctl(fileno(stderr), TIOCGWINSZ, &win) != NOTOK
150                         && (width = win.ws_col) > 0) {
151                 CO = width;
152                 initCO++;
153         } else
154 #endif /* TIOCGWINSZ */
155                 read_termcap();
156
157         return CO;
158 }
159
160
161 int
162 sc_length(void)
163 {
164 #ifdef TIOCGWINSZ
165         struct winsize win;
166
167         if (ioctl(fileno(stderr), TIOCGWINSZ, &win) != NOTOK
168                         && (LI = win.ws_row) > 0)
169                 initLI++;
170         else
171 #endif /* TIOCGWINSZ */
172                 read_termcap();
173
174         return LI;
175 }
176
177
178 void
179 clear_screen(void)
180 {
181         read_termcap();
182
183         if (CL && speedcode)
184                 tputs(CL, LI, putchar);
185         else {
186                 printf("\f");
187                 if (speedcode)
188                         printf("\200");
189         }
190
191         fflush(stdout);
192 }
193
194
195 /*
196 ** print in standout mode
197 */
198 int
199 SOprintf(char *fmt, ...)
200 {
201         va_list ap;
202
203         read_termcap();
204         if (!(SO && SE))
205                 return NOTOK;
206
207         tputs(SO, 1, putchar);
208
209         va_start(ap, fmt);
210         vprintf(fmt, ap);
211         va_end(ap);
212
213         tputs(SE, 1, putchar);
214
215         return OK;
216 }
217
218 /*
219 ** Is this a hardcopy terminal?
220 */
221
222 int
223 sc_hardcopy(void)
224 {
225         read_termcap();
226         return HC;
227 }