]>
Commit | Line | Data |
---|---|---|
44bd5ea7 A |
1 | /* $NetBSD: wwinit.c,v 1.12 1997/11/21 08:37:26 lukem Exp $ */ |
2 | ||
3 | /* | |
4 | * Copyright (c) 1983, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | |
6 | * | |
7 | * This code is derived from software contributed to Berkeley by | |
8 | * Edward Wang at The University of California, Berkeley. | |
9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | |
18 | * 3. All advertising materials mentioning features or use of this software | |
19 | * must display the following acknowledgement: | |
20 | * This product includes software developed by the University of | |
21 | * California, Berkeley and its contributors. | |
22 | * 4. Neither the name of the University nor the names of its contributors | |
23 | * may be used to endorse or promote products derived from this software | |
24 | * without specific prior written permission. | |
25 | * | |
26 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
36 | * SUCH DAMAGE. | |
37 | */ | |
38 | ||
39 | #include <sys/cdefs.h> | |
40 | #ifndef lint | |
41 | #if 0 | |
42 | static char sccsid[] = "@(#)wwinit.c 8.2 (Berkeley) 4/28/95"; | |
43 | #else | |
44 | __RCSID("$NetBSD: wwinit.c,v 1.12 1997/11/21 08:37:26 lukem Exp $"); | |
45 | #endif | |
46 | #endif /* not lint */ | |
47 | ||
48 | #include <fcntl.h> | |
49 | #include <signal.h> | |
50 | #include <stdlib.h> | |
51 | #include <stdio.h> | |
52 | #ifdef __APPLE__ | |
53 | #include <curses.h> | |
54 | #else | |
55 | #include <termcap.h> | |
56 | #endif | |
57 | #include "ww.h" | |
58 | #include "tt.h" | |
59 | #include "xx.h" | |
60 | #include "char.h" | |
61 | ||
62 | int | |
63 | wwinit() | |
64 | { | |
65 | int i, j; | |
66 | char *kp; | |
67 | sigset_t sigset, osigset; | |
68 | ||
69 | wwdtablesize = 3; | |
70 | wwhead.ww_forw = &wwhead; | |
71 | wwhead.ww_back = &wwhead; | |
72 | ||
73 | sigemptyset(&sigset); | |
74 | sigaddset(&sigset, SIGCHLD); | |
75 | sigaddset(&sigset, SIGALRM); | |
76 | sigaddset(&sigset, SIGHUP); | |
77 | sigaddset(&sigset, SIGTERM); | |
78 | sigprocmask(SIG_BLOCK, &sigset, &osigset); | |
79 | ||
80 | if (signal(SIGCHLD, wwchild) == BADSIG || | |
81 | signal(SIGHUP, wwquit) == BADSIG || | |
82 | signal(SIGTERM, wwquit) == BADSIG || | |
83 | signal(SIGPIPE, SIG_IGN) == BADSIG) { | |
84 | wwerrno = WWE_SYS; | |
85 | return -1; | |
86 | } | |
87 | ||
88 | if (wwgettty(0, &wwoldtty) < 0) | |
89 | return -1; | |
90 | wwwintty = wwoldtty; | |
91 | #ifdef OLD_TTY | |
92 | wwwintty.ww_sgttyb.sg_flags &= ~XTABS; | |
93 | wwnewtty.ww_sgttyb = wwoldtty.ww_sgttyb; | |
94 | wwnewtty.ww_sgttyb.sg_erase = -1; | |
95 | wwnewtty.ww_sgttyb.sg_kill = -1; | |
96 | wwnewtty.ww_sgttyb.sg_flags |= CBREAK; | |
97 | wwnewtty.ww_sgttyb.sg_flags &= ~(ECHO|CRMOD); | |
98 | wwnewtty.ww_tchars.t_intrc = -1; | |
99 | wwnewtty.ww_tchars.t_quitc = -1; | |
100 | wwnewtty.ww_tchars.t_startc = -1; | |
101 | wwnewtty.ww_tchars.t_stopc = -1; | |
102 | wwnewtty.ww_tchars.t_eofc = -1; | |
103 | wwnewtty.ww_tchars.t_brkc = -1; | |
104 | wwnewtty.ww_ltchars.t_suspc = -1; | |
105 | wwnewtty.ww_ltchars.t_dsuspc = -1; | |
106 | wwnewtty.ww_ltchars.t_rprntc = -1; | |
107 | wwnewtty.ww_ltchars.t_flushc = -1; | |
108 | wwnewtty.ww_ltchars.t_werasc = -1; | |
109 | wwnewtty.ww_ltchars.t_lnextc = -1; | |
110 | wwnewtty.ww_lmode = wwoldtty.ww_lmode | LLITOUT; | |
111 | wwnewtty.ww_ldisc = wwoldtty.ww_ldisc; | |
112 | #else | |
113 | #ifndef OXTABS | |
114 | #define OXTABS XTABS | |
115 | #endif | |
116 | #ifndef _POSIX_VDISABLE | |
117 | #define _POSIX_VDISABLE -1 | |
118 | #endif | |
119 | wwwintty.ww_termios.c_oflag &= ~OXTABS; | |
120 | wwnewtty.ww_termios = wwoldtty.ww_termios; | |
121 | wwnewtty.ww_termios.c_iflag &= | |
122 | ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IMAXBEL); | |
123 | wwnewtty.ww_termios.c_oflag = 0; | |
124 | wwnewtty.ww_termios.c_cflag &= ~(CSIZE | PARENB); | |
125 | wwnewtty.ww_termios.c_cflag |= CS8; | |
126 | wwnewtty.ww_termios.c_lflag = 0; | |
127 | for (i = 0; i < NCCS; i++) | |
128 | wwnewtty.ww_termios.c_cc[i] = _POSIX_VDISABLE; | |
129 | wwnewtty.ww_termios.c_cc[VMIN] = 1; | |
130 | wwnewtty.ww_termios.c_cc[VTIME] = 0; | |
131 | #endif | |
132 | if (wwsettty(0, &wwnewtty) < 0) | |
133 | goto bad; | |
134 | ||
135 | if ((wwterm = getenv("TERM")) == 0) { | |
136 | wwerrno = WWE_BADTERM; | |
137 | goto bad; | |
138 | } | |
139 | if (tgetent(wwtermcap, wwterm) != 1) { | |
140 | wwerrno = WWE_BADTERM; | |
141 | goto bad; | |
142 | } | |
143 | #ifdef OLD_TTY | |
144 | wwospeed = wwoldtty.ww_sgttyb.sg_ospeed; | |
145 | #else | |
146 | wwospeed = cfgetospeed(&wwoldtty.ww_termios); | |
147 | wwbaud = wwospeed; | |
148 | #endif | |
149 | switch (wwospeed) { | |
150 | default: | |
151 | case B0: | |
152 | wwbaud = 0; | |
153 | break; | |
154 | case B50: | |
155 | wwbaud = 50; | |
156 | break; | |
157 | case B75: | |
158 | wwbaud = 75; | |
159 | break; | |
160 | case B110: | |
161 | wwbaud = 110; | |
162 | break; | |
163 | case B134: | |
164 | wwbaud = 134; | |
165 | break; | |
166 | case B150: | |
167 | wwbaud = 150; | |
168 | break; | |
169 | case B200: | |
170 | wwbaud = 200; | |
171 | break; | |
172 | case B300: | |
173 | wwbaud = 300; | |
174 | break; | |
175 | case B600: | |
176 | wwbaud = 600; | |
177 | break; | |
178 | case B1200: | |
179 | wwbaud = 1200; | |
180 | break; | |
181 | case B1800: | |
182 | wwbaud = 1800; | |
183 | break; | |
184 | case B2400: | |
185 | wwbaud = 2400; | |
186 | break; | |
187 | case B4800: | |
188 | wwbaud = 4800; | |
189 | break; | |
190 | case B9600: | |
191 | wwbaud = 9600; | |
192 | break; | |
193 | #ifdef B19200 | |
194 | case B19200: | |
195 | #else | |
196 | case EXTA: | |
197 | #endif | |
198 | wwbaud = 19200; | |
199 | break; | |
200 | #ifdef B38400 | |
201 | case B38400: | |
202 | #else | |
203 | case EXTB: | |
204 | #endif | |
205 | wwbaud = 38400; | |
206 | break; | |
207 | #ifdef B57600 | |
208 | case B57600: | |
209 | wwbaud= 57600; | |
210 | break; | |
211 | #endif | |
212 | #ifdef B115200 | |
213 | case B115200: | |
214 | wwbaud = 115200; | |
215 | break; | |
216 | #endif | |
217 | } | |
218 | ||
219 | if (xxinit() < 0) | |
220 | goto bad; | |
221 | wwnrow = tt.tt_nrow; | |
222 | wwncol = tt.tt_ncol; | |
223 | wwavailmodes = tt.tt_availmodes; | |
224 | wwwrap = tt.tt_wrap; | |
225 | ||
226 | if (wwavailmodes & WWM_REV) | |
227 | wwcursormodes = WWM_REV | (wwavailmodes & WWM_BLK); | |
228 | else if (wwavailmodes & WWM_UL) | |
229 | wwcursormodes = WWM_UL; | |
230 | ||
231 | if ((wwib = malloc((unsigned) 512)) == 0) | |
232 | goto bad; | |
233 | wwibe = wwib + 512; | |
234 | wwibq = wwibp = wwib; | |
235 | ||
236 | wwsmap = (unsigned char **) | |
237 | wwalloc(0, 0, wwnrow, wwncol, sizeof (unsigned char)); | |
238 | if (wwsmap == 0) | |
239 | goto bad; | |
240 | for (i = 0; i < wwnrow; i++) | |
241 | for (j = 0; j < wwncol; j++) | |
242 | wwsmap[i][j] = WWX_NOBODY; | |
243 | ||
244 | wwos = (union ww_char **) | |
245 | wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char)); | |
246 | if (wwos == 0) | |
247 | goto bad; | |
248 | /* wwos is cleared in wwstart1() */ | |
249 | wwns = (union ww_char **) | |
250 | wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char)); | |
251 | if (wwns == 0) | |
252 | goto bad; | |
253 | for (i = 0; i < wwnrow; i++) | |
254 | for (j = 0; j < wwncol; j++) | |
255 | wwns[i][j].c_w = ' '; | |
256 | if (tt.tt_checkpoint) { | |
257 | /* wwcs is also cleared in wwstart1() */ | |
258 | wwcs = (union ww_char **) | |
259 | wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char)); | |
260 | if (wwcs == 0) | |
261 | goto bad; | |
262 | } | |
263 | ||
264 | wwtouched = malloc((unsigned) wwnrow); | |
265 | if (wwtouched == 0) { | |
266 | wwerrno = WWE_NOMEM; | |
267 | goto bad; | |
268 | } | |
269 | for (i = 0; i < wwnrow; i++) | |
270 | wwtouched[i] = 0; | |
271 | ||
272 | wwupd = (struct ww_update *) malloc((unsigned) wwnrow * sizeof *wwupd); | |
273 | if (wwupd == 0) { | |
274 | wwerrno = WWE_NOMEM; | |
275 | goto bad; | |
276 | } | |
277 | ||
278 | wwindex[WWX_NOBODY] = &wwnobody; | |
279 | wwnobody.ww_order = NWW; | |
280 | ||
281 | kp = wwwintermcap; | |
282 | if (wwavailmodes & WWM_REV) | |
283 | wwaddcap1(WWT_REV, &kp); | |
284 | if (wwavailmodes & WWM_BLK) | |
285 | wwaddcap1(WWT_BLK, &kp); | |
286 | if (wwavailmodes & WWM_UL) | |
287 | wwaddcap1(WWT_UL, &kp); | |
288 | if (wwavailmodes & WWM_GRP) | |
289 | wwaddcap1(WWT_GRP, &kp); | |
290 | if (wwavailmodes & WWM_DIM) | |
291 | wwaddcap1(WWT_DIM, &kp); | |
292 | if (wwavailmodes & WWM_USR) | |
293 | wwaddcap1(WWT_USR, &kp); | |
294 | if ((tt.tt_insline && tt.tt_delline) || tt.tt_setscroll) | |
295 | wwaddcap1(WWT_ALDL, &kp); | |
296 | if (tt.tt_inschar) | |
297 | wwaddcap1(WWT_IMEI, &kp); | |
298 | if (tt.tt_insspace) | |
299 | wwaddcap1(WWT_IC, &kp); | |
300 | if (tt.tt_delchar) | |
301 | wwaddcap1(WWT_DC, &kp); | |
302 | wwaddcap("kb", &kp); | |
303 | wwaddcap("ku", &kp); | |
304 | wwaddcap("kd", &kp); | |
305 | wwaddcap("kl", &kp); | |
306 | wwaddcap("kr", &kp); | |
307 | wwaddcap("kh", &kp); | |
308 | if ((j = tgetnum("kn")) >= 0) { | |
309 | char cap[32]; | |
310 | ||
311 | (void) sprintf(kp, "kn#%d:", j); | |
312 | for (; *kp; kp++) | |
313 | ; | |
314 | for (i = 1; i <= j; i++) { | |
315 | (void) sprintf(cap, "k%d", i); | |
316 | wwaddcap(cap, &kp); | |
317 | cap[0] = 'l'; | |
318 | wwaddcap(cap, &kp); | |
319 | } | |
320 | } | |
321 | /* | |
322 | * It's ok to do this here even if setenv() is destructive | |
323 | * since tt_init() has already made its own copy of it and | |
324 | * wwterm now points to the copy. | |
325 | */ | |
326 | (void) setenv("TERM", WWT_TERM, 1); | |
327 | #ifdef TERMINFO | |
328 | if (wwterminfoinit() < 0) | |
329 | goto bad; | |
330 | #endif | |
331 | ||
332 | if (tt.tt_checkpoint) | |
333 | if (signal(SIGALRM, wwalarm) == BADSIG) { | |
334 | wwerrno = WWE_SYS; | |
335 | goto bad; | |
336 | } | |
337 | wwstart1(); | |
338 | ||
339 | sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0); | |
340 | return 0; | |
341 | ||
342 | bad: | |
343 | /* | |
344 | * Don't bother to free storage. We're supposed | |
345 | * to exit when wwinit fails anyway. | |
346 | */ | |
347 | (void) wwsettty(0, &wwoldtty); | |
348 | ||
349 | sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0); | |
350 | return -1; | |
351 | } | |
352 | ||
353 | void | |
354 | wwaddcap(cap, kp) | |
355 | char *cap; | |
356 | char **kp; | |
357 | { | |
358 | char tbuf[512]; | |
359 | char *tp = tbuf; | |
360 | char *str, *p; | |
361 | ||
362 | if ((str = tgetstr(cap, &tp)) != 0) { | |
363 | while ((*(*kp)++ = *cap++)) | |
364 | ; | |
365 | (*kp)[-1] = '='; | |
366 | while (*str) { | |
367 | for (p = unctrl(*str++); (*(*kp)++ = *p++);) | |
368 | ; | |
369 | (*kp)--; | |
370 | } | |
371 | *(*kp)++ = ':'; | |
372 | **kp = 0; | |
373 | } | |
374 | } | |
375 | ||
376 | void | |
377 | wwaddcap1(cap, kp) | |
378 | char *cap; | |
379 | char **kp; | |
380 | { | |
381 | while ((*(*kp)++ = *cap++)) | |
382 | ; | |
383 | (*kp)--; | |
384 | } | |
385 | ||
386 | void | |
387 | wwstart() | |
388 | { | |
389 | int i; | |
390 | ||
391 | (void) wwsettty(0, &wwnewtty); | |
392 | for (i = 0; i < wwnrow; i++) | |
393 | wwtouched[i] = WWU_TOUCHED; | |
394 | wwstart1(); | |
395 | } | |
396 | ||
397 | void | |
398 | wwstart1() | |
399 | { | |
400 | int i, j; | |
401 | ||
402 | for (i = 0; i < wwnrow; i++) | |
403 | for (j = 0; j < wwncol; j++) { | |
404 | wwos[i][j].c_w = ' '; | |
405 | if (tt.tt_checkpoint) | |
406 | wwcs[i][j].c_w = ' '; | |
407 | } | |
408 | xxstart(); | |
409 | if (tt.tt_checkpoint) | |
410 | wwdocheckpoint = 1; | |
411 | } | |
412 | ||
413 | /* | |
414 | * Reset data structures and terminal from an unknown state. | |
415 | * Restoring wwos has been taken care of elsewhere. | |
416 | */ | |
417 | void | |
418 | wwreset() | |
419 | { | |
420 | int i; | |
421 | ||
422 | xxreset(); | |
423 | for (i = 0; i < wwnrow; i++) | |
424 | wwtouched[i] = WWU_TOUCHED; | |
425 | } |