1 /* 2 * Copyright (c) 1981, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)setterm.c 8.8 (Berkeley) 10/25/94"; 10 #endif /* not lint */ 11 12 #include <sys/ioctl.h> /* TIOCGWINSZ on old systems. */ 13 14 #include <stdlib.h> 15 #include <string.h> 16 #include <termios.h> 17 #include <unistd.h> 18 19 #include "curses.h" 20 21 static void zap __P((void)); 22 23 static char *sflags[] = { 24 /* am bs da eo hc in mi ms */ 25 &AM, &BS, &DA, &EO, &HC, &IN, &MI, &MS, 26 /* nc ns os ul xb xn xt xs xx */ 27 &NC, &NS, &OS, &UL, &XB, &XN, &XT, &XS, &XX 28 }; 29 30 static char *_PC, 31 **sstrs[] = { 32 /* AL bc bt cd ce cl cm cr cs */ 33 &AL, &BC, &BT, &CD, &CE, &CL, &CM, &CR, &CS, 34 /* dc DL dm do ed ei k0 k1 k2 */ 35 &DC, &DL, &DM, &DO, &ED, &EI, &K0, &K1, &K2, 36 /* k3 k4 k5 k6 k7 k8 k9 ho ic */ 37 &K3, &K4, &K5, &K6, &K7, &K8, &K9, &HO, &IC, 38 /* im ip kd ke kh kl kr ks ku */ 39 &IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU, 40 /* ll ma nd nl pc rc sc se SF */ 41 &LL, &MA, &ND, &NL, &_PC, &RC, &SC, &SE, &SF, 42 /* so SR ta te ti uc ue up us */ 43 &SO, &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US, 44 /* vb vs ve al dl sf sr AL */ 45 &VB, &VS, &VE, &al, &dl, &sf, &sr, &AL_PARM, 46 /* DL UP DO LE */ 47 &DL_PARM, &UP_PARM, &DOWN_PARM, &LEFT_PARM, 48 /* RI */ 49 &RIGHT_PARM, 50 }; 51 52 static char *aoftspace; /* Address of _tspace for relocation */ 53 static char tspace[2048]; /* Space for capability strings */ 54 55 char *ttytype; 56 57 int 58 setterm(type) 59 register char *type; 60 { 61 static char genbuf[1024]; 62 static char __ttytype[1024]; 63 register int unknown; 64 struct winsize win; 65 char *p; 66 67 #ifdef DEBUG 68 __CTRACE("setterm: (\"%s\")\nLINES = %d, COLS = %d\n", 69 type, LINES, COLS); 70 #endif 71 if (type[0] == '\0') 72 type = "xx"; 73 unknown = 0; 74 if (tgetent(genbuf, type) != 1) { 75 unknown++; 76 strcpy(genbuf, "xx|dumb:"); 77 } 78 #ifdef DEBUG 79 __CTRACE("setterm: tty = %s\n", type); 80 #endif 81 82 /* Try TIOCGWINSZ, and, if it fails, the termcap entry. */ 83 if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1 && 84 win.ws_row != 0 && win.ws_col != 0) { 85 LINES = win.ws_row; 86 COLS = win.ws_col; 87 } else { 88 LINES = tgetnum("li"); 89 COLS = tgetnum("co"); 90 } 91 92 /* POSIX 1003.2 requires that the environment override. */ 93 if ((p = getenv("LINES")) != NULL) 94 LINES = strtol(p, NULL, 10); 95 if ((p = getenv("COLUMNS")) != NULL) 96 COLS = strtol(p, NULL, 10); 97 98 /* 99 * Want cols > 4, otherwise things will fail. 100 */ 101 if (COLS <= 4) 102 return (ERR); 103 104 #ifdef DEBUG 105 __CTRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS); 106 #endif 107 aoftspace = tspace; 108 zap(); /* Get terminal description. */ 109 110 /* If we can't tab, we can't backtab, either. */ 111 if (!GT) 112 BT = NULL; 113 114 /* 115 * Test for cursor motion capbility. 116 * 117 * XXX 118 * This is truly stupid -- historically, tgoto returns "OOPS" if it 119 * can't do cursor motions. Some systems have been fixed to return 120 * a NULL pointer. 121 */ 122 if ((p = tgoto(CM, 0, 0)) == NULL || *p == '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 no scrolling commands, no quick change. */ 133 __noqch = 134 (CS == NULL || HO == NULL || 135 SF == NULL && sf == NULL || SR == NULL && sr == NULL) && 136 (AL == NULL && al == NULL || DL == NULL && dl == NULL); 137 138 return (unknown ? ERR : OK); 139 } 140 141 /* 142 * zap -- 143 * Gets all the terminal flags from the termcap database. 144 */ 145 static void 146 zap() 147 { 148 register char *namp, ***sp; 149 register char **fp; 150 char tmp[3]; 151 #ifdef DEBUG 152 register char *cp; 153 #endif 154 tmp[2] = '\0'; 155 156 namp = "ambsdaeohcinmimsncnsosulxbxnxtxsxx"; 157 fp = sflags; 158 do { 159 *tmp = *namp; 160 *(tmp + 1) = *(namp + 1); 161 *(*fp++) = tgetflag(tmp); 162 #ifdef DEBUG 163 __CTRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE"); 164 #endif 165 namp += 2; 166 167 } while (*namp); 168 namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI"; 169 sp = sstrs; 170 do { 171 *tmp = *namp; 172 *(tmp + 1) = *(namp + 1); 173 *(*sp++) = tgetstr(tmp, &aoftspace); 174 #ifdef DEBUG 175 __CTRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\""); 176 if (*sp[-1] != NULL) { 177 for (cp = *sp[-1]; *cp; cp++) 178 __CTRACE("%s", unctrl(*cp)); 179 __CTRACE("\"\n"); 180 } 181 #endif 182 namp += 2; 183 } while (*namp); 184 if (XS) 185 SO = SE = NULL; 186 else { 187 if (tgetnum("sg") > 0) 188 SO = NULL; 189 if (tgetnum("ug") > 0) 190 US = NULL; 191 if (!SO && US) { 192 SO = US; 193 SE = UE; 194 } 195 } 196 } 197 198 /* 199 * getcap -- 200 * Return a capability from termcap. 201 */ 202 char * 203 getcap(name) 204 char *name; 205 { 206 return (tgetstr(name, &aoftspace)); 207 } 208