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