1 /* $OpenBSD: hack.termcap.c,v 1.9 2016/01/09 18:33:15 mestre 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 <curses.h> 65 #include <stdlib.h> 66 #include <term.h> 67 68 #include "hack.h" 69 70 static char tbuf[512]; 71 static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE; 72 static char *VS, *VE; 73 static int SG; 74 static char PC = '\0'; 75 char *CD; /* tested in pri.c: docorner() */ 76 int CO, LI; /* used in pri.c and whatis.c */ 77 78 static void nocmov(int, int); 79 static void cmov(int, int); 80 static int xputc(int); 81 static void xputs(char *); 82 83 void 84 startup(void) 85 { 86 char *term; 87 char *tptr; 88 char *tbufptr, *pc; 89 90 tptr = (char *) alloc(1024); 91 92 tbufptr = tbuf; 93 if(!(term = getenv("TERM"))) 94 error("Can't get TERM."); 95 if(!strncmp(term, "5620", 4)) 96 flags.nonull = 1; /* this should be a termcap flag */ 97 if(tgetent(tptr, term) < 1) 98 error("Unknown terminal type: %s.", term); 99 if ((pc = tgetstr("pc", &tbufptr))) 100 PC = *pc; 101 if(!(BC = tgetstr("le", &tbufptr))) { 102 if(!tgetflag("bs")) 103 error("Terminal must backspace."); 104 BC = tbufptr; 105 tbufptr += 2; 106 *BC = '\b'; 107 } 108 HO = tgetstr("ho", &tbufptr); 109 CO = tgetnum("co"); 110 LI = tgetnum("li"); 111 if(CO < COLNO || LI < ROWNO+2) 112 setclipped(); 113 if(!(CL = tgetstr("cl", &tbufptr))) 114 error("Hack needs CL."); 115 ND = tgetstr("nd", &tbufptr); 116 if(tgetflag("os")) 117 error("Hack can't have OS."); 118 CE = tgetstr("ce", &tbufptr); 119 UP = tgetstr("up", &tbufptr); 120 /* It seems that xd is no longer supported, and we should use 121 a linefeed instead; unfortunately this requires resetting 122 CRMOD, and many output routines will have to be modified 123 slightly. Let's leave that till the next release. */ 124 XD = tgetstr("xd", &tbufptr); 125 /* not: XD = tgetstr("do", &tbufptr); */ 126 if(!(CM = tgetstr("cm", &tbufptr))) { 127 if(!UP && !HO) 128 error("Hack needs CM or UP or HO."); 129 printf("Playing hack on terminals without cm is suspect...\n"); 130 getret(); 131 } 132 SO = tgetstr("so", &tbufptr); 133 SE = tgetstr("se", &tbufptr); 134 SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */ 135 if(!SO || !SE || (SG > 0)) SO = SE = 0; 136 CD = tgetstr("cd", &tbufptr); 137 set_whole_screen(); /* uses LI and CD */ 138 if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n"); 139 free(tptr); 140 } 141 142 void 143 start_screen(void) 144 { 145 xputs(TI); 146 xputs(VS); 147 } 148 149 void 150 end_screen(void) 151 { 152 xputs(VE); 153 xputs(TE); 154 } 155 156 /* Cursor movements */ 157 extern xchar curx, cury; 158 159 /* int x, y; not xchar: perhaps xchar is unsigned and 160 * curx-x would be unsigned as well 161 */ 162 void 163 curs(int x, int y) 164 { 165 if (y == cury && x == curx) 166 return; 167 if(!ND && (curx != x || x <= 3)) { /* Extremely primitive */ 168 cmov(x, y); /* bunker!wtm */ 169 return; 170 } 171 if(abs(cury-y) <= 3 && abs(curx-x) <= 3) 172 nocmov(x, y); 173 else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) { 174 (void) putchar('\r'); 175 curx = 1; 176 nocmov(x, y); 177 } else if(!CM) { 178 nocmov(x, y); 179 } else 180 cmov(x, y); 181 } 182 183 static void 184 nocmov(int x, int y) 185 { 186 if (cury > y) { 187 if(UP) { 188 while (cury > y) { /* Go up. */ 189 xputs(UP); 190 cury--; 191 } 192 } else if(CM) { 193 cmov(x, y); 194 } else if(HO) { 195 home(); 196 curs(x, y); 197 } /* else impossible("..."); */ 198 } else if (cury < y) { 199 if(XD) { 200 while(cury < y) { 201 xputs(XD); 202 cury++; 203 } 204 } else if(CM) { 205 cmov(x, y); 206 } else { 207 while(cury < y) { 208 xputc('\n'); 209 curx = 1; 210 cury++; 211 } 212 } 213 } 214 if (curx < x) { /* Go to the right. */ 215 if(!ND) cmov(x, y); else /* bah */ 216 /* should instead print what is there already */ 217 while (curx < x) { 218 xputs(ND); 219 curx++; 220 } 221 } else if (curx > x) { 222 while (curx > x) { /* Go to the left. */ 223 xputs(BC); 224 curx--; 225 } 226 } 227 } 228 229 static void 230 cmov(int x, int y) 231 { 232 xputs(tgoto(CM, x-1, y-1)); 233 cury = y; 234 curx = x; 235 } 236 237 static int 238 xputc(int c) 239 { 240 return fputc(c, stdout); 241 } 242 243 static void 244 xputs(char *s) 245 { 246 tputs(s, 1, xputc); 247 } 248 249 void 250 cl_end(void) 251 { 252 if(CE) 253 xputs(CE); 254 else { /* no-CE fix - free after Harold Rynes */ 255 /* this looks terrible, especially on a slow terminal 256 but is better than nothing */ 257 int cx = curx, cy = cury; 258 259 while(curx < COLNO) { 260 xputc(' '); 261 curx++; 262 } 263 curs(cx, cy); 264 } 265 } 266 267 void 268 clr_screen(void) 269 { 270 xputs(CL); 271 curx = cury = 1; 272 } 273 274 void 275 home(void) 276 { 277 if(HO) 278 xputs(HO); 279 else if(CM) 280 xputs(tgoto(CM, 0, 0)); 281 else 282 curs(1, 1); /* using UP ... */ 283 curx = cury = 1; 284 } 285 286 void 287 standoutbeg(void) 288 { 289 if(SO) xputs(SO); 290 } 291 292 void 293 standoutend(void) 294 { 295 if(SE) xputs(SE); 296 } 297 298 void 299 backsp(void) 300 { 301 xputs(BC); 302 curx--; 303 } 304 305 void 306 hackbell(void) 307 { 308 (void) putchar('\007'); /* curx does not change */ 309 (void) fflush(stdout); 310 } 311 312 /* free after Robert Viduya 313 * must only be called with curx = 1 314 */ 315 void 316 cl_eos(void) 317 { 318 319 if(CD) 320 xputs(CD); 321 else { 322 int cx = curx, cy = cury; 323 while(cury <= LI-2) { 324 cl_end(); 325 xputc('\n'); 326 curx = 1; 327 cury++; 328 } 329 cl_end(); 330 curs(cx, cy); 331 } 332 } 333