1 /*
2 * Copyright (c) 1981, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)setterm.c 8.8 (Berkeley) 10/25/94";
10 #endif /* not lint */
11
12 #include <sys/ioctl.h> /* TIOCGWINSZ on old systems. */
13
14 #include <stdlib.h>
15 #include <string.h>
16 #include <termios.h>
17 #include <unistd.h>
18
19 #include "curses.h"
20
21 static void zap __P((void));
22
23 static char *sflags[] = {
24 /* am bs da eo hc in mi ms */
25 &AM, &BS, &DA, &EO, &HC, &IN, &MI, &MS,
26 /* nc ns os ul xb xn xt xs xx */
27 &NC, &NS, &OS, &UL, &XB, &XN, &XT, &XS, &XX
28 };
29
30 static char *_PC,
31 **sstrs[] = {
32 /* AL bc bt cd ce cl cm cr cs */
33 &AL, &BC, &BT, &CD, &CE, &CL, &CM, &CR, &CS,
34 /* dc DL dm do ed ei k0 k1 k2 */
35 &DC, &DL, &DM, &DO, &ED, &EI, &K0, &K1, &K2,
36 /* k3 k4 k5 k6 k7 k8 k9 ho ic */
37 &K3, &K4, &K5, &K6, &K7, &K8, &K9, &HO, &IC,
38 /* im ip kd ke kh kl kr ks ku */
39 &IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU,
40 /* ll ma nd nl pc rc sc se SF */
41 &LL, &MA, &ND, &NL, &_PC, &RC, &SC, &SE, &SF,
42 /* so SR ta te ti uc ue up us */
43 &SO, &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US,
44 /* vb vs ve al dl sf sr AL */
45 &VB, &VS, &VE, &al, &dl, &sf, &sr, &AL_PARM,
46 /* DL UP DO LE */
47 &DL_PARM, &UP_PARM, &DOWN_PARM, &LEFT_PARM,
48 /* RI */
49 &RIGHT_PARM,
50 };
51
52 static char *aoftspace; /* Address of _tspace for relocation */
53 static char tspace[2048]; /* Space for capability strings */
54
55 char *ttytype;
56
57 int
setterm(type)58 setterm(type)
59 register char *type;
60 {
61 static char genbuf[1024];
62 static char __ttytype[1024];
63 register int unknown;
64 struct winsize win;
65 char *p;
66
67 #ifdef DEBUG
68 __CTRACE("setterm: (\"%s\")\nLINES = %d, COLS = %d\n",
69 type, LINES, COLS);
70 #endif
71 if (type[0] == '\0')
72 type = "xx";
73 unknown = 0;
74 if (tgetent(genbuf, type) != 1) {
75 unknown++;
76 strcpy(genbuf, "xx|dumb:");
77 }
78 #ifdef DEBUG
79 __CTRACE("setterm: tty = %s\n", type);
80 #endif
81
82 /* Try TIOCGWINSZ, and, if it fails, the termcap entry. */
83 if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1 &&
84 win.ws_row != 0 && win.ws_col != 0) {
85 LINES = win.ws_row;
86 COLS = win.ws_col;
87 } else {
88 LINES = tgetnum("li");
89 COLS = tgetnum("co");
90 }
91
92 /* POSIX 1003.2 requires that the environment override. */
93 if ((p = getenv("LINES")) != NULL)
94 LINES = strtol(p, NULL, 10);
95 if ((p = getenv("COLUMNS")) != NULL)
96 COLS = strtol(p, NULL, 10);
97
98 /*
99 * Want cols > 4, otherwise things will fail.
100 */
101 if (COLS <= 4)
102 return (ERR);
103
104 #ifdef DEBUG
105 __CTRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS);
106 #endif
107 aoftspace = tspace;
108 zap(); /* Get terminal description. */
109
110 /* If we can't tab, we can't backtab, either. */
111 if (!GT)
112 BT = NULL;
113
114 /*
115 * Test for cursor motion capbility.
116 *
117 * XXX
118 * This is truly stupid -- historically, tgoto returns "OOPS" if it
119 * can't do cursor motions. Some systems have been fixed to return
120 * a NULL pointer.
121 */
122 if ((p = tgoto(CM, 0, 0)) == NULL || *p == 'O') {
123 CA = 0;
124 CM = 0;
125 } else
126 CA = 1;
127
128 PC = _PC ? _PC[0] : 0;
129 aoftspace = tspace;
130 ttytype = longname(genbuf, __ttytype);
131
132 /* If no scrolling commands, no quick change. */
133 __noqch =
134 (CS == NULL || HO == NULL ||
135 SF == NULL && sf == NULL || SR == NULL && sr == NULL) &&
136 (AL == NULL && al == NULL || DL == NULL && dl == NULL);
137
138 return (unknown ? ERR : OK);
139 }
140
141 /*
142 * zap --
143 * Gets all the terminal flags from the termcap database.
144 */
145 static void
zap()146 zap()
147 {
148 register char *namp, ***sp;
149 register char **fp;
150 char tmp[3];
151 #ifdef DEBUG
152 register char *cp;
153 #endif
154 tmp[2] = '\0';
155
156 namp = "ambsdaeohcinmimsncnsosulxbxnxtxsxx";
157 fp = sflags;
158 do {
159 *tmp = *namp;
160 *(tmp + 1) = *(namp + 1);
161 *(*fp++) = tgetflag(tmp);
162 #ifdef DEBUG
163 __CTRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE");
164 #endif
165 namp += 2;
166
167 } while (*namp);
168 namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI";
169 sp = sstrs;
170 do {
171 *tmp = *namp;
172 *(tmp + 1) = *(namp + 1);
173 *(*sp++) = tgetstr(tmp, &aoftspace);
174 #ifdef DEBUG
175 __CTRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\"");
176 if (*sp[-1] != NULL) {
177 for (cp = *sp[-1]; *cp; cp++)
178 __CTRACE("%s", unctrl(*cp));
179 __CTRACE("\"\n");
180 }
181 #endif
182 namp += 2;
183 } while (*namp);
184 if (XS)
185 SO = SE = NULL;
186 else {
187 if (tgetnum("sg") > 0)
188 SO = NULL;
189 if (tgetnum("ug") > 0)
190 US = NULL;
191 if (!SO && US) {
192 SO = US;
193 SE = UE;
194 }
195 }
196 }
197
198 /*
199 * getcap --
200 * Return a capability from termcap.
201 */
202 char *
getcap(name)203 getcap(name)
204 char *name;
205 {
206 return (tgetstr(name, &aoftspace));
207 }
208