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 1997 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 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 /*LINTLIBRARY*/ 41 42 #include <sys/types.h> 43 #include "curses_inc.h" 44 45 #define LENGTH 256 46 47 /* This routine gets a string starting at (_cury, _curx) */ 48 49 int 50 wgetstr(WINDOW *win, char *str) 51 { 52 return ((wgetnstr(win, str, LENGTH) == ERR) ? ERR : OK); 53 } 54 55 int 56 wgetnstr(WINDOW *win, char *str, int n) 57 { 58 int cpos = 0, ch; 59 int nbyte = 0; 60 int tbyte = 0; 61 int byte[LENGTH]; 62 int eucw, scrw; 63 int docont = 0; 64 char *cp = str; 65 int i = 0; 66 int total = 0; 67 char myerase, mykill; 68 char rownum[LENGTH], colnum[LENGTH], length[LENGTH]; 69 int doecho = SP->fl_echoit; 70 int savecb = cur_term->_fl_rawmode; 71 bool savsync, savimmed, savleave; 72 73 #ifdef DEBUG 74 if (outf) 75 fprintf(outf, "doecho %d, savecb %d\n", doecho, savecb); 76 #endif /* DEBUG */ 77 78 myerase = erasechar(); 79 mykill = killchar(); 80 if (!savecb) 81 (void) cbreak(); 82 83 if (doecho) { 84 SP->fl_echoit = FALSE; 85 savsync = win->_sync; 86 savimmed = win->_immed; 87 savleave = win->_leave; 88 win->_immed = win->_sync = win->_leave = FALSE; 89 (void) wrefresh(win); 90 if (n > LENGTH) 91 n = LENGTH; 92 } 93 n--; 94 95 while (nbyte < n) { 96 if (doecho && !docont) { 97 rownum[cpos] = win->_cury; 98 colnum[cpos] = win->_curx; 99 } 100 101 ch = wgetch(win); 102 if (docont) 103 goto cont; 104 105 if ((ch == ERR) || (ch == '\n') || (ch == '\r') || 106 (ch == KEY_ENTER)) 107 break; 108 if ((ch == myerase) || (ch == KEY_LEFT) || 109 (ch == KEY_BACKSPACE) || (ch == mykill)) { 110 if (cpos > 0) { 111 if (ch == mykill) { 112 i = total; 113 total = cpos = 0; 114 nbyte = 0; 115 cp = str; 116 } else { 117 cpos--; 118 cp -= byte[cpos]; 119 if (doecho) 120 total -= (i = length[cpos]); 121 } 122 if (doecho) { 123 (void) wmove(win, rownum[cpos], 124 colnum[cpos]); 125 /* Add the correct amount of blanks. */ 126 for (; i > 0; i--) 127 (void) waddch(win, ' '); 128 /* Move back after the blanks are */ 129 /* put in. */ 130 (void) wmove(win, rownum[cpos], 131 colnum[cpos]); 132 /* Update total. */ 133 (void) wrefresh(win); 134 } 135 } else 136 if (doecho) 137 (void) beep(); 138 } else if ((KEY_MIN <= ch) && (ch <= KEY_MAX)) 139 (void) beep(); 140 else { 141 cont: 142 /* LINTED */ 143 *cp++ = (char)ch; 144 if (docont) { 145 tbyte++; 146 } else if (ISMBIT(ch)) { 147 docont = 1; 148 tbyte = 1; 149 scrw = mbscrw(ch); 150 eucw = mbeucw(ch); 151 } 152 153 if (docont && (tbyte >= eucw)) { 154 docont = 0; 155 tbyte = 0; 156 if (doecho) { 157 byte[cpos] = eucw; 158 /* LINTED */ 159 length[cpos] = (char)scrw; 160 (void) wechochar(win, 161 (chtype) ch); 162 } 163 } else if (doecho) { 164 /* Add the length of the */ 165 /* character to total. */ 166 byte[cpos] = 1; 167 if (ch >= ' ') 168 length[cpos] = 1; 169 else 170 if (ch == '\t') 171 length[cpos] = TABSIZE- 172 (colnum[cpos] % 173 TABSIZE); 174 else 175 length[cpos] = 2; 176 total += length[cpos]; 177 (void) wechochar(win, (chtype) ch); 178 } 179 if (!docont) 180 cpos++; 181 nbyte++; 182 } 183 } 184 185 *cp = '\0'; 186 187 if (!savecb) 188 (void) nocbreak(); 189 /* 190 * The following code is equivalent to waddch(win, '\n') 191 * except that it does not do a wclrtoeol. 192 */ 193 if (doecho) { 194 SP->fl_echoit = TRUE; 195 win->_curx = 0; 196 if (win->_cury + 1 > win->_bmarg) 197 (void) wscrl(win, 1); 198 else 199 win->_cury++; 200 201 win->_sync = savsync; 202 win->_immed = savimmed; 203 win->_leave = savleave; 204 (void) wrefresh(win); 205 } 206 return (ch); 207 } 208