xref: /csrg-svn/lib/libcurses/setterm.c (revision 60058)
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*60058Sbostic static char sccsid[] = "@(#)setterm.c	5.19 (Berkeley) 05/16/93";
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[] = {
2259864Sbostic 		/*       am   bs   da   eo   hc   hz   in   mi   ms  */
2355987Sbostic 			&AM, &BS, &DA, &EO, &HC, &HZ, &IN, &MI, &MS,
2459864Sbostic 		/*	 nc   ns   os   ul   xb   xn   xt   xs   xx  */
2555987Sbostic 			&NC, &NS, &OS, &UL, &XB, &XN, &XT, &XS, &XX
262243Sarnold 		};
272243Sarnold 
2819875Sbloom static char	*_PC,
2919875Sbloom 		**sstrs[] = {
3059864Sbostic 		/*	 AL   bc   bt   cd   ce   cl   cm   cr   cs  */
3119875Sbloom 			&AL, &BC, &BT, &CD, &CE, &CL, &CM, &CR, &CS,
3259864Sbostic 		/*	 dc   DL   dm   do   ed   ei   k0   k1   k2  */
3319875Sbloom 			&DC, &DL, &DM, &DO, &ED, &EI, &K0, &K1, &K2,
3459864Sbostic 		/*	 k3   k4   k5   k6   k7   k8   k9   ho   ic  */
3519875Sbloom 			&K3, &K4, &K5, &K6, &K7, &K8, &K9, &HO, &IC,
3659864Sbostic 		/*	 im   ip   kd   ke   kh   kl   kr   ks   ku  */
3719875Sbloom 			&IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU,
3859864Sbostic 		/*	 ll   ma   nd   nl    pc   rc   sc   se   SF */
3919875Sbloom 			&LL, &MA, &ND, &NL, &_PC, &RC, &SC, &SE, &SF,
4059864Sbostic 		/*	 so   SR   ta   te   ti   uc   ue   up   us  */
4119875Sbloom 			&SO, &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US,
4259864Sbostic 		/*	 vb   vs   ve   al   dl   sf   sr   AL	     */
4356298Selan 			&VB, &VS, &VE, &al, &dl, &sf, &sr, &AL_PARM,
4459864Sbostic 		/*	 DL	   UP	     DO		 LE	     */
4556298Selan 			&DL_PARM, &UP_PARM, &DOWN_PARM, &LEFT_PARM,
4659864Sbostic 		/*	 RI					     */
4756298Selan 			&RIGHT_PARM,
4839140Sbostic 		};
492243Sarnold 
5019875Sbloom static char	*aoftspace;		/* Address of _tspace for relocation */
5155987Sbostic static char	tspace[2048];		/* Space for capability strings */
5219875Sbloom 
5355987Sbostic char *ttytype;
542243Sarnold 
5555987Sbostic int
562243Sarnold setterm(type)
5755987Sbostic 	register char *type;
5855987Sbostic {
5955987Sbostic 	static char genbuf[1024];
6055987Sbostic 	static char __ttytype[1024];
6155987Sbostic 	register int unknown;
6218032Sbloom 	struct winsize win;
6355987Sbostic 	char *p;
642243Sarnold 
6555987Sbostic #ifdef DEBUG
66*60058Sbostic 	__CTRACE("setterm: (\"%s\")\nLINES = %d, COLS = %d\n",
6755987Sbostic 	    type, LINES, COLS);
6855987Sbostic #endif
692243Sarnold 	if (type[0] == '\0')
702243Sarnold 		type = "xx";
7155987Sbostic 	unknown = 0;
722243Sarnold 	if (tgetent(genbuf, type) != 1) {
732243Sarnold 		unknown++;
742243Sarnold 		strcpy(genbuf, "xx|dumb:");
752243Sarnold 	}
7655987Sbostic #ifdef DEBUG
77*60058Sbostic 	__CTRACE("setterm: tty = %s\n", type);
7855987Sbostic #endif
7918032Sbloom 
8055987Sbostic 	/* Try TIOCGWINSZ, and, if it fails, the termcap entry. */
8155987Sbostic 	if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1 &&
8255987Sbostic 	    win.ws_row != 0 && win.ws_col != 0) {
8355987Sbostic 		LINES = win.ws_row;
8455987Sbostic 		COLS = win.ws_col;
8555987Sbostic 	}  else {
862243Sarnold 		LINES = tgetnum("li");
872243Sarnold 		COLS = tgetnum("co");
8855987Sbostic 	}
8912570Sarnold 
9055987Sbostic 	/* POSIX 1003.2 requires that the environment override. */
9155987Sbostic 	if ((p = getenv("ROWS")) != NULL)
9255987Sbostic 		LINES = strtol(p, NULL, 10);
9355987Sbostic 	if ((p = getenv("COLUMNS")) != NULL)
9455987Sbostic 		COLS = strtol(p, NULL, 10);
9519875Sbloom 
9619875Sbloom 	/*
9759096Selan 	 * Want cols > 4, otherwise things will fail.
9819875Sbloom 	 */
9959096Selan 	if (COLS <= 4)
10057472Sbostic 		return (ERR);
10119875Sbloom 
10255987Sbostic #ifdef DEBUG
103*60058Sbostic 	__CTRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS);
10455987Sbostic #endif
10555987Sbostic 	aoftspace = tspace;
10655987Sbostic 	zap();			/* Get terminal description. */
10719875Sbloom 
10858046Selan 	/* If we can't tab, we can't backtab, either. */
10958046Selan 	if (!GT)
11055987Sbostic 		BT = NULL;
11137420Sbostic 
11258046Selan 	/*
11358046Selan 	 * Test for cursor motion capbility.
11458046Selan 	 *
11558046Selan 	 * XXX
11658046Selan 	 * This is truly stupid -- tgoto returns "OOPS" if it can't
11758046Selan 	 * do cursor motions.
11858046Selan 	 */
11958046Selan 	if (tgoto(CM, 0, 0)[0] == 'O') {
12055987Sbostic 		CA = 0;
12155987Sbostic 		CM = 0;
12255987Sbostic 	} else
12355987Sbostic 		CA = 1;
12455987Sbostic 
12555987Sbostic 	PC = _PC ? _PC[0] : 0;
12655987Sbostic 	aoftspace = tspace;
12755987Sbostic 	ttytype = longname(genbuf, __ttytype);
12855987Sbostic 
12956298Selan 	if ((!AL && !al) || (!DL && !dl))
13056298Selan 		__noqch = 1;
13156298Selan 
13257472Sbostic 	return (unknown ? ERR : OK);
1332243Sarnold }
13419875Sbloom 
1352243Sarnold /*
13655987Sbostic  * zap --
13755987Sbostic  *	Gets all the terminal flags from the termcap database.
1382243Sarnold  */
13955987Sbostic static void
14019875Sbloom zap()
14119875Sbloom {
14255987Sbostic 	register char *namp, ***sp;
14355987Sbostic 	register char **fp;
14456238Selan 	char tmp[3];
14555987Sbostic #ifdef DEBUG
14619875Sbloom 	register char	*cp;
14719875Sbloom #endif
14856238Selan 	tmp[2] = '\0';
1492243Sarnold 
15057819Selan 	namp = "ambsdaeohchzinmimsncnsosulxbxnxtxsxx";
1512243Sarnold 	fp = sflags;
1522243Sarnold 	do {
15356238Selan 		*tmp = *namp;
15456238Selan 		*(tmp + 1) = *(namp + 1);
15556238Selan 		*(*fp++) = tgetflag(tmp);
15619875Sbloom #ifdef DEBUG
157*60058Sbostic 		__CTRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE");
15819875Sbloom #endif
1592243Sarnold 		namp += 2;
16056238Selan 
1612243Sarnold 	} while (*namp);
16256298Selan 	namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI";
1632243Sarnold 	sp = sstrs;
1642243Sarnold 	do {
16556238Selan 		*tmp = *namp;
16656238Selan 		*(tmp + 1) = *(namp + 1);
16756238Selan 		*(*sp++) = tgetstr(tmp, &aoftspace);
16819875Sbloom #ifdef DEBUG
169*60058Sbostic 		__CTRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\"");
17019875Sbloom 		if (*sp[-1] != NULL) {
17119875Sbloom 			for (cp = *sp[-1]; *cp; cp++)
172*60058Sbostic 				__CTRACE("%s", unctrl(*cp));
173*60058Sbostic 			__CTRACE("\"\n");
17419875Sbloom 		}
17519875Sbloom #endif
1762243Sarnold 		namp += 2;
1772243Sarnold 	} while (*namp);
17821040Sbloom 	if (XS)
17921040Sbloom 		SO = SE = NULL;
18021040Sbloom 	else {
18121040Sbloom 		if (tgetnum("sg") > 0)
18221040Sbloom 			SO = NULL;
18321040Sbloom 		if (tgetnum("ug") > 0)
18421040Sbloom 			US = NULL;
18521040Sbloom 		if (!SO && US) {
18621040Sbloom 			SO = US;
18721040Sbloom 			SE = UE;
18821040Sbloom 		}
1892243Sarnold 	}
1902243Sarnold }
1913786Sarnold 
1923786Sarnold /*
19355987Sbostic  * getcap --
19455987Sbostic  *	Return a capability from termcap.
1953786Sarnold  */
1963786Sarnold char *
1973786Sarnold getcap(name)
19855987Sbostic 	char *name;
1993786Sarnold {
20055987Sbostic 	return (tgetstr(name, &aoftspace));
2013786Sarnold }
202