118727Sedward /*
262479Sbostic * Copyright (c) 1983, 1993
362479Sbostic * The Regents of the University of California. 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*69073Sbostic static char sccsid[] = "@(#)wwinit.c 8.2 (Berkeley) 04/28/95";
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
wwinit()2113925Sedward wwinit()
2213925Sedward {
2314407Sedward register i, j;
2416231Sedward char *kp;
2516398Sedward int s;
2613962Sedward
27*69073Sbostic wwdtablesize = 3;
2816231Sedward wwhead.ww_forw = &wwhead;
2916231Sedward wwhead.ww_back = &wwhead;
3016111Sedward
3156710Sedward 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;
19056710Sedward /* 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 = ' ';
19856710Sedward if (tt.tt_checkpoint) {
19956710Sedward /* wwcs is also cleared in wwstart1() */
20056710Sedward wwcs = (union ww_char **)
20156710Sedward wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char));
20256710Sedward if (wwcs == 0)
20356710Sedward goto bad;
20456710Sedward }
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
27456710Sedward if (tt.tt_checkpoint)
27556710Sedward if (signal(SIGALRM, wwalarm) == BADSIG) {
27656710Sedward wwerrno = WWE_SYS;
27756710Sedward goto bad;
27856710Sedward }
27938563Sedward /* catch typeahead before ASYNC was set */
28038563Sedward (void) kill(getpid(), SIGIO);
28156710Sedward wwstart1();
28256710Sedward (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
wwaddcap(cap,kp)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
wwaddcap1(cap,kp)31734803Sedward wwaddcap1(cap, kp)
31834803Sedward register char *cap;
31934803Sedward register char **kp;
32034803Sedward {
32134803Sedward while (*(*kp)++ = *cap++)
32234803Sedward ;
32334803Sedward (*kp)--;
32434803Sedward }
32556710Sedward
wwstart()32656710Sedward wwstart()
32756710Sedward {
32856710Sedward register i;
32956710Sedward
33056710Sedward (void) wwsettty(0, &wwnewtty);
33156710Sedward for (i = 0; i < wwnrow; i++)
33256710Sedward wwtouched[i] = WWU_TOUCHED;
33356710Sedward wwstart1();
33456710Sedward }
33556710Sedward
wwstart1()33656710Sedward wwstart1()
33756710Sedward {
33856710Sedward register i, j;
33956710Sedward
34056710Sedward for (i = 0; i < wwnrow; i++)
34156710Sedward for (j = 0; j < wwncol; j++) {
34256710Sedward wwos[i][j].c_w = ' ';
34356710Sedward if (tt.tt_checkpoint)
34456710Sedward wwcs[i][j].c_w = ' ';
34556710Sedward }
34656710Sedward xxstart();
34756710Sedward if (tt.tt_checkpoint)
34856710Sedward wwdocheckpoint = 1;
34956710Sedward }
35056710Sedward
35156710Sedward /*
35256710Sedward * Reset data structures and terminal from an unknown state.
35356710Sedward * Restoring wwos has been taken care of elsewhere.
35456710Sedward */
wwreset()35556710Sedward wwreset()
35656710Sedward {
35756710Sedward register i;
35856710Sedward
35956710Sedward xxreset();
36056710Sedward for (i = 0; i < wwnrow; i++)
36156710Sedward wwtouched[i] = WWU_TOUCHED;
36256710Sedward }
363