xref: /freebsd/usr.bin/talk/display.c (revision caa648017bbb26224de634bf4c9b6a9932e34e1d)
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>
479b50d902SRodney W. Grimes 
48caa64801SMark Murray #include "talk.h"
49caa64801SMark Murray 
509b50d902SRodney W. Grimes xwin_t	my_win;
519b50d902SRodney W. Grimes xwin_t	his_win;
529b50d902SRodney W. Grimes WINDOW	*line_win;
539b50d902SRodney W. Grimes 
549b50d902SRodney W. Grimes int	curses_initialized = 0;
559b50d902SRodney W. Grimes 
569b50d902SRodney W. Grimes /*
579b50d902SRodney W. Grimes  * max HAS to be a function, it is called with
589b50d902SRodney W. Grimes  * a argument of the form --foo at least once.
599b50d902SRodney W. Grimes  */
6028592604SJoerg Wunsch int
619b50d902SRodney W. Grimes max(a,b)
629b50d902SRodney W. Grimes 	int a, 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
739b50d902SRodney W. Grimes display(win, text, size)
74caa64801SMark Murray 	xwin_t *win;
75caa64801SMark Murray 	char *text;
769b50d902SRodney W. Grimes 	int size;
779b50d902SRodney W. Grimes {
78caa64801SMark Murray 	int i;
799b50d902SRodney W. Grimes 	char cch;
809b50d902SRodney W. Grimes 
819b50d902SRodney W. Grimes 	for (i = 0; i < size; i++) {
82edee6d38SAndrey A. Chernov 		if (*text == '\n' || *text == '\r') {
83edee6d38SAndrey A. Chernov 			waddch(win->x_win, '\n');
84edee6d38SAndrey A. Chernov 			getyx(win->x_win, win->x_line, win->x_col);
859b50d902SRodney W. Grimes 			text++;
869b50d902SRodney W. Grimes 			continue;
879b50d902SRodney W. Grimes 		}
889b50d902SRodney W. Grimes 		/* erase character */
89edee6d38SAndrey A. Chernov 		if (   *text == win->cerase
90edee6d38SAndrey A. Chernov 		    || *text == 010     /* BS */
91edee6d38SAndrey A. Chernov 		    || *text == 0177    /* DEL */
92edee6d38SAndrey A. Chernov 		   ) {
939b50d902SRodney W. Grimes 			wmove(win->x_win, win->x_line, max(--win->x_col, 0));
949b50d902SRodney W. Grimes 			getyx(win->x_win, win->x_line, win->x_col);
959b50d902SRodney W. Grimes 			waddch(win->x_win, ' ');
969b50d902SRodney W. Grimes 			wmove(win->x_win, win->x_line, win->x_col);
979b50d902SRodney W. Grimes 			getyx(win->x_win, win->x_line, win->x_col);
989b50d902SRodney W. Grimes 			text++;
999b50d902SRodney W. Grimes 			continue;
1009b50d902SRodney W. Grimes 		}
1019b50d902SRodney W. Grimes 		/*
1029b50d902SRodney W. Grimes 		 * On word erase search backwards until we find
1039b50d902SRodney W. Grimes 		 * the beginning of a word or the beginning of
1049b50d902SRodney W. Grimes 		 * the line.
1059b50d902SRodney W. Grimes 		 */
106edee6d38SAndrey A. Chernov 		if (   *text == win->werase
107edee6d38SAndrey A. Chernov 		    || *text == 027     /* ^W */
108edee6d38SAndrey A. Chernov 		   ) {
109caa64801SMark Murray 			int endcol, xcol, ii, c;
1109b50d902SRodney W. Grimes 
1119b50d902SRodney W. Grimes 			endcol = win->x_col;
1129b50d902SRodney W. Grimes 			xcol = endcol - 1;
1139b50d902SRodney W. Grimes 			while (xcol >= 0) {
1149b50d902SRodney W. Grimes 				c = readwin(win->x_win, win->x_line, xcol);
1159b50d902SRodney W. Grimes 				if (c != ' ')
1169b50d902SRodney W. Grimes 					break;
1179b50d902SRodney W. Grimes 				xcol--;
1189b50d902SRodney W. Grimes 			}
1199b50d902SRodney W. Grimes 			while (xcol >= 0) {
1209b50d902SRodney W. Grimes 				c = readwin(win->x_win, win->x_line, xcol);
1219b50d902SRodney W. Grimes 				if (c == ' ')
1229b50d902SRodney W. Grimes 					break;
1239b50d902SRodney W. Grimes 				xcol--;
1249b50d902SRodney W. Grimes 			}
1259b50d902SRodney W. Grimes 			wmove(win->x_win, win->x_line, xcol + 1);
126caa64801SMark Murray 			for (ii = xcol + 1; ii < endcol; ii++)
1279b50d902SRodney W. Grimes 				waddch(win->x_win, ' ');
1289b50d902SRodney W. Grimes 			wmove(win->x_win, win->x_line, xcol + 1);
1299b50d902SRodney W. Grimes 			getyx(win->x_win, win->x_line, win->x_col);
1309b50d902SRodney W. Grimes 			text++;
1319b50d902SRodney W. Grimes 			continue;
1329b50d902SRodney W. Grimes 		}
1339b50d902SRodney W. Grimes 		/* line kill */
134edee6d38SAndrey A. Chernov 		if (   *text == win->kill
135edee6d38SAndrey A. Chernov 		    || *text == 025     /* ^U */
136edee6d38SAndrey A. Chernov 		   ) {
1379b50d902SRodney W. Grimes 			wmove(win->x_win, win->x_line, 0);
1389b50d902SRodney W. Grimes 			wclrtoeol(win->x_win);
1399b50d902SRodney W. Grimes 			getyx(win->x_win, win->x_line, win->x_col);
1409b50d902SRodney W. Grimes 			text++;
1419b50d902SRodney W. Grimes 			continue;
1429b50d902SRodney W. Grimes 		}
1439b50d902SRodney W. Grimes 		if (*text == '\f') {
1449b50d902SRodney W. Grimes 			if (win == &my_win)
1459b50d902SRodney W. Grimes 				wrefresh(curscr);
1469b50d902SRodney W. Grimes 			text++;
1479b50d902SRodney W. Grimes 			continue;
1489b50d902SRodney W. Grimes 		}
149edee6d38SAndrey A. Chernov 		if (*text == '\7') {
150e151ec23SPeter Wemm 			write(STDOUT_FILENO, text, 1);
151edee6d38SAndrey A. Chernov 			text++;
152edee6d38SAndrey A. Chernov 			continue;
1539b50d902SRodney W. Grimes 		}
154481f550eSAndrey A. Chernov 		if (!isprint((unsigned char)*text) && *text != '\t') {
1559b50d902SRodney W. Grimes 			waddch(win->x_win, '^');
1569b50d902SRodney W. Grimes 			getyx(win->x_win, win->x_line, win->x_col);
1579b50d902SRodney W. Grimes 			cch = (*text & 63) + 64;
1589b50d902SRodney W. Grimes 			waddch(win->x_win, cch);
1599b50d902SRodney W. Grimes 		} else
160481f550eSAndrey A. Chernov 			waddch(win->x_win, (unsigned char)*text);
1619b50d902SRodney W. Grimes 		getyx(win->x_win, win->x_line, win->x_col);
1629b50d902SRodney W. Grimes 		text++;
1639b50d902SRodney W. Grimes 	}
1649b50d902SRodney W. Grimes 	wrefresh(win->x_win);
1659b50d902SRodney W. Grimes }
1669b50d902SRodney W. Grimes 
1679b50d902SRodney W. Grimes /*
1689b50d902SRodney W. Grimes  * Read the character at the indicated position in win
1699b50d902SRodney W. Grimes  */
17028592604SJoerg Wunsch int
1719b50d902SRodney W. Grimes readwin(win, line, col)
1729b50d902SRodney W. Grimes 	WINDOW *win;
17328592604SJoerg Wunsch 	int line;
17428592604SJoerg Wunsch 	int col;
1759b50d902SRodney W. Grimes {
1769b50d902SRodney W. Grimes 	int oldline, oldcol;
177caa64801SMark Murray 	int c;
1789b50d902SRodney W. Grimes 
1799b50d902SRodney W. Grimes 	getyx(win, oldline, oldcol);
1809b50d902SRodney W. Grimes 	wmove(win, line, col);
1819b50d902SRodney W. Grimes 	c = winch(win);
1829b50d902SRodney W. Grimes 	wmove(win, oldline, oldcol);
1839b50d902SRodney W. Grimes 	return (c);
1849b50d902SRodney W. Grimes }
185