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