Annotation of src/usr.bin/window/wwinit.c, Revision 1.10
1.10 ! millert 1: /* $OpenBSD: wwinit.c,v 1.9 1999/11/14 17:34:24 millert 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.10 ! millert 44: static char rcsid[] = "$OpenBSD: wwinit.c,v 1.9 1999/11/14 17:34:24 millert 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>
53: #include "char.h"
54:
55: wwinit()
56: {
57: register i, j;
58: char *kp;
1.2 deraadt 59: sigset_t sigset, osigset;
1.1 deraadt 60:
61: wwdtablesize = 3;
62: wwhead.ww_forw = &wwhead;
63: wwhead.ww_back = &wwhead;
64:
1.2 deraadt 65: sigemptyset(&sigset);
66: sigaddset(&sigset, SIGCHLD);
67: sigaddset(&sigset, SIGALRM);
68: sigaddset(&sigset, SIGHUP);
69: sigaddset(&sigset, SIGTERM);
70: sigprocmask(SIG_BLOCK, &sigset, &osigset);
71:
1.8 deraadt 72: if (signal(SIGCHLD, wwchild) == SIG_ERR ||
73: signal(SIGHUP, wwquit) == SIG_ERR ||
74: signal(SIGTERM, wwquit) == SIG_ERR ||
75: signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
1.1 deraadt 76: wwerrno = WWE_SYS;
77: return -1;
78: }
79:
80: if (wwgettty(0, &wwoldtty) < 0)
81: return -1;
82: wwwintty = wwoldtty;
83: #ifdef OLD_TTY
84: wwwintty.ww_sgttyb.sg_flags &= ~XTABS;
85: wwnewtty.ww_sgttyb = wwoldtty.ww_sgttyb;
86: wwnewtty.ww_sgttyb.sg_erase = -1;
87: wwnewtty.ww_sgttyb.sg_kill = -1;
88: wwnewtty.ww_sgttyb.sg_flags |= CBREAK;
89: wwnewtty.ww_sgttyb.sg_flags &= ~(ECHO|CRMOD);
90: wwnewtty.ww_tchars.t_intrc = -1;
91: wwnewtty.ww_tchars.t_quitc = -1;
92: wwnewtty.ww_tchars.t_startc = -1;
93: wwnewtty.ww_tchars.t_stopc = -1;
94: wwnewtty.ww_tchars.t_eofc = -1;
95: wwnewtty.ww_tchars.t_brkc = -1;
96: wwnewtty.ww_ltchars.t_suspc = -1;
97: wwnewtty.ww_ltchars.t_dsuspc = -1;
98: wwnewtty.ww_ltchars.t_rprntc = -1;
99: wwnewtty.ww_ltchars.t_flushc = -1;
100: wwnewtty.ww_ltchars.t_werasc = -1;
101: wwnewtty.ww_ltchars.t_lnextc = -1;
102: wwnewtty.ww_lmode = wwoldtty.ww_lmode | LLITOUT;
103: wwnewtty.ww_ldisc = wwoldtty.ww_ldisc;
104: #else
105: #ifndef OXTABS
106: #define OXTABS XTABS
107: #endif
108: #ifndef _POSIX_VDISABLE
109: #define _POSIX_VDISABLE -1
110: #endif
111: wwwintty.ww_termios.c_oflag &= ~OXTABS;
112: wwnewtty.ww_termios = wwoldtty.ww_termios;
113: wwnewtty.ww_termios.c_iflag &=
114: ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IMAXBEL);
115: wwnewtty.ww_termios.c_oflag = 0;
116: wwnewtty.ww_termios.c_cflag &= ~(CSIZE | PARENB);
117: wwnewtty.ww_termios.c_cflag |= CS8;
118: wwnewtty.ww_termios.c_lflag = 0;
119: for (i = 0; i < NCCS; i++)
120: wwnewtty.ww_termios.c_cc[i] = _POSIX_VDISABLE;
121: wwnewtty.ww_termios.c_cc[VMIN] = 1;
122: wwnewtty.ww_termios.c_cc[VTIME] = 0;
123: #endif
124: if (wwsettty(0, &wwnewtty) < 0)
125: goto bad;
126:
127: if ((wwterm = getenv("TERM")) == 0) {
128: wwerrno = WWE_BADTERM;
129: goto bad;
130: }
1.10 ! millert 131: #ifdef TERMINFO
! 132: if (setupterm(wwterm, STDOUT_FILENO, NULL) != 0) {
! 133: wwerrno = WWE_BADTERM;
! 134: goto bad;
! 135: }
! 136: #else
1.1 deraadt 137: if (tgetent(wwtermcap, wwterm) != 1) {
138: wwerrno = WWE_BADTERM;
139: goto bad;
140: }
1.10 ! millert 141: #endif
1.1 deraadt 142: #ifdef OLD_TTY
143: wwospeed = wwoldtty.ww_sgttyb.sg_ospeed;
144: #else
145: wwospeed = cfgetospeed(&wwoldtty.ww_termios);
146: wwbaud = wwospeed;
147: #endif
148: switch (wwospeed) {
149: default:
150: case B0:
151: wwbaud = 0;
152: break;
153: case B50:
154: wwbaud = 50;
155: break;
156: case B75:
157: wwbaud = 75;
158: break;
159: case B110:
160: wwbaud = 110;
161: break;
162: case B134:
163: wwbaud = 134;
164: break;
165: case B150:
166: wwbaud = 150;
167: break;
168: case B200:
169: wwbaud = 200;
170: break;
171: case B300:
172: wwbaud = 300;
173: break;
174: case B600:
175: wwbaud = 600;
176: break;
177: case B1200:
178: wwbaud = 1200;
179: break;
180: case B1800:
181: wwbaud = 1800;
182: break;
183: case B2400:
184: wwbaud = 2400;
185: break;
186: case B4800:
187: wwbaud = 4800;
188: break;
189: case B9600:
190: wwbaud = 9600;
191: break;
192: #ifdef B19200
193: case B19200:
194: #else
195: case EXTA:
196: #endif
197: wwbaud = 19200;
198: break;
199: #ifdef B38400
200: case B38400:
201: #else
202: case EXTB:
203: #endif
204: wwbaud = 38400;
205: break;
206: #ifdef B57600
207: case B57600:
1.6 downsj 208: wwbaud = 57600;
1.1 deraadt 209: break;
210: #endif
211: #ifdef B115200
212: case B115200:
213: wwbaud = 115200;
214: break;
215: #endif
216: }
217:
218: if (xxinit() < 0)
219: goto bad;
220: wwnrow = tt.tt_nrow;
221: wwncol = tt.tt_ncol;
222: wwavailmodes = tt.tt_availmodes;
223: wwwrap = tt.tt_wrap;
224:
225: if (wwavailmodes & WWM_REV)
226: wwcursormodes = WWM_REV | wwavailmodes & WWM_BLK;
227: else if (wwavailmodes & WWM_UL)
228: wwcursormodes = WWM_UL;
229:
1.7 millert 230: if ((wwib = malloc(512)) == 0)
1.1 deraadt 231: goto bad;
232: wwibe = wwib + 512;
233: wwibq = wwibp = wwib;
234:
1.3 niklas 235: wwsmap = (unsigned char **)
236: wwalloc(0, 0, wwnrow, wwncol, sizeof (unsigned char));
237: if (wwsmap == 0)
1.1 deraadt 238: goto bad;
239: for (i = 0; i < wwnrow; i++)
240: for (j = 0; j < wwncol; j++)
241: wwsmap[i][j] = WWX_NOBODY;
242:
243: wwos = (union ww_char **)
244: wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char));
245: if (wwos == 0)
246: goto bad;
247: /* wwos is cleared in wwstart1() */
248: wwns = (union ww_char **)
249: wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char));
250: if (wwns == 0)
251: goto bad;
252: for (i = 0; i < wwnrow; i++)
253: for (j = 0; j < wwncol; j++)
254: wwns[i][j].c_w = ' ';
255: if (tt.tt_checkpoint) {
256: /* wwcs is also cleared in wwstart1() */
257: wwcs = (union ww_char **)
258: wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char));
259: if (wwcs == 0)
260: goto bad;
261: }
262:
1.7 millert 263: wwtouched = malloc(wwnrow);
1.1 deraadt 264: if (wwtouched == 0) {
265: wwerrno = WWE_NOMEM;
266: goto bad;
267: }
268: for (i = 0; i < wwnrow; i++)
269: wwtouched[i] = 0;
270:
1.7 millert 271: wwupd = (struct ww_update *) malloc(wwnrow * sizeof *wwupd);
1.1 deraadt 272: if (wwupd == 0) {
273: wwerrno = WWE_NOMEM;
274: goto bad;
275: }
276:
277: wwindex[WWX_NOBODY] = &wwnobody;
278: wwnobody.ww_order = NWW;
279:
280: kp = wwwintermcap;
281: if (wwavailmodes & WWM_REV)
282: wwaddcap1(WWT_REV, &kp);
283: if (wwavailmodes & WWM_BLK)
284: wwaddcap1(WWT_BLK, &kp);
285: if (wwavailmodes & WWM_UL)
286: wwaddcap1(WWT_UL, &kp);
287: if (wwavailmodes & WWM_GRP)
288: wwaddcap1(WWT_GRP, &kp);
289: if (wwavailmodes & WWM_DIM)
290: wwaddcap1(WWT_DIM, &kp);
291: if (wwavailmodes & WWM_USR)
292: wwaddcap1(WWT_USR, &kp);
293: if (tt.tt_insline && tt.tt_delline || tt.tt_setscroll)
294: wwaddcap1(WWT_ALDL, &kp);
295: if (tt.tt_inschar)
296: wwaddcap1(WWT_IMEI, &kp);
297: if (tt.tt_insspace)
298: wwaddcap1(WWT_IC, &kp);
299: if (tt.tt_delchar)
300: wwaddcap1(WWT_DC, &kp);
301: wwaddcap("kb", &kp);
302: wwaddcap("ku", &kp);
303: wwaddcap("kd", &kp);
304: wwaddcap("kl", &kp);
305: wwaddcap("kr", &kp);
306: wwaddcap("kh", &kp);
307: if ((j = tgetnum("kn")) >= 0) {
308: char cap[32];
309:
310: (void) sprintf(kp, "kn#%d:", j);
311: for (; *kp; kp++)
312: ;
313: for (i = 1; i <= j; i++) {
314: (void) sprintf(cap, "k%d", i);
315: wwaddcap(cap, &kp);
316: cap[0] = 'l';
317: wwaddcap(cap, &kp);
318: }
319: }
320: /*
321: * It's ok to do this here even if setenv() is destructive
322: * since tt_init() has already made its own copy of it and
323: * wwterm now points to the copy.
324: */
325: (void) setenv("TERM", WWT_TERM, 1);
326: #ifdef TERMINFO
327: if (wwterminfoinit() < 0)
328: goto bad;
329: #endif
330:
331: if (tt.tt_checkpoint)
1.8 deraadt 332: if (signal(SIGALRM, wwalarm) == SIG_ERR) {
1.1 deraadt 333: wwerrno = WWE_SYS;
334: goto bad;
335: }
336: wwstart1();
1.2 deraadt 337:
338: sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0);
1.1 deraadt 339: return 0;
1.2 deraadt 340:
1.1 deraadt 341: bad:
342: /*
343: * Don't bother to free storage. We're supposed
344: * to exit when wwinit fails anyway.
345: */
346: (void) wwsettty(0, &wwoldtty);
1.2 deraadt 347:
348: sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0);
1.1 deraadt 349: return -1;
350: }
351:
352: wwaddcap(cap, kp)
353: register char *cap;
354: register char **kp;
355: {
356: char tbuf[512];
357: char *tp = tbuf;
358: register char *str, *p;
359:
360: if ((str = tgetstr(cap, &tp)) != 0) {
361: while (*(*kp)++ = *cap++)
362: ;
363: (*kp)[-1] = '=';
364: while (*str) {
365: for (p = unctrl(*str++); *(*kp)++ = *p++;)
366: ;
367: (*kp)--;
368: }
369: *(*kp)++ = ':';
370: **kp = 0;
371: }
372: }
373:
374: wwaddcap1(cap, kp)
375: register char *cap;
376: register char **kp;
377: {
378: while (*(*kp)++ = *cap++)
379: ;
380: (*kp)--;
381: }
382:
383: wwstart()
384: {
385: register i;
386:
387: (void) wwsettty(0, &wwnewtty);
388: for (i = 0; i < wwnrow; i++)
389: wwtouched[i] = WWU_TOUCHED;
390: wwstart1();
391: }
392:
393: wwstart1()
394: {
395: register i, j;
396:
397: for (i = 0; i < wwnrow; i++)
398: for (j = 0; j < wwncol; j++) {
399: wwos[i][j].c_w = ' ';
400: if (tt.tt_checkpoint)
401: wwcs[i][j].c_w = ' ';
402: }
403: xxstart();
404: if (tt.tt_checkpoint)
405: wwdocheckpoint = 1;
406: }
407:
408: /*
409: * Reset data structures and terminal from an unknown state.
410: * Restoring wwos has been taken care of elsewhere.
411: */
412: wwreset()
413: {
414: register i;
415:
416: xxreset();
417: for (i = 0; i < wwnrow; i++)
418: wwtouched[i] = WWU_TOUCHED;
419: }