Home | History | Annotate | Download | only in talk
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 1994 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     28 /*	  All Rights Reserved  	*/
     29 
     30 /*
     31  * University Copyright- Copyright (c) 1982, 1986, 1988
     32  * The Regents of the University of California
     33  * All Rights Reserved
     34  *
     35  * University Acknowledgment- Portions of this document are derived from
     36  * software developed by the University of California, Berkeley, and its
     37  * contributors.
     38  */
     39 
     40 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     41 
     42 /*
     43  * The window 'manager', initializes curses and handles the actual
     44  * displaying of text
     45  */
     46 
     47 #include "talk.h"
     48 #include <ctype.h>
     49 
     50 static int readwin(WINDOW *, int, int);
     51 static void xscroll(register xwin_t *, int);
     52 
     53 xwin_t my_win;
     54 xwin_t rem_win;
     55 WINDOW *line_win;
     56 
     57 int curses_initialized = 0;
     58 
     59 /*
     60  * max HAS to be a function, it is called with
     61  * a argument of the form --foo at least once.
     62  */
     63 
     64 static int
     65 max(a, b)
     66 int a, b;
     67 {
     68 	if (a > b) {
     69 	return (a);
     70 	} else {
     71 	return (b);
     72 	}
     73 }
     74 
     75 /*
     76  * Display some text on somebody's window, processing some control
     77  * characters while we are at it.
     78  */
     79 
     80 int
     81 display(win, text, size)
     82 register xwin_t *win;
     83 register char *text;
     84 int size;
     85 {
     86 	register int i;
     87 	int mb_cur_max = MB_CUR_MAX;
     88 
     89 	for (i = 0; i < size; i++) {
     90 	int itext;
     91 
     92 	if (*text == '\n'|| *text == '\r') {
     93 		xscroll(win, 0);
     94 		text++;
     95 		continue;
     96 	}
     97 
     98 		/* erase character */
     99 
    100 	if (*text == win->cerase) {
    101 		wmove(win->x_win, win->x_line, max(--win->x_col, 0));
    102 		getyx(win->x_win, win->x_line, win->x_col);
    103 		waddch(win->x_win, ' ');
    104 		wmove(win->x_win, win->x_line, win->x_col);
    105 		getyx(win->x_win, win->x_line, win->x_col);
    106 		text++;
    107 		continue;
    108 	}
    109 	/*
    110 	 * On word erase search backwards until we find
    111 	 * the beginning of a word or the beginning of
    112 	 * the line.
    113 	 */
    114 	if (*text == win->werase) {
    115 		int endcol, xcol, i, c;
    116 
    117 		endcol = win->x_col;
    118 		xcol = endcol - 1;
    119 		while (xcol >= 0) {
    120 		c = readwin(win->x_win, win->x_line, xcol);
    121 		if (c != ' ')
    122 			break;
    123 		xcol--;
    124 		}
    125 		while (xcol >= 0) {
    126 		c = readwin(win->x_win, win->x_line, xcol);
    127 		if (c == ' ')
    128 			break;
    129 		xcol--;
    130 		}
    131 		wmove(win->x_win, win->x_line, xcol + 1);
    132 		for (i = xcol + 1; i < endcol; i++)
    133 		waddch(win->x_win, ' ');
    134 		wmove(win->x_win, win->x_line, xcol + 1);
    135 		getyx(win->x_win, win->x_line, win->x_col);
    136 		continue;
    137 	}
    138 		/* line kill */
    139 	if (*text == win->kill) {
    140 		wmove(win->x_win, win->x_line, 0);
    141 		wclrtoeol(win->x_win);
    142 		getyx(win->x_win, win->x_line, win->x_col);
    143 		text++;
    144 		continue;
    145 	}
    146 	if (*text == '\f') {
    147 		if (win == &my_win)
    148 		wrefresh(curscr);
    149 		text++;
    150 		continue;
    151 	}
    152 	/* EOF character */
    153 	if (*text == '\004') {
    154 		quit();
    155 	}
    156 
    157 	/* typing alert character will alert recipient's terminal */
    158 
    159 	if (*text == '\007') {
    160 		beep();
    161 		continue;
    162 	}
    163 
    164 	/* check for wrap around */
    165 	if (win->x_col == COLS-1) {
    166 		xscroll(win, 0);
    167 	}
    168 
    169 	/*
    170 	 * Handle the multibyte case
    171 	 * We print '?' for nonprintable widechars.
    172 	 */
    173 
    174 	if (mb_cur_max > 1 && mblen(text, mb_cur_max) > 1) {
    175 		wchar_t wc;
    176 		int len;
    177 
    178 		len = mbtowc(&wc, text, mb_cur_max);
    179 
    180 		if (iswprint(wc) || iswspace(wc)) {
    181 		/* its printable, put out the bytes */
    182 			do {
    183 				if (win->x_col == COLS-1) /* wraparound */
    184 					xscroll(win, 0);
    185 				waddch(win->x_win, *text++);
    186 				getyx(win->x_win, win->x_line, win->x_col);
    187 			} while (--len > 0);
    188 			continue;
    189 		}
    190 		/*
    191 		 * otherwise, punt and print a question mark.
    192 		 */
    193 		text += len;
    194 		waddch(win->x_win, '?');
    195 		getyx(win->x_win, win->x_line, win->x_col);
    196 		continue;
    197 	}
    198 
    199 	itext = (unsigned int) *text;
    200 	if (isprint(itext) || *text == ' ' || *text == '\t' ||
    201 		*text == '\013' || *text == '\007' /* bell */) {
    202 		waddch(win->x_win, *text);
    203 	} else {
    204 
    205 		if (!isascii(*text)) {
    206 			/* check for wrap around */
    207 			if (win->x_col == COLS-3) {
    208 				xscroll(win, 0);
    209 			}
    210 			waddch(win->x_win, 'M');
    211 			waddch(win->x_win, '-');
    212 			*text = toascii(*text);
    213 		}
    214 		if (iscntrl(*text)) {
    215 
    216 			/* check for wrap around */
    217 			getyx(win->x_win, win->x_line, win->x_col);
    218 			if (win->x_col == COLS-2) {
    219 				xscroll(win, 0);
    220 			}
    221 
    222 			waddch(win->x_win, '^');
    223 			waddch(win->x_win, *text + 0100);
    224 		}
    225 		else
    226 			waddch(win->x_win, *text);
    227 	}
    228 
    229 	getyx(win->x_win, win->x_line, win->x_col);
    230 	text++;
    231 
    232 	}  /* for loop */
    233 	wrefresh(win->x_win);
    234 	return (0);
    235 }
    236 
    237 /*
    238  * Read the character at the indicated position in win
    239  */
    240 
    241 static int
    242 readwin(win, line, col)
    243 WINDOW *win;
    244 int line, col;
    245 {
    246 int oldline, oldcol;
    247 register int c;
    248 
    249 	getyx(win, oldline, oldcol);
    250 	wmove(win, line, col);
    251 	c = winch(win);
    252 	wmove(win, oldline, oldcol);
    253 	return (c);
    254 }
    255 
    256 /*
    257  * Scroll a window, blanking out the line following the current line
    258  * so that the current position is obvious
    259  */
    260 
    261 static void
    262 xscroll(win, flag)
    263 register xwin_t *win;
    264 int flag;
    265 {
    266 	if (flag == -1) {
    267 		wmove(win->x_win, 0, 0);
    268 		win->x_line = 0;
    269 		win->x_col = 0;
    270 		return;
    271 	}
    272 	win->x_line = (win->x_line + 1) % win->x_nlines;
    273 	win->x_col = 0;
    274 	wmove(win->x_win, win->x_line, win->x_col);
    275 	wclrtoeol(win->x_win);
    276 	wmove(win->x_win, (win->x_line + 1) % win->x_nlines, win->x_col);
    277 	wclrtoeol(win->x_win);
    278 	wmove(win->x_win, win->x_line, win->x_col);
    279 }
    280