xref: /csrg-svn/lib/libcurses/setterm.c (revision 67852)
12243Sarnold /*
267082Sbostic  * Copyright (c) 1981, 1993, 1994
361272Sbostic  *	The Regents of the University of California.  All rights reserved.
434677Sbostic  *
542653Sbostic  * %sccs.include.redist.c%
622656Sdist  */
722656Sdist 
822656Sdist #ifndef lint
9*67852Sbostic static char sccsid[] = "@(#)setterm.c	8.8 (Berkeley) 10/25/94";
1034677Sbostic #endif /* not lint */
1122656Sdist 
1267176Sbostic #include <sys/ioctl.h>		/* TIOCGWINSZ on old systems. */
1367176Sbostic 
1455987Sbostic #include <stdlib.h>
1555987Sbostic #include <string.h>
1667082Sbostic #include <termios.h>
1755987Sbostic #include <unistd.h>
182243Sarnold 
1967082Sbostic #include "curses.h"
2067082Sbostic 
2155987Sbostic static void zap __P((void));
2255987Sbostic 
2355987Sbostic static char	*sflags[] = {
2465311Sbostic 		/*       am   bs   da   eo   hc   in   mi   ms  */
2565311Sbostic 			&AM, &BS, &DA, &EO, &HC, &IN, &MI, &MS,
2659864Sbostic 		/*	 nc   ns   os   ul   xb   xn   xt   xs   xx  */
2755987Sbostic 			&NC, &NS, &OS, &UL, &XB, &XN, &XT, &XS, &XX
282243Sarnold 		};
292243Sarnold 
3019875Sbloom static char	*_PC,
3119875Sbloom 		**sstrs[] = {
3259864Sbostic 		/*	 AL   bc   bt   cd   ce   cl   cm   cr   cs  */
3319875Sbloom 			&AL, &BC, &BT, &CD, &CE, &CL, &CM, &CR, &CS,
3459864Sbostic 		/*	 dc   DL   dm   do   ed   ei   k0   k1   k2  */
3519875Sbloom 			&DC, &DL, &DM, &DO, &ED, &EI, &K0, &K1, &K2,
3659864Sbostic 		/*	 k3   k4   k5   k6   k7   k8   k9   ho   ic  */
3719875Sbloom 			&K3, &K4, &K5, &K6, &K7, &K8, &K9, &HO, &IC,
3859864Sbostic 		/*	 im   ip   kd   ke   kh   kl   kr   ks   ku  */
3919875Sbloom 			&IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU,
4059864Sbostic 		/*	 ll   ma   nd   nl    pc   rc   sc   se   SF */
4119875Sbloom 			&LL, &MA, &ND, &NL, &_PC, &RC, &SC, &SE, &SF,
4259864Sbostic 		/*	 so   SR   ta   te   ti   uc   ue   up   us  */
4319875Sbloom 			&SO, &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US,
4459864Sbostic 		/*	 vb   vs   ve   al   dl   sf   sr   AL	     */
4556298Selan 			&VB, &VS, &VE, &al, &dl, &sf, &sr, &AL_PARM,
4659864Sbostic 		/*	 DL	   UP	     DO		 LE	     */
4756298Selan 			&DL_PARM, &UP_PARM, &DOWN_PARM, &LEFT_PARM,
4859864Sbostic 		/*	 RI					     */
4956298Selan 			&RIGHT_PARM,
5039140Sbostic 		};
512243Sarnold 
5219875Sbloom static char	*aoftspace;		/* Address of _tspace for relocation */
5355987Sbostic static char	tspace[2048];		/* Space for capability strings */
5419875Sbloom 
5555987Sbostic char *ttytype;
562243Sarnold 
5755987Sbostic int
setterm(type)582243Sarnold setterm(type)
5955987Sbostic 	register char *type;
6055987Sbostic {
6155987Sbostic 	static char genbuf[1024];
6255987Sbostic 	static char __ttytype[1024];
6355987Sbostic 	register int unknown;
6418032Sbloom 	struct winsize win;
6555987Sbostic 	char *p;
662243Sarnold 
6755987Sbostic #ifdef DEBUG
6860058Sbostic 	__CTRACE("setterm: (\"%s\")\nLINES = %d, COLS = %d\n",
6955987Sbostic 	    type, LINES, COLS);
7055987Sbostic #endif
712243Sarnold 	if (type[0] == '\0')
722243Sarnold 		type = "xx";
7355987Sbostic 	unknown = 0;
742243Sarnold 	if (tgetent(genbuf, type) != 1) {
752243Sarnold 		unknown++;
762243Sarnold 		strcpy(genbuf, "xx|dumb:");
772243Sarnold 	}
7855987Sbostic #ifdef DEBUG
7960058Sbostic 	__CTRACE("setterm: tty = %s\n", type);
8055987Sbostic #endif
8118032Sbloom 
8255987Sbostic 	/* Try TIOCGWINSZ, and, if it fails, the termcap entry. */
8355987Sbostic 	if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1 &&
8455987Sbostic 	    win.ws_row != 0 && win.ws_col != 0) {
8555987Sbostic 		LINES = win.ws_row;
8655987Sbostic 		COLS = win.ws_col;
8755987Sbostic 	}  else {
882243Sarnold 		LINES = tgetnum("li");
892243Sarnold 		COLS = tgetnum("co");
9055987Sbostic 	}
9112570Sarnold 
9255987Sbostic 	/* POSIX 1003.2 requires that the environment override. */
9365312Sbostic 	if ((p = getenv("LINES")) != NULL)
9455987Sbostic 		LINES = strtol(p, NULL, 10);
9555987Sbostic 	if ((p = getenv("COLUMNS")) != NULL)
9655987Sbostic 		COLS = strtol(p, NULL, 10);
9719875Sbloom 
9819875Sbloom 	/*
9959096Selan 	 * Want cols > 4, otherwise things will fail.
10019875Sbloom 	 */
10159096Selan 	if (COLS <= 4)
10257472Sbostic 		return (ERR);
10319875Sbloom 
10455987Sbostic #ifdef DEBUG
10560058Sbostic 	__CTRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS);
10655987Sbostic #endif
10755987Sbostic 	aoftspace = tspace;
10855987Sbostic 	zap();			/* Get terminal description. */
10919875Sbloom 
11058046Selan 	/* If we can't tab, we can't backtab, either. */
11158046Selan 	if (!GT)
11255987Sbostic 		BT = NULL;
11337420Sbostic 
11458046Selan 	/*
11558046Selan 	 * Test for cursor motion capbility.
11658046Selan 	 *
11758046Selan 	 * XXX
118*67852Sbostic 	 * This is truly stupid -- historically, tgoto returns "OOPS" if it
119*67852Sbostic 	 * can't do cursor motions.  Some systems have been fixed to return
120*67852Sbostic 	 * a NULL pointer.
12158046Selan 	 */
122*67852Sbostic 	if ((p = tgoto(CM, 0, 0)) == NULL || *p == '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 
13267572Sbostic 	/* If no scrolling commands, no quick change. */
13367572Sbostic 	__noqch =
13467574Sbostic 	    (CS == NULL || HO == NULL ||
13567574Sbostic 	    SF == NULL && sf == NULL || SR == NULL && sr == NULL) &&
13667574Sbostic 	    (AL == NULL && al == NULL || DL == NULL && dl == NULL);
13756298Selan 
13857472Sbostic 	return (unknown ? ERR : OK);
1392243Sarnold }
14019875Sbloom 
1412243Sarnold /*
14255987Sbostic  * zap --
14355987Sbostic  *	Gets all the terminal flags from the termcap database.
1442243Sarnold  */
14555987Sbostic static void
zap()14619875Sbloom zap()
14719875Sbloom {
14855987Sbostic 	register char *namp, ***sp;
14955987Sbostic 	register char **fp;
15056238Selan 	char tmp[3];
15155987Sbostic #ifdef DEBUG
15219875Sbloom 	register char	*cp;
15319875Sbloom #endif
15456238Selan 	tmp[2] = '\0';
1552243Sarnold 
15665311Sbostic 	namp = "ambsdaeohcinmimsncnsosulxbxnxtxsxx";
1572243Sarnold 	fp = sflags;
1582243Sarnold 	do {
15956238Selan 		*tmp = *namp;
16056238Selan 		*(tmp + 1) = *(namp + 1);
16156238Selan 		*(*fp++) = tgetflag(tmp);
16219875Sbloom #ifdef DEBUG
16360058Sbostic 		__CTRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE");
16419875Sbloom #endif
1652243Sarnold 		namp += 2;
16656238Selan 
1672243Sarnold 	} while (*namp);
16856298Selan 	namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI";
1692243Sarnold 	sp = sstrs;
1702243Sarnold 	do {
17156238Selan 		*tmp = *namp;
17256238Selan 		*(tmp + 1) = *(namp + 1);
17356238Selan 		*(*sp++) = tgetstr(tmp, &aoftspace);
17419875Sbloom #ifdef DEBUG
17560058Sbostic 		__CTRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\"");
17619875Sbloom 		if (*sp[-1] != NULL) {
17719875Sbloom 			for (cp = *sp[-1]; *cp; cp++)
17860058Sbostic 				__CTRACE("%s", unctrl(*cp));
17960058Sbostic 			__CTRACE("\"\n");
18019875Sbloom 		}
18119875Sbloom #endif
1822243Sarnold 		namp += 2;
1832243Sarnold 	} while (*namp);
18421040Sbloom 	if (XS)
18521040Sbloom 		SO = SE = NULL;
18621040Sbloom 	else {
18721040Sbloom 		if (tgetnum("sg") > 0)
18821040Sbloom 			SO = NULL;
18921040Sbloom 		if (tgetnum("ug") > 0)
19021040Sbloom 			US = NULL;
19121040Sbloom 		if (!SO && US) {
19221040Sbloom 			SO = US;
19321040Sbloom 			SE = UE;
19421040Sbloom 		}
1952243Sarnold 	}
1962243Sarnold }
1973786Sarnold 
1983786Sarnold /*
19955987Sbostic  * getcap --
20055987Sbostic  *	Return a capability from termcap.
2013786Sarnold  */
2023786Sarnold char *
getcap(name)2033786Sarnold getcap(name)
20455987Sbostic 	char *name;
2053786Sarnold {
20655987Sbostic 	return (tgetstr(name, &aoftspace));
2073786Sarnold }
208