1*41263Sbostic /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2*41263Sbostic /* hack.termcap.c - version 1.0.3 */
3*41263Sbostic
4*41263Sbostic #include <stdio.h>
5*41263Sbostic #include "config.h" /* for ROWNO and COLNO */
6*41263Sbostic #include "def.flag.h" /* for flags.nonull */
7*41263Sbostic extern char *tgetstr(), *tgoto(), *getenv();
8*41263Sbostic extern long *alloc();
9*41263Sbostic
10*41263Sbostic #ifndef lint
11*41263Sbostic extern /* it is defined in libtermlib (libtermcap) */
12*41263Sbostic #endif lint
13*41263Sbostic short ospeed; /* terminal baudrate; used by tputs */
14*41263Sbostic static char tbuf[512];
15*41263Sbostic static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
16*41263Sbostic static char *VS, *VE;
17*41263Sbostic static int SG;
18*41263Sbostic static char PC = '\0';
19*41263Sbostic char *CD; /* tested in pri.c: docorner() */
20*41263Sbostic int CO, LI; /* used in pri.c and whatis.c */
21*41263Sbostic
startup()22*41263Sbostic startup()
23*41263Sbostic {
24*41263Sbostic register char *term;
25*41263Sbostic register char *tptr;
26*41263Sbostic char *tbufptr, *pc;
27*41263Sbostic
28*41263Sbostic tptr = (char *) alloc(1024);
29*41263Sbostic
30*41263Sbostic tbufptr = tbuf;
31*41263Sbostic if(!(term = getenv("TERM")))
32*41263Sbostic error("Can't get TERM.");
33*41263Sbostic if(!strncmp(term, "5620", 4))
34*41263Sbostic flags.nonull = 1; /* this should be a termcap flag */
35*41263Sbostic if(tgetent(tptr, term) < 1)
36*41263Sbostic error("Unknown terminal type: %s.", term);
37*41263Sbostic if(pc = tgetstr("pc", &tbufptr))
38*41263Sbostic PC = *pc;
39*41263Sbostic if(!(BC = tgetstr("bc", &tbufptr))) {
40*41263Sbostic if(!tgetflag("bs"))
41*41263Sbostic error("Terminal must backspace.");
42*41263Sbostic BC = tbufptr;
43*41263Sbostic tbufptr += 2;
44*41263Sbostic *BC = '\b';
45*41263Sbostic }
46*41263Sbostic HO = tgetstr("ho", &tbufptr);
47*41263Sbostic CO = tgetnum("co");
48*41263Sbostic LI = tgetnum("li");
49*41263Sbostic if(CO < COLNO || LI < ROWNO+2)
50*41263Sbostic setclipped();
51*41263Sbostic if(!(CL = tgetstr("cl", &tbufptr)))
52*41263Sbostic error("Hack needs CL.");
53*41263Sbostic ND = tgetstr("nd", &tbufptr);
54*41263Sbostic if(tgetflag("os"))
55*41263Sbostic error("Hack can't have OS.");
56*41263Sbostic CE = tgetstr("ce", &tbufptr);
57*41263Sbostic UP = tgetstr("up", &tbufptr);
58*41263Sbostic /* It seems that xd is no longer supported, and we should use
59*41263Sbostic a linefeed instead; unfortunately this requires resetting
60*41263Sbostic CRMOD, and many output routines will have to be modified
61*41263Sbostic slightly. Let's leave that till the next release. */
62*41263Sbostic XD = tgetstr("xd", &tbufptr);
63*41263Sbostic /* not: XD = tgetstr("do", &tbufptr); */
64*41263Sbostic if(!(CM = tgetstr("cm", &tbufptr))) {
65*41263Sbostic if(!UP && !HO)
66*41263Sbostic error("Hack needs CM or UP or HO.");
67*41263Sbostic printf("Playing hack on terminals without cm is suspect...\n");
68*41263Sbostic getret();
69*41263Sbostic }
70*41263Sbostic SO = tgetstr("so", &tbufptr);
71*41263Sbostic SE = tgetstr("se", &tbufptr);
72*41263Sbostic SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */
73*41263Sbostic if(!SO || !SE || (SG > 0)) SO = SE = 0;
74*41263Sbostic CD = tgetstr("cd", &tbufptr);
75*41263Sbostic set_whole_screen(); /* uses LI and CD */
76*41263Sbostic if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
77*41263Sbostic free(tptr);
78*41263Sbostic }
79*41263Sbostic
start_screen()80*41263Sbostic start_screen()
81*41263Sbostic {
82*41263Sbostic xputs(TI);
83*41263Sbostic xputs(VS);
84*41263Sbostic }
85*41263Sbostic
end_screen()86*41263Sbostic end_screen()
87*41263Sbostic {
88*41263Sbostic xputs(VE);
89*41263Sbostic xputs(TE);
90*41263Sbostic }
91*41263Sbostic
92*41263Sbostic /* Cursor movements */
93*41263Sbostic extern xchar curx, cury;
94*41263Sbostic
curs(x,y)95*41263Sbostic curs(x, y)
96*41263Sbostic register int x, y; /* not xchar: perhaps xchar is unsigned and
97*41263Sbostic curx-x would be unsigned as well */
98*41263Sbostic {
99*41263Sbostic
100*41263Sbostic if (y == cury && x == curx)
101*41263Sbostic return;
102*41263Sbostic if(!ND && (curx != x || x <= 3)) { /* Extremely primitive */
103*41263Sbostic cmov(x, y); /* bunker!wtm */
104*41263Sbostic return;
105*41263Sbostic }
106*41263Sbostic if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
107*41263Sbostic nocmov(x, y);
108*41263Sbostic else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
109*41263Sbostic (void) putchar('\r');
110*41263Sbostic curx = 1;
111*41263Sbostic nocmov(x, y);
112*41263Sbostic } else if(!CM) {
113*41263Sbostic nocmov(x, y);
114*41263Sbostic } else
115*41263Sbostic cmov(x, y);
116*41263Sbostic }
117*41263Sbostic
nocmov(x,y)118*41263Sbostic nocmov(x, y)
119*41263Sbostic {
120*41263Sbostic if (cury > y) {
121*41263Sbostic if(UP) {
122*41263Sbostic while (cury > y) { /* Go up. */
123*41263Sbostic xputs(UP);
124*41263Sbostic cury--;
125*41263Sbostic }
126*41263Sbostic } else if(CM) {
127*41263Sbostic cmov(x, y);
128*41263Sbostic } else if(HO) {
129*41263Sbostic home();
130*41263Sbostic curs(x, y);
131*41263Sbostic } /* else impossible("..."); */
132*41263Sbostic } else if (cury < y) {
133*41263Sbostic if(XD) {
134*41263Sbostic while(cury < y) {
135*41263Sbostic xputs(XD);
136*41263Sbostic cury++;
137*41263Sbostic }
138*41263Sbostic } else if(CM) {
139*41263Sbostic cmov(x, y);
140*41263Sbostic } else {
141*41263Sbostic while(cury < y) {
142*41263Sbostic xputc('\n');
143*41263Sbostic curx = 1;
144*41263Sbostic cury++;
145*41263Sbostic }
146*41263Sbostic }
147*41263Sbostic }
148*41263Sbostic if (curx < x) { /* Go to the right. */
149*41263Sbostic if(!ND) cmov(x, y); else /* bah */
150*41263Sbostic /* should instead print what is there already */
151*41263Sbostic while (curx < x) {
152*41263Sbostic xputs(ND);
153*41263Sbostic curx++;
154*41263Sbostic }
155*41263Sbostic } else if (curx > x) {
156*41263Sbostic while (curx > x) { /* Go to the left. */
157*41263Sbostic xputs(BC);
158*41263Sbostic curx--;
159*41263Sbostic }
160*41263Sbostic }
161*41263Sbostic }
162*41263Sbostic
cmov(x,y)163*41263Sbostic cmov(x, y)
164*41263Sbostic register x, y;
165*41263Sbostic {
166*41263Sbostic xputs(tgoto(CM, x-1, y-1));
167*41263Sbostic cury = y;
168*41263Sbostic curx = x;
169*41263Sbostic }
170*41263Sbostic
xputc(c)171*41263Sbostic xputc(c) char c; {
172*41263Sbostic (void) fputc(c, stdout);
173*41263Sbostic }
174*41263Sbostic
xputs(s)175*41263Sbostic xputs(s) char *s; {
176*41263Sbostic tputs(s, 1, xputc);
177*41263Sbostic }
178*41263Sbostic
cl_end()179*41263Sbostic cl_end() {
180*41263Sbostic if(CE)
181*41263Sbostic xputs(CE);
182*41263Sbostic else { /* no-CE fix - free after Harold Rynes */
183*41263Sbostic /* this looks terrible, especially on a slow terminal
184*41263Sbostic but is better than nothing */
185*41263Sbostic register cx = curx, cy = cury;
186*41263Sbostic
187*41263Sbostic while(curx < COLNO) {
188*41263Sbostic xputc(' ');
189*41263Sbostic curx++;
190*41263Sbostic }
191*41263Sbostic curs(cx, cy);
192*41263Sbostic }
193*41263Sbostic }
194*41263Sbostic
clear_screen()195*41263Sbostic clear_screen() {
196*41263Sbostic xputs(CL);
197*41263Sbostic curx = cury = 1;
198*41263Sbostic }
199*41263Sbostic
home()200*41263Sbostic home()
201*41263Sbostic {
202*41263Sbostic if(HO)
203*41263Sbostic xputs(HO);
204*41263Sbostic else if(CM)
205*41263Sbostic xputs(tgoto(CM, 0, 0));
206*41263Sbostic else
207*41263Sbostic curs(1, 1); /* using UP ... */
208*41263Sbostic curx = cury = 1;
209*41263Sbostic }
210*41263Sbostic
standoutbeg()211*41263Sbostic standoutbeg()
212*41263Sbostic {
213*41263Sbostic if(SO) xputs(SO);
214*41263Sbostic }
215*41263Sbostic
standoutend()216*41263Sbostic standoutend()
217*41263Sbostic {
218*41263Sbostic if(SE) xputs(SE);
219*41263Sbostic }
220*41263Sbostic
backsp()221*41263Sbostic backsp()
222*41263Sbostic {
223*41263Sbostic xputs(BC);
224*41263Sbostic curx--;
225*41263Sbostic }
226*41263Sbostic
bell()227*41263Sbostic bell()
228*41263Sbostic {
229*41263Sbostic (void) putchar('\007'); /* curx does not change */
230*41263Sbostic (void) fflush(stdout);
231*41263Sbostic }
232*41263Sbostic
233*41263Sbostic static short tmspc10[] = { /* from termcap */
234*41263Sbostic 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
235*41263Sbostic };
236*41263Sbostic
delay_output()237*41263Sbostic delay_output() {
238*41263Sbostic /* delay 50 ms - could also use a 'nap'-system call */
239*41263Sbostic /* BUG: if the padding character is visible, as it is on the 5620
240*41263Sbostic then this looks terrible. */
241*41263Sbostic if(!flags.nonull)
242*41263Sbostic tputs("50", 1, xputc);
243*41263Sbostic
244*41263Sbostic /* cbosgd!cbcephus!pds for SYS V R2 */
245*41263Sbostic /* is this terminfo, or what? */
246*41263Sbostic /* tputs("$<50>", 1, xputc); */
247*41263Sbostic
248*41263Sbostic else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) {
249*41263Sbostic /* delay by sending cm(here) an appropriate number of times */
250*41263Sbostic register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
251*41263Sbostic register int i = 500 + tmspc10[ospeed]/2;
252*41263Sbostic
253*41263Sbostic while(i > 0) {
254*41263Sbostic cmov(curx, cury);
255*41263Sbostic i -= cmlen*tmspc10[ospeed];
256*41263Sbostic }
257*41263Sbostic }
258*41263Sbostic }
259*41263Sbostic
cl_eos()260*41263Sbostic cl_eos() /* free after Robert Viduya */
261*41263Sbostic { /* must only be called with curx = 1 */
262*41263Sbostic
263*41263Sbostic if(CD)
264*41263Sbostic xputs(CD);
265*41263Sbostic else {
266*41263Sbostic register int cx = curx, cy = cury;
267*41263Sbostic while(cury <= LI-2) {
268*41263Sbostic cl_end();
269*41263Sbostic xputc('\n');
270*41263Sbostic curx = 1;
271*41263Sbostic cury++;
272*41263Sbostic }
273*41263Sbostic cl_end();
274*41263Sbostic curs(cx, cy);
275*41263Sbostic }
276*41263Sbostic }
277