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 /*
41 * The window 'manager', initializes curses and handles the actual
42 * displaying of text
43 */
44
45 #include "talk.h"
46 #include <ctype.h>
47
48 static int readwin(WINDOW *, int, int);
49 static void xscroll(register xwin_t *, int);
50
51 xwin_t my_win;
52 xwin_t rem_win;
53 WINDOW *line_win;
54
55 int curses_initialized = 0;
56
57 /*
58 * max HAS to be a function, it is called with
59 * a argument of the form --foo at least once.
60 */
61
62 static int
max(a,b)63 max(a, b)
64 int a, b;
65 {
66 if (a > b) {
67 return (a);
68 } else {
69 return (b);
70 }
71 }
72
73 /*
74 * Display some text on somebody's window, processing some control
75 * characters while we are at it.
76 */
77
78 int
display(win,text,size)79 display(win, text, size)
80 register xwin_t *win;
81 register char *text;
82 int size;
83 {
84 register int i;
85 int mb_cur_max = MB_CUR_MAX;
86
87 for (i = 0; i < size; i++) {
88 int itext;
89
90 if (*text == '\n'|| *text == '\r') {
91 xscroll(win, 0);
92 text++;
93 continue;
94 }
95
96 /* erase character */
97
98 if (*text == win->cerase) {
99 wmove(win->x_win, win->x_line, max(--win->x_col, 0));
100 getyx(win->x_win, win->x_line, win->x_col);
101 waddch(win->x_win, ' ');
102 wmove(win->x_win, win->x_line, win->x_col);
103 getyx(win->x_win, win->x_line, win->x_col);
104 text++;
105 continue;
106 }
107 /*
108 * On word erase search backwards until we find
109 * the beginning of a word or the beginning of
110 * the line.
111 */
112 if (*text == win->werase) {
113 int endcol, xcol, i, c;
114
115 endcol = win->x_col;
116 xcol = endcol - 1;
117 while (xcol >= 0) {
118 c = readwin(win->x_win, win->x_line, xcol);
119 if (c != ' ')
120 break;
121 xcol--;
122 }
123 while (xcol >= 0) {
124 c = readwin(win->x_win, win->x_line, xcol);
125 if (c == ' ')
126 break;
127 xcol--;
128 }
129 wmove(win->x_win, win->x_line, xcol + 1);
130 for (i = xcol + 1; i < endcol; i++)
131 waddch(win->x_win, ' ');
132 wmove(win->x_win, win->x_line, xcol + 1);
133 getyx(win->x_win, win->x_line, win->x_col);
134 continue;
135 }
136 /* line kill */
137 if (*text == win->kill) {
138 wmove(win->x_win, win->x_line, 0);
139 wclrtoeol(win->x_win);
140 getyx(win->x_win, win->x_line, win->x_col);
141 text++;
142 continue;
143 }
144 if (*text == '\f') {
145 if (win == &my_win)
146 wrefresh(curscr);
147 text++;
148 continue;
149 }
150 /* EOF character */
151 if (*text == '\004') {
152 quit();
153 }
154
155 /* typing alert character will alert recipient's terminal */
156
157 if (*text == '\007') {
158 beep();
159 continue;
160 }
161
162 /* check for wrap around */
163 if (win->x_col == COLS-1) {
164 xscroll(win, 0);
165 }
166
167 /*
168 * Handle the multibyte case
169 * We print '?' for nonprintable widechars.
170 */
171
172 if (mb_cur_max > 1 && mblen(text, mb_cur_max) > 1) {
173 wchar_t wc;
174 int len;
175
176 len = mbtowc(&wc, text, mb_cur_max);
177
178 if (iswprint(wc) || iswspace(wc)) {
179 /* its printable, put out the bytes */
180 do {
181 if (win->x_col == COLS-1) /* wraparound */
182 xscroll(win, 0);
183 waddch(win->x_win, *text++);
184 getyx(win->x_win, win->x_line, win->x_col);
185 } while (--len > 0);
186 continue;
187 }
188 /*
189 * otherwise, punt and print a question mark.
190 */
191 text += len;
192 waddch(win->x_win, '?');
193 getyx(win->x_win, win->x_line, win->x_col);
194 continue;
195 }
196
197 itext = (unsigned int) *text;
198 if (isprint(itext) || *text == ' ' || *text == '\t' ||
199 *text == '\013' || *text == '\007' /* bell */) {
200 waddch(win->x_win, *text);
201 } else {
202
203 if (!isascii(*text)) {
204 /* check for wrap around */
205 if (win->x_col == COLS-3) {
206 xscroll(win, 0);
207 }
208 waddch(win->x_win, 'M');
209 waddch(win->x_win, '-');
210 *text = toascii(*text);
211 }
212 if (iscntrl(*text)) {
213
214 /* check for wrap around */
215 getyx(win->x_win, win->x_line, win->x_col);
216 if (win->x_col == COLS-2) {
217 xscroll(win, 0);
218 }
219
220 waddch(win->x_win, '^');
221 waddch(win->x_win, *text + 0100);
222 }
223 else
224 waddch(win->x_win, *text);
225 }
226
227 getyx(win->x_win, win->x_line, win->x_col);
228 text++;
229
230 } /* for loop */
231 wrefresh(win->x_win);
232 return (0);
233 }
234
235 /*
236 * Read the character at the indicated position in win
237 */
238
239 static int
readwin(win,line,col)240 readwin(win, line, col)
241 WINDOW *win;
242 int line, col;
243 {
244 int oldline, oldcol;
245 register int c;
246
247 getyx(win, oldline, oldcol);
248 wmove(win, line, col);
249 c = winch(win);
250 wmove(win, oldline, oldcol);
251 return (c);
252 }
253
254 /*
255 * Scroll a window, blanking out the line following the current line
256 * so that the current position is obvious
257 */
258
259 static void
xscroll(win,flag)260 xscroll(win, flag)
261 register xwin_t *win;
262 int flag;
263 {
264 if (flag == -1) {
265 wmove(win->x_win, 0, 0);
266 win->x_line = 0;
267 win->x_col = 0;
268 return;
269 }
270 win->x_line = (win->x_line + 1) % win->x_nlines;
271 win->x_col = 0;
272 wmove(win->x_win, win->x_line, win->x_col);
273 wclrtoeol(win->x_win);
274 wmove(win->x_win, (win->x_line + 1) % win->x_nlines, win->x_col);
275 wclrtoeol(win->x_win);
276 wmove(win->x_win, win->x_line, win->x_col);
277 }
278