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
max(a,b)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
display(win,text,size)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
readwin(win,line,col)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
xscroll(win,flag)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