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 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 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 317 wwaddcap1(cap, kp) 318 register char *cap; 319 register char **kp; 320 { 321 while (*(*kp)++ = *cap++) 322 ; 323 (*kp)--; 324 } 325 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 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 */ 355 wwreset() 356 { 357 register i; 358 359 xxreset(); 360 for (i = 0; i < wwnrow; i++) 361 wwtouched[i] = WWU_TOUCHED; 362 } 363