118727Sedward /* 233514Sbostic * Copyright (c) 1983 Regents of the University of California. 333514Sbostic * All rights reserved. 433514Sbostic * 542954Sbostic * This code is derived from software contributed to Berkeley by 642954Sbostic * Edward Wang at The University of California, Berkeley. 742954Sbostic * 842835Sbostic * %sccs.include.redist.c% 918727Sedward */ 1018727Sedward 1133514Sbostic #ifndef lint 12*56710Sedward static char sccsid[] = "@(#)wwinit.c 3.42 (Berkeley) 11/10/92"; 1333514Sbostic #endif /* not lint */ 1433514Sbostic 1513925Sedward #include "ww.h" 1614649Sedward #include "tt.h" 1716111Sedward #include <sys/signal.h> 1816111Sedward #include <fcntl.h> 1916309Sedward #include "char.h" 2013925Sedward 2113925Sedward wwinit() 2213925Sedward { 2314407Sedward register i, j; 2416231Sedward char *kp; 2516398Sedward int s; 2613962Sedward 2714407Sedward wwdtablesize = getdtablesize(); 2816231Sedward wwhead.ww_forw = &wwhead; 2916231Sedward wwhead.ww_back = &wwhead; 3016111Sedward 31*56710Sedward s = sigblock(sigmask(SIGIO) | sigmask(SIGCHLD) | sigmask(SIGALRM) | 3255911Sedward sigmask(SIGHUP) | sigmask(SIGTERM)); 3338563Sedward if (signal(SIGIO, wwrint) == BADSIG || 3438563Sedward signal(SIGCHLD, wwchild) == BADSIG || 3555911Sedward signal(SIGHUP, wwquit) == BADSIG || 3655911Sedward signal(SIGTERM, wwquit) == BADSIG || 3738563Sedward signal(SIGPIPE, SIG_IGN) == BADSIG) { 3838563Sedward wwerrno = WWE_SYS; 3916111Sedward return -1; 4038563Sedward } 4116111Sedward 4213962Sedward if (wwgettty(0, &wwoldtty) < 0) 4313962Sedward return -1; 4414295Sedward wwwintty = wwoldtty; 4545033Sedward #ifdef OLD_TTY 4614295Sedward wwwintty.ww_sgttyb.sg_flags &= ~XTABS; 4716231Sedward wwnewtty.ww_sgttyb = wwoldtty.ww_sgttyb; 4816231Sedward wwnewtty.ww_sgttyb.sg_erase = -1; 4916231Sedward wwnewtty.ww_sgttyb.sg_kill = -1; 5013962Sedward wwnewtty.ww_sgttyb.sg_flags |= CBREAK; 5113972Sedward wwnewtty.ww_sgttyb.sg_flags &= ~(ECHO|CRMOD); 5216231Sedward wwnewtty.ww_tchars.t_intrc = -1; 5316231Sedward wwnewtty.ww_tchars.t_quitc = -1; 5416231Sedward wwnewtty.ww_tchars.t_startc = -1; 5516231Sedward wwnewtty.ww_tchars.t_stopc = -1; 5616231Sedward wwnewtty.ww_tchars.t_eofc = -1; 5716231Sedward wwnewtty.ww_tchars.t_brkc = -1; 5816231Sedward wwnewtty.ww_ltchars.t_suspc = -1; 5916231Sedward wwnewtty.ww_ltchars.t_dsuspc = -1; 6016231Sedward wwnewtty.ww_ltchars.t_rprntc = -1; 6116231Sedward wwnewtty.ww_ltchars.t_flushc = -1; 6216231Sedward wwnewtty.ww_ltchars.t_werasc = -1; 6316231Sedward wwnewtty.ww_ltchars.t_lnextc = -1; 6416231Sedward wwnewtty.ww_lmode = wwoldtty.ww_lmode | LLITOUT; 6516231Sedward wwnewtty.ww_ldisc = wwoldtty.ww_ldisc; 6642834Sedward #else 6745033Sedward #ifndef OXTABS 6845033Sedward #define OXTABS XTABS 6945033Sedward #endif 7045033Sedward #ifndef _POSIX_VDISABLE 7145033Sedward #define _POSIX_VDISABLE -1 7245033Sedward #endif 7342834Sedward wwwintty.ww_termios.c_oflag &= ~OXTABS; 7442834Sedward wwnewtty.ww_termios = wwoldtty.ww_termios; 7542834Sedward wwnewtty.ww_termios.c_iflag &= 7642834Sedward ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IMAXBEL); 7742834Sedward wwnewtty.ww_termios.c_oflag = 0; 7842834Sedward wwnewtty.ww_termios.c_cflag &= ~(CSIZE | PARENB); 7942834Sedward wwnewtty.ww_termios.c_cflag |= CS8; 8042834Sedward wwnewtty.ww_termios.c_lflag = 0; 8145033Sedward for (i = 0; i < NCCS; i++) 8242834Sedward wwnewtty.ww_termios.c_cc[i] = _POSIX_VDISABLE; 8355911Sedward wwnewtty.ww_termios.c_cc[VMIN] = 0; 8455911Sedward wwnewtty.ww_termios.c_cc[VTIME] = 0; 8542834Sedward #endif 8616231Sedward wwnewtty.ww_fflags = wwoldtty.ww_fflags | FASYNC; 8745033Sedward if (wwsettty(0, &wwnewtty) < 0) 8814407Sedward goto bad; 8914135Sedward 9014851Sedward if ((wwterm = getenv("TERM")) == 0) { 9114851Sedward wwerrno = WWE_BADTERM; 9214407Sedward goto bad; 9314851Sedward } 9414851Sedward if (tgetent(wwtermcap, wwterm) != 1) { 9514851Sedward wwerrno = WWE_BADTERM; 9614407Sedward goto bad; 9714851Sedward } 9845033Sedward #ifdef OLD_TTY 9945033Sedward wwospeed = wwoldtty.ww_sgttyb.sg_ospeed; 10042834Sedward #else 10145033Sedward wwospeed = cfgetospeed(&wwoldtty.ww_termios); 10245033Sedward #endif 10345033Sedward switch (wwospeed) { 10445033Sedward default: 10545033Sedward case B0: 10645033Sedward wwbaud = 0; 10745033Sedward break; 10845033Sedward case B50: 10945033Sedward wwbaud = 50; 11045033Sedward break; 11145033Sedward case B75: 11245033Sedward wwbaud = 75; 11345033Sedward break; 11445033Sedward case B110: 11545033Sedward wwbaud = 110; 11645033Sedward break; 11745033Sedward case B134: 11845033Sedward wwbaud = 134; 11945033Sedward break; 12045033Sedward case B150: 12145033Sedward wwbaud = 150; 12245033Sedward break; 12345033Sedward case B200: 12445033Sedward wwbaud = 200; 12545033Sedward break; 12645033Sedward case B300: 12745033Sedward wwbaud = 300; 12845033Sedward break; 12945033Sedward case B600: 13045033Sedward wwbaud = 600; 13145033Sedward break; 13245033Sedward case B1200: 13345033Sedward wwbaud = 1200; 13445033Sedward break; 13545033Sedward case B1800: 13645033Sedward wwbaud = 1800; 13745033Sedward break; 13845033Sedward case B2400: 13945033Sedward wwbaud = 2400; 14045033Sedward break; 14145033Sedward case B4800: 14245033Sedward wwbaud = 4800; 14345033Sedward break; 14445033Sedward case B9600: 14545033Sedward wwbaud = 9600; 14645033Sedward break; 14745033Sedward #ifdef B19200 14845033Sedward case B19200: 14942834Sedward #else 15045033Sedward case EXTA: 15142834Sedward #endif 15245033Sedward wwbaud = 19200; 15345033Sedward break; 15445033Sedward #ifdef B38400 15545033Sedward case B38400: 15645033Sedward #else 15745033Sedward case EXTB: 15842834Sedward #endif 15945033Sedward wwbaud = 38400; 16045033Sedward break; 16145033Sedward } 16214407Sedward 16338563Sedward if (xxinit() < 0) 16414407Sedward goto bad; 16514407Sedward wwnrow = tt.tt_nrow; 16614407Sedward wwncol = tt.tt_ncol; 16714684Sedward wwavailmodes = tt.tt_availmodes; 16814696Sedward wwwrap = tt.tt_wrap; 16914407Sedward 17014763Sedward if (wwavailmodes & WWM_REV) 17114763Sedward wwcursormodes = WWM_REV | wwavailmodes & WWM_BLK; 17214763Sedward else if (wwavailmodes & WWM_UL) 17314763Sedward wwcursormodes = WWM_UL; 17414763Sedward 17515870Sedward if ((wwib = malloc((unsigned) 512)) == 0) 17615870Sedward goto bad; 17715870Sedward wwibe = wwib + 512; 17816111Sedward wwibq = wwibp = wwib; 17915870Sedward 18014985Sedward if ((wwsmap = wwalloc(0, 0, wwnrow, wwncol, sizeof (char))) == 0) 18114407Sedward goto bad; 18214407Sedward for (i = 0; i < wwnrow; i++) 18314407Sedward for (j = 0; j < wwncol; j++) 18414407Sedward wwsmap[i][j] = WWX_NOBODY; 18514591Sedward 18614407Sedward wwos = (union ww_char **) 18714985Sedward wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char)); 18814407Sedward if (wwos == 0) 18914407Sedward goto bad; 190*56710Sedward /* wwos is cleared in wwstart1() */ 19114407Sedward wwns = (union ww_char **) 19214985Sedward wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char)); 19314407Sedward if (wwns == 0) 19414407Sedward goto bad; 19514407Sedward for (i = 0; i < wwnrow; i++) 19614407Sedward for (j = 0; j < wwncol; j++) 19714407Sedward wwns[i][j].c_w = ' '; 198*56710Sedward if (tt.tt_checkpoint) { 199*56710Sedward /* wwcs is also cleared in wwstart1() */ 200*56710Sedward wwcs = (union ww_char **) 201*56710Sedward wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char)); 202*56710Sedward if (wwcs == 0) 203*56710Sedward goto bad; 204*56710Sedward } 20514407Sedward 20614662Sedward wwtouched = malloc((unsigned) wwnrow); 20714851Sedward if (wwtouched == 0) { 20814851Sedward wwerrno = WWE_NOMEM; 20914662Sedward goto bad; 21014851Sedward } 21114662Sedward for (i = 0; i < wwnrow; i++) 21214662Sedward wwtouched[i] = 0; 21314662Sedward 21435330Sedward wwupd = (struct ww_update *) malloc((unsigned) wwnrow * sizeof *wwupd); 21535330Sedward if (wwupd == 0) { 21635330Sedward wwerrno = WWE_NOMEM; 21735330Sedward goto bad; 21835330Sedward } 21935330Sedward 22014407Sedward wwindex[WWX_NOBODY] = &wwnobody; 22114407Sedward wwnobody.ww_order = NWW; 22214407Sedward 22334803Sedward kp = wwwintermcap; 22434803Sedward if (wwavailmodes & WWM_REV) 22534803Sedward wwaddcap1(WWT_REV, &kp); 22634803Sedward if (wwavailmodes & WWM_BLK) 22734803Sedward wwaddcap1(WWT_BLK, &kp); 22834803Sedward if (wwavailmodes & WWM_UL) 22934803Sedward wwaddcap1(WWT_UL, &kp); 23034803Sedward if (wwavailmodes & WWM_GRP) 23134803Sedward wwaddcap1(WWT_GRP, &kp); 23234803Sedward if (wwavailmodes & WWM_DIM) 23334803Sedward wwaddcap1(WWT_DIM, &kp); 23434803Sedward if (wwavailmodes & WWM_USR) 23534803Sedward wwaddcap1(WWT_USR, &kp); 23634803Sedward if (tt.tt_insline && tt.tt_delline || tt.tt_setscroll) 23734803Sedward wwaddcap1(WWT_ALDL, &kp); 23839338Sedward if (tt.tt_inschar) 23934803Sedward wwaddcap1(WWT_IMEI, &kp); 24039338Sedward if (tt.tt_insspace) 24139338Sedward wwaddcap1(WWT_IC, &kp); 24234803Sedward if (tt.tt_delchar) 24334803Sedward wwaddcap1(WWT_DC, &kp); 24416494Sedward wwaddcap("kb", &kp); 24516494Sedward wwaddcap("ku", &kp); 24616494Sedward wwaddcap("kd", &kp); 24716494Sedward wwaddcap("kl", &kp); 24816494Sedward wwaddcap("kr", &kp); 24916494Sedward wwaddcap("kh", &kp); 25016231Sedward if ((j = tgetnum("kn")) >= 0) { 25116231Sedward char cap[32]; 25214135Sedward 25316231Sedward (void) sprintf(kp, "kn#%d:", j); 25414135Sedward for (; *kp; kp++) 25514135Sedward ; 25616231Sedward for (i = 1; i <= j; i++) { 25714407Sedward (void) sprintf(cap, "k%d", i); 25816494Sedward wwaddcap(cap, &kp); 25914135Sedward cap[0] = 'l'; 26016494Sedward wwaddcap(cap, &kp); 26114135Sedward } 26214135Sedward } 26332322Sedward /* 26432322Sedward * It's ok to do this here even if setenv() is destructive 26532322Sedward * since tt_init() has already made its own copy of it and 26632322Sedward * wwterm now points to the copy. 26732322Sedward */ 26833758Sedward (void) setenv("TERM", WWT_TERM, 1); 26955911Sedward #ifdef TERMINFO 27055911Sedward if (wwterminfoinit() < 0) 27155911Sedward goto bad; 27255911Sedward #endif 27316231Sedward 274*56710Sedward if (tt.tt_checkpoint) 275*56710Sedward if (signal(SIGALRM, wwalarm) == BADSIG) { 276*56710Sedward wwerrno = WWE_SYS; 277*56710Sedward goto bad; 278*56710Sedward } 27938563Sedward /* catch typeahead before ASYNC was set */ 28038563Sedward (void) kill(getpid(), SIGIO); 281*56710Sedward wwstart1(); 282*56710Sedward (void) sigsetmask(s); 28313962Sedward return 0; 28414407Sedward bad: 28514662Sedward /* 28614662Sedward * Don't bother to free storage. We're supposed 28714662Sedward * to exit when wwinit fails anyway. 28814662Sedward */ 28945033Sedward (void) wwsettty(0, &wwoldtty); 29016111Sedward (void) signal(SIGIO, SIG_DFL); 29116398Sedward (void) sigsetmask(s); 29214407Sedward return -1; 29313925Sedward } 29414135Sedward 29516494Sedward wwaddcap(cap, kp) 29634803Sedward register char *cap; 29734803Sedward register char **kp; 29814135Sedward { 29914407Sedward char tbuf[512]; 30014407Sedward char *tp = tbuf; 30114287Sedward register char *str, *p; 30214135Sedward 30314135Sedward if ((str = tgetstr(cap, &tp)) != 0) { 30416231Sedward while (*(*kp)++ = *cap++) 30514135Sedward ; 30616231Sedward (*kp)[-1] = '='; 30714287Sedward while (*str) { 30816231Sedward for (p = unctrl(*str++); *(*kp)++ = *p++;) 30914287Sedward ; 31016231Sedward (*kp)--; 31114287Sedward } 31216231Sedward *(*kp)++ = ':'; 31316231Sedward **kp = 0; 31414135Sedward } 31514135Sedward } 31634803Sedward 31734803Sedward wwaddcap1(cap, kp) 31834803Sedward register char *cap; 31934803Sedward register char **kp; 32034803Sedward { 32134803Sedward while (*(*kp)++ = *cap++) 32234803Sedward ; 32334803Sedward (*kp)--; 32434803Sedward } 325*56710Sedward 326*56710Sedward wwstart() 327*56710Sedward { 328*56710Sedward register i; 329*56710Sedward 330*56710Sedward (void) wwsettty(0, &wwnewtty); 331*56710Sedward for (i = 0; i < wwnrow; i++) 332*56710Sedward wwtouched[i] = WWU_TOUCHED; 333*56710Sedward wwstart1(); 334*56710Sedward } 335*56710Sedward 336*56710Sedward wwstart1() 337*56710Sedward { 338*56710Sedward register i, j; 339*56710Sedward 340*56710Sedward for (i = 0; i < wwnrow; i++) 341*56710Sedward for (j = 0; j < wwncol; j++) { 342*56710Sedward wwos[i][j].c_w = ' '; 343*56710Sedward if (tt.tt_checkpoint) 344*56710Sedward wwcs[i][j].c_w = ' '; 345*56710Sedward } 346*56710Sedward xxstart(); 347*56710Sedward if (tt.tt_checkpoint) 348*56710Sedward wwdocheckpoint = 1; 349*56710Sedward } 350*56710Sedward 351*56710Sedward /* 352*56710Sedward * Reset data structures and terminal from an unknown state. 353*56710Sedward * Restoring wwos has been taken care of elsewhere. 354*56710Sedward */ 355*56710Sedward wwreset() 356*56710Sedward { 357*56710Sedward register i; 358*56710Sedward 359*56710Sedward xxreset(); 360*56710Sedward for (i = 0; i < wwnrow; i++) 361*56710Sedward wwtouched[i] = WWU_TOUCHED; 362*56710Sedward } 363