1*aed906e4Smestre /* $OpenBSD: hack.termcap.c,v 1.9 2016/01/09 18:33:15 mestre Exp $ */
2d0b779f3Sniklas
3df930be7Sderaadt /*
4d25013f2Scamield * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5d25013f2Scamield * Amsterdam
6d25013f2Scamield * All rights reserved.
7d25013f2Scamield *
8d25013f2Scamield * Redistribution and use in source and binary forms, with or without
9d25013f2Scamield * modification, are permitted provided that the following conditions are
10d25013f2Scamield * met:
11d25013f2Scamield *
12d25013f2Scamield * - Redistributions of source code must retain the above copyright notice,
13d25013f2Scamield * this list of conditions and the following disclaimer.
14d25013f2Scamield *
15d25013f2Scamield * - Redistributions in binary form must reproduce the above copyright
16d25013f2Scamield * notice, this list of conditions and the following disclaimer in the
17d25013f2Scamield * documentation and/or other materials provided with the distribution.
18d25013f2Scamield *
19d25013f2Scamield * - Neither the name of the Stichting Centrum voor Wiskunde en
20d25013f2Scamield * Informatica, nor the names of its contributors may be used to endorse or
21d25013f2Scamield * promote products derived from this software without specific prior
22d25013f2Scamield * written permission.
23d25013f2Scamield *
24d25013f2Scamield * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25d25013f2Scamield * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26d25013f2Scamield * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27d25013f2Scamield * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28d25013f2Scamield * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29d25013f2Scamield * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30d25013f2Scamield * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31d25013f2Scamield * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32d25013f2Scamield * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33d25013f2Scamield * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34d25013f2Scamield * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35d25013f2Scamield */
36d25013f2Scamield
37d25013f2Scamield /*
38d25013f2Scamield * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39d25013f2Scamield * All rights reserved.
40d25013f2Scamield *
41d25013f2Scamield * Redistribution and use in source and binary forms, with or without
42d25013f2Scamield * modification, are permitted provided that the following conditions
43d25013f2Scamield * are met:
44d25013f2Scamield * 1. Redistributions of source code must retain the above copyright
45d25013f2Scamield * notice, this list of conditions and the following disclaimer.
46d25013f2Scamield * 2. Redistributions in binary form must reproduce the above copyright
47d25013f2Scamield * notice, this list of conditions and the following disclaimer in the
48d25013f2Scamield * documentation and/or other materials provided with the distribution.
49d25013f2Scamield * 3. The name of the author may not be used to endorse or promote products
50d25013f2Scamield * derived from this software without specific prior written permission.
51d25013f2Scamield *
52d25013f2Scamield * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53d25013f2Scamield * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54d25013f2Scamield * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55d25013f2Scamield * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56d25013f2Scamield * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57d25013f2Scamield * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58d25013f2Scamield * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59d25013f2Scamield * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60d25013f2Scamield * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61d25013f2Scamield * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62df930be7Sderaadt */
63df930be7Sderaadt
644a5fbbc4Spjanzen #include <curses.h>
65*aed906e4Smestre #include <stdlib.h>
664a5fbbc4Spjanzen #include <term.h>
67df930be7Sderaadt
684a5fbbc4Spjanzen #include "hack.h"
694a5fbbc4Spjanzen
70df930be7Sderaadt static char tbuf[512];
71df930be7Sderaadt static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
72df930be7Sderaadt static char *VS, *VE;
73df930be7Sderaadt static int SG;
74df930be7Sderaadt static char PC = '\0';
75df930be7Sderaadt char *CD; /* tested in pri.c: docorner() */
76df930be7Sderaadt int CO, LI; /* used in pri.c and whatis.c */
77df930be7Sderaadt
784a5fbbc4Spjanzen static void nocmov(int, int);
794a5fbbc4Spjanzen static void cmov(int, int);
804a5fbbc4Spjanzen static int xputc(int);
814a5fbbc4Spjanzen static void xputs(char *);
824a5fbbc4Spjanzen
834a5fbbc4Spjanzen void
startup(void)84*aed906e4Smestre startup(void)
85df930be7Sderaadt {
864a5fbbc4Spjanzen char *term;
874a5fbbc4Spjanzen char *tptr;
88df930be7Sderaadt char *tbufptr, *pc;
89df930be7Sderaadt
90df930be7Sderaadt tptr = (char *) alloc(1024);
91df930be7Sderaadt
92df930be7Sderaadt tbufptr = tbuf;
93df930be7Sderaadt if(!(term = getenv("TERM")))
94df930be7Sderaadt error("Can't get TERM.");
95df930be7Sderaadt if(!strncmp(term, "5620", 4))
96df930be7Sderaadt flags.nonull = 1; /* this should be a termcap flag */
97df930be7Sderaadt if(tgetent(tptr, term) < 1)
98df930be7Sderaadt error("Unknown terminal type: %s.", term);
994a5fbbc4Spjanzen if ((pc = tgetstr("pc", &tbufptr)))
100df930be7Sderaadt PC = *pc;
1014e007cc2Skstailey if(!(BC = tgetstr("le", &tbufptr))) {
102df930be7Sderaadt if(!tgetflag("bs"))
103df930be7Sderaadt error("Terminal must backspace.");
104df930be7Sderaadt BC = tbufptr;
105df930be7Sderaadt tbufptr += 2;
106df930be7Sderaadt *BC = '\b';
107df930be7Sderaadt }
108df930be7Sderaadt HO = tgetstr("ho", &tbufptr);
109df930be7Sderaadt CO = tgetnum("co");
110df930be7Sderaadt LI = tgetnum("li");
111df930be7Sderaadt if(CO < COLNO || LI < ROWNO+2)
112df930be7Sderaadt setclipped();
113df930be7Sderaadt if(!(CL = tgetstr("cl", &tbufptr)))
114df930be7Sderaadt error("Hack needs CL.");
115df930be7Sderaadt ND = tgetstr("nd", &tbufptr);
116df930be7Sderaadt if(tgetflag("os"))
117df930be7Sderaadt error("Hack can't have OS.");
118df930be7Sderaadt CE = tgetstr("ce", &tbufptr);
119df930be7Sderaadt UP = tgetstr("up", &tbufptr);
120df930be7Sderaadt /* It seems that xd is no longer supported, and we should use
121df930be7Sderaadt a linefeed instead; unfortunately this requires resetting
122df930be7Sderaadt CRMOD, and many output routines will have to be modified
123df930be7Sderaadt slightly. Let's leave that till the next release. */
124df930be7Sderaadt XD = tgetstr("xd", &tbufptr);
125df930be7Sderaadt /* not: XD = tgetstr("do", &tbufptr); */
126df930be7Sderaadt if(!(CM = tgetstr("cm", &tbufptr))) {
127df930be7Sderaadt if(!UP && !HO)
128df930be7Sderaadt error("Hack needs CM or UP or HO.");
129df930be7Sderaadt printf("Playing hack on terminals without cm is suspect...\n");
130df930be7Sderaadt getret();
131df930be7Sderaadt }
132df930be7Sderaadt SO = tgetstr("so", &tbufptr);
133df930be7Sderaadt SE = tgetstr("se", &tbufptr);
134df930be7Sderaadt SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */
135df930be7Sderaadt if(!SO || !SE || (SG > 0)) SO = SE = 0;
136df930be7Sderaadt CD = tgetstr("cd", &tbufptr);
137df930be7Sderaadt set_whole_screen(); /* uses LI and CD */
138df930be7Sderaadt if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
139df930be7Sderaadt free(tptr);
140df930be7Sderaadt }
141df930be7Sderaadt
1424a5fbbc4Spjanzen void
start_screen(void)143*aed906e4Smestre start_screen(void)
144df930be7Sderaadt {
145df930be7Sderaadt xputs(TI);
146df930be7Sderaadt xputs(VS);
147df930be7Sderaadt }
148df930be7Sderaadt
1494a5fbbc4Spjanzen void
end_screen(void)150*aed906e4Smestre end_screen(void)
151df930be7Sderaadt {
152df930be7Sderaadt xputs(VE);
153df930be7Sderaadt xputs(TE);
154df930be7Sderaadt }
155df930be7Sderaadt
156df930be7Sderaadt /* Cursor movements */
157df930be7Sderaadt extern xchar curx, cury;
158df930be7Sderaadt
159*aed906e4Smestre /* int x, y; not xchar: perhaps xchar is unsigned and
160*aed906e4Smestre * curx-x would be unsigned as well
161*aed906e4Smestre */
1624a5fbbc4Spjanzen void
curs(int x,int y)1634a5fbbc4Spjanzen curs(int x, int y)
164df930be7Sderaadt {
165df930be7Sderaadt if (y == cury && x == curx)
166df930be7Sderaadt return;
167df930be7Sderaadt if(!ND && (curx != x || x <= 3)) { /* Extremely primitive */
168df930be7Sderaadt cmov(x, y); /* bunker!wtm */
169df930be7Sderaadt return;
170df930be7Sderaadt }
171df930be7Sderaadt if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
172df930be7Sderaadt nocmov(x, y);
173df930be7Sderaadt else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
174df930be7Sderaadt (void) putchar('\r');
175df930be7Sderaadt curx = 1;
176df930be7Sderaadt nocmov(x, y);
177df930be7Sderaadt } else if(!CM) {
178df930be7Sderaadt nocmov(x, y);
179df930be7Sderaadt } else
180df930be7Sderaadt cmov(x, y);
181df930be7Sderaadt }
182df930be7Sderaadt
1834a5fbbc4Spjanzen static void
nocmov(int x,int y)1844a5fbbc4Spjanzen nocmov(int x, int y)
185df930be7Sderaadt {
186df930be7Sderaadt if (cury > y) {
187df930be7Sderaadt if(UP) {
188df930be7Sderaadt while (cury > y) { /* Go up. */
189df930be7Sderaadt xputs(UP);
190df930be7Sderaadt cury--;
191df930be7Sderaadt }
192df930be7Sderaadt } else if(CM) {
193df930be7Sderaadt cmov(x, y);
194df930be7Sderaadt } else if(HO) {
195df930be7Sderaadt home();
196df930be7Sderaadt curs(x, y);
197df930be7Sderaadt } /* else impossible("..."); */
198df930be7Sderaadt } else if (cury < y) {
199df930be7Sderaadt if(XD) {
200df930be7Sderaadt while(cury < y) {
201df930be7Sderaadt xputs(XD);
202df930be7Sderaadt cury++;
203df930be7Sderaadt }
204df930be7Sderaadt } else if(CM) {
205df930be7Sderaadt cmov(x, y);
206df930be7Sderaadt } else {
207df930be7Sderaadt while(cury < y) {
208df930be7Sderaadt xputc('\n');
209df930be7Sderaadt curx = 1;
210df930be7Sderaadt cury++;
211df930be7Sderaadt }
212df930be7Sderaadt }
213df930be7Sderaadt }
214df930be7Sderaadt if (curx < x) { /* Go to the right. */
215df930be7Sderaadt if(!ND) cmov(x, y); else /* bah */
216df930be7Sderaadt /* should instead print what is there already */
217df930be7Sderaadt while (curx < x) {
218df930be7Sderaadt xputs(ND);
219df930be7Sderaadt curx++;
220df930be7Sderaadt }
221df930be7Sderaadt } else if (curx > x) {
222df930be7Sderaadt while (curx > x) { /* Go to the left. */
223df930be7Sderaadt xputs(BC);
224df930be7Sderaadt curx--;
225df930be7Sderaadt }
226df930be7Sderaadt }
227df930be7Sderaadt }
228df930be7Sderaadt
2294a5fbbc4Spjanzen static void
cmov(int x,int y)2304a5fbbc4Spjanzen cmov(int x, int y)
231df930be7Sderaadt {
232df930be7Sderaadt xputs(tgoto(CM, x-1, y-1));
233df930be7Sderaadt cury = y;
234df930be7Sderaadt curx = x;
235df930be7Sderaadt }
236df930be7Sderaadt
2374a5fbbc4Spjanzen static int
xputc(int c)2384a5fbbc4Spjanzen xputc(int c)
2394a5fbbc4Spjanzen {
2404a5fbbc4Spjanzen return fputc(c, stdout);
241df930be7Sderaadt }
242df930be7Sderaadt
2434a5fbbc4Spjanzen static void
xputs(char * s)2444a5fbbc4Spjanzen xputs(char *s)
2454a5fbbc4Spjanzen {
246df930be7Sderaadt tputs(s, 1, xputc);
247df930be7Sderaadt }
248df930be7Sderaadt
2494a5fbbc4Spjanzen void
cl_end(void)250*aed906e4Smestre cl_end(void)
2514a5fbbc4Spjanzen {
252df930be7Sderaadt if(CE)
253df930be7Sderaadt xputs(CE);
254df930be7Sderaadt else { /* no-CE fix - free after Harold Rynes */
255df930be7Sderaadt /* this looks terrible, especially on a slow terminal
256df930be7Sderaadt but is better than nothing */
2574a5fbbc4Spjanzen int cx = curx, cy = cury;
258df930be7Sderaadt
259df930be7Sderaadt while(curx < COLNO) {
260df930be7Sderaadt xputc(' ');
261df930be7Sderaadt curx++;
262df930be7Sderaadt }
263df930be7Sderaadt curs(cx, cy);
264df930be7Sderaadt }
265df930be7Sderaadt }
266df930be7Sderaadt
2674a5fbbc4Spjanzen void
clr_screen(void)268*aed906e4Smestre clr_screen(void)
2694a5fbbc4Spjanzen {
270df930be7Sderaadt xputs(CL);
271df930be7Sderaadt curx = cury = 1;
272df930be7Sderaadt }
273df930be7Sderaadt
2744a5fbbc4Spjanzen void
home(void)275*aed906e4Smestre home(void)
276df930be7Sderaadt {
277df930be7Sderaadt if(HO)
278df930be7Sderaadt xputs(HO);
279df930be7Sderaadt else if(CM)
280df930be7Sderaadt xputs(tgoto(CM, 0, 0));
281df930be7Sderaadt else
282df930be7Sderaadt curs(1, 1); /* using UP ... */
283df930be7Sderaadt curx = cury = 1;
284df930be7Sderaadt }
285df930be7Sderaadt
2864a5fbbc4Spjanzen void
standoutbeg(void)287*aed906e4Smestre standoutbeg(void)
288df930be7Sderaadt {
289df930be7Sderaadt if(SO) xputs(SO);
290df930be7Sderaadt }
291df930be7Sderaadt
2924a5fbbc4Spjanzen void
standoutend(void)293*aed906e4Smestre standoutend(void)
294df930be7Sderaadt {
295df930be7Sderaadt if(SE) xputs(SE);
296df930be7Sderaadt }
297df930be7Sderaadt
2984a5fbbc4Spjanzen void
backsp(void)299*aed906e4Smestre backsp(void)
300df930be7Sderaadt {
301df930be7Sderaadt xputs(BC);
302df930be7Sderaadt curx--;
303df930be7Sderaadt }
304df930be7Sderaadt
3054a5fbbc4Spjanzen void
hackbell(void)306*aed906e4Smestre hackbell(void)
307df930be7Sderaadt {
308df930be7Sderaadt (void) putchar('\007'); /* curx does not change */
309df930be7Sderaadt (void) fflush(stdout);
310df930be7Sderaadt }
311df930be7Sderaadt
312*aed906e4Smestre /* free after Robert Viduya
313*aed906e4Smestre * must only be called with curx = 1
314*aed906e4Smestre */
3154a5fbbc4Spjanzen void
cl_eos(void)316*aed906e4Smestre cl_eos(void)
317*aed906e4Smestre {
318df930be7Sderaadt
319df930be7Sderaadt if(CD)
320df930be7Sderaadt xputs(CD);
321df930be7Sderaadt else {
3224a5fbbc4Spjanzen int cx = curx, cy = cury;
323df930be7Sderaadt while(cury <= LI-2) {
324df930be7Sderaadt cl_end();
325df930be7Sderaadt xputc('\n');
326df930be7Sderaadt curx = 1;
327df930be7Sderaadt cury++;
328df930be7Sderaadt }
329df930be7Sderaadt cl_end();
330df930be7Sderaadt curs(cx, cy);
331df930be7Sderaadt }
332df930be7Sderaadt }
333