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.40 (Berkeley) 08/12/90"; 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)); 32 if (signal(SIGIO, wwrint) == BADSIG || 33 signal(SIGCHLD, wwchild) == BADSIG || 34 signal(SIGPIPE, SIG_IGN) == BADSIG) { 35 wwerrno = WWE_SYS; 36 return -1; 37 } 38 39 if (wwgettty(0, &wwoldtty) < 0) 40 return -1; 41 wwwintty = wwoldtty; 42 #ifdef OLD_TTY 43 wwwintty.ww_sgttyb.sg_flags &= ~XTABS; 44 wwnewtty.ww_sgttyb = wwoldtty.ww_sgttyb; 45 wwnewtty.ww_sgttyb.sg_erase = -1; 46 wwnewtty.ww_sgttyb.sg_kill = -1; 47 wwnewtty.ww_sgttyb.sg_flags |= CBREAK; 48 wwnewtty.ww_sgttyb.sg_flags &= ~(ECHO|CRMOD); 49 wwnewtty.ww_tchars.t_intrc = -1; 50 wwnewtty.ww_tchars.t_quitc = -1; 51 wwnewtty.ww_tchars.t_startc = -1; 52 wwnewtty.ww_tchars.t_stopc = -1; 53 wwnewtty.ww_tchars.t_eofc = -1; 54 wwnewtty.ww_tchars.t_brkc = -1; 55 wwnewtty.ww_ltchars.t_suspc = -1; 56 wwnewtty.ww_ltchars.t_dsuspc = -1; 57 wwnewtty.ww_ltchars.t_rprntc = -1; 58 wwnewtty.ww_ltchars.t_flushc = -1; 59 wwnewtty.ww_ltchars.t_werasc = -1; 60 wwnewtty.ww_ltchars.t_lnextc = -1; 61 wwnewtty.ww_lmode = wwoldtty.ww_lmode | LLITOUT; 62 wwnewtty.ww_ldisc = wwoldtty.ww_ldisc; 63 #else 64 #ifndef OXTABS 65 #define OXTABS XTABS 66 #endif 67 #ifndef _POSIX_VDISABLE 68 #define _POSIX_VDISABLE -1 69 #endif 70 wwwintty.ww_termios.c_oflag &= ~OXTABS; 71 wwnewtty.ww_termios = wwoldtty.ww_termios; 72 wwnewtty.ww_termios.c_iflag &= 73 ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IMAXBEL); 74 wwnewtty.ww_termios.c_iflag |= INPCK; 75 wwnewtty.ww_termios.c_oflag = 0; 76 wwnewtty.ww_termios.c_cflag &= ~(CSIZE | PARENB); 77 wwnewtty.ww_termios.c_cflag |= CS8; 78 wwnewtty.ww_termios.c_lflag = 0; 79 for (i = 0; i < NCCS; i++) 80 wwnewtty.ww_termios.c_cc[i] = _POSIX_VDISABLE; 81 #endif 82 wwnewtty.ww_fflags = wwoldtty.ww_fflags | FASYNC; 83 if (wwsettty(0, &wwnewtty) < 0) 84 goto bad; 85 86 if ((wwterm = getenv("TERM")) == 0) { 87 wwerrno = WWE_BADTERM; 88 goto bad; 89 } 90 if (tgetent(wwtermcap, wwterm) != 1) { 91 wwerrno = WWE_BADTERM; 92 goto bad; 93 } 94 #ifdef OLD_TTY 95 wwospeed = wwoldtty.ww_sgttyb.sg_ospeed; 96 #else 97 wwospeed = cfgetospeed(&wwoldtty.ww_termios); 98 #endif 99 switch (wwospeed) { 100 default: 101 case B0: 102 wwbaud = 0; 103 break; 104 case B50: 105 wwbaud = 50; 106 break; 107 case B75: 108 wwbaud = 75; 109 break; 110 case B110: 111 wwbaud = 110; 112 break; 113 case B134: 114 wwbaud = 134; 115 break; 116 case B150: 117 wwbaud = 150; 118 break; 119 case B200: 120 wwbaud = 200; 121 break; 122 case B300: 123 wwbaud = 300; 124 break; 125 case B600: 126 wwbaud = 600; 127 break; 128 case B1200: 129 wwbaud = 1200; 130 break; 131 case B1800: 132 wwbaud = 1800; 133 break; 134 case B2400: 135 wwbaud = 2400; 136 break; 137 case B4800: 138 wwbaud = 4800; 139 break; 140 case B9600: 141 wwbaud = 9600; 142 break; 143 #ifdef B19200 144 case B19200: 145 #else 146 case EXTA: 147 #endif 148 wwbaud = 19200; 149 break; 150 #ifdef B38400 151 case B38400: 152 #else 153 case EXTB: 154 #endif 155 wwbaud = 38400; 156 break; 157 } 158 159 if (xxinit() < 0) 160 goto bad; 161 wwnrow = tt.tt_nrow; 162 wwncol = tt.tt_ncol; 163 wwavailmodes = tt.tt_availmodes; 164 wwwrap = tt.tt_wrap; 165 166 if (wwavailmodes & WWM_REV) 167 wwcursormodes = WWM_REV | wwavailmodes & WWM_BLK; 168 else if (wwavailmodes & WWM_UL) 169 wwcursormodes = WWM_UL; 170 171 if ((wwib = malloc((unsigned) 512)) == 0) 172 goto bad; 173 wwibe = wwib + 512; 174 wwibq = wwibp = wwib; 175 176 if ((wwsmap = wwalloc(0, 0, wwnrow, wwncol, sizeof (char))) == 0) 177 goto bad; 178 for (i = 0; i < wwnrow; i++) 179 for (j = 0; j < wwncol; j++) 180 wwsmap[i][j] = WWX_NOBODY; 181 182 wwos = (union ww_char **) 183 wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char)); 184 if (wwos == 0) 185 goto bad; 186 for (i = 0; i < wwnrow; i++) 187 for (j = 0; j < wwncol; j++) 188 wwos[i][j].c_w = ' '; 189 wwns = (union ww_char **) 190 wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char)); 191 if (wwns == 0) 192 goto bad; 193 for (i = 0; i < wwnrow; i++) 194 for (j = 0; j < wwncol; j++) 195 wwns[i][j].c_w = ' '; 196 197 wwtouched = malloc((unsigned) wwnrow); 198 if (wwtouched == 0) { 199 wwerrno = WWE_NOMEM; 200 goto bad; 201 } 202 for (i = 0; i < wwnrow; i++) 203 wwtouched[i] = 0; 204 205 wwupd = (struct ww_update *) malloc((unsigned) wwnrow * sizeof *wwupd); 206 if (wwupd == 0) { 207 wwerrno = WWE_NOMEM; 208 goto bad; 209 } 210 211 wwindex[WWX_NOBODY] = &wwnobody; 212 wwnobody.ww_order = NWW; 213 214 kp = wwwintermcap; 215 if (wwavailmodes & WWM_REV) 216 wwaddcap1(WWT_REV, &kp); 217 if (wwavailmodes & WWM_BLK) 218 wwaddcap1(WWT_BLK, &kp); 219 if (wwavailmodes & WWM_UL) 220 wwaddcap1(WWT_UL, &kp); 221 if (wwavailmodes & WWM_GRP) 222 wwaddcap1(WWT_GRP, &kp); 223 if (wwavailmodes & WWM_DIM) 224 wwaddcap1(WWT_DIM, &kp); 225 if (wwavailmodes & WWM_USR) 226 wwaddcap1(WWT_USR, &kp); 227 if (tt.tt_insline && tt.tt_delline || tt.tt_setscroll) 228 wwaddcap1(WWT_ALDL, &kp); 229 if (tt.tt_inschar) 230 wwaddcap1(WWT_IMEI, &kp); 231 if (tt.tt_insspace) 232 wwaddcap1(WWT_IC, &kp); 233 if (tt.tt_delchar) 234 wwaddcap1(WWT_DC, &kp); 235 wwaddcap("kb", &kp); 236 wwaddcap("ku", &kp); 237 wwaddcap("kd", &kp); 238 wwaddcap("kl", &kp); 239 wwaddcap("kr", &kp); 240 wwaddcap("kh", &kp); 241 if ((j = tgetnum("kn")) >= 0) { 242 char cap[32]; 243 244 (void) sprintf(kp, "kn#%d:", j); 245 for (; *kp; kp++) 246 ; 247 for (i = 1; i <= j; i++) { 248 (void) sprintf(cap, "k%d", i); 249 wwaddcap(cap, &kp); 250 cap[0] = 'l'; 251 wwaddcap(cap, &kp); 252 } 253 } 254 /* 255 * It's ok to do this here even if setenv() is destructive 256 * since tt_init() has already made its own copy of it and 257 * wwterm now points to the copy. 258 */ 259 (void) setenv("TERM", WWT_TERM, 1); 260 261 (void) sigsetmask(s); 262 /* catch typeahead before ASYNC was set */ 263 (void) kill(getpid(), SIGIO); 264 xxstart(); 265 return 0; 266 bad: 267 /* 268 * Don't bother to free storage. We're supposed 269 * to exit when wwinit fails anyway. 270 */ 271 (void) wwsettty(0, &wwoldtty); 272 (void) signal(SIGIO, SIG_DFL); 273 (void) sigsetmask(s); 274 return -1; 275 } 276 277 wwaddcap(cap, kp) 278 register char *cap; 279 register char **kp; 280 { 281 char tbuf[512]; 282 char *tp = tbuf; 283 register char *str, *p; 284 285 if ((str = tgetstr(cap, &tp)) != 0) { 286 while (*(*kp)++ = *cap++) 287 ; 288 (*kp)[-1] = '='; 289 while (*str) { 290 for (p = unctrl(*str++); *(*kp)++ = *p++;) 291 ; 292 (*kp)--; 293 } 294 *(*kp)++ = ':'; 295 **kp = 0; 296 } 297 } 298 299 wwaddcap1(cap, kp) 300 register char *cap; 301 register char **kp; 302 { 303 while (*(*kp)++ = *cap++) 304 ; 305 (*kp)--; 306 } 307