1 /*- 2 * Display abstraction. 3 * David Leonard <d@openbsd.org>, 1999. Public domain. 4 * 5 * $OpenBSD: display.c,v 1.4 2002/02/19 19:39:36 millert Exp $ 6 */ 7 8 #define USE_CURSES 9 10 #include "display.h" 11 12 #if !defined(USE_CURSES) 13 14 #include <stdlib.h> 15 #include <unistd.h> 16 #include <signal.h> 17 #include <stdio.h> 18 #include <termios.h> 19 #define _USE_OLD_CURSES_ 20 #include <curses.h> 21 #include <err.h> 22 #include "hunt.h" 23 24 static struct termios saved_tty; 25 26 char screen[SCREEN_HEIGHT][SCREEN_WIDTH2]; 27 char blanks[SCREEN_WIDTH]; 28 int cur_row, cur_col; 29 30 /* 31 * tstp: 32 * Handle stop and start signals 33 */ 34 static void 35 tstp(int dummy) 36 { 37 int y, x; 38 39 y = cur_row; 40 x = cur_col; 41 mvcur(cur_row, cur_col, HEIGHT, 0); 42 cur_row = HEIGHT; 43 cur_col = 0; 44 _puts(VE); 45 _puts(TE); 46 fflush(stdout); 47 tcsetattr(0, TCSADRAIN, &__orig_termios); 48 kill(getpid(), SIGSTOP); 49 signal(SIGTSTP, tstp); 50 tcsetattr(0, TCSADRAIN, &saved_tty); 51 _puts(TI); 52 _puts(VS); 53 cur_row = y; 54 cur_col = x; 55 _puts(tgoto(CM, cur_row, cur_col)); 56 display_redraw_screen(); 57 fflush(stdout); 58 } 59 60 /* 61 * display_open: 62 * open the display 63 */ 64 void 65 display_open(void) 66 { 67 char *term; 68 69 if (!isatty(0) || (term = getenv("TERM")) == NULL) 70 errx(1, "no terminal type"); 71 72 gettmode(); 73 setterm(term); 74 noecho(); 75 cbreak(); 76 tcgetattr(0, &saved_tty); 77 _puts(TI); 78 _puts(VS); 79 #ifdef SIGTSTP 80 signal(SIGTSTP, tstp); 81 #endif 82 } 83 84 /* 85 * display_beep: 86 * beep 87 */ 88 void 89 display_beep(void) 90 { 91 putchar('\a'); 92 } 93 94 /* 95 * display_refresh: 96 * sync the display 97 */ 98 void 99 display_refresh(void) 100 { 101 fflush(stdout); 102 } 103 104 /* 105 * display_clear_eol: 106 * clear to end of line, without moving cursor 107 */ 108 void 109 display_clear_eol(void) 110 { 111 if (CE != NULL) 112 tputs(CE, 1, __cputchar); 113 else { 114 fwrite(blanks, sizeof (char), SCREEN_WIDTH - cur_col, stdout); 115 if (COLS != SCREEN_WIDTH) 116 mvcur(cur_row, SCREEN_WIDTH, cur_row, cur_col); 117 else if (AM) 118 mvcur(cur_row + 1, 0, cur_row, cur_col); 119 else 120 mvcur(cur_row, SCREEN_WIDTH - 1, cur_row, cur_col); 121 } 122 memcpy(&screen[cur_row][cur_col], blanks, SCREEN_WIDTH - cur_col); 123 } 124 125 /* 126 * display_putchar: 127 * put one character on the screen, move the cursor right one, 128 * with wraparound 129 */ 130 void 131 display_put_ch(char ch) 132 { 133 if (!isprint(ch)) { 134 fprintf(stderr, "r,c,ch: %d,%d,%d", cur_row, cur_col, ch); 135 return; 136 } 137 screen[cur_row][cur_col] = ch; 138 putchar(ch); 139 if (++cur_col >= COLS) { 140 if (!AM || XN) 141 putchar('\n'); 142 cur_col = 0; 143 if (++cur_row >= LINES) 144 cur_row = LINES; 145 } 146 } 147 148 /* 149 * display_put_str: 150 * put a string of characters on the screen 151 */ 152 void 153 display_put_str(const char *s) 154 { 155 for( ; *s; s++) 156 display_put_ch(*s); 157 } 158 159 /* 160 * display_clear_the_screen: 161 * clear the screen; move cursor to top left 162 */ 163 void 164 display_clear_the_screen(void) 165 { 166 int i; 167 168 if (blanks[0] == '\0') 169 for (i = 0; i < SCREEN_WIDTH; i++) 170 blanks[i] = ' '; 171 172 if (CL != NULL) { 173 tputs(CL, LINES, __cputchar); 174 for (i = 0; i < SCREEN_HEIGHT; i++) 175 memcpy(screen[i], blanks, SCREEN_WIDTH); 176 } else { 177 for (i = 0; i < SCREEN_HEIGHT; i++) { 178 mvcur(cur_row, cur_col, i, 0); 179 cur_row = i; 180 cur_col = 0; 181 display_clear_eol(); 182 } 183 mvcur(cur_row, cur_col, 0, 0); 184 } 185 cur_row = cur_col = 0; 186 } 187 188 /* 189 * display_move: 190 * move the cursor 191 */ 192 void 193 display_move(int y, int x) 194 { 195 mvcur(cur_row, cur_col, y, x); 196 cur_row = y; 197 cur_col = x; 198 } 199 200 /* 201 * display_getyx: 202 * locate the cursor 203 */ 204 void 205 display_getyx(int *yp, int *xp) 206 { 207 *xp = cur_col; 208 *yp = cur_row; 209 } 210 211 /* 212 * display_end: 213 * close the display 214 */ 215 void 216 display_end(void) 217 { 218 tcsetattr(0, TCSADRAIN, &__orig_termios); 219 _puts(VE); 220 _puts(TE); 221 } 222 223 /* 224 * display_atyx: 225 * return a character from the screen 226 */ 227 char 228 display_atyx(int y, int x) 229 { 230 return screen[y][x]; 231 } 232 233 /* 234 * display_redraw_screen: 235 * redraw the screen 236 */ 237 void 238 display_redraw_screen(void) 239 { 240 int i; 241 242 mvcur(cur_row, cur_col, 0, 0); 243 for (i = 0; i < SCREEN_HEIGHT - 1; i++) { 244 fwrite(screen[i], sizeof (char), SCREEN_WIDTH, stdout); 245 if (COLS > SCREEN_WIDTH || (COLS == SCREEN_WIDTH && !AM)) 246 putchar('\n'); 247 } 248 fwrite(screen[SCREEN_HEIGHT - 1], sizeof (char), SCREEN_WIDTH - 1, 249 stdout); 250 mvcur(SCREEN_HEIGHT - 1, SCREEN_WIDTH - 1, cur_row, cur_col); 251 } 252 253 #else /* CURSES */ /* --------------------------------------------------- */ 254 255 #include <curses.h> 256 #include "hunt.h" 257 258 void 259 display_open(void) 260 { 261 initscr(); 262 noecho(); 263 cbreak(); 264 } 265 266 void 267 display_beep(void) 268 { 269 beep(); 270 } 271 272 void 273 display_refresh(void) 274 { 275 refresh(); 276 } 277 278 void 279 display_clear_eol(void) 280 { 281 clrtoeol(); 282 } 283 284 void 285 display_put_ch(char c) 286 { 287 addch(c); 288 } 289 290 void 291 display_put_str(const char *s) 292 { 293 addstr(s); 294 } 295 296 void 297 display_clear_the_screen(void) 298 { 299 clear(); 300 move(0, 0); 301 display_refresh(); 302 } 303 304 void 305 display_move(int y, int x) 306 { 307 move(y, x); 308 } 309 310 void 311 display_getyx(int *yp, int *xp) 312 { 313 getyx(stdscr, *yp, *xp); 314 } 315 316 void 317 display_end(void) 318 { 319 endwin(); 320 } 321 322 char 323 display_atyx(int y, int x) 324 { 325 int oy, ox; 326 char c; 327 328 display_getyx(&oy, &ox); 329 c = mvwinch(stdscr, y, x) & 0x7f; 330 display_move(oy, ox); 331 return (c); 332 } 333 334 void 335 display_redraw_screen(void) 336 { 337 clearok(stdscr, TRUE); 338 touchwin(stdscr); 339 } 340 341 int 342 display_iserasechar(char ch) 343 { 344 return ch == erasechar(); 345 } 346 347 int 348 display_iskillchar(char ch) 349 { 350 return ch == killchar(); 351 } 352 353 #endif 354