1 /* $NetBSD: getstr.c,v 1.16 2002/01/02 10:38:27 blymn Exp $ */ 2 3 /* 4 * Copyright (c) 1981, 1993, 1994 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include <assert.h> 37 #include <sys/cdefs.h> 38 #ifndef lint 39 #if 0 40 static char sccsid[] = "@(#)getstr.c 8.2 (Berkeley) 5/4/94"; 41 #else 42 __RCSID("$NetBSD: getstr.c,v 1.16 2002/01/02 10:38:27 blymn Exp $"); 43 #endif 44 #endif /* not lint */ 45 46 #include "curses.h" 47 #include "curses_private.h" 48 49 #ifndef _CURSES_USE_MACROS 50 51 /* 52 * getnstr -- 53 * Get a string (of maximum n) characters from stdscr starting at 54 * (cury, curx). 55 */ 56 int 57 getnstr(char *str, int n) 58 { 59 return wgetnstr(stdscr, str, n); 60 } 61 62 /* 63 * getstr -- 64 * Get a string from stdscr starting at (cury, curx). 65 */ 66 __warn_references(getstr, 67 "warning: this program uses getstr(), which is unsafe.") 68 int 69 getstr(char *str) 70 { 71 return wgetstr(stdscr, str); 72 } 73 74 /* 75 * mvgetnstr -- 76 * Get a string (of maximum n) characters from stdscr starting at (y, x). 77 */ 78 int 79 mvgetnstr(int y, int x, char *str, int n) 80 { 81 return mvwgetnstr(stdscr, y, x, str, n); 82 } 83 84 /* 85 * mvgetstr -- 86 * Get a string from stdscr starting at (y, x). 87 */ 88 __warn_references(mvgetstr, 89 "warning: this program uses mvgetstr(), which is unsafe.") 90 int 91 mvgetstr(int y, int x, char *str) 92 { 93 return mvwgetstr(stdscr, y, x, str); 94 } 95 96 /* 97 * mvwgetnstr -- 98 * Get a string (of maximum n) characters from the given window starting 99 * at (y, x). 100 */ 101 int 102 mvwgetnstr(WINDOW *win, int y, int x, char *str, int n) 103 { 104 if (wmove(win, y, x) == ERR) 105 return ERR; 106 107 return wgetnstr(win, str, n); 108 } 109 110 /* 111 * mvwgetstr -- 112 * Get a string from the given window starting at (y, x). 113 */ 114 __warn_references(mvgetstr, 115 "warning: this program uses mvgetstr(), which is unsafe.") 116 int 117 mvwgetstr(WINDOW *win, int y, int x, char *str) 118 { 119 if (wmove(win, y, x) == ERR) 120 return ERR; 121 122 return wgetstr(win, str); 123 } 124 125 #endif 126 127 /* 128 * wgetstr -- 129 * Get a string starting at (cury, curx). 130 */ 131 __warn_references(wgetstr, 132 "warning: this program uses wgetstr(), which is unsafe.") 133 int 134 wgetstr(WINDOW *win, char *str) 135 { 136 return __wgetnstr(win, str, -1); 137 } 138 139 /* 140 * wgetnstr -- 141 * Get a string starting at (cury, curx). 142 * Note that n < 2 means that we return ERR (SUSv2 specification). 143 */ 144 int 145 wgetnstr(WINDOW *win, char *str, int n) 146 { 147 if (n < 1) 148 return (ERR); 149 if (n == 1) { 150 str[0] = '\0'; 151 return (ERR); 152 } 153 return __wgetnstr(win, str, n); 154 } 155 156 /* 157 * __wgetnstr -- 158 * The actual implementation. 159 * Note that we include a trailing '\0' for safety, so str will contain 160 * at most n - 1 other characters. 161 * XXX: character deletion from screen is based on how the characters 162 * are displayed by wgetch(). 163 */ 164 int 165 __wgetnstr(WINDOW *win, char *str, int n) 166 { 167 char *ostr, ec, kc; 168 int c, oldx, remain; 169 170 ostr = str; 171 ec = erasechar(); 172 kc = killchar(); 173 oldx = win->curx; 174 _DIAGASSERT(n == -1 || n > 1); 175 remain = n - 1; 176 177 while ((c = wgetch(win)) != ERR && c != '\n' && c != '\r') { 178 #ifdef DEBUG 179 __CTRACE("__wgetnstr: win %0.2o, char 0x%x, remain %d\n", win, 180 c, remain); 181 #endif 182 *str = c; 183 touchline(win, win->cury, 1); 184 if (c == ec || c == KEY_BACKSPACE || c == KEY_LEFT) { 185 *str = '\0'; 186 if (str != ostr) { 187 if ((char) c == ec) { 188 mvwaddch(win, win->cury, win->curx, 189 ' '); 190 wmove(win, win->cury, win->curx - 1); 191 } 192 if (c == KEY_BACKSPACE || c == KEY_LEFT) { 193 /* getch() displays the key sequence */ 194 mvwaddch(win, win->cury, win->curx - 1, 195 ' '); 196 mvwaddch(win, win->cury, win->curx - 2, 197 ' '); 198 wmove(win, win->cury, win->curx - 1); 199 } 200 str--; 201 if (n != -1) { 202 /* We're counting chars */ 203 remain++; 204 } 205 } else { /* str == ostr */ 206 if (c == KEY_BACKSPACE || c == KEY_LEFT) 207 /* getch() displays the other keys */ 208 mvwaddch(win, win->cury, win->curx - 1, 209 ' '); 210 wmove(win, win->cury, oldx); 211 } 212 } else if (c == kc) { 213 *str = '\0'; 214 if (str != ostr) { 215 /* getch() displays the kill character */ 216 mvwaddch(win, win->cury, win->curx - 1, ' '); 217 /* Clear the characters from screen and str */ 218 while (str != ostr) { 219 mvwaddch(win, win->cury, win->curx - 1, 220 ' '); 221 wmove(win, win->cury, win->curx - 1); 222 str--; 223 if (n != -1) 224 /* We're counting chars */ 225 remain++; 226 } 227 mvwaddch(win, win->cury, win->curx - 1, ' '); 228 wmove(win, win->cury, win->curx - 1); 229 } else 230 /* getch() displays the kill character */ 231 mvwaddch(win, win->cury, oldx, ' '); 232 wmove(win, win->cury, oldx); 233 } else if (c >= KEY_MIN && c <= KEY_MAX) { 234 /* getch() displays these characters */ 235 mvwaddch(win, win->cury, win->curx - 1, ' '); 236 wmove(win, win->cury, win->curx - 1); 237 } else { 238 if (remain) { 239 str++; 240 remain--; 241 } else { 242 mvwaddch(win, win->cury, win->curx - 1, ' '); 243 wmove(win, win->cury, win->curx - 1); 244 } 245 } 246 } 247 248 if (c == ERR) { 249 *str = '\0'; 250 return (ERR); 251 } 252 *str = '\0'; 253 return (OK); 254 } 255