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