xref: /netbsd-src/usr.bin/talk/display.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: display.c,v 1.8 2009/04/13 23:43:36 lukem Exp $	*/
2 
3 /*
4  * Copyright (c) 1983, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)display.c	8.1 (Berkeley) 6/6/93";
36 #endif
37 __RCSID("$NetBSD: display.c,v 1.8 2009/04/13 23:43:36 lukem Exp $");
38 #endif /* not lint */
39 
40 /*
41  * The window 'manager', initializes curses and handles the actual
42  * displaying of text
43  */
44 #include "talk.h"
45 #include <ctype.h>
46 
47 xwin_t	my_win;
48 xwin_t	his_win;
49 WINDOW	*line_win;
50 
51 int	curses_initialized = 0;
52 
53 /*
54  * max HAS to be a function, it is called with
55  * a argument of the form --foo at least once.
56  */
57 int
58 max(a,b)
59 	int a, b;
60 {
61 
62 	return (a > b ? a : b);
63 }
64 
65 /*
66  * Display some text on somebody's window, processing some control
67  * characters while we are at it.
68  */
69 void
70 display(win, text, size)
71 	xwin_t *win;
72 	char *text;
73 	int size;
74 {
75 	int i;
76 	char cch;
77 
78 	for (i = 0; i < size; i++) {
79 		if (*text == '\n') {
80 			xscroll(win, 0);
81 			text++;
82 			continue;
83 		}
84 		/* erase character */
85 		if (*text == win->cerase) {
86 			wmove(win->x_win, win->x_line, max(--win->x_col, 0));
87 			getyx(win->x_win, win->x_line, win->x_col);
88 			waddch(win->x_win, ' ');
89 			wmove(win->x_win, win->x_line, win->x_col);
90 			getyx(win->x_win, win->x_line, win->x_col);
91 			text++;
92 			continue;
93 		}
94 		/*
95 		 * On word erase search backwards until we find
96 		 * the beginning of a word or the beginning of
97 		 * the line.
98 		 */
99 		if (*text == win->werase) {
100 			int endcol, xcol, j, c;
101 
102 			endcol = win->x_col;
103 			xcol = endcol - 1;
104 			while (xcol >= 0) {
105 				c = readwin(win->x_win, win->x_line, xcol);
106 				if (c != ' ')
107 					break;
108 				xcol--;
109 			}
110 			while (xcol >= 0) {
111 				c = readwin(win->x_win, win->x_line, xcol);
112 				if (c == ' ')
113 					break;
114 				xcol--;
115 			}
116 			wmove(win->x_win, win->x_line, xcol + 1);
117 			for (j = xcol + 1; j < endcol; j++)
118 				waddch(win->x_win, ' ');
119 			wmove(win->x_win, win->x_line, xcol + 1);
120 			getyx(win->x_win, win->x_line, win->x_col);
121 			text++;
122 			continue;
123 		}
124 		/* line kill */
125 		if (*text == win->kill) {
126 			wmove(win->x_win, win->x_line, 0);
127 			wclrtoeol(win->x_win);
128 			getyx(win->x_win, win->x_line, win->x_col);
129 			text++;
130 			continue;
131 		}
132 		if (*text == '\f') {
133 			if (win == &my_win)
134 				wrefresh(curscr);
135 			text++;
136 			continue;
137 		}
138 		if (*text == '\07') {
139 			beep();
140 			text++;
141 			continue;
142 		}
143 		if (win->x_col == COLS-1) {
144 			/* check for wraparound */
145 			xscroll(win, 0);
146 		}
147 		if ( !isprint((u_char)*text) && *text != '\t') {
148 			waddch(win->x_win, '^');
149 			getyx(win->x_win, win->x_line, win->x_col);
150 			if (win->x_col == COLS-1) /* check for wraparound */
151 				xscroll(win, 0);
152 			cch = (*text & 63) + 64;
153 			waddch(win->x_win, cch);
154 		} else
155 			waddch(win->x_win, *text);
156 		getyx(win->x_win, win->x_line, win->x_col);
157 		text++;
158 	}
159 	wrefresh(win->x_win);
160 }
161 
162 /*
163  * Read the character at the indicated position in win
164  */
165 int
166 readwin(win, line, col)
167 	WINDOW *win;
168 	int line, col;
169 {
170 	int oldline, oldcol;
171 	int c;
172 
173 	getyx(win, oldline, oldcol);
174 	wmove(win, line, col);
175 	c = winch(win);
176 	wmove(win, oldline, oldcol);
177 	return (c);
178 }
179 
180 /*
181  * Scroll a window, blanking out the line following the current line
182  * so that the current position is obvious
183  */
184 void
185 xscroll(win, flag)
186 	xwin_t *win;
187 	int flag;
188 {
189 
190 	if (flag == -1) {
191 		wmove(win->x_win, 0, 0);
192 		win->x_line = 0;
193 		win->x_col = 0;
194 		return;
195 	}
196 	win->x_line = (win->x_line + 1) % win->x_nlines;
197 	win->x_col = 0;
198 	wmove(win->x_win, win->x_line, win->x_col);
199 	wclrtoeol(win->x_win);
200 	wmove(win->x_win, (win->x_line + 1) % win->x_nlines, win->x_col);
201 	wclrtoeol(win->x_win);
202 	wmove(win->x_win, win->x_line, win->x_col);
203 }
204