xref: /freebsd/usr.bin/talk/display.c (revision 3daadfc83361cf4f31017a7fed5a5910cd8c4ce9)
19b50d902SRodney W. Grimes /*
29b50d902SRodney W. Grimes  * Copyright (c) 1983, 1993
39b50d902SRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
49b50d902SRodney W. Grimes  *
59b50d902SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
69b50d902SRodney W. Grimes  * modification, are permitted provided that the following conditions
79b50d902SRodney W. Grimes  * are met:
89b50d902SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
99b50d902SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
109b50d902SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
119b50d902SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
129b50d902SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
139b50d902SRodney W. Grimes  * 3. All advertising materials mentioning features or use of this software
149b50d902SRodney W. Grimes  *    must display the following acknowledgement:
159b50d902SRodney W. Grimes  *	This product includes software developed by the University of
169b50d902SRodney W. Grimes  *	California, Berkeley and its contributors.
179b50d902SRodney W. Grimes  * 4. Neither the name of the University nor the names of its contributors
189b50d902SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
199b50d902SRodney W. Grimes  *    without specific prior written permission.
209b50d902SRodney W. Grimes  *
219b50d902SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
229b50d902SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
239b50d902SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
249b50d902SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
259b50d902SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
269b50d902SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
279b50d902SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
289b50d902SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
299b50d902SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
309b50d902SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
319b50d902SRodney W. Grimes  * SUCH DAMAGE.
329b50d902SRodney W. Grimes  */
339b50d902SRodney W. Grimes 
34caa64801SMark Murray #include <sys/cdefs.h>
35caa64801SMark Murray 
36caa64801SMark Murray __FBSDID("$FreeBSD$");
37caa64801SMark Murray 
389b50d902SRodney W. Grimes #ifndef lint
39caa64801SMark Murray static const char sccsid[] = "@(#)display.c	8.1 (Berkeley) 6/6/93";
4020868061SPhilippe Charnier #endif
419b50d902SRodney W. Grimes 
429b50d902SRodney W. Grimes /*
439b50d902SRodney W. Grimes  * The window 'manager', initializes curses and handles the actual
449b50d902SRodney W. Grimes  * displaying of text
459b50d902SRodney W. Grimes  */
46edee6d38SAndrey A. Chernov #include <ctype.h>
473daadfc8SXin LI #include <unistd.h>
489b50d902SRodney W. Grimes 
49caa64801SMark Murray #include "talk.h"
50caa64801SMark Murray 
519b50d902SRodney W. Grimes xwin_t	my_win;
529b50d902SRodney W. Grimes xwin_t	his_win;
539b50d902SRodney W. Grimes WINDOW	*line_win;
549b50d902SRodney W. Grimes 
559b50d902SRodney W. Grimes int	curses_initialized = 0;
569b50d902SRodney W. Grimes 
579b50d902SRodney W. Grimes /*
589b50d902SRodney W. Grimes  * max HAS to be a function, it is called with
599d5abbddSJens Schweikhardt  * an argument of the form --foo at least once.
609b50d902SRodney W. Grimes  */
6128592604SJoerg Wunsch int
62b6d9e1f3SXin LI max(int a, int b)
639b50d902SRodney W. Grimes {
649b50d902SRodney W. Grimes 
659b50d902SRodney W. Grimes 	return (a > b ? a : b);
669b50d902SRodney W. Grimes }
679b50d902SRodney W. Grimes 
689b50d902SRodney W. Grimes /*
699b50d902SRodney W. Grimes  * Display some text on somebody's window, processing some control
709b50d902SRodney W. Grimes  * characters while we are at it.
719b50d902SRodney W. Grimes  */
7228592604SJoerg Wunsch void
73b6d9e1f3SXin LI display(xwin_t *win, char *text, int size)
749b50d902SRodney W. Grimes {
75caa64801SMark Murray 	int i;
769b50d902SRodney W. Grimes 	char cch;
779b50d902SRodney W. Grimes 
789b50d902SRodney W. Grimes 	for (i = 0; i < size; i++) {
79edee6d38SAndrey A. Chernov 		if (*text == '\n' || *text == '\r') {
80edee6d38SAndrey A. Chernov 			waddch(win->x_win, '\n');
81edee6d38SAndrey A. Chernov 			getyx(win->x_win, win->x_line, win->x_col);
829b50d902SRodney W. Grimes 			text++;
839b50d902SRodney W. Grimes 			continue;
849b50d902SRodney W. Grimes 		}
858aed91caSLuigi Rizzo 		if (*text == 004 && win == &my_win) {
868aed91caSLuigi Rizzo 			/* control-D clears the screen */
878aed91caSLuigi Rizzo 			werase(my_win.x_win);
888aed91caSLuigi Rizzo 			getyx(my_win.x_win, my_win.x_line, my_win.x_col);
898aed91caSLuigi Rizzo 			wrefresh(my_win.x_win);
908aed91caSLuigi Rizzo 			werase(his_win.x_win);
918aed91caSLuigi Rizzo 			getyx(his_win.x_win, his_win.x_line, his_win.x_col);
928aed91caSLuigi Rizzo 			wrefresh(his_win.x_win);
938aed91caSLuigi Rizzo 			text++;
948aed91caSLuigi Rizzo 			continue;
958aed91caSLuigi Rizzo 		}
968aed91caSLuigi Rizzo 
979b50d902SRodney W. Grimes 		/* erase character */
98edee6d38SAndrey A. Chernov 		if (   *text == win->cerase
99edee6d38SAndrey A. Chernov 		    || *text == 010     /* BS */
100edee6d38SAndrey A. Chernov 		    || *text == 0177    /* DEL */
101edee6d38SAndrey A. Chernov 		   ) {
1029b50d902SRodney W. Grimes 			wmove(win->x_win, win->x_line, max(--win->x_col, 0));
1039b50d902SRodney W. Grimes 			getyx(win->x_win, win->x_line, win->x_col);
1049b50d902SRodney W. Grimes 			waddch(win->x_win, ' ');
1059b50d902SRodney W. Grimes 			wmove(win->x_win, win->x_line, win->x_col);
1069b50d902SRodney W. Grimes 			getyx(win->x_win, win->x_line, win->x_col);
1079b50d902SRodney W. Grimes 			text++;
1089b50d902SRodney W. Grimes 			continue;
1099b50d902SRodney W. Grimes 		}
1109b50d902SRodney W. Grimes 		/*
1119b50d902SRodney W. Grimes 		 * On word erase search backwards until we find
1129b50d902SRodney W. Grimes 		 * the beginning of a word or the beginning of
1139b50d902SRodney W. Grimes 		 * the line.
1149b50d902SRodney W. Grimes 		 */
115edee6d38SAndrey A. Chernov 		if (   *text == win->werase
116edee6d38SAndrey A. Chernov 		    || *text == 027     /* ^W */
117edee6d38SAndrey A. Chernov 		   ) {
118caa64801SMark Murray 			int endcol, xcol, ii, c;
1199b50d902SRodney W. Grimes 
1209b50d902SRodney W. Grimes 			endcol = win->x_col;
1219b50d902SRodney W. Grimes 			xcol = endcol - 1;
1229b50d902SRodney W. Grimes 			while (xcol >= 0) {
1239b50d902SRodney W. Grimes 				c = readwin(win->x_win, win->x_line, xcol);
1249b50d902SRodney W. Grimes 				if (c != ' ')
1259b50d902SRodney W. Grimes 					break;
1269b50d902SRodney W. Grimes 				xcol--;
1279b50d902SRodney W. Grimes 			}
1289b50d902SRodney W. Grimes 			while (xcol >= 0) {
1299b50d902SRodney W. Grimes 				c = readwin(win->x_win, win->x_line, xcol);
1309b50d902SRodney W. Grimes 				if (c == ' ')
1319b50d902SRodney W. Grimes 					break;
1329b50d902SRodney W. Grimes 				xcol--;
1339b50d902SRodney W. Grimes 			}
1349b50d902SRodney W. Grimes 			wmove(win->x_win, win->x_line, xcol + 1);
135caa64801SMark Murray 			for (ii = xcol + 1; ii < endcol; ii++)
1369b50d902SRodney W. Grimes 				waddch(win->x_win, ' ');
1379b50d902SRodney W. Grimes 			wmove(win->x_win, win->x_line, xcol + 1);
1389b50d902SRodney W. Grimes 			getyx(win->x_win, win->x_line, win->x_col);
1399b50d902SRodney W. Grimes 			text++;
1409b50d902SRodney W. Grimes 			continue;
1419b50d902SRodney W. Grimes 		}
1429b50d902SRodney W. Grimes 		/* line kill */
143edee6d38SAndrey A. Chernov 		if (   *text == win->kill
144edee6d38SAndrey A. Chernov 		    || *text == 025     /* ^U */
145edee6d38SAndrey A. Chernov 		   ) {
1469b50d902SRodney W. Grimes 			wmove(win->x_win, win->x_line, 0);
1479b50d902SRodney W. Grimes 			wclrtoeol(win->x_win);
1489b50d902SRodney W. Grimes 			getyx(win->x_win, win->x_line, win->x_col);
1499b50d902SRodney W. Grimes 			text++;
1509b50d902SRodney W. Grimes 			continue;
1519b50d902SRodney W. Grimes 		}
1529b50d902SRodney W. Grimes 		if (*text == '\f') {
1539b50d902SRodney W. Grimes 			if (win == &my_win)
1549b50d902SRodney W. Grimes 				wrefresh(curscr);
1559b50d902SRodney W. Grimes 			text++;
1569b50d902SRodney W. Grimes 			continue;
1579b50d902SRodney W. Grimes 		}
158edee6d38SAndrey A. Chernov 		if (*text == '\7') {
159e151ec23SPeter Wemm 			write(STDOUT_FILENO, text, 1);
160edee6d38SAndrey A. Chernov 			text++;
161edee6d38SAndrey A. Chernov 			continue;
1629b50d902SRodney W. Grimes 		}
163481f550eSAndrey A. Chernov 		if (!isprint((unsigned char)*text) && *text != '\t') {
1649b50d902SRodney W. Grimes 			waddch(win->x_win, '^');
1659b50d902SRodney W. Grimes 			getyx(win->x_win, win->x_line, win->x_col);
1669b50d902SRodney W. Grimes 			cch = (*text & 63) + 64;
1679b50d902SRodney W. Grimes 			waddch(win->x_win, cch);
1689b50d902SRodney W. Grimes 		} else
169481f550eSAndrey A. Chernov 			waddch(win->x_win, (unsigned char)*text);
1709b50d902SRodney W. Grimes 		getyx(win->x_win, win->x_line, win->x_col);
1719b50d902SRodney W. Grimes 		text++;
1729b50d902SRodney W. Grimes 	}
1739b50d902SRodney W. Grimes 	wrefresh(win->x_win);
1749b50d902SRodney W. Grimes }
1759b50d902SRodney W. Grimes 
1769b50d902SRodney W. Grimes /*
1779b50d902SRodney W. Grimes  * Read the character at the indicated position in win
1789b50d902SRodney W. Grimes  */
17928592604SJoerg Wunsch int
180b6d9e1f3SXin LI readwin(WINDOW *win, int line, int col)
1819b50d902SRodney W. Grimes {
1829b50d902SRodney W. Grimes 	int oldline, oldcol;
183caa64801SMark Murray 	int c;
1849b50d902SRodney W. Grimes 
1859b50d902SRodney W. Grimes 	getyx(win, oldline, oldcol);
1869b50d902SRodney W. Grimes 	wmove(win, line, col);
1879b50d902SRodney W. Grimes 	c = winch(win);
1889b50d902SRodney W. Grimes 	wmove(win, oldline, oldcol);
1899b50d902SRodney W. Grimes 	return (c);
1909b50d902SRodney W. Grimes }
191