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