1*4318c66eSSascha Wildner /* $NetBSD: hack.terminfo.c,v 1.2 2011/10/03 12:32:28 roy Exp $ */
2*4318c66eSSascha Wildner
3*4318c66eSSascha Wildner /*
4*4318c66eSSascha Wildner * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5*4318c66eSSascha Wildner * Amsterdam
6*4318c66eSSascha Wildner * All rights reserved.
7*4318c66eSSascha Wildner *
8*4318c66eSSascha Wildner * Redistribution and use in source and binary forms, with or without
9*4318c66eSSascha Wildner * modification, are permitted provided that the following conditions are
10*4318c66eSSascha Wildner * met:
11*4318c66eSSascha Wildner *
12*4318c66eSSascha Wildner * - Redistributions of source code must retain the above copyright notice,
13*4318c66eSSascha Wildner * this list of conditions and the following disclaimer.
14*4318c66eSSascha Wildner *
15*4318c66eSSascha Wildner * - Redistributions in binary form must reproduce the above copyright
16*4318c66eSSascha Wildner * notice, this list of conditions and the following disclaimer in the
17*4318c66eSSascha Wildner * documentation and/or other materials provided with the distribution.
18*4318c66eSSascha Wildner *
19*4318c66eSSascha Wildner * - Neither the name of the Stichting Centrum voor Wiskunde en
20*4318c66eSSascha Wildner * Informatica, nor the names of its contributors may be used to endorse or
21*4318c66eSSascha Wildner * promote products derived from this software without specific prior
22*4318c66eSSascha Wildner * written permission.
23*4318c66eSSascha Wildner *
24*4318c66eSSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25*4318c66eSSascha Wildner * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26*4318c66eSSascha Wildner * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27*4318c66eSSascha Wildner * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28*4318c66eSSascha Wildner * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29*4318c66eSSascha Wildner * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30*4318c66eSSascha Wildner * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31*4318c66eSSascha Wildner * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32*4318c66eSSascha Wildner * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33*4318c66eSSascha Wildner * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34*4318c66eSSascha Wildner * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*4318c66eSSascha Wildner */
36*4318c66eSSascha Wildner
37*4318c66eSSascha Wildner /*
38*4318c66eSSascha Wildner * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39*4318c66eSSascha Wildner * All rights reserved.
40*4318c66eSSascha Wildner *
41*4318c66eSSascha Wildner * Redistribution and use in source and binary forms, with or without
42*4318c66eSSascha Wildner * modification, are permitted provided that the following conditions
43*4318c66eSSascha Wildner * are met:
44*4318c66eSSascha Wildner * 1. Redistributions of source code must retain the above copyright
45*4318c66eSSascha Wildner * notice, this list of conditions and the following disclaimer.
46*4318c66eSSascha Wildner * 2. Redistributions in binary form must reproduce the above copyright
47*4318c66eSSascha Wildner * notice, this list of conditions and the following disclaimer in the
48*4318c66eSSascha Wildner * documentation and/or other materials provided with the distribution.
49*4318c66eSSascha Wildner * 3. The name of the author may not be used to endorse or promote products
50*4318c66eSSascha Wildner * derived from this software without specific prior written permission.
51*4318c66eSSascha Wildner *
52*4318c66eSSascha Wildner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53*4318c66eSSascha Wildner * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54*4318c66eSSascha Wildner * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55*4318c66eSSascha Wildner * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56*4318c66eSSascha Wildner * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57*4318c66eSSascha Wildner * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58*4318c66eSSascha Wildner * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59*4318c66eSSascha Wildner * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60*4318c66eSSascha Wildner * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61*4318c66eSSascha Wildner * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62*4318c66eSSascha Wildner */
63*4318c66eSSascha Wildner
64*4318c66eSSascha Wildner #include <string.h>
65*4318c66eSSascha Wildner #include <termios.h>
66*4318c66eSSascha Wildner #include <term.h>
67*4318c66eSSascha Wildner #include <stdlib.h>
68*4318c66eSSascha Wildner #include <unistd.h>
69*4318c66eSSascha Wildner #include "hack.h"
70*4318c66eSSascha Wildner #include "extern.h"
71*4318c66eSSascha Wildner #include "def.flag.h" /* for flags.nonull */
72*4318c66eSSascha Wildner
73*4318c66eSSascha Wildner char *CD; /* tested in pri.c: docorner() */
74*4318c66eSSascha Wildner int CO, LI; /* used in pri.c and whatis.c */
75*4318c66eSSascha Wildner
76*4318c66eSSascha Wildner void
startup(void)77*4318c66eSSascha Wildner startup(void)
78*4318c66eSSascha Wildner {
79*4318c66eSSascha Wildner
80*4318c66eSSascha Wildner /* Will exit if no suitable term found */
81*4318c66eSSascha Wildner setupterm(NULL, 0, NULL);
82*4318c66eSSascha Wildner CO = columns;
83*4318c66eSSascha Wildner LI = lines;
84*4318c66eSSascha Wildner if (CO < COLNO || LI < ROWNO + 2)
85*4318c66eSSascha Wildner setclipped();
86*4318c66eSSascha Wildner if (clear_screen == NULL)
87*4318c66eSSascha Wildner error("Hack needs clear_screen.");
88*4318c66eSSascha Wildner if (over_strike)
89*4318c66eSSascha Wildner error("Hack can't have over_strike.");
90*4318c66eSSascha Wildner if (cursor_address == NULL) {
91*4318c66eSSascha Wildner printf("Playing hack without cursor_address is suspect...");
92*4318c66eSSascha Wildner getret();
93*4318c66eSSascha Wildner }
94*4318c66eSSascha Wildner set_whole_screen();
95*4318c66eSSascha Wildner }
96*4318c66eSSascha Wildner
97*4318c66eSSascha Wildner void
startscreen(void)98*4318c66eSSascha Wildner startscreen(void)
99*4318c66eSSascha Wildner {
100*4318c66eSSascha Wildner }
101*4318c66eSSascha Wildner
102*4318c66eSSascha Wildner void
endscreen(void)103*4318c66eSSascha Wildner endscreen(void)
104*4318c66eSSascha Wildner {
105*4318c66eSSascha Wildner }
106*4318c66eSSascha Wildner
107*4318c66eSSascha Wildner static int
xputc(int c)108*4318c66eSSascha Wildner xputc(int c)
109*4318c66eSSascha Wildner {
110*4318c66eSSascha Wildner return (fputc(c, stdout));
111*4318c66eSSascha Wildner }
112*4318c66eSSascha Wildner
113*4318c66eSSascha Wildner static void
xputs(const char * s)114*4318c66eSSascha Wildner xputs(const char *s)
115*4318c66eSSascha Wildner {
116*4318c66eSSascha Wildner tputs(s, 1, xputc);
117*4318c66eSSascha Wildner }
118*4318c66eSSascha Wildner
119*4318c66eSSascha Wildner static void
cmov(int x,int y)120*4318c66eSSascha Wildner cmov(int x, int y)
121*4318c66eSSascha Wildner {
122*4318c66eSSascha Wildner char *p;
123*4318c66eSSascha Wildner
124*4318c66eSSascha Wildner p = tiparm(cursor_address, y - 1, x - 1);
125*4318c66eSSascha Wildner if (p) {
126*4318c66eSSascha Wildner xputs(p);
127*4318c66eSSascha Wildner cury = y;
128*4318c66eSSascha Wildner curx = x;
129*4318c66eSSascha Wildner }
130*4318c66eSSascha Wildner }
131*4318c66eSSascha Wildner
132*4318c66eSSascha Wildner static void
nocmov(int x,int y)133*4318c66eSSascha Wildner nocmov(int x, int y)
134*4318c66eSSascha Wildner {
135*4318c66eSSascha Wildner if (cury > y) {
136*4318c66eSSascha Wildner if (cursor_up) {
137*4318c66eSSascha Wildner while (cury > y) { /* Go up. */
138*4318c66eSSascha Wildner xputs(cursor_up);
139*4318c66eSSascha Wildner cury--;
140*4318c66eSSascha Wildner }
141*4318c66eSSascha Wildner } else if (cursor_address) {
142*4318c66eSSascha Wildner cmov(x, y);
143*4318c66eSSascha Wildner } else if (cursor_home) {
144*4318c66eSSascha Wildner home();
145*4318c66eSSascha Wildner curs(x, y);
146*4318c66eSSascha Wildner } /* else impossible("..."); */
147*4318c66eSSascha Wildner } else if (cury < y) {
148*4318c66eSSascha Wildner if (cursor_address) {
149*4318c66eSSascha Wildner cmov(x, y);
150*4318c66eSSascha Wildner #if 0
151*4318c66eSSascha Wildner } else if (XD) {
152*4318c66eSSascha Wildner while (cury < y) {
153*4318c66eSSascha Wildner xputs(XD);
154*4318c66eSSascha Wildner cury++;
155*4318c66eSSascha Wildner }
156*4318c66eSSascha Wildner #endif
157*4318c66eSSascha Wildner } else {
158*4318c66eSSascha Wildner while (cury < y) {
159*4318c66eSSascha Wildner xputc('\n');
160*4318c66eSSascha Wildner curx = 1;
161*4318c66eSSascha Wildner cury++;
162*4318c66eSSascha Wildner }
163*4318c66eSSascha Wildner }
164*4318c66eSSascha Wildner }
165*4318c66eSSascha Wildner if (curx < x) { /* Go to the right. */
166*4318c66eSSascha Wildner if (!cursor_right)
167*4318c66eSSascha Wildner cmov(x, y);
168*4318c66eSSascha Wildner else /* bah */
169*4318c66eSSascha Wildner /* should instead print what is there already */
170*4318c66eSSascha Wildner while (curx < x) {
171*4318c66eSSascha Wildner xputs(cursor_right);
172*4318c66eSSascha Wildner curx++;
173*4318c66eSSascha Wildner }
174*4318c66eSSascha Wildner } else if (curx > x) {
175*4318c66eSSascha Wildner while (curx > x)
176*4318c66eSSascha Wildner backsp();
177*4318c66eSSascha Wildner }
178*4318c66eSSascha Wildner }
179*4318c66eSSascha Wildner
180*4318c66eSSascha Wildner /*
181*4318c66eSSascha Wildner * Cursor movements
182*4318c66eSSascha Wildner *
183*4318c66eSSascha Wildner * x,y not xchar: perhaps xchar is unsigned and
184*4318c66eSSascha Wildner * curx-x would be unsigned as well
185*4318c66eSSascha Wildner */
186*4318c66eSSascha Wildner void
curs(int x,int y)187*4318c66eSSascha Wildner curs(int x, int y)
188*4318c66eSSascha Wildner {
189*4318c66eSSascha Wildner
190*4318c66eSSascha Wildner if (y == cury && x == curx)
191*4318c66eSSascha Wildner return;
192*4318c66eSSascha Wildner if (!cursor_right && (curx != x || x <= 3)) { /* Extremely primitive */
193*4318c66eSSascha Wildner cmov(x, y); /* bunker!wtm */
194*4318c66eSSascha Wildner return;
195*4318c66eSSascha Wildner }
196*4318c66eSSascha Wildner if (abs(cury - y) <= 3 && abs(curx - x) <= 3)
197*4318c66eSSascha Wildner nocmov(x, y);
198*4318c66eSSascha Wildner else if ((x <= 3 && abs(cury - y) <= 3) ||
199*4318c66eSSascha Wildner (!cursor_address && x < abs(curx - x)))
200*4318c66eSSascha Wildner {
201*4318c66eSSascha Wildner (void) putchar('\r');
202*4318c66eSSascha Wildner curx = 1;
203*4318c66eSSascha Wildner nocmov(x, y);
204*4318c66eSSascha Wildner } else if (!cursor_address) {
205*4318c66eSSascha Wildner nocmov(x, y);
206*4318c66eSSascha Wildner } else
207*4318c66eSSascha Wildner cmov(x, y);
208*4318c66eSSascha Wildner }
209*4318c66eSSascha Wildner
210*4318c66eSSascha Wildner void
cl_end(void)211*4318c66eSSascha Wildner cl_end(void)
212*4318c66eSSascha Wildner {
213*4318c66eSSascha Wildner if (clr_eol)
214*4318c66eSSascha Wildner xputs(clr_eol);
215*4318c66eSSascha Wildner else { /* no-CE fix - free after Harold Rynes */
216*4318c66eSSascha Wildner /*
217*4318c66eSSascha Wildner * this looks terrible, especially on a slow terminal but is
218*4318c66eSSascha Wildner * better than nothing
219*4318c66eSSascha Wildner */
220*4318c66eSSascha Wildner int cx = curx, cy = cury;
221*4318c66eSSascha Wildner
222*4318c66eSSascha Wildner while (curx < COLNO) {
223*4318c66eSSascha Wildner xputc(' ');
224*4318c66eSSascha Wildner curx++;
225*4318c66eSSascha Wildner }
226*4318c66eSSascha Wildner curs(cx, cy);
227*4318c66eSSascha Wildner }
228*4318c66eSSascha Wildner }
229*4318c66eSSascha Wildner
230*4318c66eSSascha Wildner void
clearscreen(void)231*4318c66eSSascha Wildner clearscreen(void)
232*4318c66eSSascha Wildner {
233*4318c66eSSascha Wildner xputs(clear_screen);
234*4318c66eSSascha Wildner curx = cury = 1;
235*4318c66eSSascha Wildner }
236*4318c66eSSascha Wildner
237*4318c66eSSascha Wildner void
home(void)238*4318c66eSSascha Wildner home(void)
239*4318c66eSSascha Wildner {
240*4318c66eSSascha Wildner char *out;
241*4318c66eSSascha Wildner
242*4318c66eSSascha Wildner if (cursor_home)
243*4318c66eSSascha Wildner xputs(cursor_home);
244*4318c66eSSascha Wildner else if ((cursor_address) && (out = tiparm(cursor_address, 0, 0)))
245*4318c66eSSascha Wildner xputs(out);
246*4318c66eSSascha Wildner else
247*4318c66eSSascha Wildner curs(1, 1); /* using UP ... */
248*4318c66eSSascha Wildner curx = cury = 1;
249*4318c66eSSascha Wildner }
250*4318c66eSSascha Wildner
251*4318c66eSSascha Wildner void
standoutbeg(void)252*4318c66eSSascha Wildner standoutbeg(void)
253*4318c66eSSascha Wildner {
254*4318c66eSSascha Wildner if (enter_standout_mode && exit_standout_mode && !magic_cookie_glitch)
255*4318c66eSSascha Wildner xputs(enter_standout_mode);
256*4318c66eSSascha Wildner }
257*4318c66eSSascha Wildner
258*4318c66eSSascha Wildner void
standoutend(void)259*4318c66eSSascha Wildner standoutend(void)
260*4318c66eSSascha Wildner {
261*4318c66eSSascha Wildner if (exit_standout_mode && enter_standout_mode && !magic_cookie_glitch)
262*4318c66eSSascha Wildner xputs(exit_standout_mode);
263*4318c66eSSascha Wildner }
264*4318c66eSSascha Wildner
265*4318c66eSSascha Wildner void
backsp(void)266*4318c66eSSascha Wildner backsp(void)
267*4318c66eSSascha Wildner {
268*4318c66eSSascha Wildner if (cursor_left)
269*4318c66eSSascha Wildner xputs(cursor_left);
270*4318c66eSSascha Wildner else
271*4318c66eSSascha Wildner (void) putchar('\b');
272*4318c66eSSascha Wildner curx--;
273*4318c66eSSascha Wildner }
274*4318c66eSSascha Wildner
275*4318c66eSSascha Wildner void
sound_bell(void)276*4318c66eSSascha Wildner sound_bell(void)
277*4318c66eSSascha Wildner {
278*4318c66eSSascha Wildner (void) putchar('\007'); /* curx does not change */
279*4318c66eSSascha Wildner (void) fflush(stdout);
280*4318c66eSSascha Wildner }
281*4318c66eSSascha Wildner
282*4318c66eSSascha Wildner void
delay_output(void)283*4318c66eSSascha Wildner delay_output(void)
284*4318c66eSSascha Wildner {
285*4318c66eSSascha Wildner
286*4318c66eSSascha Wildner /* delay 50 ms - could also use a 'nap'-system call */
287*4318c66eSSascha Wildner /* or the usleep call like this :-) */
288*4318c66eSSascha Wildner usleep(50000);
289*4318c66eSSascha Wildner }
290*4318c66eSSascha Wildner
291*4318c66eSSascha Wildner void
cl_eos(void)292*4318c66eSSascha Wildner cl_eos(void)
293*4318c66eSSascha Wildner { /* free after Robert Viduya *//* must only be
294*4318c66eSSascha Wildner * called with curx = 1 */
295*4318c66eSSascha Wildner
296*4318c66eSSascha Wildner if (clr_eos)
297*4318c66eSSascha Wildner xputs(clr_eos);
298*4318c66eSSascha Wildner else {
299*4318c66eSSascha Wildner int cx = curx, cy = cury;
300*4318c66eSSascha Wildner while (cury <= LI - 2) {
301*4318c66eSSascha Wildner cl_end();
302*4318c66eSSascha Wildner xputc('\n');
303*4318c66eSSascha Wildner curx = 1;
304*4318c66eSSascha Wildner cury++;
305*4318c66eSSascha Wildner }
306*4318c66eSSascha Wildner cl_end();
307*4318c66eSSascha Wildner curs(cx, cy);
308*4318c66eSSascha Wildner }
309*4318c66eSSascha Wildner }
310