1 /*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Edward Wang at The University of California, Berkeley.
7 *
8 * %sccs.include.redist.c%
9 */
10
11 #ifndef lint
12 static char sccsid[] = "@(#)wwinit.c 8.2 (Berkeley) 04/28/95";
13 #endif /* not lint */
14
15 #include "ww.h"
16 #include "tt.h"
17 #include <sys/signal.h>
18 #include <fcntl.h>
19 #include "char.h"
20
wwinit()21 wwinit()
22 {
23 register i, j;
24 char *kp;
25 int s;
26
27 wwdtablesize = 3;
28 wwhead.ww_forw = &wwhead;
29 wwhead.ww_back = &wwhead;
30
31 s = sigblock(sigmask(SIGIO) | sigmask(SIGCHLD) | sigmask(SIGALRM) |
32 sigmask(SIGHUP) | sigmask(SIGTERM));
33 if (signal(SIGIO, wwrint) == BADSIG ||
34 signal(SIGCHLD, wwchild) == BADSIG ||
35 signal(SIGHUP, wwquit) == BADSIG ||
36 signal(SIGTERM, wwquit) == BADSIG ||
37 signal(SIGPIPE, SIG_IGN) == BADSIG) {
38 wwerrno = WWE_SYS;
39 return -1;
40 }
41
42 if (wwgettty(0, &wwoldtty) < 0)
43 return -1;
44 wwwintty = wwoldtty;
45 #ifdef OLD_TTY
46 wwwintty.ww_sgttyb.sg_flags &= ~XTABS;
47 wwnewtty.ww_sgttyb = wwoldtty.ww_sgttyb;
48 wwnewtty.ww_sgttyb.sg_erase = -1;
49 wwnewtty.ww_sgttyb.sg_kill = -1;
50 wwnewtty.ww_sgttyb.sg_flags |= CBREAK;
51 wwnewtty.ww_sgttyb.sg_flags &= ~(ECHO|CRMOD);
52 wwnewtty.ww_tchars.t_intrc = -1;
53 wwnewtty.ww_tchars.t_quitc = -1;
54 wwnewtty.ww_tchars.t_startc = -1;
55 wwnewtty.ww_tchars.t_stopc = -1;
56 wwnewtty.ww_tchars.t_eofc = -1;
57 wwnewtty.ww_tchars.t_brkc = -1;
58 wwnewtty.ww_ltchars.t_suspc = -1;
59 wwnewtty.ww_ltchars.t_dsuspc = -1;
60 wwnewtty.ww_ltchars.t_rprntc = -1;
61 wwnewtty.ww_ltchars.t_flushc = -1;
62 wwnewtty.ww_ltchars.t_werasc = -1;
63 wwnewtty.ww_ltchars.t_lnextc = -1;
64 wwnewtty.ww_lmode = wwoldtty.ww_lmode | LLITOUT;
65 wwnewtty.ww_ldisc = wwoldtty.ww_ldisc;
66 #else
67 #ifndef OXTABS
68 #define OXTABS XTABS
69 #endif
70 #ifndef _POSIX_VDISABLE
71 #define _POSIX_VDISABLE -1
72 #endif
73 wwwintty.ww_termios.c_oflag &= ~OXTABS;
74 wwnewtty.ww_termios = wwoldtty.ww_termios;
75 wwnewtty.ww_termios.c_iflag &=
76 ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IMAXBEL);
77 wwnewtty.ww_termios.c_oflag = 0;
78 wwnewtty.ww_termios.c_cflag &= ~(CSIZE | PARENB);
79 wwnewtty.ww_termios.c_cflag |= CS8;
80 wwnewtty.ww_termios.c_lflag = 0;
81 for (i = 0; i < NCCS; i++)
82 wwnewtty.ww_termios.c_cc[i] = _POSIX_VDISABLE;
83 wwnewtty.ww_termios.c_cc[VMIN] = 0;
84 wwnewtty.ww_termios.c_cc[VTIME] = 0;
85 #endif
86 wwnewtty.ww_fflags = wwoldtty.ww_fflags | FASYNC;
87 if (wwsettty(0, &wwnewtty) < 0)
88 goto bad;
89
90 if ((wwterm = getenv("TERM")) == 0) {
91 wwerrno = WWE_BADTERM;
92 goto bad;
93 }
94 if (tgetent(wwtermcap, wwterm) != 1) {
95 wwerrno = WWE_BADTERM;
96 goto bad;
97 }
98 #ifdef OLD_TTY
99 wwospeed = wwoldtty.ww_sgttyb.sg_ospeed;
100 #else
101 wwospeed = cfgetospeed(&wwoldtty.ww_termios);
102 #endif
103 switch (wwospeed) {
104 default:
105 case B0:
106 wwbaud = 0;
107 break;
108 case B50:
109 wwbaud = 50;
110 break;
111 case B75:
112 wwbaud = 75;
113 break;
114 case B110:
115 wwbaud = 110;
116 break;
117 case B134:
118 wwbaud = 134;
119 break;
120 case B150:
121 wwbaud = 150;
122 break;
123 case B200:
124 wwbaud = 200;
125 break;
126 case B300:
127 wwbaud = 300;
128 break;
129 case B600:
130 wwbaud = 600;
131 break;
132 case B1200:
133 wwbaud = 1200;
134 break;
135 case B1800:
136 wwbaud = 1800;
137 break;
138 case B2400:
139 wwbaud = 2400;
140 break;
141 case B4800:
142 wwbaud = 4800;
143 break;
144 case B9600:
145 wwbaud = 9600;
146 break;
147 #ifdef B19200
148 case B19200:
149 #else
150 case EXTA:
151 #endif
152 wwbaud = 19200;
153 break;
154 #ifdef B38400
155 case B38400:
156 #else
157 case EXTB:
158 #endif
159 wwbaud = 38400;
160 break;
161 }
162
163 if (xxinit() < 0)
164 goto bad;
165 wwnrow = tt.tt_nrow;
166 wwncol = tt.tt_ncol;
167 wwavailmodes = tt.tt_availmodes;
168 wwwrap = tt.tt_wrap;
169
170 if (wwavailmodes & WWM_REV)
171 wwcursormodes = WWM_REV | wwavailmodes & WWM_BLK;
172 else if (wwavailmodes & WWM_UL)
173 wwcursormodes = WWM_UL;
174
175 if ((wwib = malloc((unsigned) 512)) == 0)
176 goto bad;
177 wwibe = wwib + 512;
178 wwibq = wwibp = wwib;
179
180 if ((wwsmap = wwalloc(0, 0, wwnrow, wwncol, sizeof (char))) == 0)
181 goto bad;
182 for (i = 0; i < wwnrow; i++)
183 for (j = 0; j < wwncol; j++)
184 wwsmap[i][j] = WWX_NOBODY;
185
186 wwos = (union ww_char **)
187 wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char));
188 if (wwos == 0)
189 goto bad;
190 /* wwos is cleared in wwstart1() */
191 wwns = (union ww_char **)
192 wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char));
193 if (wwns == 0)
194 goto bad;
195 for (i = 0; i < wwnrow; i++)
196 for (j = 0; j < wwncol; j++)
197 wwns[i][j].c_w = ' ';
198 if (tt.tt_checkpoint) {
199 /* wwcs is also cleared in wwstart1() */
200 wwcs = (union ww_char **)
201 wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char));
202 if (wwcs == 0)
203 goto bad;
204 }
205
206 wwtouched = malloc((unsigned) wwnrow);
207 if (wwtouched == 0) {
208 wwerrno = WWE_NOMEM;
209 goto bad;
210 }
211 for (i = 0; i < wwnrow; i++)
212 wwtouched[i] = 0;
213
214 wwupd = (struct ww_update *) malloc((unsigned) wwnrow * sizeof *wwupd);
215 if (wwupd == 0) {
216 wwerrno = WWE_NOMEM;
217 goto bad;
218 }
219
220 wwindex[WWX_NOBODY] = &wwnobody;
221 wwnobody.ww_order = NWW;
222
223 kp = wwwintermcap;
224 if (wwavailmodes & WWM_REV)
225 wwaddcap1(WWT_REV, &kp);
226 if (wwavailmodes & WWM_BLK)
227 wwaddcap1(WWT_BLK, &kp);
228 if (wwavailmodes & WWM_UL)
229 wwaddcap1(WWT_UL, &kp);
230 if (wwavailmodes & WWM_GRP)
231 wwaddcap1(WWT_GRP, &kp);
232 if (wwavailmodes & WWM_DIM)
233 wwaddcap1(WWT_DIM, &kp);
234 if (wwavailmodes & WWM_USR)
235 wwaddcap1(WWT_USR, &kp);
236 if (tt.tt_insline && tt.tt_delline || tt.tt_setscroll)
237 wwaddcap1(WWT_ALDL, &kp);
238 if (tt.tt_inschar)
239 wwaddcap1(WWT_IMEI, &kp);
240 if (tt.tt_insspace)
241 wwaddcap1(WWT_IC, &kp);
242 if (tt.tt_delchar)
243 wwaddcap1(WWT_DC, &kp);
244 wwaddcap("kb", &kp);
245 wwaddcap("ku", &kp);
246 wwaddcap("kd", &kp);
247 wwaddcap("kl", &kp);
248 wwaddcap("kr", &kp);
249 wwaddcap("kh", &kp);
250 if ((j = tgetnum("kn")) >= 0) {
251 char cap[32];
252
253 (void) sprintf(kp, "kn#%d:", j);
254 for (; *kp; kp++)
255 ;
256 for (i = 1; i <= j; i++) {
257 (void) sprintf(cap, "k%d", i);
258 wwaddcap(cap, &kp);
259 cap[0] = 'l';
260 wwaddcap(cap, &kp);
261 }
262 }
263 /*
264 * It's ok to do this here even if setenv() is destructive
265 * since tt_init() has already made its own copy of it and
266 * wwterm now points to the copy.
267 */
268 (void) setenv("TERM", WWT_TERM, 1);
269 #ifdef TERMINFO
270 if (wwterminfoinit() < 0)
271 goto bad;
272 #endif
273
274 if (tt.tt_checkpoint)
275 if (signal(SIGALRM, wwalarm) == BADSIG) {
276 wwerrno = WWE_SYS;
277 goto bad;
278 }
279 /* catch typeahead before ASYNC was set */
280 (void) kill(getpid(), SIGIO);
281 wwstart1();
282 (void) sigsetmask(s);
283 return 0;
284 bad:
285 /*
286 * Don't bother to free storage. We're supposed
287 * to exit when wwinit fails anyway.
288 */
289 (void) wwsettty(0, &wwoldtty);
290 (void) signal(SIGIO, SIG_DFL);
291 (void) sigsetmask(s);
292 return -1;
293 }
294
wwaddcap(cap,kp)295 wwaddcap(cap, kp)
296 register char *cap;
297 register char **kp;
298 {
299 char tbuf[512];
300 char *tp = tbuf;
301 register char *str, *p;
302
303 if ((str = tgetstr(cap, &tp)) != 0) {
304 while (*(*kp)++ = *cap++)
305 ;
306 (*kp)[-1] = '=';
307 while (*str) {
308 for (p = unctrl(*str++); *(*kp)++ = *p++;)
309 ;
310 (*kp)--;
311 }
312 *(*kp)++ = ':';
313 **kp = 0;
314 }
315 }
316
wwaddcap1(cap,kp)317 wwaddcap1(cap, kp)
318 register char *cap;
319 register char **kp;
320 {
321 while (*(*kp)++ = *cap++)
322 ;
323 (*kp)--;
324 }
325
wwstart()326 wwstart()
327 {
328 register i;
329
330 (void) wwsettty(0, &wwnewtty);
331 for (i = 0; i < wwnrow; i++)
332 wwtouched[i] = WWU_TOUCHED;
333 wwstart1();
334 }
335
wwstart1()336 wwstart1()
337 {
338 register i, j;
339
340 for (i = 0; i < wwnrow; i++)
341 for (j = 0; j < wwncol; j++) {
342 wwos[i][j].c_w = ' ';
343 if (tt.tt_checkpoint)
344 wwcs[i][j].c_w = ' ';
345 }
346 xxstart();
347 if (tt.tt_checkpoint)
348 wwdocheckpoint = 1;
349 }
350
351 /*
352 * Reset data structures and terminal from an unknown state.
353 * Restoring wwos has been taken care of elsewhere.
354 */
wwreset()355 wwreset()
356 {
357 register i;
358
359 xxreset();
360 for (i = 0; i < wwnrow; i++)
361 wwtouched[i] = WWU_TOUCHED;
362 }
363