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*60058Sbostic static char sccsid[] = "@(#)setterm.c 5.19 (Berkeley) 05/16/93"; 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[] = { 2259864Sbostic /* am bs da eo hc hz in mi ms */ 2355987Sbostic &AM, &BS, &DA, &EO, &HC, &HZ, &IN, &MI, &MS, 2459864Sbostic /* nc ns os ul xb xn xt xs xx */ 2555987Sbostic &NC, &NS, &OS, &UL, &XB, &XN, &XT, &XS, &XX 262243Sarnold }; 272243Sarnold 2819875Sbloom static char *_PC, 2919875Sbloom **sstrs[] = { 3059864Sbostic /* AL bc bt cd ce cl cm cr cs */ 3119875Sbloom &AL, &BC, &BT, &CD, &CE, &CL, &CM, &CR, &CS, 3259864Sbostic /* dc DL dm do ed ei k0 k1 k2 */ 3319875Sbloom &DC, &DL, &DM, &DO, &ED, &EI, &K0, &K1, &K2, 3459864Sbostic /* k3 k4 k5 k6 k7 k8 k9 ho ic */ 3519875Sbloom &K3, &K4, &K5, &K6, &K7, &K8, &K9, &HO, &IC, 3659864Sbostic /* im ip kd ke kh kl kr ks ku */ 3719875Sbloom &IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU, 3859864Sbostic /* ll ma nd nl pc rc sc se SF */ 3919875Sbloom &LL, &MA, &ND, &NL, &_PC, &RC, &SC, &SE, &SF, 4059864Sbostic /* so SR ta te ti uc ue up us */ 4119875Sbloom &SO, &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US, 4259864Sbostic /* vb vs ve al dl sf sr AL */ 4356298Selan &VB, &VS, &VE, &al, &dl, &sf, &sr, &AL_PARM, 4459864Sbostic /* DL UP DO LE */ 4556298Selan &DL_PARM, &UP_PARM, &DOWN_PARM, &LEFT_PARM, 4659864Sbostic /* RI */ 4756298Selan &RIGHT_PARM, 4839140Sbostic }; 492243Sarnold 5019875Sbloom static char *aoftspace; /* Address of _tspace for relocation */ 5155987Sbostic static char tspace[2048]; /* Space for capability strings */ 5219875Sbloom 5355987Sbostic char *ttytype; 542243Sarnold 5555987Sbostic int 562243Sarnold setterm(type) 5755987Sbostic register char *type; 5855987Sbostic { 5955987Sbostic static char genbuf[1024]; 6055987Sbostic static char __ttytype[1024]; 6155987Sbostic register int unknown; 6218032Sbloom struct winsize win; 6355987Sbostic char *p; 642243Sarnold 6555987Sbostic #ifdef DEBUG 66*60058Sbostic __CTRACE("setterm: (\"%s\")\nLINES = %d, COLS = %d\n", 6755987Sbostic type, LINES, COLS); 6855987Sbostic #endif 692243Sarnold if (type[0] == '\0') 702243Sarnold type = "xx"; 7155987Sbostic unknown = 0; 722243Sarnold if (tgetent(genbuf, type) != 1) { 732243Sarnold unknown++; 742243Sarnold strcpy(genbuf, "xx|dumb:"); 752243Sarnold } 7655987Sbostic #ifdef DEBUG 77*60058Sbostic __CTRACE("setterm: tty = %s\n", type); 7855987Sbostic #endif 7918032Sbloom 8055987Sbostic /* Try TIOCGWINSZ, and, if it fails, the termcap entry. */ 8155987Sbostic if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1 && 8255987Sbostic win.ws_row != 0 && win.ws_col != 0) { 8355987Sbostic LINES = win.ws_row; 8455987Sbostic COLS = win.ws_col; 8555987Sbostic } else { 862243Sarnold LINES = tgetnum("li"); 872243Sarnold COLS = tgetnum("co"); 8855987Sbostic } 8912570Sarnold 9055987Sbostic /* POSIX 1003.2 requires that the environment override. */ 9155987Sbostic if ((p = getenv("ROWS")) != NULL) 9255987Sbostic LINES = strtol(p, NULL, 10); 9355987Sbostic if ((p = getenv("COLUMNS")) != NULL) 9455987Sbostic COLS = strtol(p, NULL, 10); 9519875Sbloom 9619875Sbloom /* 9759096Selan * Want cols > 4, otherwise things will fail. 9819875Sbloom */ 9959096Selan if (COLS <= 4) 10057472Sbostic return (ERR); 10119875Sbloom 10255987Sbostic #ifdef DEBUG 103*60058Sbostic __CTRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS); 10455987Sbostic #endif 10555987Sbostic aoftspace = tspace; 10655987Sbostic zap(); /* Get terminal description. */ 10719875Sbloom 10858046Selan /* If we can't tab, we can't backtab, either. */ 10958046Selan if (!GT) 11055987Sbostic BT = NULL; 11137420Sbostic 11258046Selan /* 11358046Selan * Test for cursor motion capbility. 11458046Selan * 11558046Selan * XXX 11658046Selan * This is truly stupid -- tgoto returns "OOPS" if it can't 11758046Selan * do cursor motions. 11858046Selan */ 11958046Selan if (tgoto(CM, 0, 0)[0] == 'O') { 12055987Sbostic CA = 0; 12155987Sbostic CM = 0; 12255987Sbostic } else 12355987Sbostic CA = 1; 12455987Sbostic 12555987Sbostic PC = _PC ? _PC[0] : 0; 12655987Sbostic aoftspace = tspace; 12755987Sbostic ttytype = longname(genbuf, __ttytype); 12855987Sbostic 12956298Selan if ((!AL && !al) || (!DL && !dl)) 13056298Selan __noqch = 1; 13156298Selan 13257472Sbostic return (unknown ? ERR : OK); 1332243Sarnold } 13419875Sbloom 1352243Sarnold /* 13655987Sbostic * zap -- 13755987Sbostic * Gets all the terminal flags from the termcap database. 1382243Sarnold */ 13955987Sbostic static void 14019875Sbloom zap() 14119875Sbloom { 14255987Sbostic register char *namp, ***sp; 14355987Sbostic register char **fp; 14456238Selan char tmp[3]; 14555987Sbostic #ifdef DEBUG 14619875Sbloom register char *cp; 14719875Sbloom #endif 14856238Selan tmp[2] = '\0'; 1492243Sarnold 15057819Selan namp = "ambsdaeohchzinmimsncnsosulxbxnxtxsxx"; 1512243Sarnold fp = sflags; 1522243Sarnold do { 15356238Selan *tmp = *namp; 15456238Selan *(tmp + 1) = *(namp + 1); 15556238Selan *(*fp++) = tgetflag(tmp); 15619875Sbloom #ifdef DEBUG 157*60058Sbostic __CTRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE"); 15819875Sbloom #endif 1592243Sarnold namp += 2; 16056238Selan 1612243Sarnold } while (*namp); 16256298Selan namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI"; 1632243Sarnold sp = sstrs; 1642243Sarnold do { 16556238Selan *tmp = *namp; 16656238Selan *(tmp + 1) = *(namp + 1); 16756238Selan *(*sp++) = tgetstr(tmp, &aoftspace); 16819875Sbloom #ifdef DEBUG 169*60058Sbostic __CTRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\""); 17019875Sbloom if (*sp[-1] != NULL) { 17119875Sbloom for (cp = *sp[-1]; *cp; cp++) 172*60058Sbostic __CTRACE("%s", unctrl(*cp)); 173*60058Sbostic __CTRACE("\"\n"); 17419875Sbloom } 17519875Sbloom #endif 1762243Sarnold namp += 2; 1772243Sarnold } while (*namp); 17821040Sbloom if (XS) 17921040Sbloom SO = SE = NULL; 18021040Sbloom else { 18121040Sbloom if (tgetnum("sg") > 0) 18221040Sbloom SO = NULL; 18321040Sbloom if (tgetnum("ug") > 0) 18421040Sbloom US = NULL; 18521040Sbloom if (!SO && US) { 18621040Sbloom SO = US; 18721040Sbloom SE = UE; 18821040Sbloom } 1892243Sarnold } 1902243Sarnold } 1913786Sarnold 1923786Sarnold /* 19355987Sbostic * getcap -- 19455987Sbostic * Return a capability from termcap. 1953786Sarnold */ 1963786Sarnold char * 1973786Sarnold getcap(name) 19855987Sbostic char *name; 1993786Sarnold { 20055987Sbostic return (tgetstr(name, &aoftspace)); 2013786Sarnold } 202