xref: /csrg-svn/lib/libcurses/setterm.c (revision 59096)
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*59096Selan static char sccsid[] = "@(#)setterm.c	5.17 (Berkeley) 04/15/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[] = {
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,
3456298Selan 			&VB, &VS, &VE, &al, &dl, &sf, &sr, &AL_PARM,
3556298Selan 			&DL_PARM, &UP_PARM, &DOWN_PARM, &LEFT_PARM,
3656298Selan 			&RIGHT_PARM,
3739140Sbostic 		};
382243Sarnold 
3919875Sbloom static char	*aoftspace;		/* Address of _tspace for relocation */
4055987Sbostic static char	tspace[2048];		/* Space for capability strings */
4119875Sbloom 
4255987Sbostic char *ttytype;
432243Sarnold 
4455987Sbostic int
452243Sarnold setterm(type)
4655987Sbostic 	register char *type;
4755987Sbostic {
4855987Sbostic 	static char genbuf[1024];
4955987Sbostic 	static char __ttytype[1024];
5055987Sbostic 	register int unknown;
5118032Sbloom 	struct winsize win;
5255987Sbostic 	char *p;
532243Sarnold 
5455987Sbostic #ifdef DEBUG
5555987Sbostic 	__TRACE("setterm: (\"%s\")\nLINES = %d, COLS = %d\n",
5655987Sbostic 	    type, LINES, COLS);
5755987Sbostic #endif
582243Sarnold 	if (type[0] == '\0')
592243Sarnold 		type = "xx";
6055987Sbostic 	unknown = 0;
612243Sarnold 	if (tgetent(genbuf, type) != 1) {
622243Sarnold 		unknown++;
632243Sarnold 		strcpy(genbuf, "xx|dumb:");
642243Sarnold 	}
6555987Sbostic #ifdef DEBUG
6655987Sbostic 	__TRACE("setterm: tty = %s\n", type);
6755987Sbostic #endif
6818032Sbloom 
6955987Sbostic 	/* Try TIOCGWINSZ, and, if it fails, the termcap entry. */
7055987Sbostic 	if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1 &&
7155987Sbostic 	    win.ws_row != 0 && win.ws_col != 0) {
7255987Sbostic 		LINES = win.ws_row;
7355987Sbostic 		COLS = win.ws_col;
7455987Sbostic 	}  else {
752243Sarnold 		LINES = tgetnum("li");
762243Sarnold 		COLS = tgetnum("co");
7755987Sbostic 	}
7812570Sarnold 
7955987Sbostic 	/* POSIX 1003.2 requires that the environment override. */
8055987Sbostic 	if ((p = getenv("ROWS")) != NULL)
8155987Sbostic 		LINES = strtol(p, NULL, 10);
8255987Sbostic 	if ((p = getenv("COLUMNS")) != NULL)
8355987Sbostic 		COLS = strtol(p, NULL, 10);
8419875Sbloom 
8519875Sbloom 	/*
86*59096Selan 	 * Want cols > 4, otherwise things will fail.
8719875Sbloom 	 */
88*59096Selan 	if (COLS <= 4)
8957472Sbostic 		return (ERR);
9019875Sbloom 
9155987Sbostic #ifdef DEBUG
9255987Sbostic 	__TRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS);
9355987Sbostic #endif
9455987Sbostic 	aoftspace = tspace;
9555987Sbostic 	zap();			/* Get terminal description. */
9619875Sbloom 
9755987Sbostic 	/* Handle funny termcap capabilities. */
9855987Sbostic 	if (CS && SC && RC)
9955987Sbostic 		AL = DL = "";
10055987Sbostic 	if (AL_PARM && AL == NULL)
10155987Sbostic 		AL = "";
10255987Sbostic 	if (DL_PARM && DL == NULL)
10355987Sbostic 		DL = "";
10455987Sbostic 	if (IC) {
10555987Sbostic 		if (IM == NULL)
10655987Sbostic 			IM = "";
10755987Sbostic 		if (EI == NULL)
10855987Sbostic 			EI = "";
10955987Sbostic 	}
11058046Selan 
11158046Selan 	/* If we can't tab, we can't backtab, either. */
11258046Selan 	if (!GT)
11355987Sbostic 		BT = NULL;
11437420Sbostic 
11558046Selan 	/*
11658046Selan 	 * Test for cursor motion capbility.
11758046Selan 	 *
11858046Selan 	 * XXX
11958046Selan 	 * This is truly stupid -- tgoto returns "OOPS" if it can't
12058046Selan 	 * do cursor motions.
12158046Selan 	 */
12258046Selan 	if (tgoto(CM, 0, 0)[0] == 'O') {
12355987Sbostic 		CA = 0;
12455987Sbostic 		CM = 0;
12555987Sbostic 	} else
12655987Sbostic 		CA = 1;
12755987Sbostic 
12855987Sbostic 	PC = _PC ? _PC[0] : 0;
12955987Sbostic 	aoftspace = tspace;
13055987Sbostic 	ttytype = longname(genbuf, __ttytype);
13155987Sbostic 
13256298Selan 	if ((!AL && !al) || (!DL && !dl))
13356298Selan 		__noqch = 1;
13456298Selan 
13557472Sbostic 	return (unknown ? ERR : OK);
1362243Sarnold }
13719875Sbloom 
1382243Sarnold /*
13955987Sbostic  * zap --
14055987Sbostic  *	Gets all the terminal flags from the termcap database.
1412243Sarnold  */
14255987Sbostic static void
14319875Sbloom zap()
14419875Sbloom {
14555987Sbostic 	register char *namp, ***sp;
14655987Sbostic 	register char **fp;
14756238Selan 	char tmp[3];
14855987Sbostic #ifdef DEBUG
14919875Sbloom 	register char	*cp;
15019875Sbloom #endif
15156238Selan 	tmp[2] = '\0';
1522243Sarnold 
15357819Selan 	namp = "ambsdaeohchzinmimsncnsosulxbxnxtxsxx";
1542243Sarnold 	fp = sflags;
1552243Sarnold 	do {
15656238Selan 		*tmp = *namp;
15756238Selan 		*(tmp + 1) = *(namp + 1);
15856238Selan 		*(*fp++) = tgetflag(tmp);
15919875Sbloom #ifdef DEBUG
16055987Sbostic 		__TRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE");
16119875Sbloom #endif
1622243Sarnold 		namp += 2;
16356238Selan 
1642243Sarnold 	} while (*namp);
16556298Selan 	namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI";
1662243Sarnold 	sp = sstrs;
1672243Sarnold 	do {
16856238Selan 		*tmp = *namp;
16956238Selan 		*(tmp + 1) = *(namp + 1);
17056238Selan 		*(*sp++) = tgetstr(tmp, &aoftspace);
17119875Sbloom #ifdef DEBUG
17255987Sbostic 		__TRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\"");
17319875Sbloom 		if (*sp[-1] != NULL) {
17419875Sbloom 			for (cp = *sp[-1]; *cp; cp++)
17555987Sbostic 				__TRACE("%s", unctrl(*cp));
17655987Sbostic 			__TRACE("\"\n");
17719875Sbloom 		}
17819875Sbloom #endif
1792243Sarnold 		namp += 2;
1802243Sarnold 	} while (*namp);
18121040Sbloom 	if (XS)
18221040Sbloom 		SO = SE = NULL;
18321040Sbloom 	else {
18421040Sbloom 		if (tgetnum("sg") > 0)
18521040Sbloom 			SO = NULL;
18621040Sbloom 		if (tgetnum("ug") > 0)
18721040Sbloom 			US = NULL;
18821040Sbloom 		if (!SO && US) {
18921040Sbloom 			SO = US;
19021040Sbloom 			SE = UE;
19121040Sbloom 		}
1922243Sarnold 	}
1932243Sarnold }
1943786Sarnold 
1953786Sarnold /*
19655987Sbostic  * getcap --
19755987Sbostic  *	Return a capability from termcap.
1983786Sarnold  */
1993786Sarnold char *
2003786Sarnold getcap(name)
20155987Sbostic 	char *name;
2023786Sarnold {
20355987Sbostic 	return (tgetstr(name, &aoftspace));
2043786Sarnold }
205