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*59096Selan static char sccsid[] = "@(#)setterm.c 5.17 (Berkeley) 04/15/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[] = { 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, 3456298Selan &VB, &VS, &VE, &al, &dl, &sf, &sr, &AL_PARM, 3556298Selan &DL_PARM, &UP_PARM, &DOWN_PARM, &LEFT_PARM, 3656298Selan &RIGHT_PARM, 3739140Sbostic }; 382243Sarnold 3919875Sbloom static char *aoftspace; /* Address of _tspace for relocation */ 4055987Sbostic static char tspace[2048]; /* Space for capability strings */ 4119875Sbloom 4255987Sbostic char *ttytype; 432243Sarnold 4455987Sbostic int 452243Sarnold setterm(type) 4655987Sbostic register char *type; 4755987Sbostic { 4855987Sbostic static char genbuf[1024]; 4955987Sbostic static char __ttytype[1024]; 5055987Sbostic register int unknown; 5118032Sbloom struct winsize win; 5255987Sbostic char *p; 532243Sarnold 5455987Sbostic #ifdef DEBUG 5555987Sbostic __TRACE("setterm: (\"%s\")\nLINES = %d, COLS = %d\n", 5655987Sbostic type, LINES, COLS); 5755987Sbostic #endif 582243Sarnold if (type[0] == '\0') 592243Sarnold type = "xx"; 6055987Sbostic unknown = 0; 612243Sarnold if (tgetent(genbuf, type) != 1) { 622243Sarnold unknown++; 632243Sarnold strcpy(genbuf, "xx|dumb:"); 642243Sarnold } 6555987Sbostic #ifdef DEBUG 6655987Sbostic __TRACE("setterm: tty = %s\n", type); 6755987Sbostic #endif 6818032Sbloom 6955987Sbostic /* Try TIOCGWINSZ, and, if it fails, the termcap entry. */ 7055987Sbostic if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1 && 7155987Sbostic win.ws_row != 0 && win.ws_col != 0) { 7255987Sbostic LINES = win.ws_row; 7355987Sbostic COLS = win.ws_col; 7455987Sbostic } else { 752243Sarnold LINES = tgetnum("li"); 762243Sarnold COLS = tgetnum("co"); 7755987Sbostic } 7812570Sarnold 7955987Sbostic /* POSIX 1003.2 requires that the environment override. */ 8055987Sbostic if ((p = getenv("ROWS")) != NULL) 8155987Sbostic LINES = strtol(p, NULL, 10); 8255987Sbostic if ((p = getenv("COLUMNS")) != NULL) 8355987Sbostic COLS = strtol(p, NULL, 10); 8419875Sbloom 8519875Sbloom /* 86*59096Selan * Want cols > 4, otherwise things will fail. 8719875Sbloom */ 88*59096Selan if (COLS <= 4) 8957472Sbostic return (ERR); 9019875Sbloom 9155987Sbostic #ifdef DEBUG 9255987Sbostic __TRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS); 9355987Sbostic #endif 9455987Sbostic aoftspace = tspace; 9555987Sbostic zap(); /* Get terminal description. */ 9619875Sbloom 9755987Sbostic /* Handle funny termcap capabilities. */ 9855987Sbostic if (CS && SC && RC) 9955987Sbostic AL = DL = ""; 10055987Sbostic if (AL_PARM && AL == NULL) 10155987Sbostic AL = ""; 10255987Sbostic if (DL_PARM && DL == NULL) 10355987Sbostic DL = ""; 10455987Sbostic if (IC) { 10555987Sbostic if (IM == NULL) 10655987Sbostic IM = ""; 10755987Sbostic if (EI == NULL) 10855987Sbostic EI = ""; 10955987Sbostic } 11058046Selan 11158046Selan /* If we can't tab, we can't backtab, either. */ 11258046Selan if (!GT) 11355987Sbostic BT = NULL; 11437420Sbostic 11558046Selan /* 11658046Selan * Test for cursor motion capbility. 11758046Selan * 11858046Selan * XXX 11958046Selan * This is truly stupid -- tgoto returns "OOPS" if it can't 12058046Selan * do cursor motions. 12158046Selan */ 12258046Selan if (tgoto(CM, 0, 0)[0] == 'O') { 12355987Sbostic CA = 0; 12455987Sbostic CM = 0; 12555987Sbostic } else 12655987Sbostic CA = 1; 12755987Sbostic 12855987Sbostic PC = _PC ? _PC[0] : 0; 12955987Sbostic aoftspace = tspace; 13055987Sbostic ttytype = longname(genbuf, __ttytype); 13155987Sbostic 13256298Selan if ((!AL && !al) || (!DL && !dl)) 13356298Selan __noqch = 1; 13456298Selan 13557472Sbostic return (unknown ? ERR : OK); 1362243Sarnold } 13719875Sbloom 1382243Sarnold /* 13955987Sbostic * zap -- 14055987Sbostic * Gets all the terminal flags from the termcap database. 1412243Sarnold */ 14255987Sbostic static void 14319875Sbloom zap() 14419875Sbloom { 14555987Sbostic register char *namp, ***sp; 14655987Sbostic register char **fp; 14756238Selan char tmp[3]; 14855987Sbostic #ifdef DEBUG 14919875Sbloom register char *cp; 15019875Sbloom #endif 15156238Selan tmp[2] = '\0'; 1522243Sarnold 15357819Selan namp = "ambsdaeohchzinmimsncnsosulxbxnxtxsxx"; 1542243Sarnold fp = sflags; 1552243Sarnold do { 15656238Selan *tmp = *namp; 15756238Selan *(tmp + 1) = *(namp + 1); 15856238Selan *(*fp++) = tgetflag(tmp); 15919875Sbloom #ifdef DEBUG 16055987Sbostic __TRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE"); 16119875Sbloom #endif 1622243Sarnold namp += 2; 16356238Selan 1642243Sarnold } while (*namp); 16556298Selan namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI"; 1662243Sarnold sp = sstrs; 1672243Sarnold do { 16856238Selan *tmp = *namp; 16956238Selan *(tmp + 1) = *(namp + 1); 17056238Selan *(*sp++) = tgetstr(tmp, &aoftspace); 17119875Sbloom #ifdef DEBUG 17255987Sbostic __TRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\""); 17319875Sbloom if (*sp[-1] != NULL) { 17419875Sbloom for (cp = *sp[-1]; *cp; cp++) 17555987Sbostic __TRACE("%s", unctrl(*cp)); 17655987Sbostic __TRACE("\"\n"); 17719875Sbloom } 17819875Sbloom #endif 1792243Sarnold namp += 2; 1802243Sarnold } while (*namp); 18121040Sbloom if (XS) 18221040Sbloom SO = SE = NULL; 18321040Sbloom else { 18421040Sbloom if (tgetnum("sg") > 0) 18521040Sbloom SO = NULL; 18621040Sbloom if (tgetnum("ug") > 0) 18721040Sbloom US = NULL; 18821040Sbloom if (!SO && US) { 18921040Sbloom SO = US; 19021040Sbloom SE = UE; 19121040Sbloom } 1922243Sarnold } 1932243Sarnold } 1943786Sarnold 1953786Sarnold /* 19655987Sbostic * getcap -- 19755987Sbostic * Return a capability from termcap. 1983786Sarnold */ 1993786Sarnold char * 2003786Sarnold getcap(name) 20155987Sbostic char *name; 2023786Sarnold { 20355987Sbostic return (tgetstr(name, &aoftspace)); 2043786Sarnold } 205