|
|
1.1 ! root 1: /* widget.c - Provides the screen and widget code */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/others/quipu/uips/sd/RCS/widget.c,v 7.0 90/06/12 13:14:07 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/others/quipu/uips/sd/RCS/widget.c,v 7.0 90/06/12 13:14:07 mrose Exp $ ! 9: */ ! 10: ! 11: /* ! 12: * $Log: widget.c,v $ ! 13: * Revision 7.0 90/06/12 13:14:07 mrose ! 14: * *** empty log message *** ! 15: * ! 16: * Revision 1.6 90/04/26 10:36:21 emsrdsm ! 17: * *** empty log message *** ! 18: * ! 19: * Revision 1.5 90/04/25 15:07:35 emsrdsm ! 20: * i) lint'ed ! 21: * ! 22: * Revision 1.4 90/04/20 17:58:05 emsrdsm ! 23: * i) no more freeing ! 24: * ! 25: * Revision 1.3 90/04/18 18:28:11 emsrdsm ! 26: * fixed i) does not move to leaves ! 27: * ii) added default mechanism described using "typeDefaults" file. ! 28: * iii) added 'sorting' to attribute display ! 29: * ! 30: * Revision 1.2 90/03/15 16:32:15 emsrdsm ! 31: * fixes i) Prints messages correctly on exit. ! 32: * ii) Added rfc822 to greybook mailbox conversion ! 33: * iii) Removed bug that caused crash if 'local_dit' undefined ! 34: * ! 35: * Revision 1.1 90/03/09 17:40:42 emsrdsm ! 36: * Initial revision ! 37: * ! 38: * Revision 1.1 90/03/09 13:38:15 emsrdsm ! 39: * Initial revision ! 40: * ! 41: */ ! 42: ! 43: ! 44: /* This file has been modified by Damanjit Mahl @ Brunel University ! 45: * on 5th January 1990. ! 46: */ ! 47: ! 48: /* ! 49: * NOTICE ! 50: * ! 51: * Acquisition, use, and distribution of this module and related ! 52: * materials are subject to the restrictions of a license agreement. ! 53: * Consult the Preface in the User's Manual for the full terms of ! 54: * this agreement. ! 55: * ! 56: */ ! 57: ! 58: ! 59: /*****************************************************************************/ ! 60: /* File: widget.c ! 61: /* Author: Paul Sharpe @ GEC Research, Hirst Research Centre. ! 62: /* Date: August 12, 1988. ! 63: /* Function: Provides the screen and widget code. ! 64: /* ! 65: /* DISCLAIMER: ! 66: /* This source file is deemed to be public domain: any person may use the ! 67: /* code in any way, on two simple provisos - ! 68: /* 1 - That this header remains in this file, ! 69: /* 2 - It is accepted that neither the author, nor the authors employees ! 70: /* accept any responsibility for the use, abuse or misuse of the ! 71: /* contained code. ! 72: /* No guarantee is made by the author to provide maintainance or up-grading ! 73: /* of this source. However, any adaptations made to this file will be viewed ! 74: /* at least with interest. ! 75: /*****************************************************************************/ ! 76: ! 77: #include <ctype.h> ! 78: #include <stdio.h> ! 79: #include <curses.h> ! 80: #include <setjmp.h> ! 81: #include <signal.h> ! 82: ! 83: #define WIDGETLIB ! 84: #include "widget.h" ! 85: ! 86: extern char *filtvalue[]; ! 87: extern unsigned int typeindx; ! 88: extern int *av_typeindx; ! 89: ! 90: char hghlghterase = FALSE; ! 91: ! 92: struct active { ! 93: int count; ! 94: WIDGET *widgets[MAXACTIVE]; ! 95: char lastindex[MAXACTIVE]; ! 96: WINDOW *text[MAXACTIVE]; ! 97: } activelist; ! 98: ! 99: char command; ! 100: ! 101: WINDOW *Text; ! 102: ! 103: int text_height; ! 104: ! 105: jmp_buf env; ! 106: ! 107: extern char * strcpy (); ! 108: ! 109: initwidgets() ! 110: { ! 111: (void) initscr(); ! 112: (void) noecho(); ! 113: (void) crmode(); ! 114: Text = stdscr; ! 115: typetoggled = 0; ! 116: activelist.count = 0; ! 117: } ! 118: ! 119: textfresh() ! 120: { ! 121: (void) wrefresh (Text); ! 122: } ! 123: ! 124: setwidgets(thesewdgts, y) ! 125: int y; ! 126: WIDGET *thesewdgts; ! 127: { ! 128: currwidgets = thesewdgts; ! 129: lowy = posnwidgets(thesewdgts, y); ! 130: Text = newwin(LINES-1-lowy, COLS-3, lowy, 3); ! 131: text_height = LINES-1-lowy; ! 132: refresh(); ! 133: (void) scrollok(Text, FALSE); ! 134: (void) wrefresh(Text); ! 135: makewidgets(thesewdgts); ! 136: activewidget(thesewdgts, Text); ! 137: rfrshwidgets(thesewdgts); ! 138: } ! 139: ! 140: int ! 141: linec() ! 142: { ! 143: return (int) LINES; ! 144: } ! 145: ! 146: int ! 147: gety() ! 148: { ! 149: int y,x; ! 150: getyx(Text,y,x); ! 151: /* Get rid of lint warning */ ! 152: x = x+1; ! 153: return y+lowy; ! 154: } ! 155: ! 156: /* Determine the positions of the widgets: return the lowest point */ ! 157: posnwidgets(thesewdgts, starty) ! 158: int starty; ! 159: WIDGET thesewdgts[]; ! 160: { ! 161: register int cnt = 0, x = 0, hght = WDGTHGHT; ! 162: ! 163: /* If no explicit position provided, put on the next level */ ! 164: if (starty < 0) ! 165: starty = lowesty(); ! 166: ! 167: /* Set the position of the widgets, as dynamically as possible */ ! 168: ! 169: while (thesewdgts[cnt].type != FINISH) { ! 170: ! 171: if (thesewdgts[cnt].type != DUMMY) { ! 172: /* If the widget is a scrollbar put on a new line */ ! 173: if (thesewdgts[cnt].type == SCROLLBAR) { ! 174: starty += WDGTHGHT; ! 175: hght = LINES - starty; ! 176: x = 0; ! 177: } else ! 178: ! 179: /* If the initial structure y-value is CRNL, put on a new line */ ! 180: if (thesewdgts[cnt].y == CRNL) { ! 181: starty += WDGTHGHT; ! 182: hght = WDGTHGHT; ! 183: x = 0; ! 184: } ! 185: ! 186: /* If we ain't got a width, make one based on the type/label-length */ ! 187: if (thesewdgts[cnt].wdth <= 0) ! 188: setwdgtwdth(&thesewdgts[cnt], x); ! 189: ! 190: /* If the widget won't fit, start a new line of widgets */ ! 191: if (x + thesewdgts[cnt].wdth > COLS) { ! 192: starty += WDGTHGHT; ! 193: x = 0; ! 194: } ! 195: thesewdgts[cnt].x = x; ! 196: thesewdgts[cnt].y = starty; ! 197: thesewdgts[cnt].hght = hght; ! 198: x += thesewdgts[cnt].wdth; ! 199: ++cnt; ! 200: } else ! 201: ++cnt; ! 202: } ! 203: return(starty); ! 204: } ! 205: ! 206: /* Create the widgets: return the number of widgets */ ! 207: makewidgets(wdgts) ! 208: WIDGET wdgts[]; ! 209: { ! 210: register int cnt = 0; ! 211: register WIDGET *wdgt; ! 212: ! 213: /* Now try to make, box and label the widget windows */ ! 214: while (wdgts[cnt].type != FINISH) { ! 215: if (wdgts[cnt].type != DUMMY) { ! 216: wdgt = &wdgts[cnt++]; ! 217: wdgt->wndw = newwin(wdgt->hght,wdgt->wdth,wdgt->y,wdgt->x); ! 218: boxwdgt(wdgt, '-', '|'); ! 219: printwdgt(wdgt); ! 220: } else ++cnt; ! 221: } ! 222: } ! 223: ! 224: /* Set a widgets width, based on the TYPE of widget and label length */ ! 225: setwdgtwdth(wdgt, currx) ! 226: int currx; ! 227: WIDGET *wdgt; ! 228: { ! 229: char expand; ! 230: register int len = -1, cnt = -1; ! 231: ! 232: if (expand = (wdgt->wdth == EXPAND)) ! 233: wdgt->wdth = COLS - currx; ! 234: ! 235: switch (wdgt->type) { ! 236: case LABEL: ! 237: len = strlen(wdgt->label) + 2; ! 238: if (wdgt->wdth < len) ! 239: if (expand) ! 240: wdgt->wdth = COLS; ! 241: else ! 242: wdgt->wdth = len; ! 243: break; ! 244: ! 245: case DIALOG: ! 246: len = strlen(wdgt->label) + 2; ! 247: if (wdgt->dstrlen > DIALOGLEN) ! 248: len += DIALOGLEN; ! 249: else ! 250: len += wdgt->dstrlen; ! 251: if (wdgt->wdth < len) { ! 252: if (expand) ! 253: wdgt->wdth = COLS; ! 254: else ! 255: wdgt->wdth = len; ! 256: } ! 257: break; ! 258: case TOGGLE: ! 259: if (wdgt->tvalues == (char **)NULL) ! 260: wdgt->wdth = strlen(wdgt->label) + 2; ! 261: else { ! 262: while(wdgt->tvalues[++cnt] != (char *)NULL) ! 263: if (strlen(wdgt->tvalues[cnt]) > len) ! 264: len = strlen(wdgt->tvalues[cnt]); ! 265: wdgt->wdth = strlen(wdgt->label) + len + 2; ! 266: } ! 267: break; ! 268: default: wdgt->wdth = strlen(wdgt->label) + 2; ! 269: break; ! 270: } ! 271: } ! 272: ! 273: /* Erase and remove the widgets, decrementing the activelist counter */ ! 274: killwidgets(thesewdgts) ! 275: WIDGET *thesewdgts; ! 276: { ! 277: register int cnt = 0; ! 278: ! 279: while (thesewdgts[cnt].type != FINISH) ! 280: if (thesewdgts[cnt].type != DUMMY) { ! 281: (void) wclear(thesewdgts[cnt].wndw); ! 282: (void) wrefresh(thesewdgts[cnt++].wndw); ! 283: } else ++cnt; ! 284: cnt = 0; ! 285: (void) wclear(Text); ! 286: (void) wrefresh(Text); ! 287: while (thesewdgts[cnt].type != FINISH) ! 288: if (thesewdgts[cnt].type != DUMMY) ! 289: delwin(thesewdgts[cnt++].wndw); ! 290: else ++cnt; ! 291: delwin(Text); ! 292: ! 293: deleteactive(); ! 294: ! 295: Text = activelist.text[activelist.count-1]; ! 296: if (Text != (WINDOW *)NULL) ! 297: (void) wrefresh(Text); ! 298: } ! 299: ! 300: /* THESE FUNCTIONS MANIPULATE THE ACTIVELIST ARRAY OF WIDGETS */ ! 301: ! 302: /* This should check that the number of active widgets is not excessive, or ! 303: * have the activelist really as a linked list. ! 304: */ ! 305: /* ARGSUSED */ ! 306: activewidget(wdgts, text) ! 307: WIDGET wdgts[]; ! 308: WINDOW *text; ! 309: { ! 310: activelist.widgets[activelist.count] = wdgts; ! 311: activelist.text[activelist.count] = Text; ! 312: ++(activelist.count); ! 313: } ! 314: ! 315: deleteactive() ! 316: { ! 317: if (activelist.count > 0) ! 318: --(activelist.count); ! 319: } ! 320: ! 321: activeindex(index) ! 322: char index; ! 323: { ! 324: activelist.lastindex[activelist.count - 1] = index; ! 325: } ! 326: ! 327: /* Refresh each of the active widgets and the current text window */ ! 328: redraw() ! 329: { ! 330: register int i; ! 331: ! 332: clearok(curscr,TRUE); ! 333: for (i=0; i<activelist.count; i++) ! 334: rfrshwidgets(activelist.widgets[i]); ! 335: (void) wrefresh(Text); ! 336: } ! 337: ! 338: redrawt() ! 339: { ! 340: ; ! 341: } ! 342: ! 343: ! 344: rfrshwidgets(thesewdgts) ! 345: WIDGET *thesewdgts; ! 346: { ! 347: int i = 0; ! 348: ! 349: while(thesewdgts[i].wndw != (WINDOW *)NULL && thesewdgts[i].type != DUMMY){ ! 350: touchwin(thesewdgts[i].wndw); ! 351: (void) wrefresh(thesewdgts[i++].wndw); ! 352: } ! 353: } ! 354: ! 355: /* Draw a perimeter box around WDGT, with horizontal char XCH etc */ ! 356: boxwdgt(wdgt,xch,ych) ! 357: char xch, ych; ! 358: register WIDGET *wdgt; ! 359: { ! 360: register int x, y; ! 361: ! 362: mvwaddch(wdgt->wndw, 0, 0, '.'); ! 363: for (x = 1; x < wdgt->wdth-1; x++) ! 364: (void) waddch(wdgt->wndw, xch); ! 365: (void) waddch(wdgt->wndw, '.'); ! 366: ! 367: mvwaddch(wdgt->wndw, 1, 0, ych); ! 368: for (y = 1; y < wdgt->hght-1; y++) { ! 369: (void) mvwaddch(wdgt->wndw, y, 0, ych); ! 370: (void) mvwaddch(wdgt->wndw, y, wdgt->wdth-1, ych); ! 371: } ! 372: ! 373: mvwaddch(wdgt->wndw, wdgt->hght-1, 0, '`'); ! 374: for (x = 1; x < wdgt->wdth-1; x++) ! 375: (void) waddch(wdgt->wndw, xch); ! 376: (void) waddch(wdgt->wndw, '\''); ! 377: } ! 378: ! 379: /* THESE ROUTINES PRINT THE INDIVIDUAL WIDGET BOXES */ ! 380: ! 381: /* Print a widgets label, dependant on the widget type */ ! 382: printwdgt(wdgt) ! 383: WIDGET *wdgt; ! 384: { ! 385: switch(wdgt->type) { ! 386: ! 387: case LABEL: ! 388: printlabel(wdgt); ! 389: break; ! 390: ! 391: case DIALOG: ! 392: printdialog(wdgt); ! 393: break; ! 394: ! 395: case TOGGLE: ! 396: printtoggle(wdgt); ! 397: break; ! 398: ! 399: default : ! 400: printcommand(wdgt); ! 401: break; ! 402: } ! 403: } ! 404: ! 405: printbar(list_size, first, display_num) ! 406: int list_size, first, display_num; ! 407: { ! 408: WIDGET * wdgt; ! 409: int cnt, bar_size, bar_pos=0, space_size; ! 410: ! 411: for(cnt = 0; currwidgets[cnt].type != SCROLLBAR; cnt++) ; ! 412: wdgt = &currwidgets[cnt]; ! 413: ! 414: (void) wclear(wdgt->wndw); ! 415: boxwdgt(wdgt, '-', '|'); ! 416: ! 417: space_size = wdgt->hght - 4; ! 418: ! 419: if(display_num == list_size) { ! 420: bar_size = space_size; ! 421: bar_pos = 1; ! 422: } else { ! 423: bar_size = (display_num*space_size)/(list_size+1); ! 424: bar_size = bar_size? bar_size: 1; ! 425: ! 426: while(!((list_size*bar_pos)/(first*(space_size+1)))) bar_pos++; ! 427: } ! 428: ! 429: while((bar_size + bar_pos - 1) > space_size) { ! 430: bar_size--; ! 431: } ! 432: ! 433: for(cnt = 0; cnt < bar_size; cnt++) ! 434: (void) mvwaddch(wdgt->wndw, cnt+1+bar_pos, 1, '*'); ! 435: ! 436: (void) mvwaddch(wdgt->wndw, 1, 1, ']'); ! 437: (void) mvwaddch(wdgt->wndw, wdgt->hght-2, 1, '['); ! 438: ! 439: (void) wrefresh(wdgt->wndw); ! 440: } ! 441: ! 442: /* Print a LABEL widgets label string, dependant on the justification char */ ! 443: printlabel(wdgt) ! 444: WIDGET *wdgt; ! 445: { ! 446: register int x, labellen, wdgtlen; ! 447: ! 448: labellen = strlen(wdgt->label); ! 449: wdgtlen = wdgt->wdth - 2; ! 450: ! 451: if (labellen > wdgtlen) ! 452: wdgt->label[wdgtlen] = '\0'; ! 453: ! 454: if (wdgt->callch & CENTRE) ! 455: x = (wdgtlen - labellen)/2; ! 456: else ! 457: if (wdgt->callch & LEFT) ! 458: x = 0; ! 459: else ! 460: if (wdgt->callch & RIGHT) x = wdgtlen - labellen; ! 461: ! 462: mvwaddstr(wdgt->wndw,1,1+x,wdgt->label); ! 463: (void) wrefresh(wdgt->wndw); ! 464: } ! 465: ! 466: /* Print a DIALOG widget label: if it don't all fit, show the last part */ ! 467: printdialog(wdgt) ! 468: WIDGET *wdgt; ! 469: { ! 470: register int length, maxlen; ! 471: register char *showptr; ! 472: ! 473: (void) wclear(wdgt->wndw); ! 474: boxwdgt(wdgt, '-', '|'); ! 475: if (wdgt->dstr != (char *)NULL) { ! 476: length = strlen(wdgt->dstr); ! 477: maxlen = wdgt->wdth - 4 - strlen(wdgt->label); ! 478: if (length > maxlen) ! 479: showptr = &(wdgt->dstr[length - maxlen]); ! 480: else ! 481: showptr = wdgt->dstr; ! 482: (void) mvwprintw(wdgt->wndw, 1, 1, "%s%c%s",wdgt->label, ! 483: (length > maxlen)?'<':' ',showptr); ! 484: } ! 485: (void) wrefresh(wdgt->wndw); ! 486: } ! 487: ! 488: /* Print a TOGGLE widget label, and the current toggle value */ ! 489: printtoggle(wdgt) ! 490: WIDGET *wdgt; ! 491: { ! 492: (void) wclear(wdgt->wndw); ! 493: boxwdgt(wdgt, '-', '|'); ! 494: if (wdgt->tvalues == (char **)NULL) ! 495: return; ! 496: mvwaddstr(wdgt->wndw,1,1,wdgt->label); ! 497: (void) waddstr(wdgt->wndw,wdgt->tvalues[wdgt->tindx]); ! 498: (void) wclrtoeol(wdgt->wndw); ! 499: (void) mvwaddch(wdgt->wndw,1,wdgt->wdth-1,'|'); ! 500: (void) wrefresh(wdgt->wndw); ! 501: } ! 502: ! 503: /* Print a COMMAND widget label */ ! 504: printcommand(wdgt) ! 505: WIDGET *wdgt; ! 506: { ! 507: mvwaddstr(wdgt->wndw,1,1,wdgt->label); ! 508: (void) wrefresh(wdgt->wndw); ! 509: } ! 510: ! 511: /* THESE ROUTINES GET AND REACT TO A USERS INPUT FROM THE KEYBOARD */ ! 512: ! 513: /* Loop forever, calling widget callback functions when activated */ ! 514: interact() ! 515: { ! 516: register int ch, index; ! 517: void int_quit(), jumpback(); ! 518: ! 519: for (;;) { ! 520: /* Get a character input, and set the interrupt jump vector */ ! 521: (void) setjmp(env); ! 522: (void) signal(SIGINT, int_quit); ! 523: ! 524: move(0,0); ! 525: (void) wrefresh(Text); ! 526: refresh(); ! 527: ch = getchar(); ! 528: if (isupper(ch)) ! 529: ch = tolower(ch); ! 530: (void) signal(SIGINT, jumpback); ! 531: ! 532: /* Allow the user to refresh the entire screen, with a CTRL-L */ ! 533: if (ch == '\014') { ! 534: redraw(); ! 535: scrollbar('\0'); ! 536: continue; ! 537: } ! 538: ! 539: /* Search through the current widgets for one matching that required */ ! 540: command = ch; ! 541: index = findactiveinput(ch); ! 542: if (index >= 0) ! 543: docallback(index); ! 544: ch = 0; ! 545: } ! 546: } ! 547: ! 548: /* Find a callback 'ch' from the currently active set of widgets */ ! 549: findactiveinput(ch) ! 550: char ch; ! 551: { ! 552: register int index; ! 553: register WIDGET *wdgts; ! 554: ! 555: if (ch > 'z' || ch < 'a') { ! 556: switch (ch) { ! 557: case '1': ! 558: case '2': ! 559: case '3': ! 560: case '4': ! 561: case '5': ! 562: case '6': ! 563: case '7': ! 564: case '8': ! 565: case '9': ! 566: ch = '*'; ! 567: break; ! 568: case '[': ! 569: case ']': ! 570: ch = '%'; ! 571: break; ! 572: case '?': ! 573: ch = 'h'; ! 574: break; ! 575: } ! 576: } ! 577: ! 578: /* See whether the 'ch' exists in the currently active widgets */ ! 579: wdgts = activelist.widgets[activelist.count - 1]; ! 580: index = getwidgetindex(wdgts, ch); ! 581: if (index >= 0) ! 582: return(index); ! 583: ! 584: /* If not, check the previously active widgets, if possible */ ! 585: if (activelist.count <= 1) ! 586: return(-1); ! 587: index = getwidgetindex(activelist.widgets[activelist.count - 2], ch); ! 588: if (index >= 0) { ! 589: killwidgets(activelist.widgets[activelist.count - 1]); ! 590: return(index); ! 591: } ! 592: return(-1); ! 593: } ! 594: ! 595: ! 596: docallback(index) ! 597: char index; ! 598: { ! 599: WIDGET *wdgts; ! 600: ! 601: activeindex(index); ! 602: wdgts = activelist.widgets[activelist.count - 1]; ! 603: switch (wdgts[index].type) { ! 604: ! 605: case DIALOG: ! 606: if (command >= '1' && command <= '9') ! 607: get_listed_object (command, &wdgts[index]); ! 608: else { ! 609: dialog(&wdgts[index]); ! 610: (*wdgts[index].callfn)(); ! 611: } ! 612: break; ! 613: ! 614: case TOGGLE: ! 615: toggle(&wdgts[index]); ! 616: (*wdgts[index].callfn)(); ! 617: break; ! 618: ! 619: case SCROLLBAR : ! 620: scrollbar(command); ! 621: break; ! 622: ! 623: default: ! 624: (*wdgts[index].callfn)(); ! 625: break; ! 626: } ! 627: } ! 628: ! 629: /* THESE ROUTINES SEARCH THE ACTIVE WIDGET SET FOR ONE SPECIFIED WIDGET */ ! 630: ! 631: /* Find a widget based on the call-back character */ ! 632: WIDGET * ! 633: getwidget(wdgts, callch) ! 634: int callch; ! 635: WIDGET wdgts[]; ! 636: { ! 637: register int index; ! 638: ! 639: index = getwidgetindex(wdgts, callch); ! 640: if (index >= 0) return(&(wdgts[index])); ! 641: ! 642: return((WIDGET *)NULL); ! 643: } ! 644: ! 645: getwidgetindex(wdgts, callch) ! 646: int callch; ! 647: WIDGET wdgts[]; ! 648: { ! 649: register int cnt = 0; ! 650: ! 651: while (wdgts[cnt].type != FINISH) { ! 652: if (callch == wdgts[cnt].callch) break; ! 653: ++cnt; ! 654: } ! 655: if (wdgts[cnt].type != FINISH) return(cnt); ! 656: ! 657: return(-1); ! 658: } ! 659: ! 660: /* THESE ROUTINES MANIPULATE THE DIALOG WIDGETS */ ! 661: ! 662: dialog(wdgt) ! 663: WIDGET *wdgt; ! 664: { ! 665: register int i, length, labellen, maxlen; ! 666: register char ch, *endptr, *showptr; ! 667: register char *blanks; ! 668: extern char *malloc(); ! 669: ! 670: labellen = strlen(wdgt->label); /* The length of the prompt string */ ! 671: length = strlen(wdgt->dstr); /* The length of the current string */ ! 672: ! 673: maxlen = wdgt->wdth - 4 - labellen; /* The maximum length of shown str */ ! 674: blanks = malloc((unsigned)(maxlen + 2)); ! 675: for (i=0; i<maxlen; i++) ! 676: blanks[i] = ' '; ! 677: blanks[i] = '\0'; ! 678: ! 679: endptr = &(wdgt->dstr[length]); /* The next character pos'n to fill */ ! 680: *endptr = '\0'; ! 681: ! 682: if (length > maxlen) ! 683: showptr = &(wdgt->dstr[length - maxlen]); ! 684: else ! 685: showptr = wdgt->dstr; ! 686: (void) mvwprintw(wdgt->wndw,1,1,"%s%c%s",wdgt->label,(length > maxlen)?'<':' ',showptr); ! 687: (void) wrefresh(wdgt->wndw); ! 688: ! 689: while ((ch = getchar() & 127) != '\n' && ch != '\r' && ch != '\f') { ! 690: if (ch == '\014') { /* Allow for redrawing */ ! 691: redraw(); ! 692: continue; ! 693: } ! 694: ! 695: if (ch == '\b' || ch == 127) { /* Delete a character, with wrapping */ ! 696: if (length == 0) ! 697: continue; ! 698: *(--endptr) = '\0'; /* Make the last character NULL */ ! 699: if (showptr > wdgt->dstr) /* We have parts of the string hidden */ ! 700: --showptr; ! 701: --length; ! 702: if (length < maxlen) { /* Only need to erase one character */ ! 703: (void) waddstr(wdgt->wndw,"\b \b"); ! 704: (void) wrefresh(wdgt->wndw); ! 705: continue; ! 706: } ! 707: /* We'll have to erase everything */ ! 708: (void) wprintw(wdgt->wndw,"\r|%s%c%s \b",wdgt->label,(length <= maxlen)?' ':'<',showptr); ! 709: (void) wrefresh(wdgt->wndw); ! 710: continue; ! 711: } ! 712: ! 713: if (ch == 21) { /* ^U to delete the entire line of text */ ! 714: length = 0; ! 715: endptr = wdgt->dstr; ! 716: *endptr = '\0'; ! 717: showptr = wdgt->dstr; ! 718: (void) wprintw(wdgt->wndw,"\r|%s %s\r|%s ",wdgt->label,blanks,wdgt->label); ! 719: (void) wrefresh(wdgt->wndw); ! 720: continue; ! 721: } ! 722: ! 723: /* Otherwise, add the character if there is room and it ain't a control code */ ! 724: if (length == 1024 || ch < 32) ! 725: continue; ! 726: if (length == wdgt->dstrlen){ ! 727: *endptr++ = ch; ! 728: *endptr = '\0'; ! 729: setdialogstr(wdgt, showptr, wdgt->dstrlen); ! 730: continue; ! 731: } ! 732: *endptr++ = ch; ! 733: *endptr = '\0'; ! 734: if (++length <= maxlen) { /* Just add this character to the end */ ! 735: (void) waddch(wdgt->wndw,ch); ! 736: (void) wrefresh(wdgt->wndw); ! 737: continue; ! 738: } ! 739: ++showptr; ! 740: (void) wprintw(wdgt->wndw,"\r|%s<%s",wdgt->label,showptr); ! 741: (void) wrefresh(wdgt->wndw); ! 742: } ! 743: free(blanks); ! 744: } ! 745: ! 746: ! 747: setdialogstr(wdgt, dstr, maxlen) ! 748: char *dstr; ! 749: WIDGET *wdgt; ! 750: int maxlen ; ! 751: { ! 752: if (wdgt->type != DIALOG) return; ! 753: ! 754: wdgt->dstr = dstr; ! 755: wdgt->dstrlen = maxlen; ! 756: } ! 757: ! 758: getdialogstr(wdgt, str) /* 'str' must be long enough... */ ! 759: char str[]; ! 760: WIDGET *wdgt; ! 761: { ! 762: if (wdgt->type != DIALOG || wdgt->dstr == (char *)NULL) return(FALSE); ! 763: ! 764: (void) strcpy(str, wdgt->dstr); ! 765: return(TRUE); ! 766: } ! 767: ! 768: /* THESE ROUTINES MANIPULATE THE TOGGLE WIDGETS */ ! 769: ! 770: toggle(wdgt) ! 771: WIDGET *wdgt; ! 772: { ! 773: WIDGET *vwdgt; ! 774: int av_indx; ! 775: ! 776: if (wdgt->tvalues == (char **)NULL) ! 777: return; ! 778: ! 779: if (wdgt == getwidget(currwidgets, 't')) { ! 780: typetoggled = 1; ! 781: vwdgt = getwidget(currwidgets, 's'); ! 782: (void) strcpy(filtvalue[wdgt->tindx], vwdgt->dstr); ! 783: ! 784: av_indx = 0; ! 785: while (av_typeindx[av_indx] != wdgt->tindx && av_typeindx[av_indx] >= 0) ! 786: av_indx++; ! 787: ! 788: if (av_typeindx[av_indx] == wdgt->tindx) ! 789: av_indx++; ! 790: ! 791: if (av_typeindx[av_indx] < 0) ! 792: av_indx = 0; ! 793: ! 794: wdgt->tindx = av_typeindx[av_indx]; ! 795: ! 796: (void) strcpy(vwdgt->dstr, filtvalue[wdgt->tindx]); ! 797: typeindx = wdgt->tindx; ! 798: ! 799: printdialog(vwdgt); ! 800: } ! 801: ! 802: printtoggle(wdgt); ! 803: } ! 804: ! 805: settogglstrs(wdgt, togglstrs, togglindx) ! 806: int togglindx; ! 807: char **togglstrs; ! 808: WIDGET *wdgt; ! 809: { ! 810: if (wdgt->type != TOGGLE) ! 811: return; ! 812: wdgt->tvalues = togglstrs; ! 813: wdgt->tindx = togglindx; ! 814: } ! 815: ! 816: settogglindx(wdgt, indx) ! 817: int indx; ! 818: WIDGET *wdgt; ! 819: { ! 820: int i; ! 821: ! 822: if (wdgt->type != TOGGLE || wdgt->tvalues == (char **)NULL) ! 823: return(FALSE); ! 824: for (i=0; i<indx; i++) ! 825: if (wdgt->tvalues[i] == (char *)NULL) ! 826: break; ! 827: if (i != indx) /* There ain't that many toggle strings */ ! 828: return(FALSE); ! 829: wdgt->tindx = indx; ! 830: return(TRUE); ! 831: } ! 832: ! 833: gettogglindx(wdgt) ! 834: WIDGET *wdgt; ! 835: { ! 836: if (wdgt->type != TOGGLE || wdgt->tvalues == (char **)NULL) ! 837: return(-1); ! 838: return(wdgt->tindx); ! 839: } ! 840: ! 841: gettogglstr(wdgt, str) /* 'str' must be long enough... */ ! 842: WIDGET *wdgt; ! 843: char str[]; ! 844: { ! 845: if (wdgt->type != TOGGLE || wdgt->tvalues == (char **)NULL) ! 846: return(FALSE); ! 847: (void) strcpy(str, wdgt->tvalues[wdgt->tindx]); ! 848: return(TRUE); ! 849: } ! 850: ! 851: /* THESE ROUTINES MANIPULATE THE LABEL WIDGETS */ ! 852: ! 853: setlabel(wdgt, label) ! 854: WIDGET *wdgt; ! 855: char *label; ! 856: { ! 857: wdgt->label = label; ! 858: } ! 859: ! 860: getlabel(wdgt, label) /* 'label' must be long enough... */ ! 861: WIDGET *wdgt; ! 862: char label[]; ! 863: { ! 864: (void) strcpy(label, wdgt->label); ! 865: } ! 866: ! 867: /* MISCELLANEOUS FUNCTIONS */ ! 868: ! 869: /* Try to locate the bottom of the last set of widgets displayed */ ! 870: lowesty() ! 871: { ! 872: register int cnt = 0; ! 873: register WIDGET *wdgts; ! 874: ! 875: if (activelist.count <= 0) return(0); ! 876: ! 877: wdgts = activelist.widgets[activelist.count - 1]; ! 878: while (wdgts[cnt].type != FINISH) ++cnt; ! 879: ! 880: if (cnt == 0) return(0); ! 881: ! 882: return((wdgts[cnt-1].y) + WDGTHGHT); ! 883: } ! 884: ! 885: /* This satisfies the generalised printing structure */ ! 886: /* ARGSUSED */ ! 887: wprint(here, fmt, a,b,c,d,e,f,g,h,i,j) ! 888: WINDOW *here; ! 889: char *fmt, *a,*b,*c,*d,*e,*f,*g,*h,*i,*j; ! 890: { ! 891: (void) wprintw(Text,fmt,a,b,c,d,e,f,g,h,i,j); ! 892: (void) wrefresh(Text); ! 893: } ! 894: ! 895: /* This can be called as a way for an application to print text */ ! 896: /* VARARGS1 */ ! 897: tprint(fmt, a,b,c,d,e,f,g,h,i,j) ! 898: char *fmt, *a,*b,*c,*d,*e,*f,*g,*h,*i,*j; ! 899: { ! 900: (void) wprintw(Text,fmt,a,b,c,d,e,f,g,h,i,j); ! 901: (void) wrefresh(Text); ! 902: } ! 903: ! 904: xprint(fmt) ! 905: char *fmt; ! 906: { ! 907: (void) wprintw(Text,fmt); ! 908: } ! 909: ! 910: xprintint(fmt, a) ! 911: char *fmt; ! 912: int a; ! 913: { ! 914: (void) wprintw(Text,fmt, a); ! 915: } ! 916: ! 917: cleartext() ! 918: { ! 919: clearok (Text,TRUE); ! 920: (void) wclear (Text); ! 921: } ! 922: ! 923: /* Jump back to the interact function only on an interrupt */ ! 924: void jumpback() ! 925: { ! 926: (void) waddstr(Text,"\n*** Interrupted ***\n"); ! 927: (void) wrefresh(Text); ! 928: longjmp(env, TRUE); ! 929: } ! 930: ! 931: /* This is used as a declaration, when no function callback is required */ ! 932: nullfn() ! 933: {} ! 934: ! 935: /* This is used by widgets that just want to kill the current level */ ! 936: quitfn() ! 937: { ! 938: (void) wclear(Text); ! 939: (void) wrefresh(Text); ! 940: killwidgets(activelist.widgets[activelist.count - 1]); ! 941: } ! 942: ! 943: endwidgets() ! 944: { ! 945: move(LINES-1, 0); ! 946: refresh(); ! 947: endwin(); ! 948: } ! 949: ! 950: ! 951:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.