xref: /original-bsd/lib/libcurses/setterm.c (revision daedb501)
1 /*
2  * Copyright (c) 1981 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)setterm.c	5.9 (Berkeley) 08/23/92";
10 #endif /* not lint */
11 
12 #include <sys/ioctl.h>
13 
14 #include <curses.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <unistd.h>
18 
19 static void zap __P((void));
20 
21 static char	*sflags[] = {
22 			&AM, &BS, &DA, &EO, &HC, &HZ, &IN, &MI, &MS,
23 			&NC, &NS, &OS, &UL, &XB, &XN, &XT, &XS, &XX
24 		};
25 
26 static char	*_PC,
27 		**sstrs[] = {
28 			&AL, &BC, &BT, &CD, &CE, &CL, &CM, &CR, &CS,
29 			&DC, &DL, &DM, &DO, &ED, &EI, &K0, &K1, &K2,
30 			&K3, &K4, &K5, &K6, &K7, &K8, &K9, &HO, &IC,
31 			&IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU,
32 			&LL, &MA, &ND, &NL, &_PC, &RC, &SC, &SE, &SF,
33 			&SO, &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US,
34 			&VB, &VS, &VE, &AL_PARM, &DL_PARM, &UP_PARM,
35 			&DOWN_PARM, &LEFT_PARM, &RIGHT_PARM,
36 		};
37 
38 static char	*aoftspace;		/* Address of _tspace for relocation */
39 static char	tspace[2048];		/* Space for capability strings */
40 
41 static int	destcol, destline;
42 
43 char *ttytype;
44 
45 int
46 setterm(type)
47 	register char *type;
48 {
49 	static char genbuf[1024];
50 	static char __ttytype[1024];
51 	register int unknown;
52 	struct winsize win;
53 	char *p;
54 
55 #ifdef DEBUG
56 	__TRACE("setterm: (\"%s\")\nLINES = %d, COLS = %d\n",
57 	    type, LINES, COLS);
58 #endif
59 	if (type[0] == '\0')
60 		type = "xx";
61 	unknown = 0;
62 	if (tgetent(genbuf, type) != 1) {
63 		unknown++;
64 		strcpy(genbuf, "xx|dumb:");
65 	}
66 #ifdef DEBUG
67 	__TRACE("setterm: tty = %s\n", type);
68 #endif
69 
70 	/* Try TIOCGWINSZ, and, if it fails, the termcap entry. */
71 	if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1 &&
72 	    win.ws_row != 0 && win.ws_col != 0) {
73 		LINES = win.ws_row;
74 		COLS = win.ws_col;
75 	}  else {
76 		LINES = tgetnum("li");
77 		COLS = tgetnum("co");
78 	}
79 
80 	/* POSIX 1003.2 requires that the environment override. */
81 	if ((p = getenv("ROWS")) != NULL)
82 		LINES = strtol(p, NULL, 10);
83 	if ((p = getenv("COLUMNS")) != NULL)
84 		COLS = strtol(p, NULL, 10);
85 
86 	/*
87 	 * XXX
88 	 * Historically, curses fails if rows <= 5, cols <= 4.
89 	 */
90 	if (LINES <= 5 || COLS <= 4)
91 		return (ERR);
92 
93 #ifdef DEBUG
94 	__TRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS);
95 #endif
96 	aoftspace = tspace;
97 	zap();			/* Get terminal description. */
98 
99 	/* Handle funny termcap capabilities. */
100 	if (CS && SC && RC)
101 		AL = DL = "";
102 	if (AL_PARM && AL == NULL)
103 		AL = "";
104 	if (DL_PARM && DL == NULL)
105 		DL = "";
106 	if (IC) {
107 		if (IM == NULL)
108 			IM = "";
109 		if (EI == NULL)
110 			EI = "";
111 	}
112 	if (!GT)		/* If we can't tab, we can't backtab either. */
113 		BT = NULL;
114 
115 	if (tgoto(CM, destcol, destline)[0] == 'O') {
116 		CA = 0;
117 		CM = 0;
118 	} else
119 		CA = 1;
120 
121 	PC = _PC ? _PC[0] : 0;
122 	aoftspace = tspace;
123 	ttytype = longname(genbuf, __ttytype);
124 
125 	return (unknown ? ERR : OK);
126 }
127 
128 /*
129  * zap --
130  *	Gets all the terminal flags from the termcap database.
131  */
132 static void
133 zap()
134 {
135 	register char *namp, ***sp;
136 	register char **fp;
137 #ifdef DEBUG
138 	register char	*cp;
139 #endif
140 
141 	namp = "ambsdadbeohchzinmimsncnsosulxbxnxtxsxx";
142 	fp = sflags;
143 	do {
144 		*(*fp++) = tgetflag(namp);
145 #ifdef DEBUG
146 		__TRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE");
147 #endif
148 		namp += 2;
149 	} while (*namp);
150 	namp = "albcbtcdceclcmcrcsdcdldmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscsesfsosrtatetiucueupusvbvsveALDLUPDOLERI";
151 	sp = sstrs;
152 	do {
153 		*(*sp++) = tgetstr(namp, &aoftspace);
154 #ifdef DEBUG
155 		__TRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\"");
156 		if (*sp[-1] != NULL) {
157 			for (cp = *sp[-1]; *cp; cp++)
158 				__TRACE("%s", unctrl(*cp));
159 			__TRACE("\"\n");
160 		}
161 #endif
162 		namp += 2;
163 	} while (*namp);
164 	if (XS)
165 		SO = SE = NULL;
166 	else {
167 		if (tgetnum("sg") > 0)
168 			SO = NULL;
169 		if (tgetnum("ug") > 0)
170 			US = NULL;
171 		if (!SO && US) {
172 			SO = US;
173 			SE = UE;
174 		}
175 	}
176 }
177 
178 /*
179  * getcap --
180  *	Return a capability from termcap.
181  */
182 char *
183 getcap(name)
184 	char *name;
185 {
186 	return (tgetstr(name, &aoftspace));
187 }
188