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 static int initLI = 0;
23 static int initCO = 0;
24
25 static int LI = 40; /* number of lines */
26 static int CO = 80; /* number of columns */
27 static char *ti_clear = NULL; /* terminfo string to clear screen */
28 static char *ti_standend = NULL; /* terminfo string to end standout mode */
29 static char *ti_standbegin = NULL; /* terminfo string to begin standout mode */
30 static int termstatus = 0; /* terminfo initialization status */
31 static char *termcbuf = NULL; /* tputs() output buffer */
32 static char *termcbufp = NULL; /* tputs() output buffer pointer */
33 static size_t termcbufsz = 0; /* Size of termcbuf */
34
35 static void initialize_terminfo(void);
36 static int termbytes(TPUTS_PUTC_ARG);
37
38 /*
39 * Initialize the terminfo library.
40 */
41
42 static void
initialize_terminfo(void)43 initialize_terminfo(void)
44 {
45 int errret, rc;
46
47 if (termstatus)
48 return;
49
50 rc = setupterm(NULL, fileno(stdout), &errret);
51
52 if (rc != 0 || errret != 1) {
53 termstatus = -1;
54 return;
55 }
56 termstatus = 1;
57
58 if (!initCO && (CO = tigetnum ("cols")) <= 0)
59 CO = 80;
60 if (!initLI && (LI = tigetnum ("lines")) <= 0)
61 LI = 24;
62
63 ti_clear = tigetstr ("clear");
64 ti_standbegin = tigetstr ("smso");
65 ti_standend = tigetstr ("rmso");
66 }
67
68
69 int
sc_width(void)70 sc_width (void)
71 {
72 #ifdef TIOCGWINSZ
73 struct winsize win;
74 int width;
75
76 if (ioctl (fileno (stderr), TIOCGWINSZ, &win) != NOTOK
77 && (width = win.ws_col) > 0) {
78 CO = width;
79 initCO++;
80 } else
81 #endif /* TIOCGWINSZ */
82 initialize_terminfo();
83
84 return CO;
85 }
86
87
88 int
sc_length(void)89 sc_length (void)
90 {
91 #ifdef TIOCGWINSZ
92 struct winsize win;
93
94 if (ioctl (fileno (stderr), TIOCGWINSZ, &win) != NOTOK
95 && (LI = win.ws_row) > 0)
96 initLI++;
97 else
98 #endif /* TIOCGWINSZ */
99 initialize_terminfo();
100
101 return LI;
102 }
103
104
105 static int
outc(TPUTS_PUTC_ARG c)106 outc (TPUTS_PUTC_ARG c)
107 {
108 return putchar(c);
109 }
110
111
112 void
nmh_clear_screen(void)113 nmh_clear_screen (void)
114 {
115 initialize_terminfo ();
116
117 if (ti_clear)
118 tputs (ti_clear, LI, outc);
119 else {
120 putchar('\f');
121 }
122
123 fflush (stdout);
124 }
125
126
127 /*
128 * print in standout mode
129 */
130 int
SOprintf(char * fmt,...)131 SOprintf (char *fmt, ...)
132 {
133 va_list ap;
134
135 initialize_terminfo ();
136 if (!(ti_standbegin && ti_standend))
137 return NOTOK;
138
139 tputs (ti_standbegin, 1, outc);
140
141 va_start(ap, fmt);
142 vprintf (fmt, ap);
143 va_end(ap);
144
145 tputs (ti_standend, 1, outc);
146
147 return OK;
148 }
149
150 /*
151 * Return the specified capability as a string that has already been
152 * processed with tputs().
153 */
154
155 char *
get_term_stringcap(char * capability)156 get_term_stringcap(char *capability)
157 {
158 char *parm;
159
160 initialize_terminfo();
161
162 if (termstatus == -1)
163 return NULL;
164
165 termcbufp = termcbuf;
166
167 parm = tigetstr(capability);
168
169 if (parm == (char *) -1 || parm == NULL) {
170 return NULL;
171 }
172
173 tputs(parm, 1, termbytes);
174
175 *termcbufp = '\0';
176
177 return termcbuf;
178 }
179
180 /*
181 * Return a parameterized terminfo capability
182 */
183
184 char *
get_term_stringparm(char * capability,long arg1,long arg2)185 get_term_stringparm(char *capability, long arg1, long arg2)
186 {
187 char *parm;
188
189 initialize_terminfo();
190
191 if (termstatus == -1)
192 return NULL;
193
194 termcbufp = termcbuf;
195
196 parm = tigetstr(capability);
197
198 if (parm == (char *) -1 || parm == NULL) {
199 return NULL;
200 }
201
202 parm = tparm(parm, arg1, arg2, 0, 0, 0, 0, 0, 0, 0);
203
204 tputs(parm, 1, termbytes);
205
206 *termcbufp = '\0';
207
208 return termcbuf;
209 }
210
211 /*
212 * Return the value of the specified numeric capability
213 */
214
215 int
get_term_numcap(char * capability)216 get_term_numcap(char *capability)
217 {
218 initialize_terminfo();
219
220 if (termstatus == -1)
221 return -1;
222
223 return tigetnum(capability);
224 }
225
226 /*
227 * Store a sequence of characters in our local buffer
228 */
229
230 static int
termbytes(TPUTS_PUTC_ARG c)231 termbytes(TPUTS_PUTC_ARG c)
232 {
233 size_t offset;
234
235 /*
236 * Bump up the buffer size if we've reached the end (leave room for
237 * a trailing NUL)
238 */
239
240 if ((offset = termcbufp - termcbuf) - 1 >= termcbufsz) {
241 termcbufsz += 64;
242 termcbuf = mh_xrealloc(termcbuf, termcbufsz);
243 termcbufp = termcbuf + offset;
244 }
245
246 *termcbufp++ = c;
247
248 return 0;
249 }
250