|
|
1.1 ! root 1: /* uifc32.c */ ! 2: ! 3: /* Curses implementation of UIFC (user interface) library based on uifc.c */ ! 4: ! 5: /* $Id: uifc32.c,v 1.177 2006/09/15 21:05:56 deuce Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This library is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU Lesser General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU Lesser General Public License for more details: lgpl.txt or * ! 18: * http://www.fsf.org/copyleft/lesser.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #ifdef __unix__ ! 39: #include <stdio.h> ! 40: #include <unistd.h> ! 41: #ifdef __QNX__ ! 42: #include <strings.h> ! 43: #endif ! 44: #define mswait(x) delay(x) ! 45: #elif defined(_WIN32) ! 46: #include <share.h> ! 47: #include <windows.h> ! 48: #include <malloc.h> ! 49: #define mswait(x) Sleep(x) ! 50: #endif ! 51: ! 52: #include "ciolib.h" ! 53: #include "keys.h" ! 54: #include "uifc.h" ! 55: #define MAX_GETSTR 5120 ! 56: ! 57: #define BLINK 128 ! 58: ! 59: static int cursor; ! 60: static char* helpfile=0; ! 61: static uint helpline=0; ! 62: static size_t blk_scrn_len; ! 63: static char* blk_scrn; ! 64: static uchar* tmp_buffer; ! 65: static uchar* tmp_buffer2; ! 66: static win_t sav[MAX_BUFS]; ! 67: static uifcapi_t* api; ! 68: ! 69: /* Prototypes */ ! 70: static int uprintf(int x, int y, unsigned attr, char *fmt,...); ! 71: static void bottomline(int line); ! 72: static char *utimestr(time_t *intime); ! 73: static void help(void); ! 74: static int ugetstr(int left, int top, int width, char *outstr, int max, long mode, int *lastkey); ! 75: static void timedisplay(BOOL force); ! 76: ! 77: /* API routines */ ! 78: static void uifcbail(void); ! 79: static int uscrn(char *str); ! 80: static int ulist(int mode, int left, int top, int width, int *dflt, int *bar ! 81: ,char *title, char **option); ! 82: static int uinput(int imode, int left, int top, char *prompt, char *str ! 83: ,int len ,int kmode); ! 84: static void umsg(char *str); ! 85: static void upop(char *str); ! 86: static void sethelp(int line, char* file); ! 87: static void showbuf(int mode, int left, int top, int width, int height, char *title ! 88: , char *hbuf, int *curp, int *barp); ! 89: ! 90: /* Dynamic menu support */ ! 91: static int *last_menu_cur=NULL; ! 92: static int *last_menu_bar=NULL; ! 93: static int save_menu_cur=-1; ! 94: static int save_menu_bar=-1; ! 95: static int save_menu_opts=-1; ! 96: ! 97: static void reset_dynamic(void) { ! 98: last_menu_cur=NULL; ! 99: last_menu_bar=NULL; ! 100: save_menu_cur=-1; ! 101: save_menu_bar=-1; ! 102: save_menu_opts=-1; ! 103: } ! 104: ! 105: /****************************************************************************/ ! 106: /* Initialization function, see uifc.h for details. */ ! 107: /* Returns 0 on success. */ ! 108: /****************************************************************************/ ! 109: ! 110: void uifc_mouse_enable(void) ! 111: { ! 112: ciomouse_setevents(0); ! 113: ciomouse_addevent(CIOLIB_BUTTON_1_DRAG_START); ! 114: ciomouse_addevent(CIOLIB_BUTTON_1_DRAG_MOVE); ! 115: ciomouse_addevent(CIOLIB_BUTTON_1_DRAG_END); ! 116: ciomouse_addevent(CIOLIB_BUTTON_1_CLICK); ! 117: ciomouse_addevent(CIOLIB_BUTTON_2_CLICK); ! 118: ciomouse_addevent(CIOLIB_BUTTON_3_CLICK); ! 119: showmouse(); ! 120: } ! 121: ! 122: void uifc_mouse_disable(void) ! 123: { ! 124: ciomouse_setevents(0); ! 125: hidemouse(); ! 126: } ! 127: ! 128: int kbwait(void) { ! 129: int timeout=0; ! 130: while(timeout++<50) { ! 131: if(kbhit()) ! 132: return(TRUE); ! 133: mswait(1); ! 134: } ! 135: return(FALSE); ! 136: } ! 137: ! 138: int inkey(void) ! 139: { ! 140: int c; ! 141: ! 142: c=getch(); ! 143: if(!c || c==0xff) ! 144: c|=(getch()<<8); ! 145: return(c); ! 146: } ! 147: ! 148: int uifcini32(uifcapi_t* uifcapi) ! 149: { ! 150: unsigned i; ! 151: struct text_info txtinfo; ! 152: ! 153: if(uifcapi==NULL || uifcapi->size!=sizeof(uifcapi_t)) ! 154: return(-1); ! 155: ! 156: api=uifcapi; ! 157: ! 158: /* install function handlers */ ! 159: api->bail=uifcbail; ! 160: api->scrn=uscrn; ! 161: api->msg=umsg; ! 162: api->pop=upop; ! 163: api->list=ulist; ! 164: api->input=uinput; ! 165: api->sethelp=sethelp; ! 166: api->showhelp=help; ! 167: api->showbuf=showbuf; ! 168: api->timedisplay=timedisplay; ! 169: api->bottomline=bottomline; ! 170: api->getstrxy=ugetstr; ! 171: api->printf=uprintf; ! 172: ! 173: if(api->scrn_len!=0) { ! 174: switch(api->scrn_len) { ! 175: case 14: ! 176: textmode(C80X14); ! 177: break; ! 178: case 21: ! 179: textmode(C80X21); ! 180: break; ! 181: case 25: ! 182: textmode(C80); ! 183: break; ! 184: case 28: ! 185: textmode(C80X28); ! 186: break; ! 187: case 43: ! 188: textmode(C80X43); ! 189: break; ! 190: case 50: ! 191: textmode(C80X50); ! 192: break; ! 193: case 60: ! 194: textmode(C80X60); ! 195: break; ! 196: default: ! 197: textmode(C4350); ! 198: break; ! 199: } ! 200: } ! 201: ! 202: #if 0 ! 203: clrscr(); ! 204: #endif ! 205: ! 206: gettextinfo(&txtinfo); ! 207: /* unsupported mode? */ ! 208: if(txtinfo.screenheight<MIN_LINES ! 209: /* || txtinfo.screenheight>MAX_LINES */ ! 210: || txtinfo.screenwidth<40) { ! 211: textmode(C80); /* set mode to 80x25*/ ! 212: gettextinfo(&txtinfo); ! 213: } ! 214: window(1,1,txtinfo.screenwidth,txtinfo.screenheight); ! 215: ! 216: api->scrn_len=txtinfo.screenheight; ! 217: if(api->scrn_len<MIN_LINES) { ! 218: cprintf("\7UIFC: Screen length (%u) must be %d lines or greater\r\n" ! 219: ,api->scrn_len,MIN_LINES); ! 220: return(-2); ! 221: } ! 222: api->scrn_len--; /* account for status line */ ! 223: ! 224: if(txtinfo.screenwidth<40) { ! 225: cprintf("\7UIFC: Screen width (%u) must be at least 40 characters\r\n" ! 226: ,txtinfo.screenwidth); ! 227: return(-3); ! 228: } ! 229: api->scrn_width=txtinfo.screenwidth; ! 230: ! 231: if(!(api->mode&UIFC_COLOR) ! 232: && (api->mode&UIFC_MONO ! 233: || txtinfo.currmode==MONO || txtinfo.currmode==BW40 || txtinfo.currmode==BW80 ! 234: || txtinfo.currmode==MONO14 || txtinfo.currmode==BW40X14 || txtinfo.currmode==BW80X14 ! 235: || txtinfo.currmode==MONO21 || txtinfo.currmode==BW40X21 || txtinfo.currmode==BW80X21 ! 236: || txtinfo.currmode==MONO28 || txtinfo.currmode==BW40X28 || txtinfo.currmode==BW80X28 ! 237: || txtinfo.currmode==MONO43 || txtinfo.currmode==BW40X43 || txtinfo.currmode==BW80X43 ! 238: || txtinfo.currmode==MONO50 || txtinfo.currmode==BW40X50 || txtinfo.currmode==BW80X50 ! 239: || txtinfo.currmode==MONO60 || txtinfo.currmode==BW40X60 || txtinfo.currmode==BW80X60)) ! 240: { ! 241: api->bclr=BLACK; ! 242: api->hclr=WHITE; ! 243: api->lclr=LIGHTGRAY; ! 244: api->cclr=LIGHTGRAY; ! 245: api->lbclr=BLACK|(LIGHTGRAY<<4); /* lightbar color */ ! 246: } else { ! 247: api->bclr=BLUE; ! 248: api->hclr=YELLOW; ! 249: api->lclr=WHITE; ! 250: api->cclr=CYAN; ! 251: api->lbclr=BLUE|(LIGHTGRAY<<4); /* lightbar color */ ! 252: } ! 253: ! 254: blk_scrn_len=api->scrn_width*api->scrn_len*2; ! 255: if((blk_scrn=(char *)malloc(blk_scrn_len))==NULL) { ! 256: cprintf("UIFC line %d: error allocating %u bytes." ! 257: ,__LINE__,blk_scrn_len); ! 258: return(-1); ! 259: } ! 260: if((tmp_buffer=(uchar *)malloc(blk_scrn_len))==NULL) { ! 261: cprintf("UIFC line %d: error allocating %u bytes." ! 262: ,__LINE__,blk_scrn_len); ! 263: return(-1); ! 264: } ! 265: if((tmp_buffer2=(uchar *)malloc(blk_scrn_len))==NULL) { ! 266: cprintf("UIFC line %d: error allocating %u bytes." ! 267: ,__LINE__,blk_scrn_len); ! 268: return(-1); ! 269: } ! 270: for(i=0;i<blk_scrn_len;i+=2) { ! 271: blk_scrn[i]='�'; ! 272: blk_scrn[i+1]=api->cclr|(api->bclr<<4); ! 273: } ! 274: ! 275: cursor=_NOCURSOR; ! 276: _setcursortype(cursor); ! 277: ! 278: if(cio_api.mouse) { ! 279: api->mode|=UIFC_MOUSE; ! 280: uifc_mouse_enable(); ! 281: } ! 282: ! 283: /* A esc_delay of less than 10 is stupid... silently override */ ! 284: if(api->esc_delay < 10) ! 285: api->esc_delay=25; ! 286: ! 287: if(cio_api.ESCDELAY) ! 288: *(cio_api.ESCDELAY)=api->esc_delay; ! 289: ! 290: api->initialized=TRUE; ! 291: ! 292: for(i=0; i<MAX_BUFS; i++) ! 293: sav[i].buf=NULL; ! 294: ! 295: return(0); ! 296: } ! 297: ! 298: void docopy(void) ! 299: { ! 300: int key; ! 301: struct mouse_event mevent; ! 302: unsigned char *screen; ! 303: unsigned char *sbuffer; ! 304: int sbufsize=0; ! 305: int x,y,startx,starty,endx,endy,lines; ! 306: int outpos; ! 307: char *copybuf; ! 308: ! 309: sbufsize=api->scrn_width*2*(api->scrn_len+1); ! 310: screen=(unsigned char*)alloca(sbufsize); ! 311: sbuffer=(unsigned char*)alloca(sbufsize); ! 312: gettext(1,1,api->scrn_width,api->scrn_len+1,screen); ! 313: while(1) { ! 314: key=getch(); ! 315: if(key==0 || key==0xff) ! 316: key|=getch()<<8; ! 317: switch(key) { ! 318: case CIO_KEY_MOUSE: ! 319: getmouse(&mevent); ! 320: if(mevent.startx<mevent.endx) { ! 321: startx=mevent.startx; ! 322: endx=mevent.endx; ! 323: } ! 324: else { ! 325: startx=mevent.endx; ! 326: endx=mevent.startx; ! 327: } ! 328: if(mevent.starty<mevent.endy) { ! 329: starty=mevent.starty; ! 330: endy=mevent.endy; ! 331: } ! 332: else { ! 333: starty=mevent.endy; ! 334: endy=mevent.starty; ! 335: } ! 336: switch(mevent.event) { ! 337: case CIOLIB_BUTTON_1_DRAG_MOVE: ! 338: memcpy(sbuffer,screen,sbufsize); ! 339: for(y=starty-1;y<endy;y++) { ! 340: for(x=startx-1;x<endx;x++) { ! 341: int pos=y*api->scrn_width+x; ! 342: if((sbuffer[pos*2+1]&0x70)!=0x10) ! 343: sbuffer[pos*2+1]=sbuffer[pos*2+1]&0x8F|0x10; ! 344: else ! 345: sbuffer[pos*2+1]=sbuffer[pos*2+1]&0x8F|0x60; ! 346: if(((sbuffer[pos*2+1]&0x70)>>4) == (sbuffer[pos*2+1]&0x0F)) { ! 347: sbuffer[pos*2+1]|=0x08; ! 348: } ! 349: } ! 350: } ! 351: puttext(1,1,api->scrn_width,api->scrn_len+1,sbuffer); ! 352: break; ! 353: case CIOLIB_BUTTON_1_DRAG_END: ! 354: lines=abs(mevent.endy-mevent.starty)+1; ! 355: copybuf=alloca((endy-starty+1)*(endx-startx+1)+1+lines*2); ! 356: outpos=0; ! 357: for(y=starty-1;y<endy;y++) { ! 358: for(x=startx-1;x<endx;x++) { ! 359: copybuf[outpos++]=screen[(y*api->scrn_width+x)*2]; ! 360: } ! 361: copybuf[outpos++]='\r'; ! 362: copybuf[outpos++]='\n'; ! 363: } ! 364: copybuf[outpos]=0; ! 365: copytext(copybuf, strlen(copybuf)); ! 366: puttext(1,1,api->scrn_width,api->scrn_len+1,screen); ! 367: return; ! 368: } ! 369: break; ! 370: default: ! 371: puttext(1,1,api->scrn_width,api->scrn_len+1,screen); ! 372: ungetch(key); ! 373: return; ! 374: } ! 375: } ! 376: } ! 377: ! 378: static int uifc_getmouse(struct mouse_event *mevent) ! 379: { ! 380: mevent->startx=0; ! 381: mevent->starty=0; ! 382: mevent->event=0; ! 383: if(api->mode&UIFC_MOUSE) { ! 384: getmouse(mevent); ! 385: if(mevent->event==CIOLIB_BUTTON_3_CLICK) ! 386: return(ESC); ! 387: if(mevent->event==CIOLIB_BUTTON_1_DRAG_START) { ! 388: docopy(); ! 389: return(0); ! 390: } ! 391: if(mevent->starty==api->buttony) { ! 392: if(mevent->startx>=api->exitstart ! 393: && mevent->startx<=api->exitend ! 394: && mevent->event==CIOLIB_BUTTON_1_CLICK) { ! 395: return(ESC); ! 396: } ! 397: if(mevent->startx>=api->helpstart ! 398: && mevent->startx<=api->helpend ! 399: && mevent->event==CIOLIB_BUTTON_1_CLICK) { ! 400: return(CIO_KEY_F(1)); ! 401: } ! 402: } ! 403: return(0); ! 404: } ! 405: return(-1); ! 406: } ! 407: ! 408: void uifcbail(void) ! 409: { ! 410: _setcursortype(_NORMALCURSOR); ! 411: textattr(LIGHTGRAY); ! 412: uifc_mouse_disable(); ! 413: suspendciolib(); ! 414: FREE_AND_NULL(blk_scrn); ! 415: FREE_AND_NULL(tmp_buffer); ! 416: FREE_AND_NULL(tmp_buffer2); ! 417: api->initialized=FALSE; ! 418: } ! 419: ! 420: /****************************************************************************/ ! 421: /* Clear screen, fill with background attribute, display application title. */ ! 422: /* Returns 0 on success. */ ! 423: /****************************************************************************/ ! 424: int uscrn(char *str) ! 425: { ! 426: textattr(api->bclr|(api->cclr<<4)); ! 427: gotoxy(1,1); ! 428: clreol(); ! 429: gotoxy(3,1); ! 430: cputs(str); ! 431: if(!puttext(1,2,api->scrn_width,api->scrn_len,blk_scrn)) ! 432: return(-1); ! 433: gotoxy(1,api->scrn_len+1); ! 434: clreol(); ! 435: reset_dynamic(); ! 436: setname(str); ! 437: return(0); ! 438: } ! 439: ! 440: /****************************************************************************/ ! 441: /****************************************************************************/ ! 442: static void scroll_text(int x1, int y1, int x2, int y2, int down) ! 443: { ! 444: gettext(x1,y1,x2,y2,tmp_buffer2); ! 445: if(down) ! 446: puttext(x1,y1+1,x2,y2,tmp_buffer2); ! 447: else ! 448: puttext(x1,y1,x2,y2-1,tmp_buffer2+(((x2-x1)+1)*2)); ! 449: } ! 450: ! 451: /****************************************************************************/ ! 452: /* Updates time in upper left corner of screen with current time in ASCII/ */ ! 453: /* Unix format */ ! 454: /****************************************************************************/ ! 455: static void timedisplay(BOOL force) ! 456: { ! 457: static time_t savetime; ! 458: time_t now; ! 459: ! 460: now=time(NULL); ! 461: if(force || difftime(now,savetime)>=60) { ! 462: uprintf(api->scrn_width-25,1,api->bclr|(api->cclr<<4),utimestr(&now)); ! 463: savetime=now; ! 464: } ! 465: } ! 466: ! 467: /****************************************************************************/ ! 468: /* Truncates white-space chars off end of 'str' */ ! 469: /****************************************************************************/ ! 470: static void truncsp(char *str) ! 471: { ! 472: uint c; ! 473: ! 474: c=strlen(str); ! 475: while(c && (uchar)str[c-1]<=' ') c--; ! 476: if(str[c]!=0) /* don't write to string constants */ ! 477: str[c]=0; ! 478: } ! 479: ! 480: /****************************************************************************/ ! 481: /* General menu function, see uifc.h for details. */ ! 482: /****************************************************************************/ ! 483: int ulist(int mode, int left, int top, int width, int *cur, int *bar ! 484: , char *initial_title, char **option) ! 485: { ! 486: uchar line[256],shade[256],*ptr ! 487: ,search[MAX_OPLN],bline=0,*win; ! 488: int height,y; ! 489: int i,j,opts=0,s=0; /* s=search index into options */ ! 490: int is_redraw=0; ! 491: int s_top=SCRN_TOP; ! 492: int s_left=SCRN_LEFT; ! 493: int s_right=SCRN_RIGHT; ! 494: int s_bottom=api->scrn_len-3; ! 495: int hbrdrsize=2; ! 496: int lbrdrwidth=1; ! 497: int rbrdrwidth=1; ! 498: int vbrdrsize=4; ! 499: int tbrdrwidth=3; ! 500: int bbrdrwidth=1; ! 501: int title_len; ! 502: struct mouse_event mevnt; ! 503: char *title=NULL; ! 504: int a,b,c,longopt; ! 505: int optheight=0; ! 506: uchar hclr,lclr,bclr,cclr,lbclr; ! 507: ! 508: hclr=api->hclr; ! 509: lclr=api->lclr; ! 510: bclr=api->bclr; ! 511: cclr=api->cclr; ! 512: lbclr=api->lbclr; ! 513: if(mode & WIN_INACT) { ! 514: bclr=api->cclr; ! 515: hclr=api->lclr; ! 516: lclr=api->lclr; ! 517: cclr=api->cclr; ! 518: lbclr=(api->cclr<<4)|api->hclr; ! 519: } ! 520: title=strdup(initial_title==NULL?"":initial_title); ! 521: ! 522: uifc_mouse_disable(); ! 523: ! 524: title_len=strlen(title); ! 525: ! 526: if(mode&WIN_FAT) { ! 527: s_top=1; ! 528: s_left=2; ! 529: s_right=api->scrn_width-3; /* Leave space for the shadow */ ! 530: s_bottom=api->scrn_len-1; /* Leave one for the shadow */ ! 531: } ! 532: if(mode&WIN_NOBRDR) { ! 533: hbrdrsize=0; ! 534: vbrdrsize=0; ! 535: lbrdrwidth=0; ! 536: rbrdrwidth=0; ! 537: tbrdrwidth=0; ! 538: bbrdrwidth=0; ! 539: } ! 540: ! 541: if(mode&WIN_SAV && api->savnum>=MAX_BUFS-1) ! 542: putch(7); ! 543: if(api->helpbuf!=NULL || api->helpixbfile[0]!=0) bline|=BL_HELP; ! 544: if(mode&WIN_INS) bline|=BL_INS; ! 545: if(mode&WIN_DEL) bline|=BL_DEL; ! 546: if(mode&WIN_GET) bline|=BL_GET; ! 547: if(mode&WIN_PUT) bline|=BL_PUT; ! 548: if(mode&WIN_EDIT) bline|=BL_EDIT; ! 549: if(api->bottomline != NULL) ! 550: api->bottomline(bline); ! 551: while(option!=NULL && opts<MAX_OPTS) ! 552: if(option[opts]==NULL || option[opts][0]==0) ! 553: break; ! 554: else opts++; ! 555: if(mode&WIN_XTR && opts<MAX_OPTS) ! 556: opts++; ! 557: optheight=opts+vbrdrsize; ! 558: height=optheight; ! 559: if(mode&WIN_FIXEDHEIGHT) { ! 560: height=api->list_height; ! 561: } ! 562: if(top+height>s_bottom) ! 563: height=(s_bottom)-top; ! 564: if(optheight>height) ! 565: optheight=height; ! 566: if(!width || width<title_len+hbrdrsize+2) { ! 567: width=title_len+hbrdrsize+2; ! 568: for(i=0;i<opts;i++) { ! 569: if(option[i]!=NULL) { ! 570: truncsp(option[i]); ! 571: if((j=strlen(option[i])+hbrdrsize+2+1)>width) ! 572: width=j; ! 573: } ! 574: } ! 575: } ! 576: /* Determine minimum widths here to accomodate mouse "icons" in border */ ! 577: if(!(mode&WIN_NOBRDR) && api->mode&UIFC_MOUSE) { ! 578: if(bline&BL_HELP && width<8) ! 579: width=8; ! 580: else if(width<5) ! 581: width=5; ! 582: } ! 583: if(width>(s_right+1)-s_left) { ! 584: width=(s_right+1)-s_left; ! 585: if(title_len>(width-hbrdrsize-2)) { ! 586: *(title+width-hbrdrsize-2-3)='.'; ! 587: *(title+width-hbrdrsize-2-2)='.'; ! 588: *(title+width-hbrdrsize-2-1)='.'; ! 589: *(title+width-hbrdrsize-2)=0; ! 590: title_len=strlen(title); ! 591: } ! 592: } ! 593: if(mode&WIN_L2R) ! 594: left=(s_right-s_left-width+1)/2; ! 595: else if(mode&WIN_RHT) ! 596: left=s_right-(width+hbrdrsize+2+left); ! 597: if(mode&WIN_T2B) ! 598: top=(api->scrn_len-height+1)/2-2; ! 599: else if(mode&WIN_BOT) ! 600: top=s_bottom-height-top; ! 601: if(left<0) ! 602: left=0; ! 603: if(top<0) ! 604: top=0; ! 605: ! 606: /* Dynamic Menus */ ! 607: if(mode&WIN_DYN ! 608: && cur != NULL ! 609: && bar != NULL ! 610: && last_menu_cur==cur ! 611: && last_menu_bar==bar ! 612: && save_menu_cur==*cur ! 613: && save_menu_bar==*bar ! 614: && save_menu_opts==opts) { ! 615: is_redraw=1; ! 616: } ! 617: ! 618: if(mode&WIN_DYN && mode&WIN_REDRAW) ! 619: is_redraw=1; ! 620: if(mode&WIN_DYN && mode&WIN_NODRAW) ! 621: is_redraw=0; ! 622: ! 623: if(mode&WIN_ORG) { /* Clear all save buffers on WIN_ORG */ ! 624: for(i=0; i< MAX_BUFS; i++) ! 625: FREE_AND_NULL(sav[i].buf); ! 626: api->savnum=0; ! 627: } ! 628: ! 629: if(mode&WIN_SAV) { ! 630: /* Check if this screen (by cur/bar) is already saved */ ! 631: for(i=0; i<MAX_BUFS; i++) { ! 632: if(sav[i].buf!=NULL) { ! 633: if(cur==sav[i].cur && bar==sav[i].bar) { ! 634: /* Yes, it is... */ ! 635: for(j=api->savnum-1; j>i; j--) { ! 636: /* Retore old screens */ ! 637: puttext(sav[j].left,sav[j].top,sav[j].right,sav[j].bot ! 638: ,sav[j].buf); /* put original window back */ ! 639: FREE_AND_NULL(sav[j].buf); ! 640: } ! 641: api->savnum=i; ! 642: } ! 643: } ! 644: } ! 645: /* savnum not the next one - must be a dynamic window or we popped back up the stack */ ! 646: if(sav[api->savnum].buf != NULL) { ! 647: /* Is this even the right window? */ ! 648: if(sav[api->savnum].cur==cur ! 649: && sav[api->savnum].bar==bar) { ! 650: if((sav[api->savnum].left!=s_left+left ! 651: || sav[api->savnum].top!=s_top+top ! 652: || sav[api->savnum].right!=s_left+left+width+1 ! 653: || sav[api->savnum].bot!=s_top+top+height)) { /* dimensions have changed */ ! 654: puttext(sav[api->savnum].left,sav[api->savnum].top,sav[api->savnum].right,sav[api->savnum].bot ! 655: ,sav[api->savnum].buf); /* put original window back */ ! 656: FREE_AND_NULL(sav[api->savnum].buf); ! 657: if((sav[api->savnum].buf=(char *)malloc((width+3)*(height+2)*2))==NULL) { ! 658: cprintf("UIFC line %d: error allocating %u bytes." ! 659: ,__LINE__,(width+3)*(height+2)*2); ! 660: free(title); ! 661: uifc_mouse_enable(); ! 662: return(-1); ! 663: } ! 664: gettext(s_left+left,s_top+top,s_left+left+width+1 ! 665: ,s_top+top+height,sav[api->savnum].buf); /* save again */ ! 666: sav[api->savnum].left=s_left+left; ! 667: sav[api->savnum].top=s_top+top; ! 668: sav[api->savnum].right=s_left+left+width+1; ! 669: sav[api->savnum].bot=s_top+top+height; ! 670: sav[api->savnum].cur=cur; ! 671: sav[api->savnum].bar=bar; ! 672: } ! 673: } ! 674: else { ! 675: /* Find something available... */ ! 676: while(sav[api->savnum].buf!=NULL) ! 677: api->savnum++; ! 678: } ! 679: } ! 680: else { ! 681: if((sav[api->savnum].buf=(char *)malloc((width+3)*(height+2)*2))==NULL) { ! 682: cprintf("UIFC line %d: error allocating %u bytes." ! 683: ,__LINE__,(width+3)*(height+2)*2); ! 684: free(title); ! 685: uifc_mouse_enable(); ! 686: return(-1); ! 687: } ! 688: gettext(s_left+left,s_top+top,s_left+left+width+1 ! 689: ,s_top+top+height,sav[api->savnum].buf); ! 690: sav[api->savnum].left=s_left+left; ! 691: sav[api->savnum].top=s_top+top; ! 692: sav[api->savnum].right=s_left+left+width+1; ! 693: sav[api->savnum].bot=s_top+top+height; ! 694: sav[api->savnum].cur=cur; ! 695: sav[api->savnum].bar=bar; ! 696: } ! 697: } ! 698: ! 699: if(!is_redraw) { ! 700: if(mode&WIN_ORG) { /* Clear around menu */ ! 701: if(top) ! 702: puttext(1,2,api->scrn_width,s_top+top-1,blk_scrn); ! 703: if((unsigned)(s_top+height+top)<=api->scrn_len) ! 704: puttext(1,s_top+height+top,api->scrn_width,api->scrn_len,blk_scrn); ! 705: if(left) ! 706: puttext(1,s_top+top,s_left+left-1,s_top+height+top ! 707: ,blk_scrn); ! 708: if(s_left+left+width<=s_right) ! 709: puttext(s_left+left+width,s_top+top,/* s_right+2 */api->scrn_width ! 710: ,s_top+height+top,blk_scrn); ! 711: } ! 712: ptr=tmp_buffer; ! 713: if(!(mode&WIN_NOBRDR)) { ! 714: *(ptr++)='�'; ! 715: *(ptr++)=hclr|(bclr<<4); ! 716: ! 717: if(api->mode&UIFC_MOUSE) { ! 718: *(ptr++)='['; ! 719: *(ptr++)=hclr|(bclr<<4); ! 720: /* *(ptr++)='�'; */ ! 721: *(ptr++)=0xfe; ! 722: *(ptr++)=lclr|(bclr<<4); ! 723: *(ptr++)=']'; ! 724: *(ptr++)=hclr|(bclr<<4); ! 725: i=3; ! 726: if(bline&BL_HELP) { ! 727: *(ptr++)='['; ! 728: *(ptr++)=hclr|(bclr<<4); ! 729: *(ptr++)='?'; ! 730: *(ptr++)=lclr|(bclr<<4); ! 731: *(ptr++)=']'; ! 732: *(ptr++)=hclr|(bclr<<4); ! 733: i+=3; ! 734: } ! 735: api->buttony=s_top+top; ! 736: api->exitstart=s_left+left+1; ! 737: api->exitend=s_left+left+3; ! 738: api->helpstart=s_left+left+4; ! 739: api->helpend=s_left+left+6; ! 740: } ! 741: else ! 742: i=0; ! 743: ! 744: for(;i<width-2;i++) { ! 745: *(ptr++)='�'; ! 746: *(ptr++)=hclr|(bclr<<4); ! 747: } ! 748: *(ptr++)='�'; ! 749: *(ptr++)=hclr|(bclr<<4); ! 750: *(ptr++)='�'; ! 751: *(ptr++)=hclr|(bclr<<4); ! 752: a=title_len; ! 753: b=(width-a-1)/2; ! 754: for(i=0;i<b;i++) { ! 755: *(ptr++)=' '; ! 756: *(ptr++)=hclr|(bclr<<4); ! 757: } ! 758: for(i=0;i<a;i++) { ! 759: *(ptr++)=title[i]; ! 760: *(ptr++)=hclr|(bclr<<4); ! 761: } ! 762: for(i=0;i<width-(a+b)-2;i++) { ! 763: *(ptr++)=' '; ! 764: *(ptr++)=hclr|(bclr<<4); ! 765: } ! 766: *(ptr++)='�'; ! 767: *(ptr++)=hclr|(bclr<<4); ! 768: *(ptr++)='�'; ! 769: *(ptr++)=hclr|(bclr<<4); ! 770: for(i=0;i<width-2;i++) { ! 771: *(ptr++)='�'; ! 772: *(ptr++)=hclr|(bclr<<4); ! 773: } ! 774: *(ptr++)='�'; ! 775: *(ptr++)=hclr|(bclr<<4); ! 776: } ! 777: ! 778: if((*cur)>=opts) ! 779: (*cur)=opts-1; /* returned after scrolled */ ! 780: ! 781: if(!bar) { ! 782: if((*cur)>height-vbrdrsize-1) ! 783: (*cur)=height-vbrdrsize-1; ! 784: if((*cur)>opts-1) ! 785: (*cur)=opts-1; ! 786: i=0; ! 787: } ! 788: else { ! 789: if((*bar)>=opts) ! 790: (*bar)=opts-1; ! 791: if((*bar)>height-vbrdrsize-1) ! 792: (*bar)=height-vbrdrsize-1; ! 793: if((*cur)==opts-1) ! 794: (*bar)=height-vbrdrsize-1; ! 795: if((*bar)>opts-1) ! 796: (*bar)=opts-1; ! 797: if((*bar)<0) ! 798: (*bar)=0; ! 799: if((*cur)<(*bar)) ! 800: (*cur)=(*bar); ! 801: i=(*cur)-(*bar); ! 802: if(i+(height-vbrdrsize-1)>=opts) { ! 803: i=opts-(height-vbrdrsize); ! 804: if(i<0) ! 805: i=0; ! 806: (*cur)=i+(*bar); ! 807: } ! 808: } ! 809: if((*cur)<0) ! 810: (*cur)=0; ! 811: ! 812: j=0; ! 813: if(i<0) i=0; ! 814: longopt=0; ! 815: while(j<height-vbrdrsize) { ! 816: if(!(mode&WIN_NOBRDR)) { ! 817: *(ptr++)='�'; ! 818: *(ptr++)=hclr|(bclr<<4); ! 819: } ! 820: *(ptr++)=' '; ! 821: *(ptr++)=hclr|(bclr<<4); ! 822: *(ptr++)='�'; ! 823: *(ptr++)=lclr|(bclr<<4); ! 824: if(i==(*cur)) ! 825: a=lbclr; ! 826: else ! 827: a=lclr|(bclr<<4); ! 828: if(i<opts && option[i]!=NULL) { ! 829: b=strlen(option[i]); ! 830: if(b>longopt) ! 831: longopt=b; ! 832: if(b+hbrdrsize+2>width) ! 833: b=width-hbrdrsize-2; ! 834: for(c=0;c<b;c++) { ! 835: *(ptr++)=option[i][c]; ! 836: *(ptr++)=a; ! 837: } ! 838: } ! 839: else ! 840: c=0; ! 841: while(c<width-hbrdrsize-2) { ! 842: *(ptr++)=' '; ! 843: *(ptr++)=a; ! 844: c++; ! 845: } ! 846: if(!(mode&WIN_NOBRDR)) { ! 847: *(ptr++)='�'; ! 848: *(ptr++)=hclr|(bclr<<4); ! 849: } ! 850: i++; ! 851: j++; ! 852: } ! 853: if(!(mode&WIN_NOBRDR)) { ! 854: *(ptr++)='�'; ! 855: *(ptr++)=hclr|(bclr<<4); ! 856: for(i=0;i<width-2;i++) { ! 857: *(ptr++)='�'; ! 858: *(ptr++)=hclr|(bclr<<4); ! 859: } ! 860: *(ptr++)='�'; ! 861: *(ptr)=hclr|(bclr<<4); /* Not incremented to shut ot BCC */ ! 862: } ! 863: puttext(s_left+left,s_top+top,s_left+left+width-1 ! 864: ,s_top+top+height-1,tmp_buffer); ! 865: if(bar) ! 866: y=top+tbrdrwidth+(*bar); ! 867: else ! 868: y=top+tbrdrwidth+(*cur); ! 869: if(opts+vbrdrsize>height && ((!bar && (*cur)!=opts-1) ! 870: || (bar && ((*cur)-(*bar))+(height-vbrdrsize)<opts))) { ! 871: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1); ! 872: textattr(lclr|(bclr<<4)); ! 873: putch(31); /* put down arrow */ ! 874: textattr(hclr|(bclr<<4)); ! 875: } ! 876: ! 877: if(bar && (*bar)!=(*cur)) { ! 878: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth); ! 879: textattr(lclr|(bclr<<4)); ! 880: putch(30); /* put the up arrow */ ! 881: textattr(hclr|(bclr<<4)); ! 882: } ! 883: ! 884: if(!(mode&WIN_NOBRDR)) { ! 885: /* Shadow */ ! 886: if(bclr==BLUE) { ! 887: gettext(s_left+left+width,s_top+top+1,s_left+left+width+1 ! 888: ,s_top+top+height-1,shade); ! 889: for(i=1;i<height*4;i+=2) ! 890: shade[i]=DARKGRAY; ! 891: puttext(s_left+left+width,s_top+top+1,s_left+left+width+1 ! 892: ,s_top+top+height-1,shade); ! 893: gettext(s_left+left+2,s_top+top+height,s_left+left+width+1 ! 894: ,s_top+top+height,shade); ! 895: for(i=1;i<width*2;i+=2) ! 896: shade[i]=DARKGRAY; ! 897: puttext(s_left+left+2,s_top+top+height,s_left+left+width+1 ! 898: ,s_top+top+height,shade); ! 899: } ! 900: } ! 901: } ! 902: else { /* Is a redraw */ ! 903: if(bar) ! 904: y=top+tbrdrwidth+(*bar); ! 905: else ! 906: y=top+tbrdrwidth+(*cur); ! 907: i=(*cur)+(top+tbrdrwidth-y); ! 908: j=2; ! 909: ! 910: longopt=0; ! 911: while(j<height-bbrdrwidth-1) { ! 912: ptr=tmp_buffer; ! 913: if(i==(*cur)) ! 914: a=lbclr; ! 915: else ! 916: a=lclr|(bclr<<4); ! 917: if(i<opts && option[i]!=NULL) { ! 918: b=strlen(option[i]); ! 919: if(b>longopt) ! 920: longopt=b; ! 921: if(b+hbrdrsize+2>width) ! 922: b=width-hbrdrsize-2; ! 923: for(c=0;c<b;c++) { ! 924: *(ptr++)=option[i][c]; ! 925: *(ptr++)=a; ! 926: } ! 927: } ! 928: else ! 929: c=0; ! 930: while(c<width-hbrdrsize-2) { ! 931: *(ptr++)=' '; ! 932: *(ptr++)=a; ! 933: c++; ! 934: } ! 935: i++; ! 936: j++; ! 937: puttext(s_left+left+lbrdrwidth+2,s_top+top+j,s_left+left+width-rbrdrwidth-1 ! 938: ,s_top+top+j,tmp_buffer); ! 939: } ! 940: } ! 941: free(title); ! 942: ! 943: last_menu_cur=cur; ! 944: last_menu_bar=bar; ! 945: uifc_mouse_enable(); ! 946: ! 947: if(mode&WIN_IMM) { ! 948: return(-2); ! 949: } ! 950: ! 951: if(mode&WIN_ORG) { ! 952: if(api->timedisplay != NULL) ! 953: api->timedisplay(/* force? */TRUE); ! 954: } ! 955: ! 956: while(1) { ! 957: #if 0 /* debug */ ! 958: gotoxy(30,1); ! 959: cprintf("y=%2d h=%2d c=%2d b=%2d s=%2d o=%2d" ! 960: ,y,height,*cur,bar ? *bar :0xff,api->savnum,opts); ! 961: #endif ! 962: if(api->timedisplay != NULL) ! 963: api->timedisplay(/* force? */FALSE); ! 964: i=0; ! 965: if(kbwait()) { ! 966: i=inkey(); ! 967: if(i==CIO_KEY_MOUSE) { ! 968: if((i=uifc_getmouse(&mevnt))==0) { ! 969: /* Clicked in menu */ ! 970: if(mevnt.startx>=s_left+left+lbrdrwidth+2 ! 971: && mevnt.startx<=s_left+left+width-rbrdrwidth-1 ! 972: && mevnt.starty>=s_top+top+tbrdrwidth ! 973: && mevnt.starty<=(s_top+top+optheight)-bbrdrwidth-1 ! 974: && mevnt.event==CIOLIB_BUTTON_1_CLICK) { ! 975: ! 976: (*cur)=((mevnt.starty)-(s_top+top+tbrdrwidth))+(*cur+(top+tbrdrwidth-y)); ! 977: if(bar) ! 978: (*bar)=(*cur); ! 979: y=top+tbrdrwidth+((mevnt.starty)-(s_top+top+tbrdrwidth)); ! 980: ! 981: if(!opts) ! 982: continue; ! 983: ! 984: if(mode&WIN_SAV) ! 985: api->savnum++; ! 986: if(mode&WIN_ACT) { ! 987: uifc_mouse_disable(); ! 988: if((win=(char *)alloca((width+3)*(height+2)*2))==NULL) { ! 989: cprintf("UIFC line %d: error allocating %u bytes." ! 990: ,__LINE__,(width+3)*(height+2)*2); ! 991: return(-1); ! 992: } ! 993: gettext(s_left+left,s_top+top,s_left ! 994: +left+width-1,s_top+top+height-1,win); ! 995: for(i=1;i<(width*height*2);i+=2) ! 996: win[i]=lclr|(cclr<<4); ! 997: j=(((y-top)*width)*2)+7+((width-hbrdrsize-2)*2); ! 998: for(i=(((y-top)*width)*2)+7;i<j;i+=2) ! 999: win[i]=hclr|(cclr<<4); ! 1000: ! 1001: puttext(s_left+left,s_top+top,s_left ! 1002: +left+width-1,s_top+top+height-1,win); ! 1003: uifc_mouse_enable(); ! 1004: } ! 1005: else if(mode&WIN_SAV) { ! 1006: api->savnum--; ! 1007: uifc_mouse_disable(); ! 1008: puttext(sav[api->savnum].left,sav[api->savnum].top ! 1009: ,sav[api->savnum].right,sav[api->savnum].bot ! 1010: ,sav[api->savnum].buf); ! 1011: uifc_mouse_enable(); ! 1012: FREE_AND_NULL(sav[api->savnum].buf); ! 1013: } ! 1014: if(mode&WIN_XTR && (*cur)==opts-1) ! 1015: return(MSK_INS|*cur); ! 1016: return(*cur); ! 1017: } ! 1018: /* Clicked Scroll Up */ ! 1019: else if(mevnt.startx==s_left+left+lbrdrwidth ! 1020: && mevnt.starty==s_top+top+tbrdrwidth ! 1021: && mevnt.event==CIOLIB_BUTTON_1_CLICK) { ! 1022: i=CIO_KEY_PPAGE; ! 1023: } ! 1024: /* Clicked Scroll Down */ ! 1025: else if(mevnt.startx==s_left+left+lbrdrwidth ! 1026: && mevnt.starty==(s_top+top+height)-bbrdrwidth-1 ! 1027: && mevnt.event==CIOLIB_BUTTON_1_CLICK) { ! 1028: i=CIO_KEY_NPAGE; ! 1029: } ! 1030: /* Clicked Outside of Window */ ! 1031: else if((mevnt.startx<s_left+left ! 1032: || mevnt.startx>s_left+left+width-1 ! 1033: || mevnt.starty<s_top+top ! 1034: || mevnt.starty>s_top+top+height-1) ! 1035: && (mevnt.event==CIOLIB_BUTTON_1_CLICK ! 1036: || mevnt.event==CIOLIB_BUTTON_3_CLICK)) { ! 1037: if(mode&WIN_UNGETMOUSE) { ! 1038: ungetmouse(&mevnt); ! 1039: i=CIO_KEY_MOUSE; ! 1040: } ! 1041: else { ! 1042: i=ESC; ! 1043: } ! 1044: } ! 1045: } ! 1046: } ! 1047: /* For compatibility with terminals lacking special keys */ ! 1048: switch(i) { ! 1049: case '\b': ! 1050: i=ESC; ! 1051: break; ! 1052: case '+': ! 1053: i=CIO_KEY_IC; /* insert */ ! 1054: break; ! 1055: case '-': ! 1056: case DEL: ! 1057: i=CIO_KEY_DC; /* delete */ ! 1058: break; ! 1059: case CTRL_B: ! 1060: if(!(api->mode&UIFC_NOCTRL)) ! 1061: i=CIO_KEY_HOME; ! 1062: break; ! 1063: case CTRL_E: ! 1064: if(!(api->mode&UIFC_NOCTRL)) ! 1065: i=CIO_KEY_END; ! 1066: break; ! 1067: case CTRL_U: ! 1068: if(!(api->mode&UIFC_NOCTRL)) ! 1069: i=CIO_KEY_PPAGE; ! 1070: break; ! 1071: case CTRL_D: ! 1072: if(!(api->mode&UIFC_NOCTRL)) ! 1073: i=CIO_KEY_NPAGE; ! 1074: break; ! 1075: case CTRL_Z: ! 1076: if(!(api->mode&UIFC_NOCTRL)) ! 1077: i=CIO_KEY_F(1); /* help */ ! 1078: break; ! 1079: case CTRL_C: ! 1080: if(!(api->mode&UIFC_NOCTRL)) ! 1081: i=CIO_KEY_F(5); /* copy */ ! 1082: break; ! 1083: case CTRL_V: ! 1084: if(!(api->mode&UIFC_NOCTRL)) ! 1085: i=CIO_KEY_F(6); /* paste */ ! 1086: break; ! 1087: } ! 1088: if(i>255) { ! 1089: s=0; ! 1090: switch(i) { ! 1091: /* ToDo extended keys */ ! 1092: case CIO_KEY_HOME: /* home */ ! 1093: if(!opts) ! 1094: break; ! 1095: if(opts+vbrdrsize>optheight) { ! 1096: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth); ! 1097: textattr(lclr|(bclr<<4)); ! 1098: putch(' '); /* Delete the up arrow */ ! 1099: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1); ! 1100: putch(31); /* put the down arrow */ ! 1101: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth ! 1102: ,lbclr ! 1103: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[0]); ! 1104: for(i=1;i<optheight-vbrdrsize;i++) /* re-display options */ ! 1105: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+i ! 1106: ,lclr|(bclr<<4) ! 1107: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]); ! 1108: (*cur)=0; ! 1109: if(bar) ! 1110: (*bar)=0; ! 1111: y=top+tbrdrwidth; ! 1112: break; ! 1113: } ! 1114: gettext(s_left+left+lbrdrwidth+2,s_top+y ! 1115: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1116: for(i=1;i<width*2;i+=2) ! 1117: line[i]=lclr|(bclr<<4); ! 1118: puttext(s_left+left+lbrdrwidth+2,s_top+y ! 1119: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1120: (*cur)=0; ! 1121: if(bar) ! 1122: (*bar)=0; ! 1123: y=top+tbrdrwidth; ! 1124: gettext(s_left+lbrdrwidth+2+left,s_top+y ! 1125: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1126: for(i=1;i<width*2;i+=2) ! 1127: line[i]=lbclr; ! 1128: puttext(s_left+lbrdrwidth+2+left,s_top+y ! 1129: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1130: break; ! 1131: case CIO_KEY_UP: /* up arrow */ ! 1132: if(!opts) ! 1133: break; ! 1134: if(!(*cur) && opts+vbrdrsize>optheight) { ! 1135: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth); /* like end */ ! 1136: textattr(lclr|(bclr<<4)); ! 1137: putch(30); /* put the up arrow */ ! 1138: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1); ! 1139: putch(' '); /* delete the down arrow */ ! 1140: for(i=(opts+vbrdrsize)-optheight,j=0;i<opts;i++,j++) ! 1141: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+j ! 1142: ,i==opts-1 ? lbclr ! 1143: : lclr|(bclr<<4) ! 1144: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]); ! 1145: (*cur)=opts-1; ! 1146: if(bar) ! 1147: (*bar)=optheight-vbrdrsize-1; ! 1148: y=top+optheight-bbrdrwidth-1; ! 1149: break; ! 1150: } ! 1151: gettext(s_left+lbrdrwidth+2+left,s_top+y ! 1152: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1153: for(i=1;i<width*2;i+=2) ! 1154: line[i]=lclr|(bclr<<4); ! 1155: puttext(s_left+lbrdrwidth+2+left,s_top+y ! 1156: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1157: if(!(*cur)) { ! 1158: y=top+optheight-bbrdrwidth-1; ! 1159: (*cur)=opts-1; ! 1160: if(bar) ! 1161: (*bar)=optheight-vbrdrsize-1; ! 1162: } ! 1163: else { ! 1164: (*cur)--; ! 1165: y--; ! 1166: if(bar && *bar) ! 1167: (*bar)--; ! 1168: } ! 1169: if(y<top+tbrdrwidth) { /* scroll */ ! 1170: if(!(*cur)) { ! 1171: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth); ! 1172: textattr(lclr|(bclr<<4)); ! 1173: putch(' '); /* delete the up arrow */ ! 1174: } ! 1175: if((*cur)+optheight-vbrdrsize==opts-1) { ! 1176: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1); ! 1177: textattr(lclr|(bclr<<4)); ! 1178: putch(31); /* put the dn arrow */ ! 1179: } ! 1180: y++; ! 1181: scroll_text(s_left+left+lbrdrwidth+1,s_top+top+tbrdrwidth ! 1182: ,s_left+left+width-rbrdrwidth-1,s_top+top+height-bbrdrwidth-1,1); ! 1183: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth ! 1184: ,lbclr ! 1185: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[*cur]); ! 1186: } ! 1187: else { ! 1188: gettext(s_left+lbrdrwidth+2+left,s_top+y ! 1189: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1190: for(i=1;i<width*2;i+=2) ! 1191: line[i]=lbclr; ! 1192: puttext(s_left+lbrdrwidth+2+left,s_top+y ! 1193: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1194: } ! 1195: break; ! 1196: case CIO_KEY_PPAGE: /* PgUp */ ! 1197: if(!opts) ! 1198: break; ! 1199: *cur -= (optheight-vbrdrsize-1); ! 1200: if(*cur<0) ! 1201: *cur = 0; ! 1202: if(bar) ! 1203: *bar=0; ! 1204: y=top+tbrdrwidth; ! 1205: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth); ! 1206: textattr(lclr|(bclr<<4)); ! 1207: if(*cur && opts>height-tbrdrwidth) /* Scroll mode */ ! 1208: putch(30); /* put the up arrow */ ! 1209: else ! 1210: putch(' '); /* delete the up arrow */ ! 1211: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1); ! 1212: if(opts > height-tbrdrwidth && *cur + height - vbrdrsize < opts) ! 1213: putch(31); /* put the down arrow */ ! 1214: else ! 1215: putch(' '); /* delete the down arrow */ ! 1216: for(i=*cur,j=0;i<=*cur-vbrdrsize-1+optheight;i++,j++) ! 1217: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+j ! 1218: ,i==*cur ? lbclr ! 1219: : lclr|(bclr<<4) ! 1220: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]); ! 1221: break; ! 1222: case CIO_KEY_NPAGE: /* PgDn */ ! 1223: if(!opts) ! 1224: break; ! 1225: *cur += (height-vbrdrsize-1); ! 1226: if(*cur>opts-1) ! 1227: *cur = opts-1; ! 1228: if(bar) ! 1229: *bar = optheight-vbrdrsize-1; ! 1230: y=top+optheight-bbrdrwidth-1; ! 1231: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth); ! 1232: textattr(lclr|(bclr<<4)); ! 1233: if(*cur>height-vbrdrsize-1) /* Scroll mode */ ! 1234: putch(30); /* put the up arrow */ ! 1235: else ! 1236: putch(' '); /* delete the up arrow */ ! 1237: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1); ! 1238: if(*cur < opts-1) ! 1239: putch(31); /* put the down arrow */ ! 1240: else ! 1241: putch(' '); /* delete the down arrow */ ! 1242: for(i=*cur+vbrdrsize+1-optheight,j=0;i<=*cur;i++,j++) ! 1243: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+j ! 1244: ,i==*cur ? lbclr ! 1245: : lclr|(bclr<<4) ! 1246: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]); ! 1247: break; ! 1248: case CIO_KEY_END: /* end */ ! 1249: if(!opts) ! 1250: break; ! 1251: if(opts+vbrdrsize>height) { /* Scroll mode */ ! 1252: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth); ! 1253: textattr(lclr|(bclr<<4)); ! 1254: putch(30); /* put the up arrow */ ! 1255: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1); ! 1256: putch(' '); /* delete the down arrow */ ! 1257: for(i=(opts+vbrdrsize)-height,j=0;i<opts;i++,j++) ! 1258: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+j ! 1259: ,i==opts-1 ? lbclr ! 1260: : lclr|(bclr<<4) ! 1261: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]); ! 1262: (*cur)=opts-1; ! 1263: y=top+optheight-bbrdrwidth-1; ! 1264: if(bar) ! 1265: (*bar)=optheight-vbrdrsize-1; ! 1266: break; ! 1267: } ! 1268: gettext(s_left+lbrdrwidth+2+left,s_top+y ! 1269: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1270: for(i=1;i<width*2;i+=2) ! 1271: line[i]=lclr|(bclr<<4); ! 1272: puttext(s_left+lbrdrwidth+2+left,s_top+y ! 1273: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1274: (*cur)=opts-1; ! 1275: y=top+optheight-bbrdrwidth-1; ! 1276: if(bar) ! 1277: (*bar)=optheight-vbrdrsize-1; ! 1278: gettext(s_left+lbrdrwidth+2+left,s_top+y ! 1279: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1280: for(i=1;i<148;i+=2) ! 1281: line[i]=lbclr; ! 1282: puttext(s_left+lbrdrwidth+2+left,s_top+y ! 1283: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1284: break; ! 1285: case CIO_KEY_DOWN: /* dn arrow */ ! 1286: if(!opts) ! 1287: break; ! 1288: if((*cur)==opts-1 && opts+vbrdrsize>height) { /* like home */ ! 1289: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth); ! 1290: textattr(lclr|(bclr<<4)); ! 1291: putch(' '); /* Delete the up arrow */ ! 1292: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1); ! 1293: putch(31); /* put the down arrow */ ! 1294: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth ! 1295: ,lbclr ! 1296: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[0]); ! 1297: for(i=1;i<height-vbrdrsize;i++) /* re-display options */ ! 1298: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+i ! 1299: ,lclr|(bclr<<4) ! 1300: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]); ! 1301: (*cur)=0; ! 1302: y=top+tbrdrwidth; ! 1303: if(bar) ! 1304: (*bar)=0; ! 1305: break; ! 1306: } ! 1307: gettext(s_left+lbrdrwidth+2+left,s_top+y ! 1308: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1309: for(i=1;i<width*2;i+=2) ! 1310: line[i]=lclr|(bclr<<4); ! 1311: puttext(s_left+lbrdrwidth+2+left,s_top+y ! 1312: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1313: if((*cur)==opts-1) { ! 1314: (*cur)=0; ! 1315: y=top+tbrdrwidth; ! 1316: if(bar) { ! 1317: /* gotoxy(1,1); cprintf("bar=%08lX ",bar); */ ! 1318: (*bar)=0; ! 1319: } ! 1320: } ! 1321: else { ! 1322: (*cur)++; ! 1323: y++; ! 1324: if(bar && (*bar)<height-vbrdrsize-1) { ! 1325: /* gotoxy(1,1); cprintf("bar=%08lX ",bar); */ ! 1326: (*bar)++; ! 1327: } ! 1328: } ! 1329: if(y==top+height-bbrdrwidth) { /* scroll */ ! 1330: if(*cur==opts-1) { ! 1331: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1); ! 1332: textattr(lclr|(bclr<<4)); ! 1333: putch(' '); /* delete the down arrow */ ! 1334: } ! 1335: if((*cur)+vbrdrsize==height) { ! 1336: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth); ! 1337: textattr(lclr|(bclr<<4)); ! 1338: putch(30); /* put the up arrow */ ! 1339: } ! 1340: y--; ! 1341: /* gotoxy(1,1); cprintf("\rdebug: %4d ",__LINE__); */ ! 1342: scroll_text(s_left+left+lbrdrwidth+1,s_top+top+tbrdrwidth ! 1343: ,s_left+left+width-rbrdrwidth-1,s_top+top+height-bbrdrwidth-1,0); ! 1344: /* gotoxy(1,1); cprintf("\rdebug: %4d ",__LINE__); */ ! 1345: uprintf(s_left+left+lbrdrwidth+2,s_top+top+height-bbrdrwidth-1 ! 1346: ,lbclr ! 1347: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[*cur]); ! 1348: } ! 1349: else { ! 1350: gettext(s_left+lbrdrwidth+2+left,s_top+y ! 1351: ,s_left+left+width-rbrdrwidth-1,s_top+y ! 1352: ,line); ! 1353: for(i=1;i<width*2;i+=2) ! 1354: line[i]=lbclr; ! 1355: puttext(s_left+lbrdrwidth+2+left,s_top+y ! 1356: ,s_left+left+width-rbrdrwidth-1,s_top+y ! 1357: ,line); ! 1358: } ! 1359: break; ! 1360: case CIO_KEY_F(1): /* F1 - Help */ ! 1361: api->showhelp(); ! 1362: break; ! 1363: case CIO_KEY_F(2): /* F2 - Edit */ ! 1364: if(mode&WIN_XTR && (*cur)==opts-1) /* can't edit */ ! 1365: break; /* extra line */ ! 1366: if(mode&WIN_EDIT) { ! 1367: if(mode&WIN_EDITACT) { ! 1368: gettext(s_left+left,s_top+top,s_left ! 1369: +left+width-1,s_top+top+height-1,tmp_buffer); ! 1370: for(i=1;i<(width*height*2);i+=2) ! 1371: tmp_buffer[i]=lclr|(cclr<<4); ! 1372: j=(((y-top)*width)*2)+7+((width-hbrdrsize-2)*2); ! 1373: for(i=(((y-top)*width)*2)+7;i<j;i+=2) ! 1374: tmp_buffer[i]=hclr|(cclr<<4); ! 1375: puttext(s_left+left,s_top+top,s_left ! 1376: +left+width-1,s_top+top+height-1,tmp_buffer); ! 1377: } ! 1378: return((*cur)|MSK_EDIT); ! 1379: } ! 1380: break; ! 1381: case CIO_KEY_F(5): /* F5 - Copy */ ! 1382: if(mode&WIN_GET && !(mode&WIN_XTR && (*cur)==opts-1)) ! 1383: return((*cur)|MSK_GET); ! 1384: break; ! 1385: case CIO_KEY_F(6): /* F6 - Paste */ ! 1386: if(mode&WIN_PUT && !(mode&WIN_XTR && (*cur)==opts-1)) ! 1387: return((*cur)|MSK_PUT); ! 1388: break; ! 1389: case CIO_KEY_IC: /* insert */ ! 1390: if(mode&WIN_INS) { ! 1391: if(mode&WIN_INSACT) { ! 1392: gettext(s_left+left,s_top+top,s_left ! 1393: +left+width-1,s_top+top+height-1,tmp_buffer); ! 1394: for(i=1;i<(width*height*2);i+=2) ! 1395: tmp_buffer[i]=lclr|(cclr<<4); ! 1396: if(opts) { ! 1397: j=(((y-top)*width)*2)+7+((width-hbrdrsize-2)*2); ! 1398: for(i=(((y-top)*width)*2)+7;i<j;i+=2) ! 1399: tmp_buffer[i]=hclr|(cclr<<4); ! 1400: } ! 1401: puttext(s_left+left,s_top+top,s_left ! 1402: +left+width-1,s_top+top+height-1,tmp_buffer); ! 1403: } ! 1404: if(!opts) { ! 1405: return(MSK_INS); ! 1406: } ! 1407: return((*cur)|MSK_INS); ! 1408: } ! 1409: break; ! 1410: case CIO_KEY_DC: /* delete */ ! 1411: if(mode&WIN_XTR && (*cur)==opts-1) /* can't delete */ ! 1412: break; /* extra line */ ! 1413: if(mode&WIN_DEL) { ! 1414: if(mode&WIN_DELACT) { ! 1415: gettext(s_left+left,s_top+top,s_left ! 1416: +left+width-1,s_top+top+height-1,tmp_buffer); ! 1417: for(i=1;i<(width*height*2);i+=2) ! 1418: tmp_buffer[i]=lclr|(cclr<<4); ! 1419: j=(((y-top)*width)*2)+7+((width-hbrdrsize-2)*2); ! 1420: for(i=(((y-top)*width)*2)+7;i<j;i+=2) ! 1421: tmp_buffer[i]=hclr|(cclr<<4); ! 1422: puttext(s_left+left,s_top+top,s_left ! 1423: +left+width-1,s_top+top+height-1,tmp_buffer); ! 1424: } ! 1425: return((*cur)|MSK_DEL); ! 1426: } ! 1427: break; ! 1428: default: ! 1429: if(mode&WIN_EXTKEYS) ! 1430: return(-2-i); ! 1431: break; ! 1432: } ! 1433: } ! 1434: else { ! 1435: i&=0xff; ! 1436: if(isalnum(i) && opts>1 && option[0][0]) { ! 1437: search[s]=i; ! 1438: search[s+1]=0; ! 1439: for(j=(*cur)+1,a=b=0;a<2;j++) { /* a = search count */ ! 1440: if(j==opts) { /* j = option count */ ! 1441: j=-1; /* b = letter count */ ! 1442: continue; ! 1443: } ! 1444: if(j==(*cur)) { ! 1445: b++; ! 1446: continue; ! 1447: } ! 1448: if(b>=longopt) { ! 1449: b=0; ! 1450: a++; ! 1451: } ! 1452: if(a==1 && !s) ! 1453: break; ! 1454: if(option[j]!=NULL ! 1455: && strlen(option[j])>(size_t)b ! 1456: && ((!a && s && !strnicmp(option[j]+b,search,s+1)) ! 1457: || ((a || !s) && toupper(option[j][b])==toupper(i)))) { ! 1458: if(a) s=0; ! 1459: else s++; ! 1460: if(y+(j-(*cur))+2>height+top) { ! 1461: (*cur)=j; ! 1462: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth); ! 1463: textattr(lclr|(bclr<<4)); ! 1464: putch(30); /* put the up arrow */ ! 1465: if((*cur)==opts-1) { ! 1466: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1); ! 1467: putch(' '); /* delete the down arrow */ ! 1468: } ! 1469: for(i=((*cur)+vbrdrsize+1)-height,j=0;i<(*cur)+1;i++,j++) ! 1470: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+j ! 1471: ,i==(*cur) ? lbclr ! 1472: : lclr|(bclr<<4) ! 1473: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]); ! 1474: y=top+height-bbrdrwidth-1; ! 1475: if(bar) ! 1476: (*bar)=optheight-vbrdrsize-1; ! 1477: break; ! 1478: } ! 1479: if(y-((*cur)-j)<top+tbrdrwidth) { ! 1480: (*cur)=j; ! 1481: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth); ! 1482: textattr(lclr|(bclr<<4)); ! 1483: if(!(*cur)) ! 1484: putch(' '); /* Delete the up arrow */ ! 1485: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1); ! 1486: putch(31); /* put the down arrow */ ! 1487: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth ! 1488: ,lbclr ! 1489: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[(*cur)]); ! 1490: for(i=1;i<height-vbrdrsize;i++) /* re-display options */ ! 1491: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+i ! 1492: ,lclr|(bclr<<4) ! 1493: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2 ! 1494: ,option[(*cur)+i]); ! 1495: y=top+tbrdrwidth; ! 1496: if(bar) ! 1497: (*bar)=0; ! 1498: break; ! 1499: } ! 1500: gettext(s_left+lbrdrwidth+2+left,s_top+y ! 1501: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1502: for(i=1;i<width*2;i+=2) ! 1503: line[i]=lclr|(bclr<<4); ! 1504: puttext(s_left+lbrdrwidth+2+left,s_top+y ! 1505: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1506: if((*cur)>j) ! 1507: y-=(*cur)-j; ! 1508: else ! 1509: y+=j-(*cur); ! 1510: if(bar) { ! 1511: if((*cur)>j) ! 1512: (*bar)-=(*cur)-j; ! 1513: else ! 1514: (*bar)+=j-(*cur); ! 1515: } ! 1516: (*cur)=j; ! 1517: gettext(s_left+lbrdrwidth+2+left,s_top+y ! 1518: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1519: for(i=1;i<width*2;i+=2) ! 1520: line[i]=lbclr; ! 1521: puttext(s_left+lbrdrwidth+2+left,s_top+y ! 1522: ,s_left+left+width-rbrdrwidth-1,s_top+y,line); ! 1523: break; ! 1524: } ! 1525: } ! 1526: if(a==2) ! 1527: s=0; ! 1528: } ! 1529: else ! 1530: switch(i) { ! 1531: case CR: ! 1532: if(!opts) ! 1533: break; ! 1534: if(mode&WIN_SAV) ! 1535: api->savnum++; ! 1536: if(mode&WIN_ACT) { ! 1537: gettext(s_left+left,s_top+top,s_left ! 1538: +left+width-1,s_top+top+height-1,tmp_buffer); ! 1539: for(i=1;i<(width*height*2);i+=2) ! 1540: tmp_buffer[i]=lclr|(cclr<<4); ! 1541: j=(((y-top)*width)*2)+7+((width-hbrdrsize-2)*2); ! 1542: for(i=(((y-top)*width)*2)+7;i<j;i+=2) ! 1543: tmp_buffer[i]=hclr|(cclr<<4); ! 1544: ! 1545: puttext(s_left+left,s_top+top,s_left ! 1546: +left+width-1,s_top+top+height-1,tmp_buffer); ! 1547: } ! 1548: else if(mode&WIN_SAV) { ! 1549: api->savnum--; ! 1550: puttext(sav[api->savnum].left,sav[api->savnum].top ! 1551: ,sav[api->savnum].right,sav[api->savnum].bot ! 1552: ,sav[api->savnum].buf); ! 1553: FREE_AND_NULL(sav[api->savnum].buf); ! 1554: } ! 1555: if(mode&WIN_XTR && (*cur)==opts-1) ! 1556: return(MSK_INS|*cur); ! 1557: return(*cur); ! 1558: case 3: ! 1559: case ESC: ! 1560: if(mode&WIN_SAV) ! 1561: api->savnum++; ! 1562: if(mode&WIN_ESC || (mode&WIN_CHE && api->changes)) { ! 1563: gettext(s_left+left,s_top+top,s_left ! 1564: +left+width-1,s_top+top+height-1,tmp_buffer); ! 1565: for(i=1;i<(width*height*2);i+=2) ! 1566: tmp_buffer[i]=lclr|(cclr<<4); ! 1567: puttext(s_left+left,s_top+top,s_left ! 1568: +left+width-1,s_top+top+height-1,tmp_buffer); ! 1569: } ! 1570: else if(mode&WIN_SAV) { ! 1571: api->savnum--; ! 1572: puttext(sav[api->savnum].left,sav[api->savnum].top ! 1573: ,sav[api->savnum].right,sav[api->savnum].bot ! 1574: ,sav[api->savnum].buf); ! 1575: FREE_AND_NULL(sav[api->savnum].buf); ! 1576: } ! 1577: return(-1); ! 1578: default: ! 1579: if(mode&WIN_EXTKEYS) ! 1580: return(-2-i); ! 1581: } ! 1582: } ! 1583: } ! 1584: else ! 1585: mswait(1); ! 1586: if(mode&WIN_DYN) { ! 1587: save_menu_cur=*cur; ! 1588: save_menu_bar=*bar; ! 1589: save_menu_opts=opts; ! 1590: return(-2-i); ! 1591: } ! 1592: } ! 1593: } ! 1594: ! 1595: ! 1596: /*************************************************************************/ ! 1597: /* This function is a windowed input string input routine. */ ! 1598: /*************************************************************************/ ! 1599: int uinput(int mode, int left, int top, char *inprompt, char *str, ! 1600: int max, int kmode) ! 1601: { ! 1602: unsigned char save_buf[2048],in_win[2048] ! 1603: ,shade[160]; ! 1604: int width; ! 1605: int height=3; ! 1606: int i,plen,slen,j; ! 1607: int iwidth; ! 1608: int l; ! 1609: char *prompt; ! 1610: int s_top=SCRN_TOP; ! 1611: int s_left=SCRN_LEFT; ! 1612: int s_right=SCRN_RIGHT; ! 1613: int s_bottom=api->scrn_len-3; ! 1614: int hbrdrsize=2; ! 1615: int lbrdrwidth=1; ! 1616: int rbrdrwidth=1; ! 1617: int vbrdrsize=4; ! 1618: int tbrdrwidth=1; ! 1619: int bbrdrwidth=1; ! 1620: ! 1621: reset_dynamic(); ! 1622: ! 1623: if(mode&WIN_FAT) { ! 1624: s_top=1; ! 1625: s_left=2; ! 1626: s_right=api->scrn_width-3; /* Leave space for the shadow */ ! 1627: s_bottom=api->scrn_len-1; /* Leave one for the shadow */ ! 1628: } ! 1629: if(mode&WIN_NOBRDR) { ! 1630: hbrdrsize=0; ! 1631: vbrdrsize=0; ! 1632: lbrdrwidth=0; ! 1633: rbrdrwidth=0; ! 1634: tbrdrwidth=0; ! 1635: bbrdrwidth=0; ! 1636: height=1; ! 1637: } ! 1638: ! 1639: prompt=strdup(inprompt==NULL ? "":inprompt); ! 1640: plen=strlen(prompt); ! 1641: if(!plen) ! 1642: slen=2+hbrdrsize; ! 1643: else ! 1644: slen=4+hbrdrsize; ! 1645: ! 1646: width=plen+slen+max; ! 1647: if(width>(s_right-s_left+1)) ! 1648: width=(s_right-s_left+1); ! 1649: if(mode&WIN_T2B) ! 1650: top=(api->scrn_len-height+1)/2-2; ! 1651: if(mode&WIN_L2R) ! 1652: left=(s_right-s_left-width+1)/2; ! 1653: if(left<=-(s_left)) ! 1654: left=-(s_left)+1; ! 1655: if(top<0) ! 1656: top=0; ! 1657: if(mode&WIN_SAV) ! 1658: gettext(s_left+left,s_top+top,s_left+left+width+1 ! 1659: ,s_top+top+height,save_buf); ! 1660: iwidth=width-plen-slen; ! 1661: while(iwidth<1 && plen>4) { ! 1662: plen=strlen(prompt); ! 1663: prompt[plen-1]=0; ! 1664: prompt[plen-2]='.'; ! 1665: prompt[plen-3]='.'; ! 1666: prompt[plen-4]='.'; ! 1667: plen--; ! 1668: iwidth=width-plen-slen; ! 1669: } ! 1670: ! 1671: i=0; ! 1672: if(!(mode&WIN_NOBRDR)) { ! 1673: in_win[i++]='�'; ! 1674: in_win[i++]=api->hclr|(api->bclr<<4); ! 1675: for(j=1;j<width-1;j++) { ! 1676: in_win[i++]='�'; ! 1677: in_win[i++]=api->hclr|(api->bclr<<4); ! 1678: } ! 1679: if(api->mode&UIFC_MOUSE && width>6) { ! 1680: j=2; ! 1681: in_win[j++]='['; ! 1682: in_win[j++]=api->hclr|(api->bclr<<4); ! 1683: /* in_win[4]='�'; */ ! 1684: in_win[j++]=0xfe; ! 1685: in_win[j++]=api->lclr|(api->bclr<<4); ! 1686: in_win[j++]=']'; ! 1687: in_win[j++]=api->hclr|(api->bclr<<4); ! 1688: l=3; ! 1689: if(api->helpbuf!=NULL || api->helpixbfile[0]!=0) { ! 1690: in_win[j++]='['; ! 1691: in_win[j++]=api->hclr|(api->bclr<<4); ! 1692: in_win[j++]='?'; ! 1693: in_win[j++]=api->lclr|(api->bclr<<4); ! 1694: in_win[j++]=']'; ! 1695: in_win[j++]=api->hclr|(api->bclr<<4); ! 1696: l+=3; ! 1697: } ! 1698: api->buttony=s_top+top; ! 1699: api->exitstart=s_left+left+1; ! 1700: api->exitend=s_left+left+3; ! 1701: api->helpstart=s_left+left+4; ! 1702: api->helpend=s_left+left+l; ! 1703: } ! 1704: ! 1705: in_win[i++]='�'; ! 1706: in_win[i++]=api->hclr|(api->bclr<<4); ! 1707: in_win[i++]='�'; ! 1708: in_win[i++]=api->hclr|(api->bclr<<4); ! 1709: } ! 1710: ! 1711: if(plen) { ! 1712: in_win[i++]=' '; ! 1713: in_win[i++]=api->lclr|(api->bclr<<4); ! 1714: } ! 1715: ! 1716: for(j=0;prompt[j];j++) { ! 1717: in_win[i++]=prompt[j]; ! 1718: in_win[i++]=api->lclr|(api->bclr<<4); ! 1719: } ! 1720: ! 1721: if(plen) { ! 1722: in_win[i++]=':'; ! 1723: in_win[i++]=api->lclr|(api->bclr<<4); ! 1724: } ! 1725: ! 1726: for(j=0;j<iwidth+2;j++) { ! 1727: in_win[i++]=' '; ! 1728: in_win[i++]=api->lclr|(api->bclr<<4); ! 1729: } ! 1730: ! 1731: if(!(mode&WIN_NOBRDR)) { ! 1732: in_win[i++]='�'; ! 1733: in_win[i++]=api->hclr|(api->bclr<<4); ! 1734: in_win[i++]='�'; ! 1735: in_win[i++]=api->hclr|(api->bclr<<4); ! 1736: for(j=1;j<width-1;j++) { ! 1737: in_win[i++]='�'; ! 1738: in_win[i++]=api->hclr|(api->bclr<<4); ! 1739: } ! 1740: in_win[i++]='�'; ! 1741: in_win[i]=api->hclr|(api->bclr<<4); /* I is not incremented to shut up BCC */ ! 1742: } ! 1743: puttext(s_left+left,s_top+top,s_left+left+width-1 ! 1744: ,s_top+top+height-1,in_win); ! 1745: ! 1746: if(!(mode&WIN_NOBRDR)) { ! 1747: /* Shadow */ ! 1748: if(api->bclr==BLUE) { ! 1749: gettext(s_left+left+width,s_top+top+1,s_left+left+width+1 ! 1750: ,s_top+top+(height-1),shade); ! 1751: for(j=1;j<12;j+=2) ! 1752: shade[j]=DARKGRAY; ! 1753: puttext(s_left+left+width,s_top+top+1,s_left+left+width+1 ! 1754: ,s_top+top+(height-1),shade); ! 1755: gettext(s_left+left+2,s_top+top+3,s_left+left+width+1 ! 1756: ,s_top+top+height,shade); ! 1757: for(j=1;j<width*2;j+=2) ! 1758: shade[j]=DARKGRAY; ! 1759: puttext(s_left+left+2,s_top+top+3,s_left+left+width+1 ! 1760: ,s_top+top+height,shade); ! 1761: } ! 1762: } ! 1763: ! 1764: textattr(api->lclr|(api->bclr<<4)); ! 1765: if(!plen) ! 1766: i=ugetstr(s_left+left+2,s_top+top+tbrdrwidth,iwidth,str,max,kmode,NULL); ! 1767: else ! 1768: i=ugetstr(s_left+left+plen+4,s_top+top+tbrdrwidth,iwidth,str,max,kmode,NULL); ! 1769: if(mode&WIN_SAV) ! 1770: puttext(s_left+left,s_top+top,s_left+left+width+1 ! 1771: ,s_top+top+height,save_buf); ! 1772: free(prompt); ! 1773: return(i); ! 1774: } ! 1775: ! 1776: /****************************************************************************/ ! 1777: /* Displays the message 'str' and waits for the user to select "OK" */ ! 1778: /****************************************************************************/ ! 1779: void umsg(char *str) ! 1780: { ! 1781: int i=0; ! 1782: char *ok[2]={"OK",""}; ! 1783: ! 1784: if(api->mode&UIFC_INMSG) /* non-cursive */ ! 1785: return; ! 1786: api->mode|=UIFC_INMSG; ! 1787: ulist(WIN_SAV|WIN_MID,0,0,0,&i,0,str,ok); ! 1788: api->mode&=~UIFC_INMSG; ! 1789: } ! 1790: ! 1791: /***************************************/ ! 1792: /* Private sub - updates a ugetstr box */ ! 1793: /***************************************/ ! 1794: void getstrupd(int left, int top, int width, char *outstr, int cursoffset, int *scrnoffset, int mode) ! 1795: { ! 1796: _setcursortype(_NOCURSOR); ! 1797: if(cursoffset<*scrnoffset) ! 1798: *scrnoffset=cursoffset; ! 1799: ! 1800: if(*scrnoffset+width < cursoffset) ! 1801: *scrnoffset=cursoffset-width; ! 1802: ! 1803: gotoxy(left,top); ! 1804: if(mode&K_PASSWORD) ! 1805: cprintf("%-*.*s",width,width,"********************************************************************************"+(80-strlen(outstr+*scrnoffset))); ! 1806: else ! 1807: cprintf("%-*.*s",width,width,outstr+*scrnoffset); ! 1808: gotoxy(left+(cursoffset-*scrnoffset),top); ! 1809: _setcursortype(cursor); ! 1810: } ! 1811: ! 1812: /****************************************************************************/ ! 1813: /* Gets a string of characters from the user. Turns cursor on. Allows */ ! 1814: /* Different modes - K_* macros. ESC aborts input. */ ! 1815: /****************************************************************************/ ! 1816: int ugetstr(int left, int top, int width, char *outstr, int max, long mode, int *lastkey) ! 1817: { ! 1818: uchar *str,ins=0; ! 1819: int ch; ! 1820: int i,j,k,f=0; /* i=offset, j=length */ ! 1821: BOOL gotdecimal=FALSE; ! 1822: int soffset=0; ! 1823: struct mouse_event mevnt; ! 1824: unsigned char *pastebuf=NULL; ! 1825: unsigned char *pb=NULL; ! 1826: ! 1827: if((str=(uchar *)alloca(max+1))==NULL) { ! 1828: cprintf("UIFC line %d: error allocating %u bytes\r\n" ! 1829: ,__LINE__,(max+1)); ! 1830: _setcursortype(cursor); ! 1831: return(-1); ! 1832: } ! 1833: gotoxy(left,top); ! 1834: cursor=_NORMALCURSOR; ! 1835: _setcursortype(cursor); ! 1836: str[0]=0; ! 1837: if(mode&K_EDIT && outstr[0]) { ! 1838: /*** ! 1839: truncsp(outstr); ! 1840: ***/ ! 1841: outstr[max]=0; ! 1842: i=j=strlen(outstr); ! 1843: textattr(api->lbclr); ! 1844: getstrupd(left, top, width, outstr, i, &soffset, mode); ! 1845: textattr(api->lclr|(api->bclr<<4)); ! 1846: if(strlen(outstr)<(size_t)width) { ! 1847: k=wherex(); ! 1848: f=wherey(); ! 1849: cprintf("%*s",width-strlen(outstr),""); ! 1850: gotoxy(k,f); ! 1851: } ! 1852: strcpy(str,outstr); ! 1853: #if 0 ! 1854: while(kbwait()==0) { ! 1855: mswait(1); ! 1856: } ! 1857: #endif ! 1858: f=inkey(); ! 1859: if(f==CIO_KEY_MOUSE) { ! 1860: f=uifc_getmouse(&mevnt); ! 1861: if(f==0 || (f==ESC && mevnt.event==CIOLIB_BUTTON_3_CLICK)) { ! 1862: if(mode & K_MOUSEEXIT ! 1863: && (mevnt.starty != top ! 1864: || mevnt.startx > left+width ! 1865: || mevnt.startx < left) ! 1866: && mevnt.event==CIOLIB_BUTTON_1_CLICK) { ! 1867: if(lastkey) ! 1868: *lastkey=CIO_KEY_MOUSE; ! 1869: ungetmouse(&mevnt); ! 1870: return(j); ! 1871: } ! 1872: if(mevnt.startx>=left ! 1873: && mevnt.startx<=left+width ! 1874: && mevnt.event==CIOLIB_BUTTON_1_CLICK) { ! 1875: i=mevnt.startx-left+soffset; ! 1876: if(i>j) ! 1877: i=j; ! 1878: } ! 1879: if(mevnt.starty == top ! 1880: && mevnt.startx>=left ! 1881: && mevnt.startx<=left+width ! 1882: && (mevnt.event==CIOLIB_BUTTON_2_CLICK ! 1883: || mevnt.event==CIOLIB_BUTTON_3_CLICK)) { ! 1884: i=mevnt.startx-left+soffset; ! 1885: if(i>j) ! 1886: i=j; ! 1887: pastebuf=getcliptext(); ! 1888: pb=pastebuf; ! 1889: f=0; ! 1890: } ! 1891: } ! 1892: } ! 1893: ! 1894: if(f == CR ! 1895: || (f >= 0xff && f != CIO_KEY_DC) ! 1896: || (f == '\t' && mode&K_TABEXIT) ! 1897: || (f == '%' && mode&K_SCANNING) ! 1898: || f==CTRL_B ! 1899: || f==CTRL_E ! 1900: || f==CTRL_V ! 1901: || f==CTRL_Z ! 1902: || f==0) ! 1903: { ! 1904: getstrupd(left, top, width, str, i, &soffset, mode); ! 1905: } ! 1906: else ! 1907: { ! 1908: getstrupd(left, top, width, str, i, &soffset, mode); ! 1909: i=j=0; ! 1910: } ! 1911: } ! 1912: else ! 1913: i=j=0; ! 1914: ! 1915: ch=0; ! 1916: while(ch!=CR) ! 1917: { ! 1918: if(i>j) j=i; ! 1919: str[j]=0; ! 1920: getstrupd(left, top, width, str, i, &soffset, mode); ! 1921: if(f || pb!=NULL || (ch=inkey())!=0) ! 1922: { ! 1923: if(f) { ! 1924: ch=f; ! 1925: f=0; ! 1926: } ! 1927: else if(pb!=NULL) { ! 1928: ch=*(pb++); ! 1929: if(!*pb) { ! 1930: free(pastebuf); ! 1931: pastebuf=NULL; ! 1932: pb=NULL; ! 1933: } ! 1934: } ! 1935: if(ch==CIO_KEY_MOUSE) { ! 1936: ch=uifc_getmouse(&mevnt); ! 1937: if(ch==0 || (ch==ESC && mevnt.event==CIOLIB_BUTTON_3_CLICK)) { ! 1938: if(mode & K_MOUSEEXIT ! 1939: && (mevnt.starty != top ! 1940: || mevnt.startx > left+width ! 1941: || mevnt.startx < left) ! 1942: && mevnt.event==CIOLIB_BUTTON_1_CLICK) { ! 1943: if(lastkey) ! 1944: *lastkey=CIO_KEY_MOUSE; ! 1945: ungetmouse(&mevnt); ! 1946: ch=CR; ! 1947: continue; ! 1948: } ! 1949: if(mevnt.starty == top ! 1950: && mevnt.startx>=left ! 1951: && mevnt.startx<=left+width ! 1952: && mevnt.event==CIOLIB_BUTTON_1_CLICK) { ! 1953: i=mevnt.startx-left+soffset; ! 1954: if(i>j) ! 1955: i=j; ! 1956: } ! 1957: if(mevnt.starty == top ! 1958: && mevnt.startx>=left ! 1959: && mevnt.startx<=left+width ! 1960: && (mevnt.event==CIOLIB_BUTTON_2_CLICK ! 1961: || mevnt.event==CIOLIB_BUTTON_3_CLICK)) { ! 1962: i=mevnt.startx-left+soffset; ! 1963: if(i>j) ! 1964: i=j; ! 1965: pastebuf=getcliptext(); ! 1966: pb=pastebuf; ! 1967: ch=0; ! 1968: } ! 1969: } ! 1970: } ! 1971: if(lastkey != NULL) ! 1972: *lastkey=ch; ! 1973: switch(ch) ! 1974: { ! 1975: case CTRL_Z: ! 1976: case CIO_KEY_F(1): /* F1 Help */ ! 1977: api->showhelp(); ! 1978: continue; ! 1979: case CIO_KEY_LEFT: /* left arrow */ ! 1980: if(i) ! 1981: { ! 1982: i--; ! 1983: } ! 1984: continue; ! 1985: case CIO_KEY_RIGHT: /* right arrow */ ! 1986: if(i<j) ! 1987: { ! 1988: i++; ! 1989: } ! 1990: continue; ! 1991: case CTRL_B: ! 1992: case CIO_KEY_HOME: /* home */ ! 1993: if(i) ! 1994: { ! 1995: i=0; ! 1996: } ! 1997: continue; ! 1998: case CTRL_E: ! 1999: case CIO_KEY_END: /* end */ ! 2000: if(i<j) ! 2001: { ! 2002: i=j; ! 2003: } ! 2004: continue; ! 2005: case CTRL_V: ! 2006: case CIO_KEY_IC: /* insert */ ! 2007: ins=!ins; ! 2008: if(ins) ! 2009: cursor=_SOLIDCURSOR; ! 2010: else ! 2011: cursor=_NORMALCURSOR; ! 2012: _setcursortype(cursor); ! 2013: continue; ! 2014: case BS: ! 2015: if(i) ! 2016: { ! 2017: if(i==j) ! 2018: { ! 2019: j--; ! 2020: i--; ! 2021: } ! 2022: else { ! 2023: i--; ! 2024: j--; ! 2025: if(str[i]=='.') ! 2026: gotdecimal=FALSE; ! 2027: for(k=i;k<=j;k++) ! 2028: str[k]=str[k+1]; ! 2029: } ! 2030: continue; ! 2031: } ! 2032: case CIO_KEY_DC: /* delete */ ! 2033: if(i<j) ! 2034: { ! 2035: if(str[i]=='.') ! 2036: gotdecimal=FALSE; ! 2037: for(k=i;k<j;k++) ! 2038: str[k]=str[k+1]; ! 2039: j--; ! 2040: } ! 2041: continue; ! 2042: case CTRL_C: ! 2043: case ESC: ! 2044: { ! 2045: cursor=_NOCURSOR; ! 2046: _setcursortype(cursor); ! 2047: if(pastebuf!=NULL) ! 2048: free(pastebuf); ! 2049: return(-1); ! 2050: } ! 2051: case CR: ! 2052: break; ! 2053: case 3840: /* Backtab */ ! 2054: case '\t': ! 2055: if(mode&K_TABEXIT) ! 2056: ch=CR; ! 2057: break; ! 2058: case '%': /* '%' indicates that a UPC is coming next */ ! 2059: if(mode&K_SCANNING) ! 2060: ch=CR; ! 2061: break; ! 2062: case CIO_KEY_F(2): ! 2063: case CIO_KEY_UP: ! 2064: case CIO_KEY_DOWN: ! 2065: if(mode&K_DEUCEEXIT) { ! 2066: ch=CR; ! 2067: break; ! 2068: } ! 2069: continue; ! 2070: case CTRL_X: ! 2071: if(j) ! 2072: { ! 2073: i=j=0; ! 2074: } ! 2075: continue; ! 2076: case CTRL_Y: ! 2077: if(i<j) ! 2078: { ! 2079: j=i; ! 2080: } ! 2081: continue; ! 2082: } ! 2083: if(mode&K_NUMBER && !isdigit(ch)) ! 2084: continue; ! 2085: if(mode&K_DECIMAL && !isdigit(ch)) { ! 2086: if(ch!='.') ! 2087: continue; ! 2088: if(gotdecimal) ! 2089: continue; ! 2090: gotdecimal=TRUE; ! 2091: } ! 2092: if(mode&K_ALPHA && !isalpha(ch)) ! 2093: continue; ! 2094: #if 0 ! 2095: /* This broke swedish chars... */ ! 2096: if((ch>=' ' || (ch==1 && mode&K_MSG)) && i<max && (!ins || j<max) && isprint(ch)) ! 2097: #else ! 2098: if((ch>=' ' || (ch==1 && mode&K_MSG)) && i<max && (!ins || j<max) && ch < 256) ! 2099: #endif ! 2100: { ! 2101: if(mode&K_UPPER) ! 2102: ch=toupper(ch); ! 2103: if(ins) ! 2104: { ! 2105: for(k=++j;k>i;k--) ! 2106: str[k]=str[k-1]; ! 2107: } ! 2108: str[i++]=ch; ! 2109: } ! 2110: } ! 2111: } ! 2112: ! 2113: ! 2114: str[j]=0; ! 2115: if(mode&K_EDIT) ! 2116: { ! 2117: truncsp(str); ! 2118: if(strcmp(outstr,str)) ! 2119: api->changes=1; ! 2120: } ! 2121: else ! 2122: { ! 2123: if(j) ! 2124: api->changes=1; ! 2125: } ! 2126: strcpy(outstr,str); ! 2127: cursor=_NOCURSOR; ! 2128: _setcursortype(cursor); ! 2129: if(pastebuf!=NULL) ! 2130: free(pastebuf); ! 2131: return(j); ! 2132: } ! 2133: ! 2134: /****************************************************************************/ ! 2135: /* Performs printf() through puttext() routine */ ! 2136: /****************************************************************************/ ! 2137: static int uprintf(int x, int y, unsigned attr, char *fmat, ...) ! 2138: { ! 2139: va_list argptr; ! 2140: char str[256],buf[512]; ! 2141: int i,j; ! 2142: ! 2143: va_start(argptr,fmat); ! 2144: vsprintf(str,fmat,argptr); ! 2145: va_end(argptr); ! 2146: for(i=j=0;str[i];i++) { ! 2147: buf[j++]=str[i]; ! 2148: buf[j++]=attr; ! 2149: } ! 2150: puttext(x,y,x+(i-1),y,buf); ! 2151: return(i); ! 2152: } ! 2153: ! 2154: ! 2155: /****************************************************************************/ ! 2156: /* Display bottom line of screen in inverse */ ! 2157: /****************************************************************************/ ! 2158: void bottomline(int line) ! 2159: { ! 2160: int i=0; ! 2161: ! 2162: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4)," "); ! 2163: i+=4; ! 2164: if(line&BL_HELP) { ! 2165: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"F1 "); ! 2166: i+=3; ! 2167: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Help "); ! 2168: i+=6; ! 2169: } ! 2170: if(line&BL_EDIT) { ! 2171: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"F2 "); ! 2172: i+=3; ! 2173: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Edit Item "); ! 2174: i+=11; ! 2175: } ! 2176: if(line&BL_GET) { ! 2177: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"F5 "); ! 2178: i+=3; ! 2179: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Copy Item "); ! 2180: i+=11; ! 2181: } ! 2182: if(line&BL_PUT) { ! 2183: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"F6 "); ! 2184: i+=3; ! 2185: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Paste "); ! 2186: i+=7; ! 2187: } ! 2188: if(line&BL_INS) { ! 2189: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"INS "); ! 2190: i+=4; ! 2191: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Add Item "); ! 2192: i+=10; ! 2193: } ! 2194: if(line&BL_DEL) { ! 2195: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"DEL "); ! 2196: i+=4; ! 2197: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Delete Item "); ! 2198: i+=13; ! 2199: } ! 2200: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"ESC "); /* Backspace is no good no way to abort editing */ ! 2201: i+=4; ! 2202: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Exit"); ! 2203: i+=4; ! 2204: gotoxy(i,api->scrn_len+1); ! 2205: textattr(BLACK|(api->cclr<<4)); ! 2206: clreol(); ! 2207: } ! 2208: ! 2209: ! 2210: /*****************************************************************************/ ! 2211: /* Generates a 24 character ASCII string that represents the time_t pointer */ ! 2212: /* Used as a replacement for ctime() */ ! 2213: /*****************************************************************************/ ! 2214: char *utimestr(time_t *intime) ! 2215: { ! 2216: static char str[25]; ! 2217: char wday[4],mon[4],mer[3],hour; ! 2218: struct tm *gm; ! 2219: ! 2220: gm=localtime(intime); ! 2221: switch(gm->tm_wday) { ! 2222: case 0: ! 2223: strcpy(wday,"Sun"); ! 2224: break; ! 2225: case 1: ! 2226: strcpy(wday,"Mon"); ! 2227: break; ! 2228: case 2: ! 2229: strcpy(wday,"Tue"); ! 2230: break; ! 2231: case 3: ! 2232: strcpy(wday,"Wed"); ! 2233: break; ! 2234: case 4: ! 2235: strcpy(wday,"Thu"); ! 2236: break; ! 2237: case 5: ! 2238: strcpy(wday,"Fri"); ! 2239: break; ! 2240: case 6: ! 2241: strcpy(wday,"Sat"); ! 2242: break; ! 2243: } ! 2244: switch(gm->tm_mon) { ! 2245: case 0: ! 2246: strcpy(mon,"Jan"); ! 2247: break; ! 2248: case 1: ! 2249: strcpy(mon,"Feb"); ! 2250: break; ! 2251: case 2: ! 2252: strcpy(mon,"Mar"); ! 2253: break; ! 2254: case 3: ! 2255: strcpy(mon,"Apr"); ! 2256: break; ! 2257: case 4: ! 2258: strcpy(mon,"May"); ! 2259: break; ! 2260: case 5: ! 2261: strcpy(mon,"Jun"); ! 2262: break; ! 2263: case 6: ! 2264: strcpy(mon,"Jul"); ! 2265: break; ! 2266: case 7: ! 2267: strcpy(mon,"Aug"); ! 2268: break; ! 2269: case 8: ! 2270: strcpy(mon,"Sep"); ! 2271: break; ! 2272: case 9: ! 2273: strcpy(mon,"Oct"); ! 2274: break; ! 2275: case 10: ! 2276: strcpy(mon,"Nov"); ! 2277: break; ! 2278: case 11: ! 2279: strcpy(mon,"Dec"); ! 2280: break; ! 2281: } ! 2282: if(gm->tm_hour>12) { ! 2283: strcpy(mer,"pm"); ! 2284: hour=gm->tm_hour-12; ! 2285: } ! 2286: else { ! 2287: if(!gm->tm_hour) ! 2288: hour=12; ! 2289: else ! 2290: hour=gm->tm_hour; ! 2291: strcpy(mer,"am"); ! 2292: } ! 2293: sprintf(str,"%s %s %02d %4d %02d:%02d %s",wday,mon,gm->tm_mday,1900+gm->tm_year ! 2294: ,hour,gm->tm_min,mer); ! 2295: return(str); ! 2296: } ! 2297: ! 2298: /****************************************************************************/ ! 2299: /* Status popup/down function, see uifc.h for details. */ ! 2300: /****************************************************************************/ ! 2301: void upop(char *str) ! 2302: { ! 2303: static char sav[26*3*2]; ! 2304: char buf[26*3*2]; ! 2305: int i,j,k; ! 2306: ! 2307: if(!str) { ! 2308: /* puttext(28,12,53,14,sav); */ ! 2309: puttext((api->scrn_width-26+1)/2+1,(api->scrn_len-3+1)/2+1 ! 2310: ,(api->scrn_width+26-1)/2+1,(api->scrn_len+3-1)/2+1,sav); ! 2311: return; ! 2312: } ! 2313: /* gettext(28,12,53,14,sav); */ ! 2314: gettext((api->scrn_width-26+1)/2+1,(api->scrn_len-3+1)/2+1 ! 2315: ,(api->scrn_width+26-1)/2+1,(api->scrn_len+3-1)/2+1,sav); ! 2316: memset(buf,' ',25*3*2); ! 2317: for(i=1;i<26*3*2;i+=2) ! 2318: buf[i]=(api->hclr|(api->bclr<<4)); ! 2319: buf[0]='�'; ! 2320: for(i=2;i<25*2;i+=2) ! 2321: buf[i]='�'; ! 2322: buf[i]='�'; i+=2; ! 2323: buf[i]='�'; i+=2; ! 2324: i+=2; ! 2325: k=strlen(str); ! 2326: i+=(((23-k)/2)*2); ! 2327: for(j=0;j<k;j++,i+=2) { ! 2328: buf[i]=str[j]; ! 2329: buf[i+1]|=BLINK; ! 2330: } ! 2331: i=((25*2)+1)*2; ! 2332: buf[i]='�'; i+=2; ! 2333: buf[i]='�'; i+=2; ! 2334: for(;i<((26*3)-1)*2;i+=2) ! 2335: buf[i]='�'; ! 2336: buf[i]='�'; ! 2337: ! 2338: /* puttext(28,12,53,14,buf); */ ! 2339: puttext((api->scrn_width-26+1)/2+1,(api->scrn_len-3+1)/2+1 ! 2340: ,(api->scrn_width+26-1)/2+1,(api->scrn_len+3-1)/2+1,buf); ! 2341: } ! 2342: ! 2343: /****************************************************************************/ ! 2344: /* Sets the current help index by source code file and line number. */ ! 2345: /****************************************************************************/ ! 2346: void sethelp(int line, char* file) ! 2347: { ! 2348: helpline=line; ! 2349: helpfile=file; ! 2350: } ! 2351: ! 2352: /****************************************************************************/ ! 2353: /* Shows a scrollable text buffer - optionally parsing "help markup codes" */ ! 2354: /****************************************************************************/ ! 2355: void showbuf(int mode, int left, int top, int width, int height, char *title, char *hbuf, int *curp, int *barp) ! 2356: { ! 2357: char inverse=0,high=0; ! 2358: char *textbuf; ! 2359: char *p; ! 2360: char *oldp=NULL; ! 2361: int i,j,k,len; ! 2362: int lines; ! 2363: int pad=1; ! 2364: int is_redraw=0; ! 2365: uint title_len=0; ! 2366: struct mouse_event mevnt; ! 2367: ! 2368: _setcursortype(_NOCURSOR); ! 2369: ! 2370: title_len=strlen(title); ! 2371: if(api->mode&UIFC_MOUSE) ! 2372: title_len+=6; ! 2373: ! 2374: if((unsigned)(top+height)>api->scrn_len-3) ! 2375: height=(api->scrn_len-3)-top; ! 2376: if(!width || (unsigned)width<title_len+6) ! 2377: width=title_len+6; ! 2378: if((unsigned)width>api->scrn_width) ! 2379: width=api->scrn_width; ! 2380: if(mode&WIN_L2R) ! 2381: left=(api->scrn_width-width+2)/2; ! 2382: else if(mode&WIN_RHT) ! 2383: left=SCRN_RIGHT-(width+4+left); ! 2384: if(mode&WIN_T2B) ! 2385: top=(api->scrn_len-height+1)/2; ! 2386: else if(mode&WIN_BOT) ! 2387: top=api->scrn_len-height-3-top; ! 2388: if(left<0) ! 2389: left=0; ! 2390: if(top<0) ! 2391: top=0; ! 2392: ! 2393: if(mode&WIN_PACK) ! 2394: pad=0; ! 2395: ! 2396: /* Dynamic Menus */ ! 2397: if(mode&WIN_DYN ! 2398: && curp != NULL ! 2399: && barp != NULL ! 2400: && last_menu_cur==curp ! 2401: && last_menu_bar==barp ! 2402: && save_menu_cur==*curp ! 2403: && save_menu_bar==*barp) ! 2404: is_redraw=1; ! 2405: if(mode&WIN_DYN && mode&WIN_REDRAW) ! 2406: is_redraw=1; ! 2407: if(mode&WIN_DYN && mode&WIN_NODRAW) ! 2408: is_redraw=0; ! 2409: ! 2410: gettext(1,1,api->scrn_width,api->scrn_len,tmp_buffer); ! 2411: ! 2412: if(!is_redraw) { ! 2413: memset(tmp_buffer2,' ',width*height*2); ! 2414: for(i=1;i<width*height*2;i+=2) ! 2415: tmp_buffer2[i]=(api->hclr|(api->bclr<<4)); ! 2416: tmp_buffer2[0]='�'; ! 2417: j=title_len; ! 2418: if(j>width-6) { ! 2419: *(title+width-6)=0; ! 2420: j=width-6; ! 2421: } ! 2422: for(i=2;i<(width-j);i+=2) ! 2423: tmp_buffer2[i]='�'; ! 2424: if(api->mode&UIFC_MOUSE && !mode&WIN_DYN) { ! 2425: tmp_buffer2[2]='['; ! 2426: tmp_buffer2[3]=api->hclr|(api->bclr<<4); ! 2427: /* tmp_buffer2[4]='�'; */ ! 2428: tmp_buffer2[4]=0xfe; ! 2429: tmp_buffer2[5]=api->lclr|(api->bclr<<4); ! 2430: tmp_buffer2[6]=']'; ! 2431: tmp_buffer2[7]=api->hclr|(api->bclr<<4); ! 2432: /* Buttons are ignored - leave it this way to not confuse stuff from help() */ ! 2433: } ! 2434: tmp_buffer2[i]='�'; i+=4; ! 2435: for(p=title;*p;p++) { ! 2436: tmp_buffer2[i]=*p; ! 2437: i+=2; ! 2438: } ! 2439: i+=2; ! 2440: tmp_buffer2[i]='�'; i+=2; ! 2441: for(j=i;j<((width-1)*2);j+=2) ! 2442: tmp_buffer2[j]='�'; ! 2443: i=j; ! 2444: tmp_buffer2[i]='�'; i+=2; ! 2445: j=i; /* leave i alone */ ! 2446: for(k=0;k<(height-2);k++) { /* the sides of the box */ ! 2447: tmp_buffer2[j]='�'; j+=2; ! 2448: j+=((width-2)*2); ! 2449: tmp_buffer2[j]='�'; j+=2; ! 2450: } ! 2451: tmp_buffer2[j]='�'; j+=2; ! 2452: if(!(mode&WIN_DYN) && (width>31)) { ! 2453: for(k=j;k<j+(((width-4)/2-13)*2);k+=2) ! 2454: tmp_buffer2[k]='�'; ! 2455: tmp_buffer2[k]='�'; k+=4; ! 2456: tmp_buffer2[k]='H'; k+=2; ! 2457: tmp_buffer2[k]='i'; k+=2; ! 2458: tmp_buffer2[k]='t'; k+=4; ! 2459: tmp_buffer2[k]='a'; k+=2; ! 2460: tmp_buffer2[k]='n'; k+=2; ! 2461: tmp_buffer2[k]='y'; k+=4; ! 2462: tmp_buffer2[k]='k'; k+=2; ! 2463: tmp_buffer2[k]='e'; k+=2; ! 2464: tmp_buffer2[k]='y'; k+=4; ! 2465: tmp_buffer2[k]='t'; k+=2; ! 2466: tmp_buffer2[k]='o'; k+=4; ! 2467: tmp_buffer2[k]='c'; k+=2; ! 2468: tmp_buffer2[k]='o'; k+=2; ! 2469: tmp_buffer2[k]='n'; k+=2; ! 2470: tmp_buffer2[k]='t'; k+=2; ! 2471: tmp_buffer2[k]='i'; k+=2; ! 2472: tmp_buffer2[k]='n'; k+=2; ! 2473: tmp_buffer2[k]='u'; k+=2; ! 2474: tmp_buffer2[k]='e'; k+=4; ! 2475: tmp_buffer2[k]='�'; k+=2; ! 2476: for(j=k;j<k+(((width-4)/2-12)*2);j+=2) ! 2477: tmp_buffer2[j]='�'; ! 2478: } ! 2479: else { ! 2480: for(k=j;k<j+((width-2)*2);k+=2) ! 2481: tmp_buffer2[k]='�'; ! 2482: j=k; ! 2483: } ! 2484: tmp_buffer2[j]='�'; ! 2485: puttext(left,top+1,left+width-1,top+height,tmp_buffer2); ! 2486: } ! 2487: len=strlen(hbuf); ! 2488: ! 2489: lines=0; ! 2490: k=0; ! 2491: for(j=0;j<len;j++) { ! 2492: if(mode&WIN_HLP && (hbuf[j]==2 || hbuf[j]=='~' || hbuf[j]==1 || hbuf[j]=='`')) ! 2493: continue; ! 2494: if(hbuf[j]==CR) ! 2495: continue; ! 2496: k++; ! 2497: if((hbuf[j]==LF) || (k>=width-2-pad-pad && (hbuf[j+1]!='\n' && hbuf[j+1]!='\r'))) { ! 2498: k=0; ! 2499: lines++; ! 2500: } ! 2501: } ! 2502: if(k) ! 2503: lines++; ! 2504: if(lines < height-2-pad-pad) ! 2505: lines=height-2-pad-pad; ! 2506: ! 2507: if((textbuf=(char *)malloc((width-2-pad-pad)*lines*2))==NULL) { ! 2508: cprintf("UIFC line %d: error allocating %u bytes\r\n" ! 2509: ,__LINE__,(width-2-pad-pad)*lines*2); ! 2510: _setcursortype(cursor); ! 2511: return; ! 2512: } ! 2513: memset(textbuf,' ',(width-2-pad-pad)*lines*2); ! 2514: for(i=1;i<(width-2-pad-pad)*lines*2;i+=2) ! 2515: textbuf[i]=(api->hclr|(api->bclr<<4)); ! 2516: ! 2517: i=0; ! 2518: ! 2519: for(j=i;j<len;j++,i+=2) { ! 2520: if(hbuf[j]==LF) { ! 2521: i+=2; ! 2522: while(i%((width-2-pad-pad)*2)) i++; i-=2; ! 2523: } ! 2524: else if(mode&WIN_HLP && (hbuf[j]==2 || hbuf[j]=='~')) { /* Ctrl-b toggles inverse */ ! 2525: inverse=!inverse; ! 2526: i-=2; ! 2527: } ! 2528: else if(mode&WIN_HLP && (hbuf[j]==1 || hbuf[j]=='`')) { /* Ctrl-a toggles high intensity */ ! 2529: high=!high; ! 2530: i-=2; ! 2531: } ! 2532: else if(hbuf[j]!=CR) { ! 2533: textbuf[i]=hbuf[j]; ! 2534: textbuf[i+1]=inverse ? (api->bclr|(api->cclr<<4)) ! 2535: : high ? (api->hclr|(api->bclr<<4)) : (api->lclr|(api->bclr<<4)); ! 2536: if((i+2)%((width-2-pad-pad)*2)==0 && (hbuf[j+1]==LF) || (hbuf[j+1]==CR && hbuf[j+2]==LF)) ! 2537: i-=2; ! 2538: } ! 2539: else ! 2540: i-=2; ! 2541: } ! 2542: i=0; ! 2543: p=textbuf; ! 2544: if(mode&WIN_DYN) { ! 2545: puttext(left+1+pad,top+2+pad,left+width-2-pad,top+height-1-pad,p); ! 2546: } ! 2547: else { ! 2548: while(i==0) { ! 2549: if(p!=oldp) { ! 2550: if(p > textbuf+(lines-(height-2-pad-pad))*(width-2-pad-pad)*2) ! 2551: p=textbuf+(lines-(height-2-pad-pad))*(width-2-pad-pad)*2; ! 2552: if(p<textbuf) ! 2553: p=textbuf; ! 2554: if(p!=oldp) { ! 2555: puttext(left+1+pad,top+2+pad,left+width-2-pad,top+height-1-pad,p); ! 2556: oldp=p; ! 2557: } ! 2558: } ! 2559: if(kbwait()) { ! 2560: j=inkey(); ! 2561: if(j==CIO_KEY_MOUSE) { ! 2562: /* Ignores return value to avoid hitting help/exit hotspots */ ! 2563: if(uifc_getmouse(&mevnt)>=0) { ! 2564: /* Clicked Scroll Up */ ! 2565: if(mevnt.startx>=left+pad ! 2566: && mevnt.startx<=left+pad+width-3 ! 2567: && mevnt.starty>=top+pad+1 ! 2568: && mevnt.starty<=top+pad+(height/2)-2 ! 2569: && mevnt.event==CIOLIB_BUTTON_1_CLICK) { ! 2570: p = p-((width-2-pad-pad)*2*(height-5)); ! 2571: continue; ! 2572: } ! 2573: /* Clicked Scroll Down */ ! 2574: else if(mevnt.startx>=left+pad ! 2575: && mevnt.startx<=left+pad+width ! 2576: && mevnt.starty<=top+pad+height-2 ! 2577: && mevnt.starty>=top+pad+height-(height/2+1)-2 ! 2578: && mevnt.event==CIOLIB_BUTTON_1_CLICK) { ! 2579: p=p+(width-2-pad-pad)*2*(height-5); ! 2580: continue; ! 2581: } ! 2582: i=1; ! 2583: } ! 2584: continue; ! 2585: } ! 2586: switch(j) { ! 2587: case CIO_KEY_HOME: /* home */ ! 2588: p=textbuf; ! 2589: break; ! 2590: ! 2591: case CIO_KEY_UP: /* up arrow */ ! 2592: p = p-((width-2-pad-pad)*2); ! 2593: break; ! 2594: ! 2595: case CIO_KEY_PPAGE: /* PgUp */ ! 2596: p = p-((width-2-pad-pad)*2*(height-5)); ! 2597: break; ! 2598: ! 2599: case CIO_KEY_NPAGE: /* PgDn */ ! 2600: p=p+(width-2-pad-pad)*2*(height-5); ! 2601: break; ! 2602: ! 2603: case CIO_KEY_END: /* end */ ! 2604: p=textbuf+(lines-height+1)*(width-2-pad-pad)*2; ! 2605: break; ! 2606: ! 2607: case CIO_KEY_DOWN: /* dn arrow */ ! 2608: p = p+((width-2-pad-pad)*2); ! 2609: break; ! 2610: ! 2611: default: ! 2612: i=1; ! 2613: } ! 2614: } ! 2615: mswait(1); ! 2616: } ! 2617: ! 2618: puttext(1,1,api->scrn_width,api->scrn_len,tmp_buffer); ! 2619: } ! 2620: free(textbuf); ! 2621: if(is_redraw) /* Force redraw of menu also. */ ! 2622: reset_dynamic(); ! 2623: _setcursortype(cursor); ! 2624: } ! 2625: ! 2626: /************************************************************/ ! 2627: /* Help (F1) key function. Uses helpbuf as the help input. */ ! 2628: /************************************************************/ ! 2629: static void help(void) ! 2630: { ! 2631: char hbuf[HELPBUF_SIZE],str[256]; ! 2632: char *p; ! 2633: unsigned short line; /* This must be 16-bits */ ! 2634: long l; ! 2635: FILE *fp; ! 2636: ! 2637: if(api->helpbuf==NULL && api->helpixbfile[0]==0) ! 2638: return; ! 2639: ! 2640: _setcursortype(_NOCURSOR); ! 2641: ! 2642: if(api->helpbuf!=NULL) ! 2643: strcpy(hbuf,api->helpbuf); ! 2644: else { ! 2645: if((fp=fopen(api->helpixbfile,"rb"))==NULL) { ! 2646: sprintf(hbuf,"\2 ERROR \2 Cannot open help index:\r\n %s" ! 2647: ,api->helpixbfile); ! 2648: } ! 2649: else { ! 2650: p=strrchr(helpfile,'/'); ! 2651: if(p==NULL) ! 2652: p=strrchr(helpfile,'\\'); ! 2653: if(p==NULL) ! 2654: p=helpfile; ! 2655: else ! 2656: p++; ! 2657: l=-1L; ! 2658: while(!feof(fp)) { ! 2659: if(!fread(str,12,1,fp)) ! 2660: break; ! 2661: str[12]=0; ! 2662: fread(&line,sizeof(line),1,fp); ! 2663: if(stricmp(str,p) || line!=helpline) { ! 2664: fseek(fp,sizeof(l),SEEK_CUR); ! 2665: continue; ! 2666: } ! 2667: fread(&l,sizeof(l),1,fp); ! 2668: break; ! 2669: } ! 2670: fclose(fp); ! 2671: if(l==-1L) ! 2672: sprintf(hbuf,"\2 ERROR \2 Cannot locate help key (%s:%u) in:\r\n" ! 2673: " %s",p,helpline,api->helpixbfile); ! 2674: else { ! 2675: if((fp=fopen(api->helpdatfile,"rb"))==NULL) ! 2676: sprintf(hbuf,"\2 ERROR \2 Cannot open help file:\r\n %s" ! 2677: ,api->helpdatfile); ! 2678: else { ! 2679: fseek(fp,l,SEEK_SET); ! 2680: fread(hbuf,HELPBUF_SIZE,1,fp); ! 2681: fclose(fp); ! 2682: } ! 2683: } ! 2684: } ! 2685: } ! 2686: ! 2687: showbuf(WIN_MID|WIN_HLP, 0, 0, 76, api->scrn_len, "Online Help", hbuf, NULL, NULL); ! 2688: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.