xref: /original-bsd/usr.bin/talk/display.c (revision e74403ba)
1 #ifndef lint
2 static char sccsid[] = "@(#)display.c	1.2 (Berkeley) 04/11/84";
3 #endif
4 
5 /*
6  * The window 'manager', initializes curses and handles the actual
7  * displaying of text
8  */
9 #include "talk.h"
10 
11 xwin_t	my_win;
12 xwin_t	his_win;
13 WINDOW	*line_win;
14 
15 int	curses_initialized = 0;
16 
17 /*
18  * max HAS to be a function, it is called with
19  * a argument of the form --foo at least once.
20  */
21 max(a,b)
22 	int a, b;
23 {
24 
25 	return (a > b ? a : b);
26 }
27 
28 /*
29  * Display some text on somebody's window, processing some control
30  * characters while we are at it.
31  */
32 display(win, text, size)
33 	register xwin_t *win;
34 	register char *text;
35 	int size;
36 {
37 	register int i;
38 	char cch;
39 
40 	for (i = 0; i < size; i++) {
41 		if (*text == '\n') {
42 			xscroll(win, 0);
43 			text++;
44 			continue;
45 		}
46 		/* erase character */
47 		if (*text == win->cerase) {
48 			wmove(win->x_win, win->x_line, max(--win->x_col, 0));
49 			getyx(win->x_win, win->x_line, win->x_col);
50 			waddch(win->x_win, ' ');
51 			wmove(win->x_win, win->x_line, win->x_col);
52 			getyx(win->x_win, win->x_line, win->x_col);
53 			text++;
54 			continue;
55 		}
56 		/*
57 		 * On word erase search backwards until we find
58 		 * the beginning of a word or the beginning of
59 		 * the line.
60 		 */
61 		if (*text == win->werase) {
62 			int endcol, xcol, i, c;
63 
64 			endcol = win->x_col;
65 			xcol = endcol - 1;
66 			while (xcol >= 0) {
67 				c = readwin(win->x_win, win->x_line, xcol);
68 				if (c != ' ')
69 					break;
70 				xcol--;
71 			}
72 			while (xcol >= 0) {
73 				c = readwin(win->x_win, win->x_line, xcol);
74 				if (c == ' ')
75 					break;
76 				xcol--;
77 			}
78 			wmove(win->x_win, win->x_line, xcol + 1);
79 			for (i = xcol + 1; i < endcol; i++)
80 				waddch(win->x_win, ' ');
81 			wmove(win->x_win, win->x_line, xcol + 1);
82 			getyx(win->x_win, win->x_line, win->x_col);
83 			continue;
84 		}
85 		/* line kill */
86 		if (*text == win->kill) {
87 			wmove(win->x_win, win->x_line, 0);
88 			wclrtoeol(win->x_win);
89 			getyx(win->x_win, win->x_line, win->x_col);
90 			text++;
91 			continue;
92 		}
93 		if (*text == '\f') {
94 			if (win == &my_win)
95 				wrefresh(curscr);
96 			text++;
97 			continue;
98 		}
99 		if (win->x_col == COLS-1) {
100 			/* check for wraparound */
101 			xscroll(win, 0);
102 		}
103 		if (*text < ' ' && *text != '\t') {
104 			waddch(win->x_win, '^');
105 			getyx(win->x_win, win->x_line, win->x_col);
106 			if (win->x_col == COLS-1) /* check for wraparound */
107 				xscroll(win, 0);
108 			cch = (*text & 63) + 64;
109 			waddch(win->x_win, cch);
110 		} else
111 			waddch(win->x_win, *text);
112 		getyx(win->x_win, win->x_line, win->x_col);
113 		text++;
114 	}
115 	wrefresh(win->x_win);
116 }
117 
118 /*
119  * Read the character at the indicated position in win
120  */
121 readwin(win, line, col)
122 	WINDOW *win;
123 {
124 	int oldline, oldcol;
125 	register int c;
126 
127 	getyx(win, oldline, oldcol);
128 	wmove(win, line, col);
129 	c = winch(win);
130 	wmove(win, oldline, oldcol);
131 	return (c);
132 }
133 
134 /*
135  * Scroll a window, blanking out the line following the current line
136  * so that the current position is obvious
137  */
138 xscroll(win, flag)
139 	register xwin_t *win;
140 	int flag;
141 {
142 
143 	if (flag == -1) {
144 		wmove(win->x_win, 0, 0);
145 		win->x_line = 0;
146 		win->x_col = 0;
147 		return;
148 	}
149 	win->x_line = (win->x_line + 1) % win->x_nlines;
150 	win->x_col = 0;
151 	wmove(win->x_win, win->x_line, win->x_col);
152 	wclrtoeol(win->x_win);
153 	wmove(win->x_win, (win->x_line + 1) % win->x_nlines, win->x_col);
154 	wclrtoeol(win->x_win);
155 	wmove(win->x_win, win->x_line, win->x_col);
156 }
157