xref: /csrg-svn/lib/libcurses/setterm.c (revision 56298)
12243Sarnold /*
234677Sbostic  * Copyright (c) 1981 Regents of the University of California.
334677Sbostic  * All rights reserved.
434677Sbostic  *
542653Sbostic  * %sccs.include.redist.c%
622656Sdist  */
722656Sdist 
822656Sdist #ifndef lint
9*56298Selan static char sccsid[] = "@(#)setterm.c	5.11 (Berkeley) 09/21/92";
1034677Sbostic #endif /* not lint */
1122656Sdist 
1255987Sbostic #include <sys/ioctl.h>
132243Sarnold 
1455987Sbostic #include <curses.h>
1555987Sbostic #include <stdlib.h>
1655987Sbostic #include <string.h>
1755987Sbostic #include <unistd.h>
182243Sarnold 
1955987Sbostic static void zap __P((void));
2055987Sbostic 
2155987Sbostic static char	*sflags[] = {
2255987Sbostic 			&AM, &BS, &DA, &EO, &HC, &HZ, &IN, &MI, &MS,
2355987Sbostic 			&NC, &NS, &OS, &UL, &XB, &XN, &XT, &XS, &XX
242243Sarnold 		};
252243Sarnold 
2619875Sbloom static char	*_PC,
2719875Sbloom 		**sstrs[] = {
2819875Sbloom 			&AL, &BC, &BT, &CD, &CE, &CL, &CM, &CR, &CS,
2919875Sbloom 			&DC, &DL, &DM, &DO, &ED, &EI, &K0, &K1, &K2,
3019875Sbloom 			&K3, &K4, &K5, &K6, &K7, &K8, &K9, &HO, &IC,
3119875Sbloom 			&IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU,
3219875Sbloom 			&LL, &MA, &ND, &NL, &_PC, &RC, &SC, &SE, &SF,
3319875Sbloom 			&SO, &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US,
34*56298Selan 			&VB, &VS, &VE, &al, &dl, &sf, &sr, &AL_PARM,
35*56298Selan 			&DL_PARM, &UP_PARM, &DOWN_PARM, &LEFT_PARM,
36*56298Selan 			&RIGHT_PARM,
3739140Sbostic 		};
382243Sarnold 
3919875Sbloom static char	*aoftspace;		/* Address of _tspace for relocation */
4055987Sbostic static char	tspace[2048];		/* Space for capability strings */
4119875Sbloom 
422243Sarnold static int	destcol, destline;
432243Sarnold 
4455987Sbostic char *ttytype;
452243Sarnold 
4655987Sbostic int
472243Sarnold setterm(type)
4855987Sbostic 	register char *type;
4955987Sbostic {
5055987Sbostic 	static char genbuf[1024];
5155987Sbostic 	static char __ttytype[1024];
5255987Sbostic 	register int unknown;
5318032Sbloom 	struct winsize win;
5455987Sbostic 	char *p;
552243Sarnold 
5655987Sbostic #ifdef DEBUG
5755987Sbostic 	__TRACE("setterm: (\"%s\")\nLINES = %d, COLS = %d\n",
5855987Sbostic 	    type, LINES, COLS);
5955987Sbostic #endif
602243Sarnold 	if (type[0] == '\0')
612243Sarnold 		type = "xx";
6255987Sbostic 	unknown = 0;
632243Sarnold 	if (tgetent(genbuf, type) != 1) {
642243Sarnold 		unknown++;
652243Sarnold 		strcpy(genbuf, "xx|dumb:");
662243Sarnold 	}
6755987Sbostic #ifdef DEBUG
6855987Sbostic 	__TRACE("setterm: tty = %s\n", type);
6955987Sbostic #endif
7018032Sbloom 
7155987Sbostic 	/* Try TIOCGWINSZ, and, if it fails, the termcap entry. */
7255987Sbostic 	if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1 &&
7355987Sbostic 	    win.ws_row != 0 && win.ws_col != 0) {
7455987Sbostic 		LINES = win.ws_row;
7555987Sbostic 		COLS = win.ws_col;
7655987Sbostic 	}  else {
772243Sarnold 		LINES = tgetnum("li");
782243Sarnold 		COLS = tgetnum("co");
7955987Sbostic 	}
8012570Sarnold 
8155987Sbostic 	/* POSIX 1003.2 requires that the environment override. */
8255987Sbostic 	if ((p = getenv("ROWS")) != NULL)
8355987Sbostic 		LINES = strtol(p, NULL, 10);
8455987Sbostic 	if ((p = getenv("COLUMNS")) != NULL)
8555987Sbostic 		COLS = strtol(p, NULL, 10);
8619875Sbloom 
8719875Sbloom 	/*
8855987Sbostic 	 * XXX
8955987Sbostic 	 * Historically, curses fails if rows <= 5, cols <= 4.
9019875Sbloom 	 */
9155987Sbostic 	if (LINES <= 5 || COLS <= 4)
9255987Sbostic 		return (ERR);
9319875Sbloom 
9455987Sbostic #ifdef DEBUG
9555987Sbostic 	__TRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS);
9655987Sbostic #endif
9755987Sbostic 	aoftspace = tspace;
9855987Sbostic 	zap();			/* Get terminal description. */
9919875Sbloom 
10055987Sbostic 	/* Handle funny termcap capabilities. */
10155987Sbostic 	if (CS && SC && RC)
10255987Sbostic 		AL = DL = "";
10355987Sbostic 	if (AL_PARM && AL == NULL)
10455987Sbostic 		AL = "";
10555987Sbostic 	if (DL_PARM && DL == NULL)
10655987Sbostic 		DL = "";
10755987Sbostic 	if (IC) {
10855987Sbostic 		if (IM == NULL)
10955987Sbostic 			IM = "";
11055987Sbostic 		if (EI == NULL)
11155987Sbostic 			EI = "";
11255987Sbostic 	}
11355987Sbostic 	if (!GT)		/* If we can't tab, we can't backtab either. */
11455987Sbostic 		BT = NULL;
11537420Sbostic 
11655987Sbostic 	if (tgoto(CM, destcol, destline)[0] == 'O') {
11755987Sbostic 		CA = 0;
11855987Sbostic 		CM = 0;
11955987Sbostic 	} else
12055987Sbostic 		CA = 1;
12155987Sbostic 
12255987Sbostic 	PC = _PC ? _PC[0] : 0;
12355987Sbostic 	aoftspace = tspace;
12455987Sbostic 	ttytype = longname(genbuf, __ttytype);
12555987Sbostic 
126*56298Selan 	if ((!AL && !al) || (!DL && !dl))
127*56298Selan 		__noqch = 1;
128*56298Selan 
12955987Sbostic 	return (unknown ? ERR : OK);
1302243Sarnold }
13119875Sbloom 
1322243Sarnold /*
13355987Sbostic  * zap --
13455987Sbostic  *	Gets all the terminal flags from the termcap database.
1352243Sarnold  */
13655987Sbostic static void
13719875Sbloom zap()
13819875Sbloom {
13955987Sbostic 	register char *namp, ***sp;
14055987Sbostic 	register char **fp;
14156238Selan 	char tmp[3];
14255987Sbostic #ifdef DEBUG
14319875Sbloom 	register char	*cp;
14419875Sbloom #endif
14556238Selan 	tmp[2] = '\0';
1462243Sarnold 
14721040Sbloom 	namp = "ambsdadbeohchzinmimsncnsosulxbxnxtxsxx";
1482243Sarnold 	fp = sflags;
1492243Sarnold 	do {
15056238Selan 		*tmp = *namp;
15156238Selan 		*(tmp + 1) = *(namp + 1);
15256238Selan 		*(*fp++) = tgetflag(tmp);
15319875Sbloom #ifdef DEBUG
15455987Sbostic 		__TRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE");
15519875Sbloom #endif
1562243Sarnold 		namp += 2;
15756238Selan 
1582243Sarnold 	} while (*namp);
159*56298Selan 	namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI";
1602243Sarnold 	sp = sstrs;
1612243Sarnold 	do {
16256238Selan 		*tmp = *namp;
16356238Selan 		*(tmp + 1) = *(namp + 1);
16456238Selan 		*(*sp++) = tgetstr(tmp, &aoftspace);
16519875Sbloom #ifdef DEBUG
16655987Sbostic 		__TRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\"");
16719875Sbloom 		if (*sp[-1] != NULL) {
16819875Sbloom 			for (cp = *sp[-1]; *cp; cp++)
16955987Sbostic 				__TRACE("%s", unctrl(*cp));
17055987Sbostic 			__TRACE("\"\n");
17119875Sbloom 		}
17219875Sbloom #endif
1732243Sarnold 		namp += 2;
1742243Sarnold 	} while (*namp);
17521040Sbloom 	if (XS)
17621040Sbloom 		SO = SE = NULL;
17721040Sbloom 	else {
17821040Sbloom 		if (tgetnum("sg") > 0)
17921040Sbloom 			SO = NULL;
18021040Sbloom 		if (tgetnum("ug") > 0)
18121040Sbloom 			US = NULL;
18221040Sbloom 		if (!SO && US) {
18321040Sbloom 			SO = US;
18421040Sbloom 			SE = UE;
18521040Sbloom 		}
1862243Sarnold 	}
1872243Sarnold }
1883786Sarnold 
1893786Sarnold /*
19055987Sbostic  * getcap --
19155987Sbostic  *	Return a capability from termcap.
1923786Sarnold  */
1933786Sarnold char *
1943786Sarnold getcap(name)
19555987Sbostic 	char *name;
1963786Sarnold {
19755987Sbostic 	return (tgetstr(name, &aoftspace));
1983786Sarnold }
199