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