e7ba35ae2a3f0bc8cde31e7e64c87d9cb3c38d30
[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 LI = 40;      /* number of lines */
64 static int CO = 80;      /* number of colums */
65 static char *CL = NULL;  /* termcap string to clear screen */
66 static char *SE = NULL;  /* termcap string to end standout mode   */
67 static char *SO = NULL;  /* termcap string to begin standout mode */
68
69 static char termcap[TXTSIZ];
70
71
72 static void
73 read_termcap(void)
74 {
75         char *bp, *cp;
76         char *term;
77
78 #ifndef TGETENT_ACCEPTS_NULL
79         char termbuf[TXTSIZ];
80 #endif
81
82 #ifdef HAVE_TERMIOS_H
83         struct termios tio;
84 #else
85 # ifdef HAVE_TERMIO_H
86         struct termio tio;
87 # else
88         struct sgttyb tio;
89 # endif
90 #endif
91
92         static int inited = 0;
93
94         if (inited++)
95                 return;
96
97         if (!(term = getenv("TERM")))
98                 return;
99
100 /*
101 ** If possible, we let tgetent allocate its own termcap buffer
102 */
103 #ifdef TGETENT_ACCEPTS_NULL
104         if (tgetent(NULL, term) != TGETENT_SUCCESS)
105                 return;
106 #else
107         if (tgetent(termbuf, term) != TGETENT_SUCCESS)
108                 return;
109 #endif
110
111 #ifdef HAVE_TERMIOS_H
112         speedcode = cfgetospeed(&tio);
113 #else
114 # ifdef HAVE_TERMIO_H
115         speedcode = ioctl(fileno(stdout), TCGETA, &tio) != NOTOK ?
116                         tio.c_cflag & CBAUD : 0;
117 # else
118         speedcode = ioctl(fileno(stdout), TIOCGETP, (char *) &tio) != NOTOK ?
119                         tio.sg_ospeed : 0;
120 # endif
121 #endif
122
123         if (!initCO && (CO = tgetnum("co")) <= 0)
124                 CO = 80;
125         if (!initLI && (LI = tgetnum("li")) <= 0)
126                 LI = 24;
127
128         cp = termcap;
129         CL = tgetstr("cl", &cp);
130         if ((bp = tgetstr("pc", &cp)))
131                 PC = *bp;
132         if (tgetnum("sg") <= 0) {
133                 SE = tgetstr("se", &cp);
134                 SO = tgetstr("so", &cp);
135         }
136 }
137
138
139 int
140 sc_width(void)
141 {
142 #ifdef TIOCGWINSZ
143         struct winsize win;
144         int width;
145
146         if (ioctl(fileno(stderr), TIOCGWINSZ, &win) != NOTOK
147                         && (width = win.ws_col) > 0) {
148                 CO = width;
149                 initCO++;
150         } else
151 #endif /* TIOCGWINSZ */
152                 read_termcap();
153
154         return CO;
155 }
156
157
158 int
159 sc_length(void)
160 {
161 #ifdef TIOCGWINSZ
162         struct winsize win;
163
164         if (ioctl(fileno(stderr), TIOCGWINSZ, &win) != NOTOK
165                         && (LI = win.ws_row) > 0)
166                 initLI++;
167         else
168 #endif /* TIOCGWINSZ */
169                 read_termcap();
170
171         return LI;
172 }
173
174
175 void
176 clear_screen(void)
177 {
178         read_termcap();
179
180         if (CL && speedcode)
181                 tputs(CL, LI, putchar);
182         else {
183                 printf("\f");
184                 if (speedcode)
185                         printf("\200");
186         }
187
188         fflush(stdout);
189 }
190
191
192 /*
193 ** print in standout mode
194 */
195 int
196 SOprintf(char *fmt, ...)
197 {
198         va_list ap;
199
200         read_termcap();
201         if (!(SO && SE))
202                 return NOTOK;
203
204         tputs(SO, 1, putchar);
205
206         va_start(ap, fmt);
207         vprintf(fmt, ap);
208         va_end(ap);
209
210         tputs(SE, 1, putchar);
211
212         return OK;
213 }