1 /* $NetBSD: setterm.c,v 1.13 1999/12/07 03:18:52 simonb 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.8 (Berkeley) 10/25/94"; 40 #else 41 __RCSID("$NetBSD: setterm.c,v 1.13 1999/12/07 03:18:52 simonb 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 bl bt cd ce cl cm cr */ 66 &AL, &BC, &BL, &BT, &CD, &CE, &CL, &CM, &CR, 67 /* cs dc DL dm do ed ei k0 k1 */ 68 &CS, &DC, &DL, &DM, &DO, &ED, &EI, &K0, &K1, 69 /* k2 k3 k4 k5 k6 k7 k8 k9 ho */ 70 &K2, &K3, &K4, &K5, &K6, &K7, &K8, &K9, &HO, 71 /* ic im ip kd ke kh kl kr ks */ 72 &IC, &IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, 73 /* ku ll ma mb md me mh mk mp */ 74 &KU, &LL, &MA, &MB, &MD, &ME, &MH, &MK, &MP, 75 /* mr nd nl pc rc sc se SF so */ 76 &MR, &ND, &NL, &_PC, &RC, &SC, &SE, &SF, &SO, 77 /* SR ta te ti uc ue up us vb */ 78 &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US, &VB, 79 /* vs ve al dl sf sr AL DL */ 80 &VS, &VE, &al, &dl, &sf, &sr, &AL_PARM, &DL_PARM, 81 /* UP DO LE RI */ 82 &UP_PARM, &DOWN_PARM, &LEFT_PARM, &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 char *type; 93 { 94 static char genbuf[1024]; 95 static char __ttytype[1024]; 96 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 = (int) strtol(p, NULL, 10); 128 if ((p = getenv("COLUMNS")) != NULL) 129 COLS = (int) 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 -- historically, tgoto returns "OOPS" if it 152 * can't do cursor motions. Some systems have been fixed to return 153 * a NULL pointer. 154 */ 155 if ((p = tgoto(CM, 0, 0)) == NULL || *p == 'O') { 156 CA = 0; 157 CM = 0; 158 } else 159 CA = 1; 160 161 PC = _PC ? _PC[0] : 0; 162 aoftspace = tspace; 163 ttytype = longname(genbuf, __ttytype); 164 165 /* If no scrolling commands, no quick change. */ 166 __noqch = 167 (CS == NULL || HO == NULL || 168 (SF == NULL && sf == NULL) || (SR == NULL && sr == NULL)) && 169 ((AL == NULL && al == NULL) || (DL == NULL && dl == NULL)); 170 171 return (unknown ? ERR : OK); 172 } 173 174 /* 175 * zap -- 176 * Gets all the terminal flags from the termcap database. 177 */ 178 static void 179 zap() 180 { 181 char *namp, ***sp; 182 char **fp; 183 char tmp[3]; 184 #ifdef DEBUG 185 char *cp; 186 #endif 187 tmp[2] = '\0'; 188 189 namp = "ambsdaeohcinmimsncnsosulxbxnxtxsxx"; 190 fp = sflags; 191 do { 192 *tmp = *namp; 193 *(tmp + 1) = *(namp + 1); 194 *(*fp++) = tgetflag(tmp); 195 #ifdef DEBUG 196 __CTRACE("%2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE"); 197 #endif 198 namp += 2; 199 200 } while (*namp); 201 namp = "ALbcblbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmambmdmemhmkmpmrndnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI"; 202 sp = sstrs; 203 do { 204 *tmp = *namp; 205 *(tmp + 1) = *(namp + 1); 206 *(*sp++) = tgetstr(tmp, &aoftspace); 207 #ifdef DEBUG 208 __CTRACE("%2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\""); 209 if (*sp[-1] != NULL) { 210 for (cp = *sp[-1]; *cp; cp++) 211 __CTRACE("%s", unctrl(*cp)); 212 __CTRACE("\"\n"); 213 } 214 #endif 215 namp += 2; 216 } while (*namp); 217 if (XS) 218 SO = SE = NULL; 219 else { 220 if (tgetnum("sg") > 0) 221 SO = NULL; 222 if (tgetnum("ug") > 0) 223 US = NULL; 224 if (!SO && US) { 225 SO = US; 226 SE = UE; 227 } 228 } 229 } 230 231 /* 232 * getcap -- 233 * Return a capability from termcap. 234 */ 235 char * 236 getcap(name) 237 char *name; 238 { 239 return (tgetstr(name, &aoftspace)); 240 } 241