xref: /original-bsd/usr.bin/window/wwinit.c (revision 9e3bee04)
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.32 (Berkeley) 08/04/88";
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 	(*tt.tt_init)();
86 
87 	if (wwavailmodes & WWM_REV)
88 		wwcursormodes = WWM_REV | wwavailmodes & WWM_BLK;
89 	else if (wwavailmodes & WWM_UL)
90 		wwcursormodes = WWM_UL;
91 
92 	if ((wwib = malloc((unsigned) 512)) == 0)
93 		goto bad;
94 	wwibe = wwib + 512;
95 	wwibq = wwibp = wwib;
96 
97 	if ((wwsmap = wwalloc(0, 0, wwnrow, wwncol, sizeof (char))) == 0)
98 		goto bad;
99 	for (i = 0; i < wwnrow; i++)
100 		for (j = 0; j < wwncol; j++)
101 			wwsmap[i][j] = WWX_NOBODY;
102 
103 	wwos = (union ww_char **)
104 		wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char));
105 	if (wwos == 0)
106 		goto bad;
107 	for (i = 0; i < wwnrow; i++)
108 		for (j = 0; j < wwncol; j++)
109 			wwos[i][j].c_w = ' ';
110 	wwns = (union ww_char **)
111 		wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char));
112 	if (wwns == 0)
113 		goto bad;
114 	for (i = 0; i < wwnrow; i++)
115 		for (j = 0; j < wwncol; j++)
116 			wwns[i][j].c_w = ' ';
117 
118 	wwtouched = malloc((unsigned) wwnrow);
119 	if (wwtouched == 0) {
120 		wwerrno = WWE_NOMEM;
121 		goto bad;
122 	}
123 	for (i = 0; i < wwnrow; i++)
124 		wwtouched[i] = 0;
125 
126 	wwupd = (struct ww_update *) malloc((unsigned) wwnrow * sizeof *wwupd);
127 	if (wwupd == 0) {
128 		wwerrno = WWE_NOMEM;
129 		goto bad;
130 	}
131 
132 	wwindex[WWX_NOBODY] = &wwnobody;
133 	wwnobody.ww_order = NWW;
134 
135 	kp = wwwintermcap;
136 	if (wwavailmodes & WWM_REV)
137 		wwaddcap1(WWT_REV, &kp);
138 	if (wwavailmodes & WWM_BLK)
139 		wwaddcap1(WWT_BLK, &kp);
140 	if (wwavailmodes & WWM_UL)
141 		wwaddcap1(WWT_UL, &kp);
142 	if (wwavailmodes & WWM_GRP)
143 		wwaddcap1(WWT_GRP, &kp);
144 	if (wwavailmodes & WWM_DIM)
145 		wwaddcap1(WWT_DIM, &kp);
146 	if (wwavailmodes & WWM_USR)
147 		wwaddcap1(WWT_USR, &kp);
148 	if (tt.tt_insline && tt.tt_delline || tt.tt_setscroll)
149 		wwaddcap1(WWT_ALDL, &kp);
150 	if (tt.tt_hasinsert)
151 		wwaddcap1(WWT_IMEI, &kp);
152 	if (tt.tt_delchar)
153 		wwaddcap1(WWT_DC, &kp);
154 	wwaddcap("kb", &kp);
155 	wwaddcap("ku", &kp);
156 	wwaddcap("kd", &kp);
157 	wwaddcap("kl", &kp);
158 	wwaddcap("kr", &kp);
159 	wwaddcap("kh", &kp);
160 	if ((j = tgetnum("kn")) >= 0) {
161 		char cap[32];
162 
163 		(void) sprintf(kp, "kn#%d:", j);
164 		for (; *kp; kp++)
165 			;
166 		for (i = 1; i <= j; i++) {
167 			(void) sprintf(cap, "k%d", i);
168 			wwaddcap(cap, &kp);
169 			cap[0] = 'l';
170 			wwaddcap(cap, &kp);
171 		}
172 	}
173 	/*
174 	 * It's ok to do this here even if setenv() is destructive
175 	 * since tt_init() has already made its own copy of it and
176 	 * wwterm now points to the copy.
177 	 */
178 	(void) setenv("TERM", WWT_TERM, 1);
179 
180 	(void) signal(SIGPIPE, SIG_IGN);
181 	(void) sigsetmask(s);
182 	return 0;
183 bad:
184 	/*
185 	 * Don't bother to free storage.  We're supposed
186 	 * to exit when wwinit fails anyway.
187 	 */
188 	(void) wwsettty(0, &wwoldtty, &wwnewtty);
189 	(void) signal(SIGIO, SIG_DFL);
190 	(void) sigsetmask(s);
191 	return -1;
192 }
193 
194 wwaddcap(cap, kp)
195 	register char *cap;
196 	register char **kp;
197 {
198 	char tbuf[512];
199 	char *tp = tbuf;
200 	register char *str, *p;
201 
202 	if ((str = tgetstr(cap, &tp)) != 0) {
203 		while (*(*kp)++ = *cap++)
204 			;
205 		(*kp)[-1] = '=';
206 		while (*str) {
207 			for (p = unctrl(*str++); *(*kp)++ = *p++;)
208 				;
209 			(*kp)--;
210 		}
211 		*(*kp)++ = ':';
212 		**kp = 0;
213 	}
214 }
215 
216 wwaddcap1(cap, kp)
217 	register char *cap;
218 	register char **kp;
219 {
220 	while (*(*kp)++ = *cap++)
221 		;
222 	(*kp)--;
223 }
224