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
tstp(int dummy)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
display_open(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
display_beep(void)89 display_beep(void)
90 {
91 putchar('\a');
92 }
93
94 /*
95 * display_refresh:
96 * sync the display
97 */
98 void
display_refresh(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
display_clear_eol(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
display_put_ch(char ch)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
display_put_str(const char * s)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
display_clear_the_screen(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
display_move(int y,int x)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
display_getyx(int * yp,int * xp)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
display_end(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
display_atyx(int y,int x)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
display_redraw_screen(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
display_open(void)259 display_open(void)
260 {
261 initscr();
262 noecho();
263 cbreak();
264 }
265
266 void
display_beep(void)267 display_beep(void)
268 {
269 beep();
270 }
271
272 void
display_refresh(void)273 display_refresh(void)
274 {
275 refresh();
276 }
277
278 void
display_clear_eol(void)279 display_clear_eol(void)
280 {
281 clrtoeol();
282 }
283
284 void
display_put_ch(char c)285 display_put_ch(char c)
286 {
287 addch(c);
288 }
289
290 void
display_put_str(const char * s)291 display_put_str(const char *s)
292 {
293 addstr(s);
294 }
295
296 void
display_clear_the_screen(void)297 display_clear_the_screen(void)
298 {
299 clear();
300 move(0, 0);
301 display_refresh();
302 }
303
304 void
display_move(int y,int x)305 display_move(int y, int x)
306 {
307 move(y, x);
308 }
309
310 void
display_getyx(int * yp,int * xp)311 display_getyx(int *yp, int *xp)
312 {
313 getyx(stdscr, *yp, *xp);
314 }
315
316 void
display_end(void)317 display_end(void)
318 {
319 endwin();
320 }
321
322 char
display_atyx(int y,int x)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
display_redraw_screen(void)335 display_redraw_screen(void)
336 {
337 clearok(stdscr, TRUE);
338 touchwin(stdscr);
339 }
340
341 int
display_iserasechar(char ch)342 display_iserasechar(char ch)
343 {
344 return ch == erasechar();
345 }
346
347 int
display_iskillchar(char ch)348 display_iskillchar(char ch)
349 {
350 return ch == killchar();
351 }
352
353 #endif
354