xref: /csrg-svn/usr.bin/window/wwinit.c (revision 69073)
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