1 /* $NetBSD: hack.terminfo.c,v 1.2 2011/10/03 12:32:28 roy 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@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 <string.h> 65 #include <termios.h> 66 #include <term.h> 67 #include <stdlib.h> 68 #include <unistd.h> 69 #include "hack.h" 70 #include "extern.h" 71 #include "def.flag.h" /* for flags.nonull */ 72 73 char *CD; /* tested in pri.c: docorner() */ 74 int CO, LI; /* used in pri.c and whatis.c */ 75 76 void 77 startup(void) 78 { 79 80 /* Will exit if no suitable term found */ 81 setupterm(NULL, 0, NULL); 82 CO = columns; 83 LI = lines; 84 if (CO < COLNO || LI < ROWNO + 2) 85 setclipped(); 86 if (clear_screen == NULL) 87 error("Hack needs clear_screen."); 88 if (over_strike) 89 error("Hack can't have over_strike."); 90 if (cursor_address == NULL) { 91 printf("Playing hack without cursor_address is suspect..."); 92 getret(); 93 } 94 set_whole_screen(); 95 } 96 97 void 98 startscreen(void) 99 { 100 } 101 102 void 103 endscreen(void) 104 { 105 } 106 107 static int 108 xputc(int c) 109 { 110 return (fputc(c, stdout)); 111 } 112 113 static void 114 xputs(const char *s) 115 { 116 tputs(s, 1, xputc); 117 } 118 119 static void 120 cmov(int x, int y) 121 { 122 char *p; 123 124 p = tiparm(cursor_address, y - 1, x - 1); 125 if (p) { 126 xputs(p); 127 cury = y; 128 curx = x; 129 } 130 } 131 132 static void 133 nocmov(int x, int y) 134 { 135 if (cury > y) { 136 if (cursor_up) { 137 while (cury > y) { /* Go up. */ 138 xputs(cursor_up); 139 cury--; 140 } 141 } else if (cursor_address) { 142 cmov(x, y); 143 } else if (cursor_home) { 144 home(); 145 curs(x, y); 146 } /* else impossible("..."); */ 147 } else if (cury < y) { 148 if (cursor_address) { 149 cmov(x, y); 150 #if 0 151 } else if (XD) { 152 while (cury < y) { 153 xputs(XD); 154 cury++; 155 } 156 #endif 157 } else { 158 while (cury < y) { 159 xputc('\n'); 160 curx = 1; 161 cury++; 162 } 163 } 164 } 165 if (curx < x) { /* Go to the right. */ 166 if (!cursor_right) 167 cmov(x, y); 168 else /* bah */ 169 /* should instead print what is there already */ 170 while (curx < x) { 171 xputs(cursor_right); 172 curx++; 173 } 174 } else if (curx > x) { 175 while (curx > x) 176 backsp(); 177 } 178 } 179 180 /* 181 * Cursor movements 182 * 183 * x,y not xchar: perhaps xchar is unsigned and 184 * curx-x would be unsigned as well 185 */ 186 void 187 curs(int x, int y) 188 { 189 190 if (y == cury && x == curx) 191 return; 192 if (!cursor_right && (curx != x || x <= 3)) { /* Extremely primitive */ 193 cmov(x, y); /* bunker!wtm */ 194 return; 195 } 196 if (abs(cury - y) <= 3 && abs(curx - x) <= 3) 197 nocmov(x, y); 198 else if ((x <= 3 && abs(cury - y) <= 3) || 199 (!cursor_address && x < abs(curx - x))) 200 { 201 (void) putchar('\r'); 202 curx = 1; 203 nocmov(x, y); 204 } else if (!cursor_address) { 205 nocmov(x, y); 206 } else 207 cmov(x, y); 208 } 209 210 void 211 cl_end(void) 212 { 213 if (clr_eol) 214 xputs(clr_eol); 215 else { /* no-CE fix - free after Harold Rynes */ 216 /* 217 * this looks terrible, especially on a slow terminal but is 218 * better than nothing 219 */ 220 int cx = curx, cy = cury; 221 222 while (curx < COLNO) { 223 xputc(' '); 224 curx++; 225 } 226 curs(cx, cy); 227 } 228 } 229 230 void 231 clearscreen(void) 232 { 233 xputs(clear_screen); 234 curx = cury = 1; 235 } 236 237 void 238 home(void) 239 { 240 char *out; 241 242 if (cursor_home) 243 xputs(cursor_home); 244 else if ((cursor_address) && (out = tiparm(cursor_address, 0, 0))) 245 xputs(out); 246 else 247 curs(1, 1); /* using UP ... */ 248 curx = cury = 1; 249 } 250 251 void 252 standoutbeg(void) 253 { 254 if (enter_standout_mode && exit_standout_mode && !magic_cookie_glitch) 255 xputs(enter_standout_mode); 256 } 257 258 void 259 standoutend(void) 260 { 261 if (exit_standout_mode && enter_standout_mode && !magic_cookie_glitch) 262 xputs(exit_standout_mode); 263 } 264 265 void 266 backsp(void) 267 { 268 if (cursor_left) 269 xputs(cursor_left); 270 else 271 (void) putchar('\b'); 272 curx--; 273 } 274 275 void 276 sound_bell(void) 277 { 278 (void) putchar('\007'); /* curx does not change */ 279 (void) fflush(stdout); 280 } 281 282 void 283 delay_output(void) 284 { 285 286 /* delay 50 ms - could also use a 'nap'-system call */ 287 /* or the usleep call like this :-) */ 288 usleep(50000); 289 } 290 291 void 292 cl_eos(void) 293 { /* free after Robert Viduya *//* must only be 294 * called with curx = 1 */ 295 296 if (clr_eos) 297 xputs(clr_eos); 298 else { 299 int cx = curx, cy = cury; 300 while (cury <= LI - 2) { 301 cl_end(); 302 xputc('\n'); 303 curx = 1; 304 cury++; 305 } 306 cl_end(); 307 curs(cx, cy); 308 } 309 } 310