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 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 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 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 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