1/**************************************************************************** 2 * Copyright (c) 2003-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: demo_forms.c,v 1.30 2008/10/18 20:38:20 tom Exp $ 30 * 31 * Demonstrate a variety of functions from the form library. 32 * Thomas Dickey - 2003/4/26 33 */ 34/* 35TYPE_ENUM - 36TYPE_REGEXP - 37dup_field - 38field_init - 39field_just - 40field_term - 41form_init - 42form_opts - 43form_opts_off - 44form_opts_on - 45form_request_by_name - 46form_term - 47form_userptr - 48free_fieldtype - 49link_field - 50link_fieldtype - 51move_field - 52new_page - 53pos_form_cursor - 54set_field_init - 55set_field_term - 56set_fieldtype_arg - 57set_fieldtype_choice - 58set_form_fields - 59set_form_init - 60set_form_opts - 61set_form_page - 62set_form_term - 63set_form_userptr - 64set_max_field - 65*/ 66 67#include <test.priv.h> 68 69#if USE_LIBFORM 70 71#include <edit_field.h> 72 73static int d_option = 0; 74static int j_value = 0; 75static int m_value = 0; 76static int o_value = 0; 77static char *t_value = 0; 78 79static FIELD * 80make_label(int frow, int fcol, NCURSES_CONST char *label) 81{ 82 FIELD *f = new_field(1, (int) strlen(label), frow, fcol, 0, 0); 83 84 if (f) { 85 set_field_buffer(f, 0, label); 86 set_field_opts(f, (int) (field_opts(f) & ~O_ACTIVE)); 87 } 88 return (f); 89} 90 91/* 92 * Define each field with an extra one, for reflecting "actual" text. 93 */ 94static FIELD * 95make_field(int frow, int fcol, int rows, int cols) 96{ 97 FIELD *f = new_field(rows, cols, frow, fcol, o_value, 1); 98 99 if (f) { 100 set_field_back(f, A_UNDERLINE); 101 /* 102 * If -j and -d options are combined, -j loses. It is documented in 103 * "Character User Interface Programming", page 12-15 that setting 104 * O_STATIC off makes the form library ignore justification. 105 */ 106 set_field_just(f, j_value); 107 if (d_option) { 108 if (has_colors()) { 109 set_field_fore(f, COLOR_PAIR(2)); 110 set_field_back(f, A_UNDERLINE | COLOR_PAIR(3)); 111 } else { 112 set_field_fore(f, A_BOLD); 113 } 114 /* 115 * The field_opts_off() call dumps core with Solaris curses, 116 * but that is a known bug in Solaris' form library -TD 117 */ 118 field_opts_off(f, O_STATIC); 119 set_max_field(f, m_value); 120 } 121 122 /* 123 * The userptr is used in edit_field.c's inactive_field(). 124 */ 125 set_field_userptr(f, (void *) (long) field_back(f)); 126 if (t_value) 127 set_field_buffer(f, 0, t_value); 128 } 129 return (f); 130} 131 132static void 133display_form(FORM * f) 134{ 135 WINDOW *w; 136 int rows, cols; 137 138 scale_form(f, &rows, &cols); 139 140 /* 141 * Put the form at the upper-left corner of the display, with just a box 142 * around it. 143 */ 144 if ((w = newwin(rows + 2, cols + 4, 0, 0)) != (WINDOW *) 0) { 145 set_form_win(f, w); 146 set_form_sub(f, derwin(w, rows, cols, 1, 2)); 147 box(w, 0, 0); 148 keypad(w, TRUE); 149 } 150 151 if (post_form(f) != E_OK) 152 wrefresh(w); 153} 154 155static void 156erase_form(FORM * f) 157{ 158 WINDOW *w = form_win(f); 159 WINDOW *s = form_sub(f); 160 161 unpost_form(f); 162 werase(w); 163 wrefresh(w); 164 delwin(s); 165 delwin(w); 166} 167 168static void 169show_insert_mode(bool insert_mode) 170{ 171 mvaddstr(5, 57, (insert_mode 172 ? "form_status: insert " 173 : "form_status: overlay")); 174} 175 176#define O_SELECTABLE (O_ACTIVE | O_VISIBLE) 177 178static FIELD * 179another_field(FORM * form, FIELD * field) 180{ 181 FIELD **f = form_fields(form); 182 FIELD *result = 0; 183 int n; 184 185 for (n = 0; f[n] != 0; ++n) { 186 if (f[n] != field) { 187 result = f[n]; 188 field_opts_on(result, O_SELECTABLE); 189 break; 190 } 191 } 192 return result; 193} 194 195static int 196my_form_driver(FORM * form, int c) 197{ 198 static bool insert_mode = TRUE; 199 FIELD *field; 200 201 switch (c) { 202 case MY_QUIT: 203 if (form_driver(form, REQ_VALIDATION) == E_OK) 204 return (TRUE); 205 break; 206 case MY_HELP: 207 help_edit_field(); 208 break; 209 case MY_EDT_MODE: 210 if ((field = current_field(form)) != 0) { 211 set_current_field(form, another_field(form, field)); 212 if (field_opts(field) & O_EDIT) { 213 field_opts_off(field, O_EDIT); 214 set_field_status(field, 0); 215 } else { 216 field_opts_on(field, O_EDIT); 217 } 218 set_current_field(form, field); 219 } 220 break; 221 case MY_INS_MODE: 222 /* there should be a form_status() function, but there is none */ 223 if (!insert_mode) { 224 if (form_driver(form, REQ_INS_MODE) == E_OK) { 225 insert_mode = TRUE; 226 } 227 } else { 228 if (form_driver(form, REQ_OVL_MODE) == E_OK) { 229 insert_mode = FALSE; 230 } 231 } 232 show_insert_mode(insert_mode); 233 refresh(); 234 break; 235 default: 236 beep(); 237 break; 238 } 239 return (FALSE); 240} 241 242static void 243show_current_field(WINDOW *win, FORM * form) 244{ 245 FIELD *field; 246 FIELDTYPE *type; 247 char *buffer; 248 int nbuf; 249 int field_rows, field_cols, field_max; 250 251 if (has_colors()) { 252 wbkgd(win, COLOR_PAIR(1)); 253 } 254 werase(win); 255 wprintw(win, "Cursor: %d,%d", form->currow, form->curcol); 256 if (data_ahead(form)) 257 waddstr(win, " ahead"); 258 if (data_behind(form)) 259 waddstr(win, " behind"); 260 waddch(win, '\n'); 261 if ((field = current_field(form)) != 0) { 262 wprintw(win, "Page %d%s, Field %d/%d%s:", 263 form_page(form), 264 new_page(field) ? "*" : "", 265 field_index(field), field_count(form), 266 field_arg(field) ? "(arg)" : ""); 267 if ((type = field_type(field)) != 0) { 268 if (type == TYPE_ALNUM) 269 waddstr(win, "ALNUM"); 270 else if (type == TYPE_ALPHA) 271 waddstr(win, "ALPHA"); 272 else if (type == TYPE_ENUM) 273 waddstr(win, "ENUM"); 274 else if (type == TYPE_INTEGER) 275 waddstr(win, "INTEGER"); 276#ifdef NCURSES_VERSION 277 else if (type == TYPE_IPV4) 278 waddstr(win, "IPV4"); 279#endif 280 else if (type == TYPE_NUMERIC) 281 waddstr(win, "NUMERIC"); 282 else if (type == TYPE_REGEXP) 283 waddstr(win, "REGEXP"); 284 else 285 waddstr(win, "other"); 286 } 287 288 if (field_opts(field) & O_EDIT) 289 waddstr(win, " editable"); 290 else 291 waddstr(win, " readonly"); 292 293 if (field_status(field)) 294 waddstr(win, " modified"); 295 296 if (dynamic_field_info(field, &field_rows, &field_cols, &field_max) 297 != ERR) { 298 wprintw(win, " size %dx%d (max %d)", 299 field_rows, field_cols, field_max); 300 } 301 302 waddch(win, ' '); 303 wattrset(win, field_fore(field)); 304 waddstr(win, "fore"); 305 wattroff(win, field_fore(field)); 306 307 waddch(win, '/'); 308 309 wattrset(win, field_back(field)); 310 waddstr(win, "back"); 311 wattroff(win, field_back(field)); 312 313 wprintw(win, ", pad '%c'", 314 field_pad(field)); 315 316 waddstr(win, "\n"); 317 for (nbuf = 0; nbuf <= 2; ++nbuf) { 318 if ((buffer = field_buffer(field, nbuf)) != 0) { 319 wprintw(win, "buffer %d:", nbuf); 320 wattrset(win, A_REVERSE); 321 waddstr(win, buffer); 322 wattroff(win, A_REVERSE); 323 waddstr(win, "\n"); 324 } 325 } 326 } 327 wrefresh(win); 328} 329 330static void 331demo_forms(void) 332{ 333 WINDOW *w; 334 FORM *form; 335 FIELD *f[100]; /* FIXME memset to zero */ 336 int finished = 0, c; 337 unsigned n = 0; 338 int pg; 339 WINDOW *also; 340 341#ifdef NCURSES_MOUSE_VERSION 342 mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0); 343#endif 344 345 help_edit_field(); 346 347 mvaddstr(4, 57, "Forms Entry Test"); 348 show_insert_mode(TRUE); 349 350 refresh(); 351 352 /* describe the form */ 353 memset(f, 0, sizeof(f)); 354 for (pg = 0; pg < 4; ++pg) { 355 char label[80]; 356 sprintf(label, "Sample Form Page %d", pg + 1); 357 f[n++] = make_label(0, 15, label); 358 set_new_page(f[n - 1], TRUE); 359 360 switch (pg) { 361 default: 362 f[n++] = make_label(2, 0, "Last Name"); 363 f[n++] = make_field(3, 0, 1, 18); 364 set_field_type(f[n - 1], TYPE_ALPHA, 1); 365 366 f[n++] = make_label(2, 20, "First Name"); 367 f[n++] = make_field(3, 20, 1, 12); 368 set_field_type(f[n - 1], TYPE_ALPHA, 1); 369 370 f[n++] = make_label(2, 34, "Middle Name"); 371 f[n++] = make_field(3, 34, 1, 12); 372 set_field_type(f[n - 1], TYPE_ALPHA, 1); 373 break; 374 case 1: 375 f[n++] = make_label(2, 0, "Last Name"); 376 f[n++] = make_field(3, 0, 1, 18); 377 set_field_type(f[n - 1], TYPE_ALPHA, 1); 378 379 f[n++] = make_label(2, 20, "First Name"); 380 f[n++] = make_field(3, 20, 1, 12); 381 set_field_type(f[n - 1], TYPE_ALPHA, 1); 382 383 f[n++] = make_label(2, 34, "MI"); 384 f[n++] = make_field(3, 34, 1, 1); 385 set_field_pad(f[n - 1], '?'); 386 set_field_type(f[n - 1], TYPE_ALPHA, 1); 387 break; 388 case 2: 389 f[n++] = make_label(2, 0, "Host Name"); 390 f[n++] = make_field(3, 0, 1, 18); 391 set_field_type(f[n - 1], TYPE_ALNUM, 1); 392 393#ifdef NCURSES_VERSION 394 f[n++] = make_label(2, 20, "IP Address"); 395 f[n++] = make_field(3, 20, 1, 12); 396 set_field_type(f[n - 1], TYPE_IPV4, 1); 397#endif 398 399 break; 400 401 case 3: 402 f[n++] = make_label(2, 0, "Four digits"); 403 f[n++] = make_field(3, 0, 1, 18); 404 set_field_type(f[n - 1], TYPE_INTEGER, 4, 0, 0); 405 406 f[n++] = make_label(2, 20, "Numeric"); 407 f[n++] = make_field(3, 20, 1, 12); 408 set_field_type(f[n - 1], TYPE_NUMERIC, 3, -10000.0, 100000000.0); 409 410 break; 411 } 412 413 f[n++] = make_label(5, 0, "Comments"); 414 f[n++] = make_field(6, 0, 4, 46); 415 set_field_buffer(f[n - 1], 0, "HELLO\nWORLD!"); 416 set_field_buffer(f[n - 1], 1, "Hello\nWorld!"); 417 } 418 419 f[n++] = (FIELD *) 0; 420 421 if ((form = new_form(f)) != 0) { 422 423 display_form(form); 424 425 w = form_win(form); 426 also = newwin(getmaxy(stdscr) - getmaxy(w), COLS, getmaxy(w), 0); 427 show_current_field(also, form); 428 429 while (!finished) { 430 switch (edit_field(form, &c)) { 431 case E_OK: 432 break; 433 case E_UNKNOWN_COMMAND: 434 finished = my_form_driver(form, c); 435 break; 436 default: 437 beep(); 438 break; 439 } 440 show_current_field(also, form); 441 } 442 443 erase_form(form); 444 445 free_form(form); 446 } 447 for (c = 0; f[c] != 0; c++) 448 free_field(f[c]); 449 noraw(); 450 nl(); 451 452#ifdef NCURSES_MOUSE_VERSION 453 mousemask(0, (mmask_t *) 0); 454#endif 455} 456 457static void 458usage(void) 459{ 460 static const char *tbl[] = 461 { 462 "Usage: demo_forms [options]" 463 ,"" 464 ," -d make fields dynamic" 465 ," -j value justify (1=left, 2=center, 3=right)" 466 ," -m value set maximum size of dynamic fields" 467 ," -o value specify number of offscreen rows in new_field()" 468 ," -t value specify text to fill fields initially" 469 }; 470 unsigned int j; 471 for (j = 0; j < SIZEOF(tbl); ++j) 472 fprintf(stderr, "%s\n", tbl[j]); 473 exit(EXIT_FAILURE); 474} 475 476int 477main(int argc, char *argv[]) 478{ 479 int ch; 480 481 setlocale(LC_ALL, ""); 482 483 while ((ch = getopt(argc, argv, "dj:m:o:t:")) != -1) { 484 switch (ch) { 485 case 'd': 486 d_option = TRUE; 487 break; 488 case 'j': 489 j_value = atoi(optarg); 490 if (j_value < NO_JUSTIFICATION 491 || j_value > JUSTIFY_RIGHT) 492 usage(); 493 break; 494 case 'm': 495 m_value = atoi(optarg); 496 break; 497 case 'o': 498 o_value = atoi(optarg); 499 break; 500 case 't': 501 t_value = optarg; 502 break; 503 default: 504 usage(); 505 506 } 507 } 508 509 initscr(); 510 cbreak(); 511 noecho(); 512 raw(); 513 nonl(); /* lets us read ^M's */ 514 intrflush(stdscr, FALSE); 515 keypad(stdscr, TRUE); 516 517 if (has_colors()) { 518 start_color(); 519 init_pair(1, COLOR_WHITE, COLOR_BLUE); 520 init_pair(2, COLOR_GREEN, COLOR_BLACK); 521 init_pair(3, COLOR_CYAN, COLOR_BLACK); 522 bkgd(COLOR_PAIR(1)); 523 refresh(); 524 } 525 526 demo_forms(); 527 528 endwin(); 529 ExitProgram(EXIT_SUCCESS); 530} 531#else 532int 533main(void) 534{ 535 printf("This program requires the curses form library\n"); 536 ExitProgram(EXIT_FAILURE); 537} 538#endif 539