1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * 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 3.41 (Berkeley) 08/16/92"; 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 21 wwinit() 22 { 23 register i, j; 24 char *kp; 25 int s; 26 27 wwdtablesize = getdtablesize(); 28 wwhead.ww_forw = &wwhead; 29 wwhead.ww_back = &wwhead; 30 31 s = sigblock(sigmask(SIGIO) | sigmask(SIGCHLD) | 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 for (i = 0; i < wwnrow; i++) 191 for (j = 0; j < wwncol; j++) 192 wwos[i][j].c_w = ' '; 193 wwns = (union ww_char **) 194 wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char)); 195 if (wwns == 0) 196 goto bad; 197 for (i = 0; i < wwnrow; i++) 198 for (j = 0; j < wwncol; j++) 199 wwns[i][j].c_w = ' '; 200 201 wwtouched = malloc((unsigned) wwnrow); 202 if (wwtouched == 0) { 203 wwerrno = WWE_NOMEM; 204 goto bad; 205 } 206 for (i = 0; i < wwnrow; i++) 207 wwtouched[i] = 0; 208 209 wwupd = (struct ww_update *) malloc((unsigned) wwnrow * sizeof *wwupd); 210 if (wwupd == 0) { 211 wwerrno = WWE_NOMEM; 212 goto bad; 213 } 214 215 wwindex[WWX_NOBODY] = &wwnobody; 216 wwnobody.ww_order = NWW; 217 218 kp = wwwintermcap; 219 if (wwavailmodes & WWM_REV) 220 wwaddcap1(WWT_REV, &kp); 221 if (wwavailmodes & WWM_BLK) 222 wwaddcap1(WWT_BLK, &kp); 223 if (wwavailmodes & WWM_UL) 224 wwaddcap1(WWT_UL, &kp); 225 if (wwavailmodes & WWM_GRP) 226 wwaddcap1(WWT_GRP, &kp); 227 if (wwavailmodes & WWM_DIM) 228 wwaddcap1(WWT_DIM, &kp); 229 if (wwavailmodes & WWM_USR) 230 wwaddcap1(WWT_USR, &kp); 231 if (tt.tt_insline && tt.tt_delline || tt.tt_setscroll) 232 wwaddcap1(WWT_ALDL, &kp); 233 if (tt.tt_inschar) 234 wwaddcap1(WWT_IMEI, &kp); 235 if (tt.tt_insspace) 236 wwaddcap1(WWT_IC, &kp); 237 if (tt.tt_delchar) 238 wwaddcap1(WWT_DC, &kp); 239 wwaddcap("kb", &kp); 240 wwaddcap("ku", &kp); 241 wwaddcap("kd", &kp); 242 wwaddcap("kl", &kp); 243 wwaddcap("kr", &kp); 244 wwaddcap("kh", &kp); 245 if ((j = tgetnum("kn")) >= 0) { 246 char cap[32]; 247 248 (void) sprintf(kp, "kn#%d:", j); 249 for (; *kp; kp++) 250 ; 251 for (i = 1; i <= j; i++) { 252 (void) sprintf(cap, "k%d", i); 253 wwaddcap(cap, &kp); 254 cap[0] = 'l'; 255 wwaddcap(cap, &kp); 256 } 257 } 258 /* 259 * It's ok to do this here even if setenv() is destructive 260 * since tt_init() has already made its own copy of it and 261 * wwterm now points to the copy. 262 */ 263 (void) setenv("TERM", WWT_TERM, 1); 264 #ifdef TERMINFO 265 if (wwterminfoinit() < 0) 266 goto bad; 267 #endif 268 269 (void) sigsetmask(s); 270 /* catch typeahead before ASYNC was set */ 271 (void) kill(getpid(), SIGIO); 272 xxstart(); 273 return 0; 274 bad: 275 /* 276 * Don't bother to free storage. We're supposed 277 * to exit when wwinit fails anyway. 278 */ 279 (void) wwsettty(0, &wwoldtty); 280 (void) signal(SIGIO, SIG_DFL); 281 (void) sigsetmask(s); 282 return -1; 283 } 284 285 wwaddcap(cap, kp) 286 register char *cap; 287 register char **kp; 288 { 289 char tbuf[512]; 290 char *tp = tbuf; 291 register char *str, *p; 292 293 if ((str = tgetstr(cap, &tp)) != 0) { 294 while (*(*kp)++ = *cap++) 295 ; 296 (*kp)[-1] = '='; 297 while (*str) { 298 for (p = unctrl(*str++); *(*kp)++ = *p++;) 299 ; 300 (*kp)--; 301 } 302 *(*kp)++ = ':'; 303 **kp = 0; 304 } 305 } 306 307 wwaddcap1(cap, kp) 308 register char *cap; 309 register char **kp; 310 { 311 while (*(*kp)++ = *cap++) 312 ; 313 (*kp)--; 314 } 315