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