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