1 /* 2 * Copyright (c) 1981, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 static char sccsid[] = "@(#)setterm.c 8.7 (Berkeley) 7/27/94"; 36 #endif /* not lint */ 37 38 #include <sys/ioctl.h> /* TIOCGWINSZ on old systems. */ 39 40 #include <stdlib.h> 41 #include <string.h> 42 #include <termios.h> 43 #include <unistd.h> 44 45 #include "curses.h" 46 47 static void zap __P((void)); 48 49 static char *sflags[] = { 50 /* am bs da eo hc in mi ms */ 51 &AM, &BS, &DA, &EO, &HC, &IN, &MI, &MS, 52 /* nc ns os ul xb xn xt xs xx */ 53 &NC, &NS, &OS, &UL, &XB, &XN, &XT, &XS, &XX 54 }; 55 56 static char *_PC, 57 **sstrs[] = { 58 /* AL bc bt cd ce cl cm cr cs */ 59 &AL, &BC, &BT, &CD, &CE, &CL, &CM, &CR, &CS, 60 /* dc DL dm do ed ei k0 k1 k2 */ 61 &DC, &DL, &DM, &DO, &ED, &EI, &K0, &K1, &K2, 62 /* k3 k4 k5 k6 k7 k8 k9 ho ic */ 63 &K3, &K4, &K5, &K6, &K7, &K8, &K9, &HO, &IC, 64 /* im ip kd ke kh kl kr ks ku */ 65 &IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU, 66 /* ll ma nd nl pc rc sc se SF */ 67 &LL, &MA, &ND, &NL, &_PC, &RC, &SC, &SE, &SF, 68 /* so SR ta te ti uc ue up us */ 69 &SO, &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US, 70 /* vb vs ve al dl sf sr AL */ 71 &VB, &VS, &VE, &al, &dl, &sf, &sr, &AL_PARM, 72 /* DL UP DO LE */ 73 &DL_PARM, &UP_PARM, &DOWN_PARM, &LEFT_PARM, 74 /* RI */ 75 &RIGHT_PARM, 76 }; 77 78 static char *aoftspace; /* Address of _tspace for relocation */ 79 static char tspace[2048]; /* Space for capability strings */ 80 81 char *ttytype; 82 83 int 84 setterm(type) 85 register char *type; 86 { 87 static char genbuf[1024]; 88 static char __ttytype[1024]; 89 register int unknown; 90 struct winsize win; 91 char *p; 92 93 #ifdef DEBUG 94 __CTRACE("setterm: (\"%s\")\nLINES = %d, COLS = %d\n", 95 type, LINES, COLS); 96 #endif 97 if (type[0] == '\0') 98 type = "xx"; 99 unknown = 0; 100 if (tgetent(genbuf, type) != 1) { 101 unknown++; 102 strcpy(genbuf, "xx|dumb:"); 103 } 104 #ifdef DEBUG 105 __CTRACE("setterm: tty = %s\n", type); 106 #endif 107 108 /* Try TIOCGWINSZ, and, if it fails, the termcap entry. */ 109 if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1 && 110 win.ws_row != 0 && win.ws_col != 0) { 111 LINES = win.ws_row; 112 COLS = win.ws_col; 113 } else { 114 LINES = tgetnum("li"); 115 COLS = tgetnum("co"); 116 } 117 118 /* POSIX 1003.2 requires that the environment override. */ 119 if ((p = getenv("LINES")) != NULL) 120 LINES = strtol(p, NULL, 10); 121 if ((p = getenv("COLUMNS")) != NULL) 122 COLS = strtol(p, NULL, 10); 123 124 /* 125 * Want cols > 4, otherwise things will fail. 126 */ 127 if (COLS <= 4) 128 return (ERR); 129 130 #ifdef DEBUG 131 __CTRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS); 132 #endif 133 aoftspace = tspace; 134 zap(); /* Get terminal description. */ 135 136 /* If we can't tab, we can't backtab, either. */ 137 if (!GT) 138 BT = NULL; 139 140 /* 141 * Test for cursor motion capbility. 142 * 143 * XXX 144 * This is truly stupid -- tgoto returns "OOPS" if it can't 145 * do cursor motions. 146 */ 147 if (tgoto(CM, 0, 0)[0] == 'O') { 148 CA = 0; 149 CM = 0; 150 } else 151 CA = 1; 152 153 PC = _PC ? _PC[0] : 0; 154 aoftspace = tspace; 155 ttytype = longname(genbuf, __ttytype); 156 157 /* If no scrolling commands, no quick change. */ 158 __noqch = 159 (CS == NULL || HO == NULL || 160 SF == NULL && sf == NULL || SR == NULL && sr == NULL) && 161 (AL == NULL && al == NULL || DL == NULL && dl == NULL); 162 163 return (unknown ? ERR : OK); 164 } 165 166 /* 167 * zap -- 168 * Gets all the terminal flags from the termcap database. 169 */ 170 static void 171 zap() 172 { 173 register char *namp, ***sp; 174 register char **fp; 175 char tmp[3]; 176 #ifdef DEBUG 177 register char *cp; 178 #endif 179 tmp[2] = '\0'; 180 181 namp = "ambsdaeohcinmimsncnsosulxbxnxtxsxx"; 182 fp = sflags; 183 do { 184 *tmp = *namp; 185 *(tmp + 1) = *(namp + 1); 186 *(*fp++) = tgetflag(tmp); 187 #ifdef DEBUG 188 __CTRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE"); 189 #endif 190 namp += 2; 191 192 } while (*namp); 193 namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI"; 194 sp = sstrs; 195 do { 196 *tmp = *namp; 197 *(tmp + 1) = *(namp + 1); 198 *(*sp++) = tgetstr(tmp, &aoftspace); 199 #ifdef DEBUG 200 __CTRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\""); 201 if (*sp[-1] != NULL) { 202 for (cp = *sp[-1]; *cp; cp++) 203 __CTRACE("%s", unctrl(*cp)); 204 __CTRACE("\"\n"); 205 } 206 #endif 207 namp += 2; 208 } while (*namp); 209 if (XS) 210 SO = SE = NULL; 211 else { 212 if (tgetnum("sg") > 0) 213 SO = NULL; 214 if (tgetnum("ug") > 0) 215 US = NULL; 216 if (!SO && US) { 217 SO = US; 218 SE = UE; 219 } 220 } 221 } 222 223 /* 224 * getcap -- 225 * Return a capability from termcap. 226 */ 227 char * 228 getcap(name) 229 char *name; 230 { 231 return (tgetstr(name, &aoftspace)); 232 } 233