1/**************************************************************************** 2 * Copyright (c) 2007,2008 Free Software Foundation, Inc. * 3 * * 4 * Permission is hereby granted, free of charge, to any person obtaining a * 5 * copy of this software and associated documentation files (the * 6 * "Software"), to deal in the Software without restriction, including * 7 * without limitation the rights to use, copy, modify, merge, publish, * 8 * distribute, distribute with modifications, sublicense, and/or sell * 9 * copies of the Software, and to permit persons to whom the Software is * 10 * furnished to do so, subject to the following conditions: * 11 * * 12 * The above copyright notice and this permission notice shall be included * 13 * in all copies or substantial portions of the Software. * 14 * * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22 * * 23 * Except as contained in this notice, the name(s) of the above copyright * 24 * holders shall not be used in advertising or otherwise to promote the * 25 * sale, use or other dealings in this Software without prior written * 26 * authorization. * 27 ****************************************************************************/ 28/* 29 * $Id: test_getstr.c,v 1.8 2008/02/09 18:09:35 tom Exp $ 30 * 31 * Author: Thomas E Dickey 32 * 33 * Demonstrate the getstr functions from the curses library. 34 35 int getstr(char *str); 36 int getnstr(char *str, int n); 37 int wgetstr(WINDOW *win, char *str); 38 int wgetnstr(WINDOW *win, char *str, int n); 39 int mvgetstr(int y, int x, char *str); 40 int mvwgetstr(WINDOW *win, int y, int x, char *str); 41 int mvgetnstr(int y, int x, char *str, int n); 42 int mvwgetnstr(WINDOW *, int y, int x, char *str, int n); 43 */ 44 45#include <test.priv.h> 46 47#if HAVE_CHGAT 48/* Solaris SVr4 curses lacks wchgat, mvgetnstr, mvwgetnstr */ 49 50#define BASE_Y 6 51#define MAX_COLS 1024 52 53typedef enum { 54 eGetStr = 0, 55 eGetNStr, 56 eMvGetStr, 57 eMvGetNStr, 58 eMaxFlavor 59} Flavors; 60 61static bool 62Quit(int ch) 63{ 64 return (ch == ERR || ch == 'q' || ch == QUIT || ch == ESCAPE); 65} 66 67static int 68Remainder(WINDOW *txtwin) 69{ 70 int result = getmaxx(txtwin) - getcurx(txtwin); 71 return (result > 0) ? result : 0; 72} 73 74/* 75 * Show a highlighted line in the place where input will happen. 76 */ 77static void 78ShowPrompt(WINDOW *txtwin, int limit) 79{ 80 wchgat(txtwin, limit, A_REVERSE, 0, NULL); 81 wnoutrefresh(txtwin); 82} 83 84static void 85MovePrompt(WINDOW *txtwin, int limit, int y, int x) 86{ 87 wchgat(txtwin, Remainder(txtwin), A_NORMAL, 0, NULL); 88 wmove(txtwin, y, x); 89 ShowPrompt(txtwin, limit); 90} 91 92static int 93ShowFlavor(WINDOW *strwin, WINDOW *txtwin, int flavor, int limit) 94{ 95 const char *name = "?"; 96 bool limited = FALSE; 97 bool wins = (txtwin != stdscr); 98 int result; 99 100 switch (flavor) { 101 case eGetStr: 102 name = wins ? "wgetstr" : "getstr"; 103 break; 104 case eGetNStr: 105 limited = TRUE; 106 name = wins ? "wgetnstr" : "getnstr"; 107 break; 108 case eMvGetStr: 109 name = wins ? "mvwgetstr" : "mvgetstr"; 110 break; 111 case eMvGetNStr: 112 limited = TRUE; 113 name = wins ? "mvwgetnstr" : "mvgetnstr"; 114 break; 115 case eMaxFlavor: 116 break; 117 } 118 119 wmove(strwin, 0, 0); 120 werase(strwin); 121 122 if (limited) { 123 wprintw(strwin, "%s(%d):", name, limit); 124 } else { 125 wprintw(strwin, "%s:", name); 126 } 127 result = limited ? limit : Remainder(txtwin); 128 ShowPrompt(txtwin, result); 129 130 wnoutrefresh(strwin); 131 return result; 132} 133 134static int 135test_getstr(int level, char **argv, WINDOW *strwin) 136{ 137 WINDOW *txtbox = 0; 138 WINDOW *txtwin = 0; 139 FILE *fp; 140 int ch; 141 int rc; 142 int txt_x = 0, txt_y = 0; 143 int base_y; 144 int flavor = 0; 145 int limit = getmaxx(strwin) - 5; 146 int actual; 147 148 char buffer[MAX_COLS]; 149 150 if (argv[level] == 0) { 151 beep(); 152 return FALSE; 153 } 154 155 if (level > 1) { 156 txtbox = newwin(LINES - BASE_Y, COLS - level, BASE_Y, level); 157 box(txtbox, 0, 0); 158 wnoutrefresh(txtbox); 159 160 txtwin = derwin(txtbox, 161 getmaxy(txtbox) - 2, 162 getmaxx(txtbox) - 2, 163 1, 1); 164 base_y = 0; 165 } else { 166 txtwin = stdscr; 167 base_y = BASE_Y; 168 } 169 170 keypad(txtwin, TRUE); /* enable keyboard mapping */ 171 (void) cbreak(); /* take input chars one at a time, no wait for \n */ 172 (void) noecho(); /* don't echo input */ 173 174 txt_y = base_y; 175 txt_x = 0; 176 wmove(txtwin, txt_y, txt_x); 177 178 if ((fp = fopen(argv[level], "r")) != 0) { 179 while ((ch = fgetc(fp)) != EOF) { 180 if (waddch(txtwin, UChar(ch)) != OK) { 181 break; 182 } 183 } 184 fclose(fp); 185 } else { 186 wprintw(txtwin, "Cannot open:\n%s", argv[1]); 187 } 188 189 wmove(txtwin, txt_y, txt_x); 190 actual = ShowFlavor(strwin, txtwin, flavor, limit); 191 while (!Quit(ch = mvwgetch(txtwin, txt_y, txt_x))) { 192 switch (ch) { 193 case KEY_DOWN: 194 case 'j': 195 if (txt_y < getmaxy(txtwin) - 1) { 196 MovePrompt(txtwin, actual, ++txt_y, txt_x); 197 } else { 198 beep(); 199 } 200 break; 201 case KEY_UP: 202 case 'k': 203 if (txt_y > base_y) { 204 MovePrompt(txtwin, actual, --txt_y, txt_x); 205 } else { 206 beep(); 207 } 208 break; 209 case KEY_LEFT: 210 case 'h': 211 if (txt_x > 0) { 212 MovePrompt(txtwin, actual, txt_y, --txt_x); 213 } else { 214 beep(); 215 } 216 break; 217 case KEY_RIGHT: 218 case 'l': 219 if (txt_x < getmaxx(txtwin) - 1) { 220 MovePrompt(txtwin, actual, txt_y, ++txt_x); 221 } else { 222 beep(); 223 } 224 break; 225 226 case 'w': 227 test_getstr(level + 1, argv, strwin); 228 if (txtbox != 0) { 229 touchwin(txtbox); 230 wnoutrefresh(txtbox); 231 } else { 232 touchwin(txtwin); 233 wnoutrefresh(txtwin); 234 } 235 break; 236 237 case '-': 238 if (limit > 0) { 239 actual = ShowFlavor(strwin, txtwin, flavor, --limit); 240 MovePrompt(txtwin, actual, txt_y, txt_x); 241 } else { 242 beep(); 243 } 244 break; 245 246 case '+': 247 actual = ShowFlavor(strwin, txtwin, flavor, ++limit); 248 MovePrompt(txtwin, actual, txt_y, txt_x); 249 break; 250 251 case '<': 252 if (flavor > 0) { 253 actual = ShowFlavor(strwin, txtwin, --flavor, limit); 254 MovePrompt(txtwin, actual, txt_y, txt_x); 255 } else { 256 beep(); 257 } 258 break; 259 260 case '>': 261 if (flavor + 1 < eMaxFlavor) { 262 actual = ShowFlavor(strwin, txtwin, ++flavor, limit); 263 MovePrompt(txtwin, actual, txt_y, txt_x); 264 } else { 265 beep(); 266 } 267 break; 268 269 case ':': 270 actual = ShowFlavor(strwin, txtwin, flavor, limit); 271 *buffer = '\0'; 272 rc = ERR; 273 echo(); 274 wattrset(txtwin, A_REVERSE); 275 switch (flavor) { 276 case eGetStr: 277 if (txtwin != stdscr) { 278 wmove(txtwin, txt_y, txt_x); 279 rc = wgetstr(txtwin, buffer); 280 } else { 281 move(txt_y, txt_x); 282 rc = getstr(buffer); 283 } 284 break; 285 case eGetNStr: 286 if (txtwin != stdscr) { 287 wmove(txtwin, txt_y, txt_x); 288 rc = wgetnstr(txtwin, buffer, limit); 289 } else { 290 move(txt_y, txt_x); 291 rc = getnstr(buffer, limit); 292 } 293 break; 294 case eMvGetStr: 295 if (txtwin != stdscr) { 296 rc = mvwgetstr(txtwin, txt_y, txt_x, buffer); 297 } else { 298 rc = mvgetstr(txt_y, txt_x, buffer); 299 } 300 break; 301 case eMvGetNStr: 302 if (txtwin != stdscr) { 303 rc = mvwgetnstr(txtwin, txt_y, txt_x, buffer, limit); 304 } else { 305 rc = mvgetnstr(txt_y, txt_x, buffer, limit); 306 } 307 break; 308 case eMaxFlavor: 309 break; 310 } 311 noecho(); 312 wattrset(txtwin, A_NORMAL); 313 wprintw(strwin, "%d:%s", rc, buffer); 314 wnoutrefresh(strwin); 315 break; 316 default: 317 beep(); 318 break; 319 } 320 doupdate(); 321 } 322 if (level > 1) { 323 delwin(txtwin); 324 delwin(txtbox); 325 } 326 return TRUE; 327} 328 329int 330main(int argc, char *argv[]) 331{ 332 WINDOW *chrbox; 333 WINDOW *strwin; 334 335 setlocale(LC_ALL, ""); 336 337 if (argc < 2) { 338 fprintf(stderr, "usage: %s file\n", argv[0]); 339 return EXIT_FAILURE; 340 } 341 342 initscr(); 343 344 chrbox = derwin(stdscr, BASE_Y, COLS, 0, 0); 345 box(chrbox, 0, 0); 346 wnoutrefresh(chrbox); 347 348 strwin = derwin(chrbox, 4, COLS - 2, 1, 1); 349 350 test_getstr(1, argv, strwin); 351 352 endwin(); 353 ExitProgram(EXIT_SUCCESS); 354} 355 356#else 357int 358main(void) 359{ 360 printf("This program requires the curses chgat function\n"); 361 ExitProgram(EXIT_FAILURE); 362} 363#endif 364