16693db17SSascha Wildner /*-
282a5c12eSMatthew Dillon * Display abstraction.
382a5c12eSMatthew Dillon * David Leonard <d@openbsd.org>, 1999. Public domain.
482a5c12eSMatthew Dillon *
582a5c12eSMatthew Dillon * $OpenBSD: display.c,v 1.4 2002/02/19 19:39:36 millert Exp $
682a5c12eSMatthew Dillon */
782a5c12eSMatthew Dillon
882a5c12eSMatthew Dillon #define USE_CURSES
982a5c12eSMatthew Dillon
1082a5c12eSMatthew Dillon #include "display.h"
1182a5c12eSMatthew Dillon
1282a5c12eSMatthew Dillon #if !defined(USE_CURSES)
1382a5c12eSMatthew Dillon
1482a5c12eSMatthew Dillon #include <stdlib.h>
1582a5c12eSMatthew Dillon #include <unistd.h>
1682a5c12eSMatthew Dillon #include <signal.h>
1782a5c12eSMatthew Dillon #include <stdio.h>
1882a5c12eSMatthew Dillon #include <termios.h>
1982a5c12eSMatthew Dillon #define _USE_OLD_CURSES_
2082a5c12eSMatthew Dillon #include <curses.h>
2182a5c12eSMatthew Dillon #include <err.h>
2282a5c12eSMatthew Dillon #include "hunt.h"
2382a5c12eSMatthew Dillon
2482a5c12eSMatthew Dillon static struct termios saved_tty;
2582a5c12eSMatthew Dillon
2682a5c12eSMatthew Dillon char screen[SCREEN_HEIGHT][SCREEN_WIDTH2];
2782a5c12eSMatthew Dillon char blanks[SCREEN_WIDTH];
2882a5c12eSMatthew Dillon int cur_row, cur_col;
2982a5c12eSMatthew Dillon
3082a5c12eSMatthew Dillon /*
3182a5c12eSMatthew Dillon * tstp:
3282a5c12eSMatthew Dillon * Handle stop and start signals
3382a5c12eSMatthew Dillon */
3482a5c12eSMatthew Dillon static void
tstp(int dummy)356beb426bSSascha Wildner tstp(int dummy)
3682a5c12eSMatthew Dillon {
3782a5c12eSMatthew Dillon int y, x;
3882a5c12eSMatthew Dillon
3982a5c12eSMatthew Dillon y = cur_row;
4082a5c12eSMatthew Dillon x = cur_col;
4182a5c12eSMatthew Dillon mvcur(cur_row, cur_col, HEIGHT, 0);
4282a5c12eSMatthew Dillon cur_row = HEIGHT;
4382a5c12eSMatthew Dillon cur_col = 0;
4482a5c12eSMatthew Dillon _puts(VE);
4582a5c12eSMatthew Dillon _puts(TE);
46*d9f85b33Szrj fflush(stdout);
4782a5c12eSMatthew Dillon tcsetattr(0, TCSADRAIN, &__orig_termios);
48*d9f85b33Szrj kill(getpid(), SIGSTOP);
49*d9f85b33Szrj signal(SIGTSTP, tstp);
5082a5c12eSMatthew Dillon tcsetattr(0, TCSADRAIN, &saved_tty);
5182a5c12eSMatthew Dillon _puts(TI);
5282a5c12eSMatthew Dillon _puts(VS);
5382a5c12eSMatthew Dillon cur_row = y;
5482a5c12eSMatthew Dillon cur_col = x;
5582a5c12eSMatthew Dillon _puts(tgoto(CM, cur_row, cur_col));
5682a5c12eSMatthew Dillon display_redraw_screen();
57*d9f85b33Szrj fflush(stdout);
5882a5c12eSMatthew Dillon }
5982a5c12eSMatthew Dillon
6082a5c12eSMatthew Dillon /*
6182a5c12eSMatthew Dillon * display_open:
6282a5c12eSMatthew Dillon * open the display
6382a5c12eSMatthew Dillon */
6482a5c12eSMatthew Dillon void
display_open(void)656beb426bSSascha Wildner display_open(void)
6682a5c12eSMatthew Dillon {
6782a5c12eSMatthew Dillon char *term;
6882a5c12eSMatthew Dillon
6982a5c12eSMatthew Dillon if (!isatty(0) || (term = getenv("TERM")) == NULL)
7082a5c12eSMatthew Dillon errx(1, "no terminal type");
7182a5c12eSMatthew Dillon
7282a5c12eSMatthew Dillon gettmode();
73*d9f85b33Szrj setterm(term);
74*d9f85b33Szrj noecho();
75*d9f85b33Szrj cbreak();
7682a5c12eSMatthew Dillon tcgetattr(0, &saved_tty);
7782a5c12eSMatthew Dillon _puts(TI);
7882a5c12eSMatthew Dillon _puts(VS);
7982a5c12eSMatthew Dillon #ifdef SIGTSTP
80*d9f85b33Szrj signal(SIGTSTP, tstp);
8182a5c12eSMatthew Dillon #endif
8282a5c12eSMatthew Dillon }
8382a5c12eSMatthew Dillon
8482a5c12eSMatthew Dillon /*
8582a5c12eSMatthew Dillon * display_beep:
8682a5c12eSMatthew Dillon * beep
8782a5c12eSMatthew Dillon */
8882a5c12eSMatthew Dillon void
display_beep(void)896beb426bSSascha Wildner display_beep(void)
9082a5c12eSMatthew Dillon {
91*d9f85b33Szrj putchar('\a');
9282a5c12eSMatthew Dillon }
9382a5c12eSMatthew Dillon
9482a5c12eSMatthew Dillon /*
9582a5c12eSMatthew Dillon * display_refresh:
9682a5c12eSMatthew Dillon * sync the display
9782a5c12eSMatthew Dillon */
9882a5c12eSMatthew Dillon void
display_refresh(void)996beb426bSSascha Wildner display_refresh(void)
10082a5c12eSMatthew Dillon {
101*d9f85b33Szrj fflush(stdout);
10282a5c12eSMatthew Dillon }
10382a5c12eSMatthew Dillon
10482a5c12eSMatthew Dillon /*
10582a5c12eSMatthew Dillon * display_clear_eol:
10682a5c12eSMatthew Dillon * clear to end of line, without moving cursor
10782a5c12eSMatthew Dillon */
10882a5c12eSMatthew Dillon void
display_clear_eol(void)1096beb426bSSascha Wildner display_clear_eol(void)
11082a5c12eSMatthew Dillon {
11182a5c12eSMatthew Dillon if (CE != NULL)
11282a5c12eSMatthew Dillon tputs(CE, 1, __cputchar);
11382a5c12eSMatthew Dillon else {
11482a5c12eSMatthew Dillon fwrite(blanks, sizeof (char), SCREEN_WIDTH - cur_col, stdout);
11582a5c12eSMatthew Dillon if (COLS != SCREEN_WIDTH)
11682a5c12eSMatthew Dillon mvcur(cur_row, SCREEN_WIDTH, cur_row, cur_col);
11782a5c12eSMatthew Dillon else if (AM)
11882a5c12eSMatthew Dillon mvcur(cur_row + 1, 0, cur_row, cur_col);
11982a5c12eSMatthew Dillon else
12082a5c12eSMatthew Dillon mvcur(cur_row, SCREEN_WIDTH - 1, cur_row, cur_col);
12182a5c12eSMatthew Dillon }
12282a5c12eSMatthew Dillon memcpy(&screen[cur_row][cur_col], blanks, SCREEN_WIDTH - cur_col);
12382a5c12eSMatthew Dillon }
12482a5c12eSMatthew Dillon
12582a5c12eSMatthew Dillon /*
12682a5c12eSMatthew Dillon * display_putchar:
12782a5c12eSMatthew Dillon * put one character on the screen, move the cursor right one,
12882a5c12eSMatthew Dillon * with wraparound
12982a5c12eSMatthew Dillon */
13082a5c12eSMatthew Dillon void
display_put_ch(char ch)1316beb426bSSascha Wildner display_put_ch(char ch)
13282a5c12eSMatthew Dillon {
13382a5c12eSMatthew Dillon if (!isprint(ch)) {
13482a5c12eSMatthew Dillon fprintf(stderr, "r,c,ch: %d,%d,%d", cur_row, cur_col, ch);
13582a5c12eSMatthew Dillon return;
13682a5c12eSMatthew Dillon }
13782a5c12eSMatthew Dillon screen[cur_row][cur_col] = ch;
13882a5c12eSMatthew Dillon putchar(ch);
13982a5c12eSMatthew Dillon if (++cur_col >= COLS) {
14082a5c12eSMatthew Dillon if (!AM || XN)
14182a5c12eSMatthew Dillon putchar('\n');
14282a5c12eSMatthew Dillon cur_col = 0;
14382a5c12eSMatthew Dillon if (++cur_row >= LINES)
14482a5c12eSMatthew Dillon cur_row = LINES;
14582a5c12eSMatthew Dillon }
14682a5c12eSMatthew Dillon }
14782a5c12eSMatthew Dillon
14882a5c12eSMatthew Dillon /*
14982a5c12eSMatthew Dillon * display_put_str:
15082a5c12eSMatthew Dillon * put a string of characters on the screen
15182a5c12eSMatthew Dillon */
15282a5c12eSMatthew Dillon void
display_put_str(const char * s)15382a5c12eSMatthew Dillon display_put_str(const char *s)
15482a5c12eSMatthew Dillon {
15582a5c12eSMatthew Dillon for( ; *s; s++)
15682a5c12eSMatthew Dillon display_put_ch(*s);
15782a5c12eSMatthew Dillon }
15882a5c12eSMatthew Dillon
15982a5c12eSMatthew Dillon /*
16082a5c12eSMatthew Dillon * display_clear_the_screen:
16182a5c12eSMatthew Dillon * clear the screen; move cursor to top left
16282a5c12eSMatthew Dillon */
16382a5c12eSMatthew Dillon void
display_clear_the_screen(void)1646beb426bSSascha Wildner display_clear_the_screen(void)
16582a5c12eSMatthew Dillon {
16682a5c12eSMatthew Dillon int i;
16782a5c12eSMatthew Dillon
16882a5c12eSMatthew Dillon if (blanks[0] == '\0')
16982a5c12eSMatthew Dillon for (i = 0; i < SCREEN_WIDTH; i++)
17082a5c12eSMatthew Dillon blanks[i] = ' ';
17182a5c12eSMatthew Dillon
17282a5c12eSMatthew Dillon if (CL != NULL) {
17382a5c12eSMatthew Dillon tputs(CL, LINES, __cputchar);
17482a5c12eSMatthew Dillon for (i = 0; i < SCREEN_HEIGHT; i++)
17582a5c12eSMatthew Dillon memcpy(screen[i], blanks, SCREEN_WIDTH);
17682a5c12eSMatthew Dillon } else {
17782a5c12eSMatthew Dillon for (i = 0; i < SCREEN_HEIGHT; i++) {
17882a5c12eSMatthew Dillon mvcur(cur_row, cur_col, i, 0);
17982a5c12eSMatthew Dillon cur_row = i;
18082a5c12eSMatthew Dillon cur_col = 0;
18182a5c12eSMatthew Dillon display_clear_eol();
18282a5c12eSMatthew Dillon }
18382a5c12eSMatthew Dillon mvcur(cur_row, cur_col, 0, 0);
18482a5c12eSMatthew Dillon }
18582a5c12eSMatthew Dillon cur_row = cur_col = 0;
18682a5c12eSMatthew Dillon }
18782a5c12eSMatthew Dillon
18882a5c12eSMatthew Dillon /*
18982a5c12eSMatthew Dillon * display_move:
19082a5c12eSMatthew Dillon * move the cursor
19182a5c12eSMatthew Dillon */
19282a5c12eSMatthew Dillon void
display_move(int y,int x)1936beb426bSSascha Wildner display_move(int y, int x)
19482a5c12eSMatthew Dillon {
19582a5c12eSMatthew Dillon mvcur(cur_row, cur_col, y, x);
19682a5c12eSMatthew Dillon cur_row = y;
19782a5c12eSMatthew Dillon cur_col = x;
19882a5c12eSMatthew Dillon }
19982a5c12eSMatthew Dillon
20082a5c12eSMatthew Dillon /*
20182a5c12eSMatthew Dillon * display_getyx:
20282a5c12eSMatthew Dillon * locate the cursor
20382a5c12eSMatthew Dillon */
20482a5c12eSMatthew Dillon void
display_getyx(int * yp,int * xp)2056beb426bSSascha Wildner display_getyx(int *yp, int *xp)
20682a5c12eSMatthew Dillon {
20782a5c12eSMatthew Dillon *xp = cur_col;
20882a5c12eSMatthew Dillon *yp = cur_row;
20982a5c12eSMatthew Dillon }
21082a5c12eSMatthew Dillon
21182a5c12eSMatthew Dillon /*
21282a5c12eSMatthew Dillon * display_end:
21382a5c12eSMatthew Dillon * close the display
21482a5c12eSMatthew Dillon */
21582a5c12eSMatthew Dillon void
display_end(void)2166beb426bSSascha Wildner display_end(void)
21782a5c12eSMatthew Dillon {
21882a5c12eSMatthew Dillon tcsetattr(0, TCSADRAIN, &__orig_termios);
21982a5c12eSMatthew Dillon _puts(VE);
22082a5c12eSMatthew Dillon _puts(TE);
22182a5c12eSMatthew Dillon }
22282a5c12eSMatthew Dillon
22382a5c12eSMatthew Dillon /*
22482a5c12eSMatthew Dillon * display_atyx:
22582a5c12eSMatthew Dillon * return a character from the screen
22682a5c12eSMatthew Dillon */
22782a5c12eSMatthew Dillon char
display_atyx(int y,int x)2286beb426bSSascha Wildner display_atyx(int y, int x)
22982a5c12eSMatthew Dillon {
23082a5c12eSMatthew Dillon return screen[y][x];
23182a5c12eSMatthew Dillon }
23282a5c12eSMatthew Dillon
23382a5c12eSMatthew Dillon /*
23482a5c12eSMatthew Dillon * display_redraw_screen:
23582a5c12eSMatthew Dillon * redraw the screen
23682a5c12eSMatthew Dillon */
23782a5c12eSMatthew Dillon void
display_redraw_screen(void)2386beb426bSSascha Wildner display_redraw_screen(void)
23982a5c12eSMatthew Dillon {
24082a5c12eSMatthew Dillon int i;
24182a5c12eSMatthew Dillon
24282a5c12eSMatthew Dillon mvcur(cur_row, cur_col, 0, 0);
24382a5c12eSMatthew Dillon for (i = 0; i < SCREEN_HEIGHT - 1; i++) {
24482a5c12eSMatthew Dillon fwrite(screen[i], sizeof (char), SCREEN_WIDTH, stdout);
24582a5c12eSMatthew Dillon if (COLS > SCREEN_WIDTH || (COLS == SCREEN_WIDTH && !AM))
24682a5c12eSMatthew Dillon putchar('\n');
24782a5c12eSMatthew Dillon }
24882a5c12eSMatthew Dillon fwrite(screen[SCREEN_HEIGHT - 1], sizeof (char), SCREEN_WIDTH - 1,
24982a5c12eSMatthew Dillon stdout);
25082a5c12eSMatthew Dillon mvcur(SCREEN_HEIGHT - 1, SCREEN_WIDTH - 1, cur_row, cur_col);
25182a5c12eSMatthew Dillon }
25282a5c12eSMatthew Dillon
25382a5c12eSMatthew Dillon #else /* CURSES */ /* --------------------------------------------------- */
25482a5c12eSMatthew Dillon
25582a5c12eSMatthew Dillon #include <curses.h>
25682a5c12eSMatthew Dillon #include "hunt.h"
25782a5c12eSMatthew Dillon
25882a5c12eSMatthew Dillon void
display_open(void)2596beb426bSSascha Wildner display_open(void)
26082a5c12eSMatthew Dillon {
26182a5c12eSMatthew Dillon initscr();
262*d9f85b33Szrj noecho();
263*d9f85b33Szrj cbreak();
26482a5c12eSMatthew Dillon }
26582a5c12eSMatthew Dillon
26682a5c12eSMatthew Dillon void
display_beep(void)2676beb426bSSascha Wildner display_beep(void)
26882a5c12eSMatthew Dillon {
26982a5c12eSMatthew Dillon beep();
27082a5c12eSMatthew Dillon }
27182a5c12eSMatthew Dillon
27282a5c12eSMatthew Dillon void
display_refresh(void)2736beb426bSSascha Wildner display_refresh(void)
27482a5c12eSMatthew Dillon {
27582a5c12eSMatthew Dillon refresh();
27682a5c12eSMatthew Dillon }
27782a5c12eSMatthew Dillon
27882a5c12eSMatthew Dillon void
display_clear_eol(void)2796beb426bSSascha Wildner display_clear_eol(void)
28082a5c12eSMatthew Dillon {
28182a5c12eSMatthew Dillon clrtoeol();
28282a5c12eSMatthew Dillon }
28382a5c12eSMatthew Dillon
28482a5c12eSMatthew Dillon void
display_put_ch(char c)2856beb426bSSascha Wildner display_put_ch(char c)
28682a5c12eSMatthew Dillon {
28782a5c12eSMatthew Dillon addch(c);
28882a5c12eSMatthew Dillon }
28982a5c12eSMatthew Dillon
29082a5c12eSMatthew Dillon void
display_put_str(const char * s)29182a5c12eSMatthew Dillon display_put_str(const char *s)
29282a5c12eSMatthew Dillon {
29382a5c12eSMatthew Dillon addstr(s);
29482a5c12eSMatthew Dillon }
29582a5c12eSMatthew Dillon
29682a5c12eSMatthew Dillon void
display_clear_the_screen(void)2976beb426bSSascha Wildner display_clear_the_screen(void)
29882a5c12eSMatthew Dillon {
29982a5c12eSMatthew Dillon clear();
30082a5c12eSMatthew Dillon move(0, 0);
30182a5c12eSMatthew Dillon display_refresh();
30282a5c12eSMatthew Dillon }
30382a5c12eSMatthew Dillon
30482a5c12eSMatthew Dillon void
display_move(int y,int x)3056beb426bSSascha Wildner display_move(int y, int x)
30682a5c12eSMatthew Dillon {
30782a5c12eSMatthew Dillon move(y, x);
30882a5c12eSMatthew Dillon }
30982a5c12eSMatthew Dillon
31082a5c12eSMatthew Dillon void
display_getyx(int * yp,int * xp)3116beb426bSSascha Wildner display_getyx(int *yp, int *xp)
31282a5c12eSMatthew Dillon {
31382a5c12eSMatthew Dillon getyx(stdscr, *yp, *xp);
31482a5c12eSMatthew Dillon }
31582a5c12eSMatthew Dillon
31682a5c12eSMatthew Dillon void
display_end(void)3176beb426bSSascha Wildner display_end(void)
31882a5c12eSMatthew Dillon {
31982a5c12eSMatthew Dillon endwin();
32082a5c12eSMatthew Dillon }
32182a5c12eSMatthew Dillon
32282a5c12eSMatthew Dillon char
display_atyx(int y,int x)3236beb426bSSascha Wildner display_atyx(int y, int x)
32482a5c12eSMatthew Dillon {
32582a5c12eSMatthew Dillon int oy, ox;
32682a5c12eSMatthew Dillon char c;
32782a5c12eSMatthew Dillon
32882a5c12eSMatthew Dillon display_getyx(&oy, &ox);
32982a5c12eSMatthew Dillon c = mvwinch(stdscr, y, x) & 0x7f;
33082a5c12eSMatthew Dillon display_move(oy, ox);
33182a5c12eSMatthew Dillon return (c);
33282a5c12eSMatthew Dillon }
33382a5c12eSMatthew Dillon
33482a5c12eSMatthew Dillon void
display_redraw_screen(void)3356beb426bSSascha Wildner display_redraw_screen(void)
33682a5c12eSMatthew Dillon {
33782a5c12eSMatthew Dillon clearok(stdscr, TRUE);
33882a5c12eSMatthew Dillon touchwin(stdscr);
33982a5c12eSMatthew Dillon }
34082a5c12eSMatthew Dillon
34182a5c12eSMatthew Dillon int
display_iserasechar(char ch)3426beb426bSSascha Wildner display_iserasechar(char ch)
34382a5c12eSMatthew Dillon {
34482a5c12eSMatthew Dillon return ch == erasechar();
34582a5c12eSMatthew Dillon }
34682a5c12eSMatthew Dillon
34782a5c12eSMatthew Dillon int
display_iskillchar(char ch)3486beb426bSSascha Wildner display_iskillchar(char ch)
34982a5c12eSMatthew Dillon {
35082a5c12eSMatthew Dillon return ch == killchar();
35182a5c12eSMatthew Dillon }
35282a5c12eSMatthew Dillon
35382a5c12eSMatthew Dillon #endif
354