]> diplodocus.org Git - nmh/blob - sbr/terminal.c
new.c: Order two return statements to match comment.
[nmh] / sbr / terminal.c
1 /* terminal.c -- termcap support
2 *
3 * This code is Copyright (c) 2002, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
6 */
7
8 #include <h/mh.h>
9 #include <h/utils.h>
10
11 #include <sys/ioctl.h>
12
13 #include <curses.h>
14 #include <term.h>
15 #include <termios.h>
16
17 #ifdef WINSIZE_IN_PTEM
18 # include <sys/stream.h>
19 # include <sys/ptem.h>
20 #endif
21
22 #include "terminal.h"
23
24 static int initLI = 0;
25 static int initCO = 0;
26
27 static int LI = 40; /* number of lines */
28 static int CO = 80; /* number of columns */
29 static char *ti_clear = NULL; /* terminfo string to clear screen */
30 static char *ti_standend = NULL; /* terminfo string to end standout mode */
31 static char *ti_standbegin = NULL; /* terminfo string to begin standout mode */
32 static int termstatus = 0; /* terminfo initialization status */
33 static char *termcbuf = NULL; /* tputs() output buffer */
34 static char *termcbufp = NULL; /* tputs() output buffer pointer */
35 static size_t termcbufsz = 0; /* Size of termcbuf */
36
37 static void initialize_terminfo(void);
38 static int termbytes(TPUTS_PUTC_ARG);
39
40 /*
41 * Initialize the terminfo library.
42 */
43
44 static void
45 initialize_terminfo(void)
46 {
47 int errret, rc;
48
49 if (termstatus)
50 return;
51
52 rc = setupterm(NULL, fileno(stdout), &errret);
53
54 if (rc != 0 || errret != 1) {
55 termstatus = -1;
56 return;
57 }
58 termstatus = 1;
59
60 if (!initCO && (CO = tigetnum ("cols")) <= 0)
61 CO = 80;
62 if (!initLI && (LI = tigetnum ("lines")) <= 0)
63 LI = 24;
64
65 ti_clear = tigetstr ("clear");
66 ti_standbegin = tigetstr ("smso");
67 ti_standend = tigetstr ("rmso");
68 }
69
70
71 int
72 sc_width (void)
73 {
74 #ifdef TIOCGWINSZ
75 struct winsize win;
76 int width;
77
78 if (ioctl (fileno (stderr), TIOCGWINSZ, &win) != NOTOK
79 && (width = win.ws_col) > 0) {
80 CO = width;
81 initCO++;
82 } else
83 #endif /* TIOCGWINSZ */
84 initialize_terminfo();
85
86 return CO;
87 }
88
89
90 int
91 sc_length (void)
92 {
93 #ifdef TIOCGWINSZ
94 struct winsize win;
95
96 if (ioctl (fileno (stderr), TIOCGWINSZ, &win) != NOTOK
97 && (LI = win.ws_row) > 0)
98 initLI++;
99 else
100 #endif /* TIOCGWINSZ */
101 initialize_terminfo();
102
103 return LI;
104 }
105
106
107 static int
108 outc (TPUTS_PUTC_ARG c)
109 {
110 return putchar(c);
111 }
112
113
114 void
115 nmh_clear_screen (void)
116 {
117 initialize_terminfo ();
118
119 if (ti_clear)
120 tputs (ti_clear, LI, outc);
121 else {
122 putchar('\f');
123 }
124
125 fflush (stdout);
126 }
127
128
129 /*
130 * print in standout mode
131 */
132 int
133 SOprintf (char *fmt, ...)
134 {
135 va_list ap;
136
137 initialize_terminfo ();
138 if (!(ti_standbegin && ti_standend))
139 return NOTOK;
140
141 tputs (ti_standbegin, 1, outc);
142
143 va_start(ap, fmt);
144 vprintf (fmt, ap);
145 va_end(ap);
146
147 tputs (ti_standend, 1, outc);
148
149 return OK;
150 }
151
152 /*
153 * Get a string from the terminfo database for the current terminal.
154 *
155 * Retrieve the specified terminfo capability and return a string that
156 * can be output to the terminal. The string returned has already been
157 * processed by tputs(), so it is safe to output directly. The return
158 * value of this function is valid until the next call.
159 *
160 * Arguments:
161 *
162 * capability - The name of the terminfo capability (see terminfo(5)).
163 *
164 * Returns a tputs-processed string, or NULL if terminal initialization failed
165 * or the capability wasn't found.
166 */
167
168 char *
169 get_term_stringcap(char *capability)
170 {
171 char *parm;
172
173 initialize_terminfo();
174
175 if (termstatus == -1)
176 return NULL;
177
178 termcbufp = termcbuf;
179
180 parm = tigetstr(capability);
181
182 if (parm == (char *) -1 || parm == NULL) {
183 return NULL;
184 }
185
186 tputs(parm, 1, termbytes);
187
188 *termcbufp = '\0';
189
190 return termcbuf;
191 }
192
193 /*
194 * Get a parameterized string from the terminfo database for the current
195 * terminal.
196 *
197 * We don't yet have a standardized tparm() that will take a stdarg
198 * argument. Right now we don't want many parameters, so we only
199 * take two. Everything gets passed to tparm() as-is. If we need
200 * a capability with more arguments, we'll just add more later.
201 *
202 * Arguments:
203 *
204 * capability - The name of the terminfo capability (see terminfo(5)).
205 * arg1..argN - Arguments 1-N.
206 *
207 * Returns a tparm and tputs-processed string, or NULL if there was a problem
208 * initialising the terminal or retrieving the capability.
209 */
210 char *
211 get_term_stringparm(char *capability, long arg1, long arg2)
212 {
213 char *parm;
214
215 initialize_terminfo();
216
217 if (termstatus == -1)
218 return NULL;
219
220 termcbufp = termcbuf;
221
222 parm = tigetstr(capability);
223
224 if (parm == (char *) -1 || parm == NULL) {
225 return NULL;
226 }
227
228 parm = tparm(parm, arg1, arg2, 0, 0, 0, 0, 0, 0, 0);
229
230 tputs(parm, 1, termbytes);
231
232 *termcbufp = '\0';
233
234 return termcbuf;
235 }
236
237 /*
238 * Get a number from the terminfo database for the current terminal.
239 *
240 * Retrieve the specified terminfo capability and return the numeric
241 * value of that capability from the terminfo database.
242 *
243 * Arguments:
244 *
245 * capability - The name of the terminfo capability (see terminfo(5)).
246 *
247 * Returns the output of tigetnum() for that capability, or -1 if it was
248 * unable to initialize the terminfo database.
249 */
250 int
251 get_term_numcap(char *capability)
252 {
253 initialize_terminfo();
254
255 if (termstatus == -1)
256 return -1;
257
258 return tigetnum(capability);
259 }
260
261 /*
262 * Store a sequence of characters in our local buffer
263 */
264
265 static int
266 termbytes(TPUTS_PUTC_ARG c)
267 {
268 size_t offset;
269
270 /*
271 * Bump up the buffer size if we've reached the end (leave room for
272 * a trailing NUL)
273 */
274
275 if ((offset = termcbufp - termcbuf) - 1 >= termcbufsz) {
276 termcbufsz += 64;
277 termcbuf = mh_xrealloc(termcbuf, termcbufsz);
278 termcbufp = termcbuf + offset;
279 }
280
281 *termcbufp++ = c;
282
283 return 0;
284 }