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.17 (Berkeley) 04/15/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 * Want cols > 4, otherwise things will fail. 87 */ 88 if (COLS <= 4) 89 return (ERR); 90 91 #ifdef DEBUG 92 __TRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS); 93 #endif 94 aoftspace = tspace; 95 zap(); /* Get terminal description. */ 96 97 /* Handle funny termcap capabilities. */ 98 if (CS && SC && RC) 99 AL = DL = ""; 100 if (AL_PARM && AL == NULL) 101 AL = ""; 102 if (DL_PARM && DL == NULL) 103 DL = ""; 104 if (IC) { 105 if (IM == NULL) 106 IM = ""; 107 if (EI == NULL) 108 EI = ""; 109 } 110 111 /* If we can't tab, we can't backtab, either. */ 112 if (!GT) 113 BT = NULL; 114 115 /* 116 * Test for cursor motion capbility. 117 * 118 * XXX 119 * This is truly stupid -- tgoto returns "OOPS" if it can't 120 * do cursor motions. 121 */ 122 if (tgoto(CM, 0, 0)[0] == 'O') { 123 CA = 0; 124 CM = 0; 125 } else 126 CA = 1; 127 128 PC = _PC ? _PC[0] : 0; 129 aoftspace = tspace; 130 ttytype = longname(genbuf, __ttytype); 131 132 if ((!AL && !al) || (!DL && !dl)) 133 __noqch = 1; 134 135 return (unknown ? ERR : OK); 136 } 137 138 /* 139 * zap -- 140 * Gets all the terminal flags from the termcap database. 141 */ 142 static void 143 zap() 144 { 145 register char *namp, ***sp; 146 register char **fp; 147 char tmp[3]; 148 #ifdef DEBUG 149 register char *cp; 150 #endif 151 tmp[2] = '\0'; 152 153 namp = "ambsdaeohchzinmimsncnsosulxbxnxtxsxx"; 154 fp = sflags; 155 do { 156 *tmp = *namp; 157 *(tmp + 1) = *(namp + 1); 158 *(*fp++) = tgetflag(tmp); 159 #ifdef DEBUG 160 __TRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE"); 161 #endif 162 namp += 2; 163 164 } while (*namp); 165 namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI"; 166 sp = sstrs; 167 do { 168 *tmp = *namp; 169 *(tmp + 1) = *(namp + 1); 170 *(*sp++) = tgetstr(tmp, &aoftspace); 171 #ifdef DEBUG 172 __TRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\""); 173 if (*sp[-1] != NULL) { 174 for (cp = *sp[-1]; *cp; cp++) 175 __TRACE("%s", unctrl(*cp)); 176 __TRACE("\"\n"); 177 } 178 #endif 179 namp += 2; 180 } while (*namp); 181 if (XS) 182 SO = SE = NULL; 183 else { 184 if (tgetnum("sg") > 0) 185 SO = NULL; 186 if (tgetnum("ug") > 0) 187 US = NULL; 188 if (!SO && US) { 189 SO = US; 190 SE = UE; 191 } 192 } 193 } 194 195 /* 196 * getcap -- 197 * Return a capability from termcap. 198 */ 199 char * 200 getcap(name) 201 char *name; 202 { 203 return (tgetstr(name, &aoftspace)); 204 } 205