12243Sarnold /*
267082Sbostic * Copyright (c) 1981, 1993, 1994
361272Sbostic * The Regents of the University of California. All rights reserved.
434677Sbostic *
542653Sbostic * %sccs.include.redist.c%
622656Sdist */
722656Sdist
822656Sdist #ifndef lint
9*67852Sbostic static char sccsid[] = "@(#)setterm.c 8.8 (Berkeley) 10/25/94";
1034677Sbostic #endif /* not lint */
1122656Sdist
1267176Sbostic #include <sys/ioctl.h> /* TIOCGWINSZ on old systems. */
1367176Sbostic
1455987Sbostic #include <stdlib.h>
1555987Sbostic #include <string.h>
1667082Sbostic #include <termios.h>
1755987Sbostic #include <unistd.h>
182243Sarnold
1967082Sbostic #include "curses.h"
2067082Sbostic
2155987Sbostic static void zap __P((void));
2255987Sbostic
2355987Sbostic static char *sflags[] = {
2465311Sbostic /* am bs da eo hc in mi ms */
2565311Sbostic &AM, &BS, &DA, &EO, &HC, &IN, &MI, &MS,
2659864Sbostic /* nc ns os ul xb xn xt xs xx */
2755987Sbostic &NC, &NS, &OS, &UL, &XB, &XN, &XT, &XS, &XX
282243Sarnold };
292243Sarnold
3019875Sbloom static char *_PC,
3119875Sbloom **sstrs[] = {
3259864Sbostic /* AL bc bt cd ce cl cm cr cs */
3319875Sbloom &AL, &BC, &BT, &CD, &CE, &CL, &CM, &CR, &CS,
3459864Sbostic /* dc DL dm do ed ei k0 k1 k2 */
3519875Sbloom &DC, &DL, &DM, &DO, &ED, &EI, &K0, &K1, &K2,
3659864Sbostic /* k3 k4 k5 k6 k7 k8 k9 ho ic */
3719875Sbloom &K3, &K4, &K5, &K6, &K7, &K8, &K9, &HO, &IC,
3859864Sbostic /* im ip kd ke kh kl kr ks ku */
3919875Sbloom &IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU,
4059864Sbostic /* ll ma nd nl pc rc sc se SF */
4119875Sbloom &LL, &MA, &ND, &NL, &_PC, &RC, &SC, &SE, &SF,
4259864Sbostic /* so SR ta te ti uc ue up us */
4319875Sbloom &SO, &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US,
4459864Sbostic /* vb vs ve al dl sf sr AL */
4556298Selan &VB, &VS, &VE, &al, &dl, &sf, &sr, &AL_PARM,
4659864Sbostic /* DL UP DO LE */
4756298Selan &DL_PARM, &UP_PARM, &DOWN_PARM, &LEFT_PARM,
4859864Sbostic /* RI */
4956298Selan &RIGHT_PARM,
5039140Sbostic };
512243Sarnold
5219875Sbloom static char *aoftspace; /* Address of _tspace for relocation */
5355987Sbostic static char tspace[2048]; /* Space for capability strings */
5419875Sbloom
5555987Sbostic char *ttytype;
562243Sarnold
5755987Sbostic int
setterm(type)582243Sarnold setterm(type)
5955987Sbostic register char *type;
6055987Sbostic {
6155987Sbostic static char genbuf[1024];
6255987Sbostic static char __ttytype[1024];
6355987Sbostic register int unknown;
6418032Sbloom struct winsize win;
6555987Sbostic char *p;
662243Sarnold
6755987Sbostic #ifdef DEBUG
6860058Sbostic __CTRACE("setterm: (\"%s\")\nLINES = %d, COLS = %d\n",
6955987Sbostic type, LINES, COLS);
7055987Sbostic #endif
712243Sarnold if (type[0] == '\0')
722243Sarnold type = "xx";
7355987Sbostic unknown = 0;
742243Sarnold if (tgetent(genbuf, type) != 1) {
752243Sarnold unknown++;
762243Sarnold strcpy(genbuf, "xx|dumb:");
772243Sarnold }
7855987Sbostic #ifdef DEBUG
7960058Sbostic __CTRACE("setterm: tty = %s\n", type);
8055987Sbostic #endif
8118032Sbloom
8255987Sbostic /* Try TIOCGWINSZ, and, if it fails, the termcap entry. */
8355987Sbostic if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1 &&
8455987Sbostic win.ws_row != 0 && win.ws_col != 0) {
8555987Sbostic LINES = win.ws_row;
8655987Sbostic COLS = win.ws_col;
8755987Sbostic } else {
882243Sarnold LINES = tgetnum("li");
892243Sarnold COLS = tgetnum("co");
9055987Sbostic }
9112570Sarnold
9255987Sbostic /* POSIX 1003.2 requires that the environment override. */
9365312Sbostic if ((p = getenv("LINES")) != NULL)
9455987Sbostic LINES = strtol(p, NULL, 10);
9555987Sbostic if ((p = getenv("COLUMNS")) != NULL)
9655987Sbostic COLS = strtol(p, NULL, 10);
9719875Sbloom
9819875Sbloom /*
9959096Selan * Want cols > 4, otherwise things will fail.
10019875Sbloom */
10159096Selan if (COLS <= 4)
10257472Sbostic return (ERR);
10319875Sbloom
10455987Sbostic #ifdef DEBUG
10560058Sbostic __CTRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS);
10655987Sbostic #endif
10755987Sbostic aoftspace = tspace;
10855987Sbostic zap(); /* Get terminal description. */
10919875Sbloom
11058046Selan /* If we can't tab, we can't backtab, either. */
11158046Selan if (!GT)
11255987Sbostic BT = NULL;
11337420Sbostic
11458046Selan /*
11558046Selan * Test for cursor motion capbility.
11658046Selan *
11758046Selan * XXX
118*67852Sbostic * This is truly stupid -- historically, tgoto returns "OOPS" if it
119*67852Sbostic * can't do cursor motions. Some systems have been fixed to return
120*67852Sbostic * a NULL pointer.
12158046Selan */
122*67852Sbostic if ((p = tgoto(CM, 0, 0)) == NULL || *p == '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
13267572Sbostic /* If no scrolling commands, no quick change. */
13367572Sbostic __noqch =
13467574Sbostic (CS == NULL || HO == NULL ||
13567574Sbostic SF == NULL && sf == NULL || SR == NULL && sr == NULL) &&
13667574Sbostic (AL == NULL && al == NULL || DL == NULL && dl == NULL);
13756298Selan
13857472Sbostic return (unknown ? ERR : OK);
1392243Sarnold }
14019875Sbloom
1412243Sarnold /*
14255987Sbostic * zap --
14355987Sbostic * Gets all the terminal flags from the termcap database.
1442243Sarnold */
14555987Sbostic static void
zap()14619875Sbloom zap()
14719875Sbloom {
14855987Sbostic register char *namp, ***sp;
14955987Sbostic register char **fp;
15056238Selan char tmp[3];
15155987Sbostic #ifdef DEBUG
15219875Sbloom register char *cp;
15319875Sbloom #endif
15456238Selan tmp[2] = '\0';
1552243Sarnold
15665311Sbostic namp = "ambsdaeohcinmimsncnsosulxbxnxtxsxx";
1572243Sarnold fp = sflags;
1582243Sarnold do {
15956238Selan *tmp = *namp;
16056238Selan *(tmp + 1) = *(namp + 1);
16156238Selan *(*fp++) = tgetflag(tmp);
16219875Sbloom #ifdef DEBUG
16360058Sbostic __CTRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE");
16419875Sbloom #endif
1652243Sarnold namp += 2;
16656238Selan
1672243Sarnold } while (*namp);
16856298Selan namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI";
1692243Sarnold sp = sstrs;
1702243Sarnold do {
17156238Selan *tmp = *namp;
17256238Selan *(tmp + 1) = *(namp + 1);
17356238Selan *(*sp++) = tgetstr(tmp, &aoftspace);
17419875Sbloom #ifdef DEBUG
17560058Sbostic __CTRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\"");
17619875Sbloom if (*sp[-1] != NULL) {
17719875Sbloom for (cp = *sp[-1]; *cp; cp++)
17860058Sbostic __CTRACE("%s", unctrl(*cp));
17960058Sbostic __CTRACE("\"\n");
18019875Sbloom }
18119875Sbloom #endif
1822243Sarnold namp += 2;
1832243Sarnold } while (*namp);
18421040Sbloom if (XS)
18521040Sbloom SO = SE = NULL;
18621040Sbloom else {
18721040Sbloom if (tgetnum("sg") > 0)
18821040Sbloom SO = NULL;
18921040Sbloom if (tgetnum("ug") > 0)
19021040Sbloom US = NULL;
19121040Sbloom if (!SO && US) {
19221040Sbloom SO = US;
19321040Sbloom SE = UE;
19421040Sbloom }
1952243Sarnold }
1962243Sarnold }
1973786Sarnold
1983786Sarnold /*
19955987Sbostic * getcap --
20055987Sbostic * Return a capability from termcap.
2013786Sarnold */
2023786Sarnold char *
getcap(name)2033786Sarnold getcap(name)
20455987Sbostic char *name;
2053786Sarnold {
20655987Sbostic return (tgetstr(name, &aoftspace));
2073786Sarnold }
208