xref: /original-bsd/usr.bin/window/wwinit.c (revision a9a02843)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)wwinit.c	3.33 (Berkeley) 05/11/89";
20 #endif /* not lint */
21 
22 #include "ww.h"
23 #include "tt.h"
24 #include <sys/signal.h>
25 #include <fcntl.h>
26 #include "char.h"
27 
28 wwinit()
29 {
30 	register i, j;
31 	char *kp;
32 	int s;
33 
34 	wwdtablesize = getdtablesize();
35 	wwhead.ww_forw = &wwhead;
36 	wwhead.ww_back = &wwhead;
37 
38 	s = sigblock(sigmask(SIGIO));
39 	if (signal(SIGIO, wwrint) == BADSIG)
40 		return -1;
41 
42 	if (wwgettty(0, &wwoldtty) < 0)
43 		return -1;
44 	wwwintty = wwoldtty;
45 	wwwintty.ww_sgttyb.sg_flags &= ~XTABS;
46 	wwnewtty.ww_sgttyb = wwoldtty.ww_sgttyb;
47 	wwnewtty.ww_sgttyb.sg_erase = -1;
48 	wwnewtty.ww_sgttyb.sg_kill = -1;
49 	wwnewtty.ww_sgttyb.sg_flags |= CBREAK;
50 	wwnewtty.ww_sgttyb.sg_flags &= ~(ECHO|CRMOD);
51 	wwnewtty.ww_tchars.t_intrc = -1;
52 	wwnewtty.ww_tchars.t_quitc = -1;
53 	wwnewtty.ww_tchars.t_startc = -1;
54 	wwnewtty.ww_tchars.t_stopc = -1;
55 	wwnewtty.ww_tchars.t_eofc = -1;
56 	wwnewtty.ww_tchars.t_brkc = -1;
57 	wwnewtty.ww_ltchars.t_suspc = -1;
58 	wwnewtty.ww_ltchars.t_dsuspc = -1;
59 	wwnewtty.ww_ltchars.t_rprntc = -1;
60 	wwnewtty.ww_ltchars.t_flushc = -1;
61 	wwnewtty.ww_ltchars.t_werasc = -1;
62 	wwnewtty.ww_ltchars.t_lnextc = -1;
63 	wwnewtty.ww_lmode = wwoldtty.ww_lmode | LLITOUT;
64 	wwnewtty.ww_ldisc = wwoldtty.ww_ldisc;
65 	wwnewtty.ww_fflags = wwoldtty.ww_fflags | FASYNC;
66 	if (wwsettty(0, &wwnewtty, &wwoldtty) < 0)
67 		goto bad;
68 
69 	if ((wwterm = getenv("TERM")) == 0) {
70 		wwerrno = WWE_BADTERM;
71 		goto bad;
72 	}
73 	if (tgetent(wwtermcap, wwterm) != 1) {
74 		wwerrno = WWE_BADTERM;
75 		goto bad;
76 	}
77 	wwbaud = wwbaudmap[wwoldtty.ww_sgttyb.sg_ospeed];
78 
79 	if (ttinit() < 0)
80 		goto bad;
81 	wwnrow = tt.tt_nrow;
82 	wwncol = tt.tt_ncol;
83 	wwavailmodes = tt.tt_availmodes;
84 	wwwrap = tt.tt_wrap;
85 	if (xxinit() < 0)
86 		return -1;
87 	(*tt.tt_init)();
88 
89 	if (wwavailmodes & WWM_REV)
90 		wwcursormodes = WWM_REV | wwavailmodes & WWM_BLK;
91 	else if (wwavailmodes & WWM_UL)
92 		wwcursormodes = WWM_UL;
93 
94 	if ((wwib = malloc((unsigned) 512)) == 0)
95 		goto bad;
96 	wwibe = wwib + 512;
97 	wwibq = wwibp = wwib;
98 
99 	if ((wwsmap = wwalloc(0, 0, wwnrow, wwncol, sizeof (char))) == 0)
100 		goto bad;
101 	for (i = 0; i < wwnrow; i++)
102 		for (j = 0; j < wwncol; j++)
103 			wwsmap[i][j] = WWX_NOBODY;
104 
105 	wwos = (union ww_char **)
106 		wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char));
107 	if (wwos == 0)
108 		goto bad;
109 	for (i = 0; i < wwnrow; i++)
110 		for (j = 0; j < wwncol; j++)
111 			wwos[i][j].c_w = ' ';
112 	wwns = (union ww_char **)
113 		wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char));
114 	if (wwns == 0)
115 		goto bad;
116 	for (i = 0; i < wwnrow; i++)
117 		for (j = 0; j < wwncol; j++)
118 			wwns[i][j].c_w = ' ';
119 
120 	wwtouched = malloc((unsigned) wwnrow);
121 	if (wwtouched == 0) {
122 		wwerrno = WWE_NOMEM;
123 		goto bad;
124 	}
125 	for (i = 0; i < wwnrow; i++)
126 		wwtouched[i] = 0;
127 
128 	wwupd = (struct ww_update *) malloc((unsigned) wwnrow * sizeof *wwupd);
129 	if (wwupd == 0) {
130 		wwerrno = WWE_NOMEM;
131 		goto bad;
132 	}
133 
134 	wwindex[WWX_NOBODY] = &wwnobody;
135 	wwnobody.ww_order = NWW;
136 
137 	kp = wwwintermcap;
138 	if (wwavailmodes & WWM_REV)
139 		wwaddcap1(WWT_REV, &kp);
140 	if (wwavailmodes & WWM_BLK)
141 		wwaddcap1(WWT_BLK, &kp);
142 	if (wwavailmodes & WWM_UL)
143 		wwaddcap1(WWT_UL, &kp);
144 	if (wwavailmodes & WWM_GRP)
145 		wwaddcap1(WWT_GRP, &kp);
146 	if (wwavailmodes & WWM_DIM)
147 		wwaddcap1(WWT_DIM, &kp);
148 	if (wwavailmodes & WWM_USR)
149 		wwaddcap1(WWT_USR, &kp);
150 	if (tt.tt_insline && tt.tt_delline || tt.tt_setscroll)
151 		wwaddcap1(WWT_ALDL, &kp);
152 	if (tt.tt_inschar || tt.tt_setinsert)
153 		wwaddcap1(WWT_IMEI, &kp);
154 	if (tt.tt_delchar)
155 		wwaddcap1(WWT_DC, &kp);
156 	wwaddcap("kb", &kp);
157 	wwaddcap("ku", &kp);
158 	wwaddcap("kd", &kp);
159 	wwaddcap("kl", &kp);
160 	wwaddcap("kr", &kp);
161 	wwaddcap("kh", &kp);
162 	if ((j = tgetnum("kn")) >= 0) {
163 		char cap[32];
164 
165 		(void) sprintf(kp, "kn#%d:", j);
166 		for (; *kp; kp++)
167 			;
168 		for (i = 1; i <= j; i++) {
169 			(void) sprintf(cap, "k%d", i);
170 			wwaddcap(cap, &kp);
171 			cap[0] = 'l';
172 			wwaddcap(cap, &kp);
173 		}
174 	}
175 	/*
176 	 * It's ok to do this here even if setenv() is destructive
177 	 * since tt_init() has already made its own copy of it and
178 	 * wwterm now points to the copy.
179 	 */
180 	(void) setenv("TERM", WWT_TERM, 1);
181 
182 	(void) signal(SIGPIPE, SIG_IGN);
183 	(void) sigsetmask(s);
184 	return 0;
185 bad:
186 	/*
187 	 * Don't bother to free storage.  We're supposed
188 	 * to exit when wwinit fails anyway.
189 	 */
190 	(void) wwsettty(0, &wwoldtty, &wwnewtty);
191 	(void) signal(SIGIO, SIG_DFL);
192 	(void) sigsetmask(s);
193 	return -1;
194 }
195 
196 wwaddcap(cap, kp)
197 	register char *cap;
198 	register char **kp;
199 {
200 	char tbuf[512];
201 	char *tp = tbuf;
202 	register char *str, *p;
203 
204 	if ((str = tgetstr(cap, &tp)) != 0) {
205 		while (*(*kp)++ = *cap++)
206 			;
207 		(*kp)[-1] = '=';
208 		while (*str) {
209 			for (p = unctrl(*str++); *(*kp)++ = *p++;)
210 				;
211 			(*kp)--;
212 		}
213 		*(*kp)++ = ':';
214 		**kp = 0;
215 	}
216 }
217 
218 wwaddcap1(cap, kp)
219 	register char *cap;
220 	register char **kp;
221 {
222 	while (*(*kp)++ = *cap++)
223 		;
224 	(*kp)--;
225 }
226