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.5 (Berkeley) 05/19/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 -- tgoto returns "OOPS" if it can't 119 * do cursor motions. 120 */ 121 if (tgoto(CM, 0, 0)[0] == 'O') { 122 CA = 0; 123 CM = 0; 124 } else 125 CA = 1; 126 127 PC = _PC ? _PC[0] : 0; 128 aoftspace = tspace; 129 ttytype = longname(genbuf, __ttytype); 130 131 if ((!AL && !al) || (!DL && !dl)) 132 __noqch = 1; 133 134 return (unknown ? ERR : OK); 135 } 136 137 /* 138 * zap -- 139 * Gets all the terminal flags from the termcap database. 140 */ 141 static void 142 zap() 143 { 144 register char *namp, ***sp; 145 register char **fp; 146 char tmp[3]; 147 #ifdef DEBUG 148 register char *cp; 149 #endif 150 tmp[2] = '\0'; 151 152 namp = "ambsdaeohcinmimsncnsosulxbxnxtxsxx"; 153 fp = sflags; 154 do { 155 *tmp = *namp; 156 *(tmp + 1) = *(namp + 1); 157 *(*fp++) = tgetflag(tmp); 158 #ifdef DEBUG 159 __CTRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE"); 160 #endif 161 namp += 2; 162 163 } while (*namp); 164 namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI"; 165 sp = sstrs; 166 do { 167 *tmp = *namp; 168 *(tmp + 1) = *(namp + 1); 169 *(*sp++) = tgetstr(tmp, &aoftspace); 170 #ifdef DEBUG 171 __CTRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\""); 172 if (*sp[-1] != NULL) { 173 for (cp = *sp[-1]; *cp; cp++) 174 __CTRACE("%s", unctrl(*cp)); 175 __CTRACE("\"\n"); 176 } 177 #endif 178 namp += 2; 179 } while (*namp); 180 if (XS) 181 SO = SE = NULL; 182 else { 183 if (tgetnum("sg") > 0) 184 SO = NULL; 185 if (tgetnum("ug") > 0) 186 US = NULL; 187 if (!SO && US) { 188 SO = US; 189 SE = UE; 190 } 191 } 192 } 193 194 /* 195 * getcap -- 196 * Return a capability from termcap. 197 */ 198 char * 199 getcap(name) 200 char *name; 201 { 202 return (tgetstr(name, &aoftspace)); 203 } 204