|
|
1.1 ! root 1: /* uifc.c */ ! 2: ! 3: /* Original implementation of UIFC (user interface) library based on conio */ ! 4: ! 5: /* $Id: uifc.c,v 1.30 2005/09/20 05:39:41 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 2003 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: #include "uifc.h" ! 39: #include <share.h> ! 40: #include <conio.h> ! 41: ! 42: #if defined(__OS2__) ! 43: ! 44: #define INCL_BASE ! 45: #include <os2.h> ! 46: ! 47: void mswait(int msec) ! 48: { ! 49: DosSleep(msec ? msec : 1); ! 50: } ! 51: ! 52: #elif defined(_WIN32) ! 53: #include <windows.h> ! 54: #define mswait(x) Sleep(x) ! 55: #else ! 56: #define mswait(x) delay(x) ! 57: #endif ! 58: ! 59: static char hclr,lclr,bclr,cclr,show_free_mem=0; ! 60: static int cursor; ! 61: static char* helpfile=0; ! 62: static uint helpline=0; ! 63: static char blk_scrn[MAX_BFLN]; ! 64: static win_t sav[MAX_BUFS]; ! 65: static uint max_opts=MAX_OPTS; ! 66: static uifcapi_t* api; ! 67: ! 68: /* Prototypes */ ! 69: static int uprintf(int x, int y, char attr, char *fmt,...); ! 70: static void bottomline(int line); ! 71: static char *utimestr(time_t *intime); ! 72: static void help(void); ! 73: static int getstr(char *outstr, int max, long mode); ! 74: ! 75: /* API routines */ ! 76: static void uifcbail(void); ! 77: static int uscrn(char *str); ! 78: static int ulist(int mode, int left, int top, int width, int *dflt, int *bar ! 79: ,char *title, char **option); ! 80: static int uinput(int imode, int left, int top, char *prompt, char *str ! 81: ,int len ,int kmode); ! 82: static void umsg(char *str); ! 83: static void upop(char *str); ! 84: static void sethelp(int line, char* file); ! 85: static void timedisplay(void); ! 86: ! 87: int inkey(int mode) ! 88: { ! 89: int c; ! 90: ! 91: if(mode) ! 92: return(kbhit()); ! 93: c=getch(); ! 94: if(!c) ! 95: c=(getch()<<8); ! 96: return(c); ! 97: } ! 98: ! 99: static uint mousecursor=0x28; ! 100: ! 101: /****************************************************************************/ ! 102: /* Initialization function, see uifc.h for details. */ ! 103: /* Returns 0 on success. */ ! 104: /****************************************************************************/ ! 105: int uifcini(uifcapi_t* uifcapi) ! 106: { ! 107: int i; ! 108: struct text_info txtinfo; ! 109: ! 110: if(uifcapi==NULL || uifcapi->size!=sizeof(uifcapi_t)) ! 111: return(-1); ! 112: ! 113: api=uifcapi; ! 114: ! 115: /* install function handlers */ ! 116: api->bail=uifcbail; ! 117: api->scrn=uscrn; ! 118: api->msg=umsg; ! 119: api->pop=upop; ! 120: api->list=ulist; ! 121: api->input=uinput; ! 122: api->sethelp=sethelp; ! 123: api->showhelp=help; ! 124: api->showbuf=NULL; ! 125: api->timedisplay=timedisplay; ! 126: api->bottomline=bottomline; ! 127: ! 128: if(api->scrn_len!=0) { ! 129: switch(api->scrn_len) { ! 130: case 14: ! 131: textmode(C80X14); ! 132: break; ! 133: case 21: ! 134: textmode(C80X21); ! 135: break; ! 136: case 25: ! 137: textmode(C80); ! 138: break; ! 139: case 28: ! 140: textmode(C80X28); ! 141: break; ! 142: case 43: ! 143: textmode(C80X43); ! 144: break; ! 145: case 50: ! 146: textmode(C80X50); ! 147: break; ! 148: case 60: ! 149: textmode(C80X60); ! 150: break; ! 151: default: ! 152: textmode(C4350); ! 153: break; ! 154: } ! 155: } ! 156: ! 157: clrscr(); ! 158: gettextinfo(&txtinfo); ! 159: /* unsupported mode? */ ! 160: if(txtinfo.screenheight<MIN_LINES ! 161: || txtinfo.screenheight>MAX_LINES ! 162: || txtinfo.screenwidth<80) { ! 163: textmode(C80); /* set mode to 80x25*/ ! 164: gettextinfo(&txtinfo); ! 165: } ! 166: window(1,1,txtinfo.screenwidth,txtinfo.screenheight); ! 167: ! 168: api->scrn_len=txtinfo.screenheight; ! 169: if(api->scrn_len<MIN_LINES || api->scrn_len>MAX_LINES) { ! 170: cprintf("\7UIFC: Screen length (%u) must be between %d and %d lines\r\n" ! 171: ,api->scrn_len,MIN_LINES,MAX_LINES); ! 172: return(-2); ! 173: } ! 174: api->scrn_len--; /* account for status line */ ! 175: ! 176: if(txtinfo.screenwidth<80) { ! 177: cprintf("\7UIFC: Screen width (%u) must be at least 80 characters\r\n" ! 178: ,txtinfo.screenwidth); ! 179: return(-3); ! 180: } ! 181: api->scrn_width=txtinfo.screenwidth; ! 182: ! 183: if(!(api->mode&UIFC_COLOR) ! 184: && (api->mode&UIFC_MONO ! 185: || txtinfo.currmode==MONO || txtinfo.currmode==BW80)) { ! 186: bclr=BLACK; ! 187: hclr=WHITE; ! 188: lclr=LIGHTGRAY; ! 189: cclr=LIGHTGRAY; ! 190: } else { ! 191: bclr=BLUE; ! 192: hclr=YELLOW; ! 193: lclr=WHITE; ! 194: cclr=CYAN; ! 195: } ! 196: for(i=0;i<MAX_BFLN;i+=2) { ! 197: blk_scrn[i]='�'; ! 198: blk_scrn[i+1]=cclr|(bclr<<4); ! 199: } ! 200: ! 201: cursor=_NOCURSOR; ! 202: _setcursortype(cursor); ! 203: ! 204: return(0); ! 205: } ! 206: ! 207: static void hidemouse(void) ! 208: { ! 209: } ! 210: ! 211: static void showmouse(void) ! 212: { ! 213: } ! 214: ! 215: ! 216: void uifcbail(void) ! 217: { ! 218: ! 219: hidemouse(); ! 220: _setcursortype(_NORMALCURSOR); ! 221: textattr(LIGHTGRAY); ! 222: clrscr(); ! 223: } ! 224: ! 225: /****************************************************************************/ ! 226: /* Clear screen, fill with background attribute, display application title. */ ! 227: /* Returns 0 on success. */ ! 228: /****************************************************************************/ ! 229: int uscrn(char *str) ! 230: { ! 231: textattr(bclr|(cclr<<4)); ! 232: gotoxy(1,1); ! 233: clreol(); ! 234: gotoxy(3,1); ! 235: cputs(str); ! 236: if(!puttext(1,2,80,api->scrn_len,blk_scrn)) ! 237: return(-1); ! 238: gotoxy(1,api->scrn_len+1); ! 239: clreol(); ! 240: return(0); ! 241: } ! 242: ! 243: /****************************************************************************/ ! 244: /****************************************************************************/ ! 245: static void scroll_text(int x1, int y1, int x2, int y2, int down) ! 246: { ! 247: uchar buf[MAX_BFLN]; ! 248: ! 249: gettext(x1,y1,x2,y2,buf); ! 250: if(down) ! 251: puttext(x1,y1+1,x2,y2,buf); ! 252: else ! 253: puttext(x1,y1,x2,y2-1,buf+(((x2-x1)+1)*2)); ! 254: } ! 255: ! 256: /****************************************************************************/ ! 257: /* Updates time in upper left corner of screen with current time in ASCII/ */ ! 258: /* Unix format */ ! 259: /****************************************************************************/ ! 260: static void timedisplay(BOOL force) ! 261: { ! 262: static time_t savetime; ! 263: time_t now; ! 264: ! 265: now=time(NULL); ! 266: if(force || difftime(now,savetime)>=60) { ! 267: uprintf(55,1,bclr|(cclr<<4),utimestr(&now)); ! 268: savetime=now; ! 269: } ! 270: } ! 271: ! 272: /****************************************************************************/ ! 273: /* Truncates white-space chars off end of 'str' */ ! 274: /****************************************************************************/ ! 275: static void truncsp(char *str) ! 276: { ! 277: uint c; ! 278: ! 279: c=strlen(str); ! 280: while(c && (uchar)str[c-1]<=' ') c--; ! 281: str[c]=0; ! 282: } ! 283: ! 284: /****************************************************************************/ ! 285: /* General menu function, see uifc.h for details. */ ! 286: /****************************************************************************/ ! 287: int ulist(int mode, int left, int top, int width, int *cur, int *bar ! 288: , char *title, char **option) ! 289: { ! 290: uchar line[256],shade[256],win[MAX_BFLN],*ptr,a,b,c,longopt ! 291: ,search[MAX_OPLN],bline=0; ! 292: int height,y; ! 293: int i,j,opts=0,s=0; /* s=search index into options */ ! 294: ! 295: if(mode&WIN_SAV && api->savnum>=MAX_BUFS-1) ! 296: putch(7); ! 297: i=0; ! 298: if(mode&WIN_INS) bline|=BL_INS; ! 299: if(mode&WIN_DEL) bline|=BL_DEL; ! 300: if(mode&WIN_GET) bline|=BL_GET; ! 301: if(mode&WIN_PUT) bline|=BL_PUT; ! 302: if(api->bottomline != NULL) ! 303: api->bottomline(bline); ! 304: while(opts<max_opts && opts<MAX_OPTS) ! 305: if(option[opts]==NULL || option[opts][0]==0) ! 306: break; ! 307: else opts++; ! 308: if(mode&WIN_XTR && opts<max_opts && opts<MAX_OPTS) ! 309: option[opts++][0]=0; ! 310: height=opts+4; ! 311: if(top+height>api->scrn_len-3) ! 312: height=(api->scrn_len-3)-top; ! 313: if(!width || width<strlen(title)+6) { ! 314: width=strlen(title)+6; ! 315: for(i=0;i<opts;i++) { ! 316: truncsp(option[i]); ! 317: if((j=strlen(option[i])+5)>width) ! 318: width=j; } } ! 319: if(width>(SCRN_RIGHT+1)-SCRN_LEFT) ! 320: width=(SCRN_RIGHT+1)-SCRN_LEFT; ! 321: if(mode&WIN_L2R) ! 322: left=36-(width/2); ! 323: else if(mode&WIN_RHT) ! 324: left=SCRN_RIGHT-(width+4+left); ! 325: if(mode&WIN_T2B) ! 326: top=(api->scrn_len/2)-(height/2)-2; ! 327: else if(mode&WIN_BOT) ! 328: top=api->scrn_len-height-3-top; ! 329: if(mode&WIN_SAV && api->savdepth==api->savnum) { ! 330: if((sav[api->savnum].buf=(char *)malloc((width+3)*(height+2)*2))==NULL) { ! 331: cprintf("UIFC line %d: error allocating %u bytes." ! 332: ,__LINE__,(width+3)*(height+2)*2); ! 333: return(-1); } ! 334: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width+1 ! 335: ,SCRN_TOP+top+height,sav[api->savnum].buf); ! 336: sav[api->savnum].left=SCRN_LEFT+left; ! 337: sav[api->savnum].top=SCRN_TOP+top; ! 338: sav[api->savnum].right=SCRN_LEFT+left+width+1; ! 339: sav[api->savnum].bot=SCRN_TOP+top+height; ! 340: api->savdepth++; } ! 341: else if(mode&WIN_SAV ! 342: && (sav[api->savnum].left!=SCRN_LEFT+left ! 343: || sav[api->savnum].top!=SCRN_TOP+top ! 344: || sav[api->savnum].right!=SCRN_LEFT+left+width+1 ! 345: || sav[api->savnum].bot!=SCRN_TOP+top+height)) { /* dimensions have changed */ ! 346: puttext(sav[api->savnum].left,sav[api->savnum].top,sav[api->savnum].right,sav[api->savnum].bot ! 347: ,sav[api->savnum].buf); /* put original window back */ ! 348: free(sav[api->savnum].buf); ! 349: if((sav[api->savnum].buf=(char *)malloc((width+3)*(height+2)*2))==NULL) { ! 350: cprintf("UIFC line %d: error allocating %u bytes." ! 351: ,__LINE__,(width+3)*(height+2)*2); ! 352: return(-1); } ! 353: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width+1 ! 354: ,SCRN_TOP+top+height,sav[api->savnum].buf); /* save again */ ! 355: sav[api->savnum].left=SCRN_LEFT+left; ! 356: sav[api->savnum].top=SCRN_TOP+top; ! 357: sav[api->savnum].right=SCRN_LEFT+left+width+1; ! 358: sav[api->savnum].bot=SCRN_TOP+top+height; } ! 359: ! 360: ! 361: ! 362: if(mode&WIN_ORG) { /* Clear around menu */ ! 363: if(top) ! 364: puttext(SCRN_LEFT,SCRN_TOP,SCRN_RIGHT+2,SCRN_TOP+top-1,blk_scrn); ! 365: if(SCRN_TOP+height+top<=api->scrn_len) ! 366: puttext(SCRN_LEFT,SCRN_TOP+height+top,SCRN_RIGHT+2,api->scrn_len,blk_scrn); ! 367: if(left) ! 368: puttext(SCRN_LEFT,SCRN_TOP+top,SCRN_LEFT+left-1,SCRN_TOP+height+top ! 369: ,blk_scrn); ! 370: if(SCRN_LEFT+left+width<=SCRN_RIGHT) ! 371: puttext(SCRN_LEFT+left+width,SCRN_TOP+top,SCRN_RIGHT+2 ! 372: ,SCRN_TOP+height+top,blk_scrn); } ! 373: ptr=win; ! 374: *(ptr++)='�'; ! 375: *(ptr++)=hclr|(bclr<<4); ! 376: ! 377: if(api->mode&UIFC_MOUSE) { ! 378: *(ptr++)='['; ! 379: *(ptr++)=hclr|(bclr<<4); ! 380: *(ptr++)='�'; ! 381: *(ptr++)=lclr|(bclr<<4); ! 382: *(ptr++)=']'; ! 383: *(ptr++)=hclr|(bclr<<4); ! 384: *(ptr++)='['; ! 385: *(ptr++)=hclr|(bclr<<4); ! 386: *(ptr++)='?'; ! 387: *(ptr++)=lclr|(bclr<<4); ! 388: *(ptr++)=']'; ! 389: *(ptr++)=hclr|(bclr<<4); ! 390: i=6; } ! 391: else ! 392: i=0; ! 393: for(;i<width-2;i++) { ! 394: *(ptr++)='�'; ! 395: *(ptr++)=hclr|(bclr<<4); } ! 396: *(ptr++)='�'; ! 397: *(ptr++)=hclr|(bclr<<4); ! 398: *(ptr++)='�'; ! 399: *(ptr++)=hclr|(bclr<<4); ! 400: a=strlen(title); ! 401: b=(width-a-1)/2; ! 402: for(i=0;i<b;i++) { ! 403: *(ptr++)=' '; ! 404: *(ptr++)=hclr|(bclr<<4); } ! 405: for(i=0;i<a;i++) { ! 406: *(ptr++)=title[i]; ! 407: *(ptr++)=hclr|(bclr<<4); } ! 408: for(i=0;i<width-(a+b)-2;i++) { ! 409: *(ptr++)=' '; ! 410: *(ptr++)=hclr|(bclr<<4); } ! 411: *(ptr++)='�'; ! 412: *(ptr++)=hclr|(bclr<<4); ! 413: *(ptr++)='�'; ! 414: *(ptr++)=hclr|(bclr<<4); ! 415: for(i=0;i<width-2;i++) { ! 416: *(ptr++)='�'; ! 417: *(ptr++)=hclr|(bclr<<4); } ! 418: *(ptr++)='�'; ! 419: *(ptr++)=hclr|(bclr<<4); ! 420: ! 421: if((*cur)>=opts) ! 422: (*cur)=opts-1; /* returned after scrolled */ ! 423: ! 424: if(!bar) { ! 425: if((*cur)>height-5) ! 426: (*cur)=height-5; ! 427: i=0; } ! 428: else { ! 429: if((*bar)>=opts) ! 430: (*bar)=opts-1; ! 431: if((*bar)>height-5) ! 432: (*bar)=height-5; ! 433: if((*cur)==opts-1) ! 434: (*bar)=height-5; ! 435: if((*bar)<0) ! 436: (*bar)=0; ! 437: if((*cur)<(*bar)) ! 438: (*cur)=(*bar); ! 439: i=(*cur)-(*bar); ! 440: ! 441: if(i+(height-5)>=opts) { ! 442: i=opts-(height-4); ! 443: (*cur)=i+(*bar); ! 444: } ! 445: } ! 446: if((*cur)<0) ! 447: (*cur)=0; ! 448: ! 449: j=0; ! 450: if(i<0) i=0; ! 451: longopt=0; ! 452: while(j<height-4 && i<opts) { ! 453: *(ptr++)='�'; ! 454: *(ptr++)=hclr|(bclr<<4); ! 455: *(ptr++)=' '; ! 456: *(ptr++)=hclr|(bclr<<4); ! 457: *(ptr++)='�'; ! 458: *(ptr++)=lclr|(bclr<<4); ! 459: if(i==(*cur)) ! 460: a=bclr|(LIGHTGRAY<<4); ! 461: else ! 462: a=lclr|(bclr<<4); ! 463: b=strlen(option[i]); ! 464: if(b>longopt) ! 465: longopt=b; ! 466: if(b+4>width) ! 467: b=width-4; ! 468: for(c=0;c<b;c++) { ! 469: *(ptr++)=option[i][c]; ! 470: *(ptr++)=a; } ! 471: while(c<width-4) { ! 472: *(ptr++)=' '; ! 473: *(ptr++)=a; ! 474: c++; } ! 475: *(ptr++)='�'; ! 476: *(ptr++)=hclr|(bclr<<4); ! 477: i++; ! 478: j++; } ! 479: *(ptr++)='�'; ! 480: *(ptr++)=hclr|(bclr<<4); ! 481: for(i=0;i<width-2;i++) { ! 482: *(ptr++)='�'; ! 483: *(ptr++)=hclr|(bclr<<4); } ! 484: *(ptr++)='�'; ! 485: *(ptr++)=hclr|(bclr<<4); ! 486: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width-1 ! 487: ,SCRN_TOP+top+height-1,win); ! 488: if(bar) ! 489: y=top+3+(*bar); ! 490: else ! 491: y=top+3+(*cur); ! 492: if(opts+4>height && ((!bar && (*cur)!=opts-1) ! 493: || (bar && ((*cur)-(*bar))+(height-4)<opts))) { ! 494: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2); ! 495: textattr(lclr|(bclr<<4)); ! 496: putch(31); /* put down arrow */ ! 497: textattr(hclr|(bclr<<4)); } ! 498: ! 499: if(bar && (*bar)!=(*cur)) { ! 500: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3); ! 501: textattr(lclr|(bclr<<4)); ! 502: putch(30); /* put the up arrow */ ! 503: textattr(hclr|(bclr<<4)); } ! 504: ! 505: if(bclr==BLUE) { ! 506: gettext(SCRN_LEFT+left+width,SCRN_TOP+top+1,SCRN_LEFT+left+width+1 ! 507: ,SCRN_TOP+top+height-1,shade); ! 508: for(i=1;i<height*4;i+=2) ! 509: shade[i]=DARKGRAY; ! 510: puttext(SCRN_LEFT+left+width,SCRN_TOP+top+1,SCRN_LEFT+left+width+1 ! 511: ,SCRN_TOP+top+height-1,shade); ! 512: gettext(SCRN_LEFT+left+2,SCRN_TOP+top+height,SCRN_LEFT+left+width+1 ! 513: ,SCRN_TOP+top+height,shade); ! 514: for(i=1;i<width*2;i+=2) ! 515: shade[i]=DARKGRAY; ! 516: puttext(SCRN_LEFT+left+2,SCRN_TOP+top+height,SCRN_LEFT+left+width+1 ! 517: ,SCRN_TOP+top+height,shade); } ! 518: showmouse(); ! 519: while(1) { ! 520: #if 0 /* debug */ ! 521: gotoxy(30,1); ! 522: cprintf("y=%2d h=%2d c=%2d b=%2d s=%2d o=%2d" ! 523: ,y,height,*cur,bar ? *bar :0xff,api->savdepth,opts); ! 524: #endif ! 525: if(!show_free_mem) { ! 526: if(api->timedisplay != NULL) ! 527: api->timedisplay(FALSE); ! 528: } ! 529: ! 530: if(inkey(1)) { ! 531: i=inkey(0); ! 532: if(!(i&0xff)) { ! 533: s=0; ! 534: switch(i>>8) { ! 535: case 71: /* home */ ! 536: if(!opts) ! 537: break; ! 538: if(opts+4>height) { ! 539: hidemouse(); ! 540: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3); ! 541: textattr(lclr|(bclr<<4)); ! 542: putch(' '); /* Delete the up arrow */ ! 543: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2); ! 544: putch(31); /* put the down arrow */ ! 545: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3 ! 546: ,bclr|(LIGHTGRAY<<4) ! 547: ,"%-*.*s",width-4,width-4,option[0]); ! 548: for(i=1;i<height-4;i++) /* re-display options */ ! 549: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+i ! 550: ,lclr|(bclr<<4) ! 551: ,"%-*.*s",width-4,width-4,option[i]); ! 552: (*cur)=0; ! 553: if(bar) ! 554: (*bar)=0; ! 555: y=top+3; ! 556: showmouse(); ! 557: break; } ! 558: hidemouse(); ! 559: gettext(SCRN_LEFT+3+left,SCRN_TOP+y ! 560: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 561: for(i=1;i<width*2;i+=2) ! 562: line[i]=lclr|(bclr<<4); ! 563: puttext(SCRN_LEFT+3+left,SCRN_TOP+y ! 564: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 565: (*cur)=0; ! 566: if(bar) ! 567: (*bar)=0; ! 568: y=top+3; ! 569: gettext(SCRN_LEFT+3+left,SCRN_TOP+y ! 570: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 571: for(i=1;i<width*2;i+=2) ! 572: line[i]=bclr|(LIGHTGRAY<<4); ! 573: puttext(SCRN_LEFT+3+left,SCRN_TOP+y ! 574: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 575: showmouse(); ! 576: break; ! 577: case 72: /* up arrow */ ! 578: if(!opts) ! 579: break; ! 580: if(!(*cur) && opts+4>height) { ! 581: hidemouse(); ! 582: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3); /* like end */ ! 583: textattr(lclr|(bclr<<4)); ! 584: putch(30); /* put the up arrow */ ! 585: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2); ! 586: putch(' '); /* delete the down arrow */ ! 587: for(i=(opts+4)-height,j=0;i<opts;i++,j++) ! 588: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+j ! 589: ,i==opts-1 ? bclr|(LIGHTGRAY<<4) ! 590: : lclr|(bclr<<4) ! 591: ,"%-*.*s",width-4,width-4,option[i]); ! 592: (*cur)=opts-1; ! 593: if(bar) ! 594: (*bar)=height-5; ! 595: y=top+height-2; ! 596: showmouse(); ! 597: break; } ! 598: hidemouse(); ! 599: gettext(SCRN_LEFT+3+left,SCRN_TOP+y ! 600: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 601: for(i=1;i<width*2;i+=2) ! 602: line[i]=lclr|(bclr<<4); ! 603: puttext(SCRN_LEFT+3+left,SCRN_TOP+y ! 604: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 605: showmouse(); ! 606: if(!(*cur)) { ! 607: y=top+height-2; ! 608: (*cur)=opts-1; ! 609: if(bar) ! 610: (*bar)=height-5; } ! 611: else { ! 612: (*cur)--; ! 613: y--; ! 614: if(bar && *bar) ! 615: (*bar)--; } ! 616: if(y<top+3) { /* scroll */ ! 617: hidemouse(); ! 618: if(!(*cur)) { ! 619: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3); ! 620: textattr(lclr|(bclr<<4)); ! 621: putch(' '); } /* delete the up arrow */ ! 622: if((*cur)+height-4==opts-1) { ! 623: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2); ! 624: textattr(lclr|(bclr<<4)); ! 625: putch(31); } /* put the dn arrow */ ! 626: y++; ! 627: scroll_text(SCRN_LEFT+left+2,SCRN_TOP+top+3 ! 628: ,SCRN_LEFT+left+width-3,SCRN_TOP+top+height-2,1); ! 629: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3 ! 630: ,bclr|(LIGHTGRAY<<4) ! 631: ,"%-*.*s",width-4,width-4,option[*cur]); ! 632: showmouse(); } ! 633: else { ! 634: hidemouse(); ! 635: gettext(SCRN_LEFT+3+left,SCRN_TOP+y ! 636: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 637: for(i=1;i<width*2;i+=2) ! 638: line[i]=bclr|(LIGHTGRAY<<4); ! 639: puttext(SCRN_LEFT+3+left,SCRN_TOP+y ! 640: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 641: showmouse(); } ! 642: break; ! 643: #if 0 ! 644: case 0x49; /* PgUp */ ! 645: case 0x51; /* PgDn */ ! 646: if(!opts || (*cur)==(opts-1)) ! 647: break; ! 648: (*cur)+=(height-4); ! 649: if((*cur)>(opts-1)) ! 650: (*cur)=(opts-1); ! 651: ! 652: hidemouse(); ! 653: gettext(SCRN_LEFT+3+left,SCRN_TOP+y ! 654: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 655: for(i=1;i<width*2;i+=2) ! 656: line[i]=lclr|(bclr<<4); ! 657: puttext(SCRN_LEFT+3+left,SCRN_TOP+y ! 658: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 659: ! 660: for(i=(opts+4)-height,j=0;i<opts;i++,j++) ! 661: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+j ! 662: ,i==(*cur) bclr|(LIGHTGRAY<<4) : lclr|(bclr<<4) ! 663: ,"%-*.*s",width-4,width-4,option[i]); ! 664: y=top+height-2; ! 665: if(bar) ! 666: (*bar)=height-5; ! 667: gettext(SCRN_LEFT+3+left,SCRN_TOP+y ! 668: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 669: for(i=1;i<148;i+=2) ! 670: line[i]=bclr|(LIGHTGRAY<<4); ! 671: puttext(SCRN_LEFT+3+left,SCRN_TOP+y ! 672: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 673: showmouse(); ! 674: break; ! 675: #endif ! 676: case 79: /* end */ ! 677: if(!opts) ! 678: break; ! 679: if(opts+4>height) { /* Scroll mode */ ! 680: hidemouse(); ! 681: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3); ! 682: textattr(lclr|(bclr<<4)); ! 683: putch(30); /* put the up arrow */ ! 684: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2); ! 685: putch(' '); /* delete the down arrow */ ! 686: for(i=(opts+4)-height,j=0;i<opts;i++,j++) ! 687: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+j ! 688: ,i==opts-1 ? bclr|(LIGHTGRAY<<4) ! 689: : lclr|(bclr<<4) ! 690: ,"%-*.*s",width-4,width-4,option[i]); ! 691: (*cur)=opts-1; ! 692: y=top+height-2; ! 693: if(bar) ! 694: (*bar)=height-5; ! 695: showmouse(); ! 696: break; } ! 697: hidemouse(); ! 698: gettext(SCRN_LEFT+3+left,SCRN_TOP+y ! 699: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 700: for(i=1;i<width*2;i+=2) ! 701: line[i]=lclr|(bclr<<4); ! 702: puttext(SCRN_LEFT+3+left,SCRN_TOP+y ! 703: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 704: (*cur)=opts-1; ! 705: y=top+height-2; ! 706: if(bar) ! 707: (*bar)=height-5; ! 708: gettext(SCRN_LEFT+3+left,SCRN_TOP+y ! 709: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 710: for(i=1;i<148;i+=2) ! 711: line[i]=bclr|(LIGHTGRAY<<4); ! 712: puttext(SCRN_LEFT+3+left,SCRN_TOP+y ! 713: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 714: showmouse(); ! 715: break; ! 716: case 80: /* dn arrow */ ! 717: if(!opts) ! 718: break; ! 719: if((*cur)==opts-1 && opts+4>height) { /* like home */ ! 720: hidemouse(); ! 721: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3); ! 722: textattr(lclr|(bclr<<4)); ! 723: putch(' '); /* Delete the up arrow */ ! 724: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2); ! 725: putch(31); /* put the down arrow */ ! 726: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3 ! 727: ,bclr|(LIGHTGRAY<<4) ! 728: ,"%-*.*s",width-4,width-4,option[0]); ! 729: for(i=1;i<height-4;i++) /* re-display options */ ! 730: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+i ! 731: ,lclr|(bclr<<4) ! 732: ,"%-*.*s",width-4,width-4,option[i]); ! 733: (*cur)=0; ! 734: y=top+3; ! 735: if(bar) ! 736: (*bar)=0; ! 737: showmouse(); ! 738: break; } ! 739: hidemouse(); ! 740: gettext(SCRN_LEFT+3+left,SCRN_TOP+y ! 741: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 742: for(i=1;i<width*2;i+=2) ! 743: line[i]=lclr|(bclr<<4); ! 744: puttext(SCRN_LEFT+3+left,SCRN_TOP+y ! 745: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 746: showmouse(); ! 747: if((*cur)==opts-1) { ! 748: (*cur)=0; ! 749: y=top+3; ! 750: if(bar) { ! 751: /* gotoxy(1,1); cprintf("bar=%08lX ",bar); */ ! 752: (*bar)=0; } } ! 753: else { ! 754: (*cur)++; ! 755: y++; ! 756: if(bar && (*bar)<height-5) { ! 757: /* gotoxy(1,1); cprintf("bar=%08lX ",bar); */ ! 758: (*bar)++; } } ! 759: if(y==top+height-1) { /* scroll */ ! 760: hidemouse(); ! 761: if(*cur==opts-1) { ! 762: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2); ! 763: textattr(lclr|(bclr<<4)); ! 764: putch(' '); } /* delete the down arrow */ ! 765: if((*cur)+4==height) { ! 766: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3); ! 767: textattr(lclr|(bclr<<4)); ! 768: putch(30); } /* put the up arrow */ ! 769: y--; ! 770: /* gotoxy(1,1); cprintf("\rdebug: %4d ",__LINE__); */ ! 771: scroll_text(SCRN_LEFT+left+2,SCRN_TOP+top+3 ! 772: ,SCRN_LEFT+left+width-3,SCRN_TOP+top+height-2,0); ! 773: /* gotoxy(1,1); cprintf("\rdebug: %4d ",__LINE__); */ ! 774: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+height-2 ! 775: ,bclr|(LIGHTGRAY<<4) ! 776: ,"%-*.*s",width-4,width-4,option[*cur]); ! 777: showmouse(); } ! 778: else { ! 779: hidemouse(); ! 780: gettext(SCRN_LEFT+3+left,SCRN_TOP+y ! 781: ,SCRN_LEFT+left+width-2,SCRN_TOP+y ! 782: ,line); ! 783: for(i=1;i<width*2;i+=2) ! 784: line[i]=bclr|(LIGHTGRAY<<4); ! 785: puttext(SCRN_LEFT+3+left,SCRN_TOP+y ! 786: ,SCRN_LEFT+left+width-2,SCRN_TOP+y ! 787: ,line); ! 788: showmouse(); } ! 789: break; ! 790: case 0x3b: /* F1 */ ! 791: help(); ! 792: break; ! 793: case 0x3f: /* F5 */ ! 794: if(mode&WIN_GET && !(mode&WIN_XTR && (*cur)==opts-1)) ! 795: return((*cur)|MSK_GET); ! 796: break; ! 797: case 0x40: /* F6 */ ! 798: if(mode&WIN_PUT && !(mode&WIN_XTR && (*cur)==opts-1)) ! 799: return((*cur)|MSK_PUT); ! 800: break; ! 801: case 82: /* insert */ ! 802: if(mode&WIN_INS) { ! 803: if(mode&WIN_INSACT) { ! 804: hidemouse(); ! 805: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT ! 806: +left+width-1,SCRN_TOP+top+height-1,win); ! 807: for(i=1;i<(width*height*2);i+=2) ! 808: win[i]=lclr|(cclr<<4); ! 809: if(opts) { ! 810: j=(((y-top)*width)*2)+7+((width-4)*2); ! 811: for(i=(((y-top)*width)*2)+7;i<j;i+=2) ! 812: win[i]=hclr|(cclr<<4); } ! 813: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT ! 814: +left+width-1,SCRN_TOP+top+height-1,win); ! 815: showmouse(); } ! 816: if(!opts) ! 817: return(MSK_INS); ! 818: return((*cur)|MSK_INS); } ! 819: break; ! 820: case 83: /* delete */ ! 821: if(mode&WIN_XTR && (*cur)==opts-1) /* can't delete */ ! 822: break; /* extra line */ ! 823: if(mode&WIN_DEL) { ! 824: if(mode&WIN_DELACT) { ! 825: hidemouse(); ! 826: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT ! 827: +left+width-1,SCRN_TOP+top+height-1,win); ! 828: for(i=1;i<(width*height*2);i+=2) ! 829: win[i]=lclr|(cclr<<4); ! 830: j=(((y-top)*width)*2)+7+((width-4)*2); ! 831: for(i=(((y-top)*width)*2)+7;i<j;i+=2) ! 832: win[i]=hclr|(cclr<<4); ! 833: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT ! 834: +left+width-1,SCRN_TOP+top+height-1,win); ! 835: showmouse(); } ! 836: return((*cur)|MSK_DEL); } ! 837: break; } } ! 838: else { ! 839: i&=0xff; ! 840: if(isalnum(i) && opts && option[0][0]) { ! 841: search[s]=i; ! 842: search[s+1]=0; ! 843: for(j=(*cur)+1,a=b=0;a<2;j++) { /* a = search count */ ! 844: if(j==opts) { /* j = option count */ ! 845: j=-1; /* b = letter count */ ! 846: continue; } ! 847: if(j==(*cur)) { ! 848: b++; ! 849: continue; } ! 850: if(b>=longopt) { ! 851: b=0; ! 852: a++; } ! 853: if(a==1 && !s) ! 854: break; ! 855: if(strlen(option[j])>b ! 856: && ((!a && s && !strncmpi(option[j]+b,search,s+1)) ! 857: || ((a || !s) && toupper(option[j][b])==toupper(i)))) { ! 858: if(a) s=0; ! 859: else s++; ! 860: if(y+(j-(*cur))+2>height+top) { ! 861: (*cur)=j; ! 862: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3); ! 863: textattr(lclr|(bclr<<4)); ! 864: putch(30); /* put the up arrow */ ! 865: if((*cur)==opts-1) { ! 866: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2); ! 867: putch(' '); } /* delete the down arrow */ ! 868: for(i=((*cur)+5)-height,j=0;i<(*cur)+1;i++,j++) ! 869: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+j ! 870: ,i==(*cur) ? bclr|(LIGHTGRAY<<4) ! 871: : lclr|(bclr<<4) ! 872: ,"%-*.*s",width-4,width-4,option[i]); ! 873: y=top+height-2; ! 874: if(bar) ! 875: (*bar)=height-5; ! 876: break; } ! 877: if(y-((*cur)-j)<top+3) { ! 878: (*cur)=j; ! 879: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3); ! 880: textattr(lclr|(bclr<<4)); ! 881: if(!(*cur)) ! 882: putch(' '); /* Delete the up arrow */ ! 883: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2); ! 884: putch(31); /* put the down arrow */ ! 885: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3 ! 886: ,bclr|(LIGHTGRAY<<4) ! 887: ,"%-*.*s",width-4,width-4,option[(*cur)]); ! 888: for(i=1;i<height-4;i++) /* re-display options */ ! 889: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+i ! 890: ,lclr|(bclr<<4) ! 891: ,"%-*.*s",width-4,width-4 ! 892: ,option[(*cur)+i]); ! 893: y=top+3; ! 894: if(bar) ! 895: (*bar)=0; ! 896: break; } ! 897: hidemouse(); ! 898: gettext(SCRN_LEFT+3+left,SCRN_TOP+y ! 899: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 900: for(i=1;i<width*2;i+=2) ! 901: line[i]=lclr|(bclr<<4); ! 902: puttext(SCRN_LEFT+3+left,SCRN_TOP+y ! 903: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 904: if((*cur)>j) ! 905: y-=(*cur)-j; ! 906: else ! 907: y+=j-(*cur); ! 908: if(bar) { ! 909: if((*cur)>j) ! 910: (*bar)-=(*cur)-j; ! 911: else ! 912: (*bar)+=j-(*cur); } ! 913: (*cur)=j; ! 914: gettext(SCRN_LEFT+3+left,SCRN_TOP+y ! 915: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 916: for(i=1;i<width*2;i+=2) ! 917: line[i]=bclr|(LIGHTGRAY<<4); ! 918: puttext(SCRN_LEFT+3+left,SCRN_TOP+y ! 919: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); ! 920: showmouse(); ! 921: break; } } ! 922: if(a==2) ! 923: s=0; } ! 924: else ! 925: switch(i) { ! 926: case CR: ! 927: if(!opts || (mode&WIN_XTR && (*cur)==opts-1)) ! 928: break; ! 929: if(mode&WIN_ACT) { ! 930: hidemouse(); ! 931: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT ! 932: +left+width-1,SCRN_TOP+top+height-1,win); ! 933: for(i=1;i<(width*height*2);i+=2) ! 934: win[i]=lclr|(cclr<<4); ! 935: j=(((y-top)*width)*2)+7+((width-4)*2); ! 936: for(i=(((y-top)*width)*2)+7;i<j;i+=2) ! 937: win[i]=hclr|(cclr<<4); ! 938: ! 939: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT ! 940: +left+width-1,SCRN_TOP+top+height-1,win); ! 941: showmouse(); } ! 942: else if(mode&WIN_SAV) { ! 943: hidemouse(); ! 944: puttext(sav[api->savnum].left,sav[api->savnum].top ! 945: ,sav[api->savnum].right,sav[api->savnum].bot ! 946: ,sav[api->savnum].buf); ! 947: showmouse(); ! 948: free(sav[api->savnum].buf); ! 949: api->savdepth--; } ! 950: return(*cur); ! 951: case ESC: ! 952: case '\b': /* backspace */ ! 953: if(mode&WIN_ESC || (mode&WIN_CHE && api->changes) ! 954: && !(mode&WIN_SAV)) { ! 955: hidemouse(); ! 956: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT ! 957: +left+width-1,SCRN_TOP+top+height-1,win); ! 958: for(i=1;i<(width*height*2);i+=2) ! 959: win[i]=lclr|(cclr<<4); ! 960: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT ! 961: +left+width-1,SCRN_TOP+top+height-1,win); ! 962: showmouse(); } ! 963: else if(mode&WIN_SAV) { ! 964: hidemouse(); ! 965: puttext(sav[api->savnum].left,sav[api->savnum].top ! 966: ,sav[api->savnum].right,sav[api->savnum].bot ! 967: ,sav[api->savnum].buf); ! 968: showmouse(); ! 969: free(sav[api->savnum].buf); ! 970: api->savdepth--; } ! 971: return(-1); } } } ! 972: else ! 973: mswait(1); ! 974: } ! 975: } ! 976: ! 977: ! 978: /*************************************************************************/ ! 979: /* This function is a windowed input string input routine. */ ! 980: /*************************************************************************/ ! 981: int uinput(int mode, int left, int top, char *prompt, char *str, ! 982: int max, int kmode) ! 983: { ! 984: unsigned char c,tmp[81],save_buf[2048],in_win[2048] ! 985: ,shade[160],width,height=3; ! 986: int i,j,plen,slen; ! 987: ! 988: hidemouse(); ! 989: plen=strlen(prompt); ! 990: if(!plen) ! 991: slen=4; ! 992: else ! 993: slen=6; ! 994: width=plen+slen+max; ! 995: if(mode&WIN_T2B) ! 996: top=(api->scrn_len/2)-(height/2)-2; ! 997: if(mode&WIN_L2R) ! 998: left=36-(width/2); ! 999: if(mode&WIN_SAV) ! 1000: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width+1 ! 1001: ,SCRN_TOP+top+height,save_buf); ! 1002: i=0; ! 1003: in_win[i++]='�'; ! 1004: in_win[i++]=hclr|(bclr<<4); ! 1005: for(c=1;c<width-1;c++) { ! 1006: in_win[i++]='�'; ! 1007: in_win[i++]=hclr|(bclr<<4); } ! 1008: in_win[i++]='�'; ! 1009: in_win[i++]=hclr|(bclr<<4); ! 1010: in_win[i++]='�'; ! 1011: in_win[i++]=hclr|(bclr<<4); ! 1012: ! 1013: if(plen) { ! 1014: in_win[i++]=' '; ! 1015: in_win[i++]=lclr|(bclr<<4); } ! 1016: ! 1017: for(c=0;prompt[c];c++) { ! 1018: in_win[i++]=prompt[c]; ! 1019: in_win[i++]=lclr|(bclr<<4); } ! 1020: ! 1021: if(plen) { ! 1022: in_win[i++]=':'; ! 1023: in_win[i++]=lclr|(bclr<<4); ! 1024: c++; } ! 1025: ! 1026: for(c=0;c<max+2;c++) { ! 1027: in_win[i++]=' '; ! 1028: in_win[i++]=lclr|(bclr<<4); } ! 1029: ! 1030: in_win[i++]='�'; ! 1031: in_win[i++]=hclr|(bclr<<4); ! 1032: in_win[i++]='�'; ! 1033: in_win[i++]=hclr|(bclr<<4); ! 1034: for(c=1;c<width-1;c++) { ! 1035: in_win[i++]='�'; ! 1036: in_win[i++]=hclr|(bclr<<4); } ! 1037: in_win[i++]='�'; ! 1038: in_win[i++]=hclr|(bclr<<4); ! 1039: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width-1 ! 1040: ,SCRN_TOP+top+height-1,in_win); ! 1041: ! 1042: if(bclr==BLUE) { ! 1043: gettext(SCRN_LEFT+left+width,SCRN_TOP+top+1,SCRN_LEFT+left+width+1 ! 1044: ,SCRN_TOP+top+(height-1),shade); ! 1045: for(c=1;c<12;c+=2) ! 1046: shade[c]=DARKGRAY; ! 1047: puttext(SCRN_LEFT+left+width,SCRN_TOP+top+1,SCRN_LEFT+left+width+1 ! 1048: ,SCRN_TOP+top+(height-1),shade); ! 1049: gettext(SCRN_LEFT+left+2,SCRN_TOP+top+3,SCRN_LEFT+left+width+1 ! 1050: ,SCRN_TOP+top+height,shade); ! 1051: for(c=1;c<width*2;c+=2) ! 1052: shade[c]=DARKGRAY; ! 1053: puttext(SCRN_LEFT+left+2,SCRN_TOP+top+3,SCRN_LEFT+left+width+1 ! 1054: ,SCRN_TOP+top+height,shade); } ! 1055: ! 1056: textattr(lclr|(bclr<<4)); ! 1057: if(!plen) ! 1058: gotoxy(SCRN_LEFT+left+2,SCRN_TOP+top+1); ! 1059: else ! 1060: gotoxy(SCRN_LEFT+left+plen+4,SCRN_TOP+top+1); ! 1061: i=getstr(str,max,kmode); ! 1062: if(mode&WIN_SAV) ! 1063: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width+1 ! 1064: ,SCRN_TOP+top+height,save_buf); ! 1065: showmouse(); ! 1066: return(i); ! 1067: } ! 1068: ! 1069: /****************************************************************************/ ! 1070: /* Displays the message 'str' and waits for the user to select "OK" */ ! 1071: /****************************************************************************/ ! 1072: void umsg(char *str) ! 1073: { ! 1074: int i=0; ! 1075: char *ok[2]={"OK",""}; ! 1076: ! 1077: if(api->mode&UIFC_INMSG) /* non-cursive */ ! 1078: return; ! 1079: api->mode|=UIFC_INMSG; ! 1080: if(api->savdepth) api->savnum++; ! 1081: ulist(WIN_SAV|WIN_MID,0,0,0,&i,0,str,ok); ! 1082: if(api->savdepth) api->savnum--; ! 1083: api->mode&=~UIFC_INMSG; ! 1084: } ! 1085: ! 1086: /****************************************************************************/ ! 1087: /* Gets a string of characters from the user. Turns cursor on. Allows */ ! 1088: /* Different modes - K_* macros. ESC aborts input. */ ! 1089: /* Cursor should be at END of where string prompt will be placed. */ ! 1090: /****************************************************************************/ ! 1091: static int getstr(char *outstr, int max, long mode) ! 1092: { ! 1093: uchar ch,str[256],ins=0,buf[256],y; ! 1094: int i,j,k,f=0; /* i=offset, j=length */ ! 1095: ! 1096: cursor=_NORMALCURSOR; ! 1097: _setcursortype(cursor); ! 1098: y=wherey(); ! 1099: if(mode&K_EDIT) { ! 1100: /*** ! 1101: truncsp(outstr); ! 1102: ***/ ! 1103: outstr[max]=0; ! 1104: textattr(bclr|(LIGHTGRAY<<4)); ! 1105: cputs(outstr); ! 1106: textattr(lclr|(bclr<<4)); ! 1107: strcpy(str,outstr); ! 1108: i=j=strlen(str); ! 1109: while(inkey(1)==0) { ! 1110: mswait(1); ! 1111: } ! 1112: f=inkey(0); ! 1113: gotoxy(wherex()-i,y); ! 1114: if(!isprint(f&0xff) && f!=0x5300) ! 1115: cputs(outstr); ! 1116: else { ! 1117: cprintf("%*s",i,""); ! 1118: gotoxy(wherex()-i,y); ! 1119: i=j=0; } } ! 1120: else ! 1121: i=j=0; ! 1122: ! 1123: ! 1124: while(1) { ! 1125: ! 1126: ! 1127: if(i>j) j=i; ! 1128: if(f || inkey(1)) { ! 1129: if(f) k=f; /* First key */ ! 1130: else k=inkey(0); ! 1131: f=0; ! 1132: ch=k&0xff; ! 1133: if(!ch) { ! 1134: switch(k>>8) { ! 1135: case 0x3b: /* F1 Help */ ! 1136: help(); ! 1137: continue; ! 1138: case 0x4b: /* left arrow */ ! 1139: if(i) { ! 1140: gotoxy(wherex()-1,y); ! 1141: i--; } ! 1142: continue; ! 1143: case 0x4d: /* right arrow */ ! 1144: if(i<j) { ! 1145: gotoxy(wherex()+1,y); ! 1146: i++; } ! 1147: continue; ! 1148: case 0x47: /* home */ ! 1149: if(i) { ! 1150: gotoxy(wherex()-i,y); ! 1151: i=0; } ! 1152: continue; ! 1153: case 0x4f: /* end */ ! 1154: if(i<j) { ! 1155: gotoxy(wherex()+(j-i),y); ! 1156: i=j; } ! 1157: continue; ! 1158: case 0x52: /* insert */ ! 1159: ins=!ins; ! 1160: if(ins) ! 1161: cursor=_SOLIDCURSOR; ! 1162: else ! 1163: cursor=_NORMALCURSOR; ! 1164: _setcursortype(cursor); ! 1165: continue; ! 1166: case 0x53: /* delete */ ! 1167: if(i<j) { ! 1168: gettext(wherex()+1,y,wherex()+(j-i),y,buf); ! 1169: puttext(wherex(),y,wherex()+(j-i)-1,y,buf); ! 1170: gotoxy(wherex()+(j-i),y); ! 1171: putch(' '); ! 1172: gotoxy(wherex()-((j-i)+1),y); ! 1173: for(k=i;k<j;k++) ! 1174: str[k]=str[k+1]; ! 1175: j--; } ! 1176: continue; } ! 1177: continue; } ! 1178: if(ch==03 || ch==ESC) { ! 1179: cursor=_NOCURSOR; ! 1180: _setcursortype(cursor); ! 1181: return(-1); } ! 1182: if(ch==BS && i) { ! 1183: if(i==j) { ! 1184: cputs("\b \b"); ! 1185: j--; ! 1186: i--; } ! 1187: else { ! 1188: gettext(wherex(),y,wherex()+(j-i),y,buf); ! 1189: puttext(wherex()-1,y,wherex()+(j-i)-1,y,buf); ! 1190: gotoxy(wherex()+(j-i),y); ! 1191: putch(' '); ! 1192: gotoxy(wherex()-((j-i)+2),y); ! 1193: i--; ! 1194: j--; ! 1195: for(k=i;k<j;k++) ! 1196: str[k]=str[k+1]; } ! 1197: continue; } ! 1198: if(ch==CR) ! 1199: break; ! 1200: if(ch==24) { /* ctrl-x */ ! 1201: if(j) { ! 1202: gotoxy(wherex()-i,y); ! 1203: cprintf("%*s",j,""); ! 1204: gotoxy(wherex()-j,y); ! 1205: i=j=0; } ! 1206: continue; } ! 1207: if(ch==25) { /* ctrl-y */ ! 1208: if(i<j) { ! 1209: cprintf("%*s",(j-i),""); ! 1210: gotoxy(wherex()-(j-i),y); ! 1211: j=i; } ! 1212: continue; } ! 1213: if(mode&K_NUMBER && !isdigit(ch)) ! 1214: continue; ! 1215: if(mode&K_ALPHA && !isalpha(ch)) ! 1216: continue; ! 1217: if((ch>=' ' || (ch==1 && mode&K_MSG)) && i<max && (!ins || j<max)) { ! 1218: if(mode&K_UPPER) ! 1219: ch=toupper(ch); ! 1220: if(ins) { ! 1221: gettext(wherex(),y,wherex()+(j-i),y,buf); ! 1222: puttext(wherex()+1,y,wherex()+(j-i)+1,y,buf); ! 1223: for(k=++j;k>i;k--) ! 1224: str[k]=str[k-1]; } ! 1225: putch(ch); ! 1226: str[i++]=ch; } } ! 1227: else ! 1228: mswait(1); ! 1229: } ! 1230: str[j]=0; ! 1231: if(mode&K_EDIT) { ! 1232: truncsp(str); ! 1233: if(strcmp(outstr,str)) ! 1234: api->changes=1; } ! 1235: else { ! 1236: if(j) ! 1237: api->changes=1; } ! 1238: strcpy(outstr,str); ! 1239: cursor=_NOCURSOR; ! 1240: _setcursortype(cursor); ! 1241: return(j); ! 1242: } ! 1243: ! 1244: /****************************************************************************/ ! 1245: /* Performs printf() through puttext() routine */ ! 1246: /****************************************************************************/ ! 1247: static int uprintf(int x, int y, char attr, char *fmat, ...) ! 1248: { ! 1249: va_list argptr; ! 1250: char str[256],buf[512]; ! 1251: int i,j; ! 1252: ! 1253: va_start(argptr,fmat); ! 1254: vsprintf(str,fmat,argptr); ! 1255: va_end(argptr); ! 1256: for(i=j=0;str[i];i++) { ! 1257: buf[j++]=str[i]; ! 1258: buf[j++]=attr; } ! 1259: puttext(x,y,x+(i-1),y,buf); ! 1260: return(i); ! 1261: } ! 1262: ! 1263: ! 1264: /****************************************************************************/ ! 1265: /* Display bottom line of screen in inverse */ ! 1266: /****************************************************************************/ ! 1267: void bottomline(int line) ! 1268: { ! 1269: int i=0; ! 1270: uprintf(i,api->scrn_len+1,bclr|(cclr<<4)," "); ! 1271: i+=4; ! 1272: uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"F1 "); ! 1273: i+=3; ! 1274: uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Help "); ! 1275: i+=6; ! 1276: if(line&BL_GET) { ! 1277: uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"F5 "); ! 1278: i+=3; ! 1279: uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Copy Item "); ! 1280: i+=11; } ! 1281: if(line&BL_PUT) { ! 1282: uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"F6 "); ! 1283: i+=3; ! 1284: uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Paste "); ! 1285: i+=7; } ! 1286: if(line&BL_INS) { ! 1287: uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"INS "); ! 1288: i+=4; ! 1289: uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Add Item "); ! 1290: i+=10; } ! 1291: if(line&BL_DEL) { ! 1292: uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"DEL "); ! 1293: i+=4; ! 1294: uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Delete Item "); ! 1295: i+=13; } ! 1296: uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"ESC "); ! 1297: i+=4; ! 1298: uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Exit"); ! 1299: i+=4; ! 1300: gotoxy(i,api->scrn_len+1); ! 1301: textattr(BLACK|(cclr<<4)); ! 1302: clreol(); ! 1303: } ! 1304: ! 1305: ! 1306: /*****************************************************************************/ ! 1307: /* Generates a 24 character ASCII string that represents the time_t pointer */ ! 1308: /* Used as a replacement for ctime() */ ! 1309: /*****************************************************************************/ ! 1310: char *utimestr(time_t *intime) ! 1311: { ! 1312: static char str[25]; ! 1313: char wday[4],mon[4],mer[3],hour; ! 1314: struct tm *gm; ! 1315: ! 1316: gm=localtime(intime); ! 1317: switch(gm->tm_wday) { ! 1318: case 0: ! 1319: strcpy(wday,"Sun"); ! 1320: break; ! 1321: case 1: ! 1322: strcpy(wday,"Mon"); ! 1323: break; ! 1324: case 2: ! 1325: strcpy(wday,"Tue"); ! 1326: break; ! 1327: case 3: ! 1328: strcpy(wday,"Wed"); ! 1329: break; ! 1330: case 4: ! 1331: strcpy(wday,"Thu"); ! 1332: break; ! 1333: case 5: ! 1334: strcpy(wday,"Fri"); ! 1335: break; ! 1336: case 6: ! 1337: strcpy(wday,"Sat"); ! 1338: break; } ! 1339: switch(gm->tm_mon) { ! 1340: case 0: ! 1341: strcpy(mon,"Jan"); ! 1342: break; ! 1343: case 1: ! 1344: strcpy(mon,"Feb"); ! 1345: break; ! 1346: case 2: ! 1347: strcpy(mon,"Mar"); ! 1348: break; ! 1349: case 3: ! 1350: strcpy(mon,"Apr"); ! 1351: break; ! 1352: case 4: ! 1353: strcpy(mon,"May"); ! 1354: break; ! 1355: case 5: ! 1356: strcpy(mon,"Jun"); ! 1357: break; ! 1358: case 6: ! 1359: strcpy(mon,"Jul"); ! 1360: break; ! 1361: case 7: ! 1362: strcpy(mon,"Aug"); ! 1363: break; ! 1364: case 8: ! 1365: strcpy(mon,"Sep"); ! 1366: break; ! 1367: case 9: ! 1368: strcpy(mon,"Oct"); ! 1369: break; ! 1370: case 10: ! 1371: strcpy(mon,"Nov"); ! 1372: break; ! 1373: case 11: ! 1374: strcpy(mon,"Dec"); ! 1375: break; } ! 1376: if(gm->tm_hour>12) { ! 1377: strcpy(mer,"pm"); ! 1378: hour=gm->tm_hour-12; } ! 1379: else { ! 1380: if(!gm->tm_hour) ! 1381: hour=12; ! 1382: else ! 1383: hour=gm->tm_hour; ! 1384: strcpy(mer,"am"); } ! 1385: sprintf(str,"%s %s %02d %4d %02d:%02d %s",wday,mon,gm->tm_mday,1900+gm->tm_year ! 1386: ,hour,gm->tm_min,mer); ! 1387: return(str); ! 1388: } ! 1389: ! 1390: /****************************************************************************/ ! 1391: /* Status popup/down function, see uifc.h for details. */ ! 1392: /****************************************************************************/ ! 1393: void upop(char *str) ! 1394: { ! 1395: static char sav[26*3*2]; ! 1396: char buf[26*3*2]; ! 1397: int i,j,k; ! 1398: ! 1399: hidemouse(); ! 1400: if(!str) { ! 1401: puttext(28,12,53,14,sav); ! 1402: showmouse(); ! 1403: return; } ! 1404: gettext(28,12,53,14,sav); ! 1405: memset(buf,' ',25*3*2); ! 1406: for(i=1;i<26*3*2;i+=2) ! 1407: buf[i]=(hclr|(bclr<<4)); ! 1408: buf[0]='�'; ! 1409: for(i=2;i<25*2;i+=2) ! 1410: buf[i]='�'; ! 1411: buf[i]='�'; i+=2; ! 1412: buf[i]='�'; i+=2; ! 1413: i+=2; ! 1414: k=strlen(str); ! 1415: i+=(((23-k)/2)*2); ! 1416: for(j=0;j<k;j++,i+=2) { ! 1417: buf[i]=str[j]; ! 1418: buf[i+1]|=BLINK; } ! 1419: i=((25*2)+1)*2; ! 1420: buf[i]='�'; i+=2; ! 1421: buf[i]='�'; i+=2; ! 1422: for(;i<((26*3)-1)*2;i+=2) ! 1423: buf[i]='�'; ! 1424: buf[i]='�'; ! 1425: ! 1426: puttext(28,12,53,14,buf); ! 1427: showmouse(); ! 1428: } ! 1429: ! 1430: /****************************************************************************/ ! 1431: /* Sets the current help index by source code file and line number. */ ! 1432: /****************************************************************************/ ! 1433: void sethelp(int line, char* file) ! 1434: { ! 1435: helpline=line; ! 1436: helpfile=file; ! 1437: } ! 1438: ! 1439: /************************************************************/ ! 1440: /* Help (F1) key function. Uses helpbuf as the help input. */ ! 1441: /************************************************************/ ! 1442: void help() ! 1443: { ! 1444: char *savscrn,*buf,inverse=0,high=0 ! 1445: ,hbuf[HELPBUF_SIZE],str[256]; ! 1446: char *p; ! 1447: uint i,j,k,len; ! 1448: unsigned short line; ! 1449: long l; ! 1450: FILE *fp; ! 1451: ! 1452: _setcursortype(_NOCURSOR); ! 1453: ! 1454: if((savscrn=(char *)malloc(80*25*2))==NULL) { ! 1455: cprintf("UIFC line %d: error allocating %u bytes\r\n" ! 1456: ,__LINE__,80*25*2); ! 1457: _setcursortype(cursor); ! 1458: return; } ! 1459: if((buf=(char *)malloc(76*21*2))==NULL) { ! 1460: cprintf("UIFC line %d: error allocating %u bytes\r\n" ! 1461: ,__LINE__,76*21*2); ! 1462: free(savscrn); ! 1463: _setcursortype(cursor); ! 1464: return; } ! 1465: hidemouse(); ! 1466: gettext(1,1,80,25,savscrn); ! 1467: memset(buf,' ',76*21*2); ! 1468: for(i=1;i<76*21*2;i+=2) ! 1469: buf[i]=(hclr|(bclr<<4)); ! 1470: buf[0]='�'; ! 1471: for(i=2;i<30*2;i+=2) ! 1472: buf[i]='�'; ! 1473: buf[i]='�'; i+=4; ! 1474: buf[i]='O'; i+=2; ! 1475: buf[i]='n'; i+=2; ! 1476: buf[i]='l'; i+=2; ! 1477: buf[i]='i'; i+=2; ! 1478: buf[i]='n'; i+=2; ! 1479: buf[i]='e'; i+=4; ! 1480: buf[i]='H'; i+=2; ! 1481: buf[i]='e'; i+=2; ! 1482: buf[i]='l'; i+=2; ! 1483: buf[i]='p'; i+=4; ! 1484: buf[i]='�'; i+=2; ! 1485: for(j=i;j<i+(30*2);j+=2) ! 1486: buf[j]='�'; ! 1487: i=j; ! 1488: buf[i]='�'; i+=2; ! 1489: j=i; /* leave i alone */ ! 1490: for(k=0;k<19;k++) { /* the sides of the box */ ! 1491: buf[j]='�'; j+=2; ! 1492: j+=(74*2); ! 1493: buf[j]='�'; j+=2; } ! 1494: buf[j]='�'; j+=2; ! 1495: for(k=j;k<j+(23*2);k+=2) ! 1496: buf[k]='�'; ! 1497: buf[k]='�'; k+=4; ! 1498: buf[k]='H'; k+=2; ! 1499: buf[k]='i'; k+=2; ! 1500: buf[k]='t'; k+=4; ! 1501: buf[k]='a'; k+=2; ! 1502: buf[k]='n'; k+=2; ! 1503: buf[k]='y'; k+=4; ! 1504: buf[k]='k'; k+=2; ! 1505: buf[k]='e'; k+=2; ! 1506: buf[k]='y'; k+=4; ! 1507: buf[k]='t'; k+=2; ! 1508: buf[k]='o'; k+=4; ! 1509: buf[k]='c'; k+=2; ! 1510: buf[k]='o'; k+=2; ! 1511: buf[k]='n'; k+=2; ! 1512: buf[k]='t'; k+=2; ! 1513: buf[k]='i'; k+=2; ! 1514: buf[k]='n'; k+=2; ! 1515: buf[k]='u'; k+=2; ! 1516: buf[k]='e'; k+=4; ! 1517: buf[k]='�'; k+=2; ! 1518: for(j=k;j<k+(24*2);j+=2) ! 1519: buf[j]='�'; ! 1520: buf[j]='�'; ! 1521: ! 1522: if(!api->helpbuf) { ! 1523: if((fp=_fsopen(api->helpixbfile,"rb",SH_DENYWR))==NULL) ! 1524: sprintf(hbuf," ERROR Cannot open help index:\r\n %s" ! 1525: ,api->helpixbfile); ! 1526: else { ! 1527: p=strrchr(helpfile,'/'); ! 1528: if(p==NULL) ! 1529: p=strrchr(helpfile,'\\'); ! 1530: if(p==NULL) ! 1531: p=helpfile; ! 1532: else ! 1533: p++; ! 1534: l=-1L; ! 1535: while(!feof(fp)) { ! 1536: if(!fread(str,12,1,fp)) ! 1537: break; ! 1538: str[12]=0; ! 1539: fread(&line,2,1,fp); ! 1540: if(stricmp(str,p) || line!=helpline) { ! 1541: fseek(fp,4,SEEK_CUR); ! 1542: continue; } ! 1543: fread(&l,4,1,fp); ! 1544: break; } ! 1545: fclose(fp); ! 1546: if(l==-1L) ! 1547: sprintf(hbuf," ERROR Cannot locate help key (%s:%u) in:\r\n" ! 1548: " %s",p,helpline,api->helpixbfile); ! 1549: else { ! 1550: if((fp=_fsopen(api->helpdatfile,"rb",SH_DENYWR))==NULL) ! 1551: sprintf(hbuf," ERROR Cannot open help file:\r\n %s" ! 1552: ,api->helpdatfile); ! 1553: else { ! 1554: fseek(fp,l,SEEK_SET); ! 1555: fread(hbuf,HELPBUF_SIZE,1,fp); ! 1556: fclose(fp); } } } } ! 1557: else ! 1558: strcpy(hbuf,api->helpbuf); ! 1559: ! 1560: len=strlen(hbuf); ! 1561: ! 1562: i+=78*2; ! 1563: for(j=0;j<len;j++,i+=2) { ! 1564: if(hbuf[j]==LF) { ! 1565: while(i%(76*2)) i++; ! 1566: i+=2; } ! 1567: else if(hbuf[j]==2 || hbuf[j]=='~') { /* Ctrl-b toggles inverse */ ! 1568: inverse=!inverse; ! 1569: i-=2; } ! 1570: else if(hbuf[j]==1 || hbuf[j]=='`') { /* Ctrl-a toggles high intensity */ ! 1571: high=!high; ! 1572: i-=2; } ! 1573: else if(hbuf[j]!=CR) { ! 1574: buf[i]=hbuf[j]; ! 1575: buf[i+1]=inverse ? (bclr|(cclr<<4)) ! 1576: : high ? (hclr|(bclr<<4)) : (lclr|(bclr<<4)); } } ! 1577: puttext(3,3,78,23,buf); ! 1578: showmouse(); ! 1579: while(1) { ! 1580: if(inkey(1)) { ! 1581: inkey(0); ! 1582: break; } ! 1583: mswait(1); ! 1584: } ! 1585: ! 1586: hidemouse(); ! 1587: puttext(1,1,80,25,savscrn); ! 1588: showmouse(); ! 1589: free(savscrn); ! 1590: free(buf); ! 1591: _setcursortype(cursor); ! 1592: } ! 1593:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.