12243Sarnold /* 234677Sbostic * Copyright (c) 1981 Regents of the University of California. 334677Sbostic * All rights reserved. 434677Sbostic * 542653Sbostic * %sccs.include.redist.c% 622656Sdist */ 722656Sdist 822656Sdist #ifndef lint 9*56298Selan static char sccsid[] = "@(#)setterm.c 5.11 (Berkeley) 09/21/92"; 1034677Sbostic #endif /* not lint */ 1122656Sdist 1255987Sbostic #include <sys/ioctl.h> 132243Sarnold 1455987Sbostic #include <curses.h> 1555987Sbostic #include <stdlib.h> 1655987Sbostic #include <string.h> 1755987Sbostic #include <unistd.h> 182243Sarnold 1955987Sbostic static void zap __P((void)); 2055987Sbostic 2155987Sbostic static char *sflags[] = { 2255987Sbostic &AM, &BS, &DA, &EO, &HC, &HZ, &IN, &MI, &MS, 2355987Sbostic &NC, &NS, &OS, &UL, &XB, &XN, &XT, &XS, &XX 242243Sarnold }; 252243Sarnold 2619875Sbloom static char *_PC, 2719875Sbloom **sstrs[] = { 2819875Sbloom &AL, &BC, &BT, &CD, &CE, &CL, &CM, &CR, &CS, 2919875Sbloom &DC, &DL, &DM, &DO, &ED, &EI, &K0, &K1, &K2, 3019875Sbloom &K3, &K4, &K5, &K6, &K7, &K8, &K9, &HO, &IC, 3119875Sbloom &IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU, 3219875Sbloom &LL, &MA, &ND, &NL, &_PC, &RC, &SC, &SE, &SF, 3319875Sbloom &SO, &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US, 34*56298Selan &VB, &VS, &VE, &al, &dl, &sf, &sr, &AL_PARM, 35*56298Selan &DL_PARM, &UP_PARM, &DOWN_PARM, &LEFT_PARM, 36*56298Selan &RIGHT_PARM, 3739140Sbostic }; 382243Sarnold 3919875Sbloom static char *aoftspace; /* Address of _tspace for relocation */ 4055987Sbostic static char tspace[2048]; /* Space for capability strings */ 4119875Sbloom 422243Sarnold static int destcol, destline; 432243Sarnold 4455987Sbostic char *ttytype; 452243Sarnold 4655987Sbostic int 472243Sarnold setterm(type) 4855987Sbostic register char *type; 4955987Sbostic { 5055987Sbostic static char genbuf[1024]; 5155987Sbostic static char __ttytype[1024]; 5255987Sbostic register int unknown; 5318032Sbloom struct winsize win; 5455987Sbostic char *p; 552243Sarnold 5655987Sbostic #ifdef DEBUG 5755987Sbostic __TRACE("setterm: (\"%s\")\nLINES = %d, COLS = %d\n", 5855987Sbostic type, LINES, COLS); 5955987Sbostic #endif 602243Sarnold if (type[0] == '\0') 612243Sarnold type = "xx"; 6255987Sbostic unknown = 0; 632243Sarnold if (tgetent(genbuf, type) != 1) { 642243Sarnold unknown++; 652243Sarnold strcpy(genbuf, "xx|dumb:"); 662243Sarnold } 6755987Sbostic #ifdef DEBUG 6855987Sbostic __TRACE("setterm: tty = %s\n", type); 6955987Sbostic #endif 7018032Sbloom 7155987Sbostic /* Try TIOCGWINSZ, and, if it fails, the termcap entry. */ 7255987Sbostic if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1 && 7355987Sbostic win.ws_row != 0 && win.ws_col != 0) { 7455987Sbostic LINES = win.ws_row; 7555987Sbostic COLS = win.ws_col; 7655987Sbostic } else { 772243Sarnold LINES = tgetnum("li"); 782243Sarnold COLS = tgetnum("co"); 7955987Sbostic } 8012570Sarnold 8155987Sbostic /* POSIX 1003.2 requires that the environment override. */ 8255987Sbostic if ((p = getenv("ROWS")) != NULL) 8355987Sbostic LINES = strtol(p, NULL, 10); 8455987Sbostic if ((p = getenv("COLUMNS")) != NULL) 8555987Sbostic COLS = strtol(p, NULL, 10); 8619875Sbloom 8719875Sbloom /* 8855987Sbostic * XXX 8955987Sbostic * Historically, curses fails if rows <= 5, cols <= 4. 9019875Sbloom */ 9155987Sbostic if (LINES <= 5 || COLS <= 4) 9255987Sbostic return (ERR); 9319875Sbloom 9455987Sbostic #ifdef DEBUG 9555987Sbostic __TRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS); 9655987Sbostic #endif 9755987Sbostic aoftspace = tspace; 9855987Sbostic zap(); /* Get terminal description. */ 9919875Sbloom 10055987Sbostic /* Handle funny termcap capabilities. */ 10155987Sbostic if (CS && SC && RC) 10255987Sbostic AL = DL = ""; 10355987Sbostic if (AL_PARM && AL == NULL) 10455987Sbostic AL = ""; 10555987Sbostic if (DL_PARM && DL == NULL) 10655987Sbostic DL = ""; 10755987Sbostic if (IC) { 10855987Sbostic if (IM == NULL) 10955987Sbostic IM = ""; 11055987Sbostic if (EI == NULL) 11155987Sbostic EI = ""; 11255987Sbostic } 11355987Sbostic if (!GT) /* If we can't tab, we can't backtab either. */ 11455987Sbostic BT = NULL; 11537420Sbostic 11655987Sbostic if (tgoto(CM, destcol, destline)[0] == 'O') { 11755987Sbostic CA = 0; 11855987Sbostic CM = 0; 11955987Sbostic } else 12055987Sbostic CA = 1; 12155987Sbostic 12255987Sbostic PC = _PC ? _PC[0] : 0; 12355987Sbostic aoftspace = tspace; 12455987Sbostic ttytype = longname(genbuf, __ttytype); 12555987Sbostic 126*56298Selan if ((!AL && !al) || (!DL && !dl)) 127*56298Selan __noqch = 1; 128*56298Selan 12955987Sbostic return (unknown ? ERR : OK); 1302243Sarnold } 13119875Sbloom 1322243Sarnold /* 13355987Sbostic * zap -- 13455987Sbostic * Gets all the terminal flags from the termcap database. 1352243Sarnold */ 13655987Sbostic static void 13719875Sbloom zap() 13819875Sbloom { 13955987Sbostic register char *namp, ***sp; 14055987Sbostic register char **fp; 14156238Selan char tmp[3]; 14255987Sbostic #ifdef DEBUG 14319875Sbloom register char *cp; 14419875Sbloom #endif 14556238Selan tmp[2] = '\0'; 1462243Sarnold 14721040Sbloom namp = "ambsdadbeohchzinmimsncnsosulxbxnxtxsxx"; 1482243Sarnold fp = sflags; 1492243Sarnold do { 15056238Selan *tmp = *namp; 15156238Selan *(tmp + 1) = *(namp + 1); 15256238Selan *(*fp++) = tgetflag(tmp); 15319875Sbloom #ifdef DEBUG 15455987Sbostic __TRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE"); 15519875Sbloom #endif 1562243Sarnold namp += 2; 15756238Selan 1582243Sarnold } while (*namp); 159*56298Selan namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI"; 1602243Sarnold sp = sstrs; 1612243Sarnold do { 16256238Selan *tmp = *namp; 16356238Selan *(tmp + 1) = *(namp + 1); 16456238Selan *(*sp++) = tgetstr(tmp, &aoftspace); 16519875Sbloom #ifdef DEBUG 16655987Sbostic __TRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\""); 16719875Sbloom if (*sp[-1] != NULL) { 16819875Sbloom for (cp = *sp[-1]; *cp; cp++) 16955987Sbostic __TRACE("%s", unctrl(*cp)); 17055987Sbostic __TRACE("\"\n"); 17119875Sbloom } 17219875Sbloom #endif 1732243Sarnold namp += 2; 1742243Sarnold } while (*namp); 17521040Sbloom if (XS) 17621040Sbloom SO = SE = NULL; 17721040Sbloom else { 17821040Sbloom if (tgetnum("sg") > 0) 17921040Sbloom SO = NULL; 18021040Sbloom if (tgetnum("ug") > 0) 18121040Sbloom US = NULL; 18221040Sbloom if (!SO && US) { 18321040Sbloom SO = US; 18421040Sbloom SE = UE; 18521040Sbloom } 1862243Sarnold } 1872243Sarnold } 1883786Sarnold 1893786Sarnold /* 19055987Sbostic * getcap -- 19155987Sbostic * Return a capability from termcap. 1923786Sarnold */ 1933786Sarnold char * 1943786Sarnold getcap(name) 19555987Sbostic char *name; 1963786Sarnold { 19755987Sbostic return (tgetstr(name, &aoftspace)); 1983786Sarnold } 199