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