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