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