|
|
1.1 ! root 1: /* uifcx.c */ ! 2: ! 3: /* Standard I/O Implementation of UIFC (user interface) library */ ! 4: ! 5: /* $Id: uifcx.c,v 1.23 2004/07/27 22:36:54 rswindell 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: ! 40: #include <sys/types.h> ! 41: ! 42: #ifdef __unix__ ! 43: /* #include <sys/time.h> why? */ ! 44: #include <unistd.h> ! 45: #endif ! 46: ! 47: static char *helpfile=0; ! 48: static uint helpline=0; ! 49: static uifcapi_t* api; ! 50: ! 51: /* Prototypes */ ! 52: static void help(void); ! 53: ! 54: /* API routines */ ! 55: static void uifcbail(void); ! 56: static int uscrn(char *str); ! 57: static int ulist(int mode, int left, int top, int width, int *dflt, int *bar ! 58: ,char *title, char **option); ! 59: static int uinput(int imode, int left, int top, char *prompt, char *str ! 60: ,int len ,int kmode); ! 61: static void umsg(char *str); ! 62: static void upop(char *str); ! 63: static void sethelp(int line, char* file); ! 64: ! 65: /****************************************************************************/ ! 66: /* Initialization function, see uifc.h for details. */ ! 67: /* Returns 0 on success. */ ! 68: /****************************************************************************/ ! 69: int uifcinix(uifcapi_t* uifcapi) ! 70: { ! 71: ! 72: if(uifcapi==NULL || uifcapi->size!=sizeof(uifcapi_t)) ! 73: return(-1); ! 74: ! 75: api=uifcapi; ! 76: ! 77: /* install function handlers */ ! 78: api->bail=uifcbail; ! 79: api->scrn=uscrn; ! 80: api->msg=umsg; ! 81: api->pop=upop; ! 82: api->list=ulist; ! 83: api->input=uinput; ! 84: api->sethelp=sethelp; ! 85: api->showhelp=help; ! 86: api->showbuf=NULL; ! 87: api->timedisplay=NULL; ! 88: ! 89: setvbuf(stdin,NULL,_IONBF,0); ! 90: setvbuf(stdout,NULL,_IONBF,0); ! 91: api->scrn_len=24; ! 92: ! 93: return(0); ! 94: } ! 95: ! 96: /****************************************************************************/ ! 97: /* Exit/uninitialize UIFC implementation. */ ! 98: /****************************************************************************/ ! 99: void uifcbail(void) ! 100: { ! 101: } ! 102: ! 103: /****************************************************************************/ ! 104: /* Clear screen, fill with background attribute, display application title. */ ! 105: /* Returns 0 on success. */ ! 106: /****************************************************************************/ ! 107: int uscrn(char *str) ! 108: { ! 109: return(0); ! 110: } ! 111: ! 112: static int getstr(char* str, int maxlen) ! 113: { ! 114: char ch; ! 115: int len=0; ! 116: #ifdef __unix__ ! 117: int istty; ! 118: ! 119: istty=isatty(fileno(stdin)); ! 120: #endif ! 121: while(1) { ! 122: fread(&ch,1,1,stdin); ! 123: #ifdef __unix__ ! 124: if(!istty) { ! 125: printf("%c",ch); ! 126: fflush(stdout); ! 127: } ! 128: #endif ! 129: if(ch=='\r' || ch=='\n') /* enter */ ! 130: break; ! 131: if(ch=='\b' || ch==DEL) { /* backspace */ ! 132: if(len) len--; ! 133: continue; ! 134: } ! 135: if(len<maxlen) ! 136: str[len++]=ch; ! 137: } ! 138: str[len]=0; /* we need The Terminator */ ! 139: ! 140: return(len); ! 141: } ! 142: ! 143: ! 144: /****************************************************************************/ ! 145: /* Local utility function. */ ! 146: /****************************************************************************/ ! 147: static int which(char* prompt, int max) ! 148: { ! 149: char str[41]; ! 150: int i; ! 151: ! 152: while(1) { ! 153: printf("%s which (1-%d): ",prompt,max); ! 154: str[0]=0; ! 155: getstr(str,sizeof(str)-1); ! 156: i=atoi(str); ! 157: if(i>0 && i<=max) ! 158: return(i-1); ! 159: } ! 160: } ! 161: ! 162: /****************************************************************************/ ! 163: /* Truncates white-space chars off end of 'str' */ ! 164: /****************************************************************************/ ! 165: static void truncsp(char *str) ! 166: { ! 167: uint c; ! 168: ! 169: c=strlen(str); ! 170: while(c && (uchar)str[c-1]<=' ') c--; ! 171: str[c]=0; ! 172: } ! 173: ! 174: /****************************************************************************/ ! 175: /* Convert ASCIIZ string to upper case */ ! 176: /****************************************************************************/ ! 177: #if defined(__unix__) ! 178: static char* strupr(char* str) ! 179: { ! 180: char* p=str; ! 181: ! 182: while(*p) { ! 183: *p=toupper(*p); ! 184: p++; ! 185: } ! 186: return(str); ! 187: } ! 188: #endif ! 189: ! 190: /****************************************************************************/ ! 191: /* General menu function, see uifc.h for details. */ ! 192: /****************************************************************************/ ! 193: int ulist(int mode, int left, int top, int width, int *cur, int *bar ! 194: , char *title, char **option) ! 195: { ! 196: char str[128]; ! 197: int i,opts; ! 198: int optnumlen; ! 199: int yesno=0; ! 200: int lines; ! 201: ! 202: for(opts=0;opts<MAX_OPTS;opts++) ! 203: if(option[opts]==NULL || option[opts][0]==0) ! 204: break; ! 205: ! 206: if((*cur)>=opts) ! 207: (*cur)=opts-1; /* returned after scrolled */ ! 208: ! 209: if((*cur)<0) ! 210: (*cur)=0; ! 211: ! 212: if(opts>999) ! 213: optnumlen=4; ! 214: else if(opts>99) ! 215: optnumlen=3; ! 216: else if(opts>9) ! 217: optnumlen=2; ! 218: else ! 219: optnumlen=1; ! 220: while(1) { ! 221: if(opts==2 && !stricmp(option[0],"Yes") && !stricmp(option[1],"No")) { ! 222: yesno=1; ! 223: printf("%s? ",title); ! 224: } else { ! 225: printf("\n[%s]\n",title); ! 226: lines=2; ! 227: for(i=0;i<opts;i++) { ! 228: printf("%*d: %s\n",optnumlen,i+1,option[i]); ! 229: lines++; ! 230: if(!(lines%api->scrn_len)) { ! 231: printf("More? "); ! 232: str[0]=0; ! 233: getstr(str,sizeof(str)-1); ! 234: if(toupper(*str)=='N') ! 235: break; ! 236: } ! 237: } ! 238: str[0]=0; ! 239: if(mode&WIN_GET) ! 240: strcat(str,", Copy"); ! 241: if(mode&WIN_PUT) ! 242: strcat(str,", Paste"); ! 243: if(mode&WIN_INS) ! 244: strcat(str,", Add"); ! 245: if(mode&WIN_DEL) ! 246: strcat(str,", Delete"); ! 247: printf("\nWhich (Help%s or Quit): ",str); ! 248: } ! 249: str[0]=0; ! 250: getstr(str,sizeof(str)-1); ! 251: ! 252: truncsp(str); ! 253: i=atoi(str); ! 254: if(i>0 && i<=opts) { ! 255: *cur=--i; ! 256: return(*cur); ! 257: } ! 258: i=atoi(str+1); ! 259: switch(toupper(*str)) { ! 260: case 0: ! 261: case ESC: ! 262: case 'Q': ! 263: printf("Quit\n"); ! 264: return(-1); ! 265: case 'Y': ! 266: if(!yesno) ! 267: break; ! 268: printf("Yes\n"); ! 269: return(0); ! 270: case 'N': ! 271: if(!yesno) ! 272: break; ! 273: printf("No\n"); ! 274: return(1); ! 275: case 'H': ! 276: case '?': ! 277: printf("Help\n"); ! 278: help(); ! 279: break; ! 280: case 'A': /* Add/Insert */ ! 281: if(!(mode&WIN_INS)) ! 282: break; ! 283: if(!opts) ! 284: return(MSK_INS); ! 285: if(i>0 && i<=opts+1) ! 286: return((i-1)|MSK_INS); ! 287: return(which("Add before",opts+1)|MSK_INS); ! 288: case 'D': /* Delete */ ! 289: if(!(mode&WIN_DEL)) ! 290: break; ! 291: if(!opts) ! 292: break; ! 293: if(i>0 && i<=opts) ! 294: return((i-1)|MSK_DEL); ! 295: if(opts==1) ! 296: return(MSK_DEL); ! 297: return(which("Delete",opts)|MSK_DEL); ! 298: case 'C': /* Copy/Get */ ! 299: if(!(mode&WIN_GET)) ! 300: break; ! 301: if(!opts) ! 302: break; ! 303: if(i>0 && i<=opts) ! 304: return((i-1)|MSK_GET); ! 305: if(opts==1) ! 306: return(MSK_GET); ! 307: return(which("Copy",opts)|MSK_GET); ! 308: case 'P': /* Paste/Put */ ! 309: if(!(mode&WIN_PUT)) ! 310: break; ! 311: if(!opts) ! 312: break; ! 313: if(i>0 && i<=opts) ! 314: return((i-1)|MSK_PUT); ! 315: if(opts==1) ! 316: return(MSK_PUT); ! 317: return(which("Paste",opts)|MSK_PUT); ! 318: } ! 319: } ! 320: } ! 321: ! 322: ! 323: /*************************************************************************/ ! 324: /* This function is a windowed input string input routine. */ ! 325: /*************************************************************************/ ! 326: int uinput(int mode, int left, int top, char *prompt, char *outstr, ! 327: int max, int kmode) ! 328: { ! 329: char str[256]; ! 330: ! 331: while(1) { ! 332: printf("%s (maxlen=%u): ",prompt,max); ! 333: ! 334: getstr(str,max); ! 335: truncsp(str); ! 336: if(strcmp(str,"?")) ! 337: break; ! 338: help(); ! 339: } ! 340: if(strcmp(outstr,str)) ! 341: api->changes=1; ! 342: if(kmode&K_UPPER) /* convert to uppercase? */ ! 343: strupr(str); ! 344: strcpy(outstr,str); ! 345: return(strlen(outstr)); ! 346: } ! 347: ! 348: /****************************************************************************/ ! 349: /* Displays the message 'str' and waits for the user to select "OK" */ ! 350: /****************************************************************************/ ! 351: void umsg(char *str) ! 352: { ! 353: printf("%s\n",str); ! 354: } ! 355: ! 356: /****************************************************************************/ ! 357: /* Status popup/down function, see uifc.h for details. */ ! 358: /****************************************************************************/ ! 359: void upop(char *str) ! 360: { ! 361: if(str==NULL) ! 362: printf("\n"); ! 363: else ! 364: printf("\r%-79s",str); ! 365: } ! 366: ! 367: /****************************************************************************/ ! 368: /* Sets the current help index by source code file and line number. */ ! 369: /****************************************************************************/ ! 370: void sethelp(int line, char* file) ! 371: { ! 372: helpline=line; ! 373: helpfile=file; ! 374: } ! 375: ! 376: /****************************************************************************/ ! 377: /* Help function. */ ! 378: /****************************************************************************/ ! 379: void help() ! 380: { ! 381: char hbuf[HELPBUF_SIZE],str[256]; ! 382: char *p; ! 383: unsigned short line; ! 384: long l; ! 385: FILE *fp; ! 386: ! 387: printf("\n"); ! 388: if(!api->helpbuf) { ! 389: if((fp=fopen(api->helpixbfile,"rb"))==NULL) ! 390: sprintf(hbuf,"ERROR: Cannot open help index: %s" ! 391: ,api->helpixbfile); ! 392: else { ! 393: p=strrchr(helpfile,'/'); ! 394: if(p==NULL) ! 395: p=strrchr(helpfile,'\\'); ! 396: if(p==NULL) ! 397: p=helpfile; ! 398: else ! 399: p++; ! 400: l=-1L; ! 401: while(!feof(fp)) { ! 402: if(!fread(str,12,1,fp)) ! 403: break; ! 404: str[12]=0; ! 405: fread(&line,2,1,fp); ! 406: if(stricmp(str,p) || line!=helpline) { ! 407: fseek(fp,4,SEEK_CUR); ! 408: continue; } ! 409: fread(&l,4,1,fp); ! 410: break; } ! 411: fclose(fp); ! 412: if(l==-1L) ! 413: sprintf(hbuf,"ERROR: Cannot locate help key (%s:%u) in: %s" ! 414: ,p,helpline,api->helpixbfile); ! 415: else { ! 416: if((fp=fopen(api->helpdatfile,"rb"))==NULL) ! 417: sprintf(hbuf,"ERROR: Cannot open help file: %s" ! 418: ,api->helpdatfile); ! 419: else { ! 420: fseek(fp,l,SEEK_SET); ! 421: fread(hbuf,HELPBUF_SIZE,1,fp); ! 422: fclose(fp); ! 423: } ! 424: } ! 425: } ! 426: } ! 427: else ! 428: strcpy(hbuf,api->helpbuf); ! 429: ! 430: puts(hbuf); ! 431: if(strlen(hbuf)>200) { ! 432: printf("Hit enter"); ! 433: getstr(str,sizeof(str)-1); ! 434: } ! 435: } ! 436: ! 437:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.