|
|
1.1 ! root 1: /* uifcx.c */ ! 2: ! 3: /* Standard I/O Implementation of UIFC (user interface) library */ ! 4: ! 5: /* $Id: uifcx.c,v 1.24 2005/11/19 02:32:59 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 2005 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This library is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU Lesser General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU Lesser General Public License for more details: lgpl.txt or * ! 18: * http://www.fsf.org/copyleft/lesser.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #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: api->initialized=TRUE; ! 93: ! 94: return(0); ! 95: } ! 96: ! 97: /****************************************************************************/ ! 98: /* Exit/uninitialize UIFC implementation. */ ! 99: /****************************************************************************/ ! 100: void uifcbail(void) ! 101: { ! 102: api->initialized=FALSE; ! 103: } ! 104: ! 105: /****************************************************************************/ ! 106: /* Clear screen, fill with background attribute, display application title. */ ! 107: /* Returns 0 on success. */ ! 108: /****************************************************************************/ ! 109: int uscrn(char *str) ! 110: { ! 111: return(0); ! 112: } ! 113: ! 114: static int getstr(char* str, int maxlen) ! 115: { ! 116: char ch; ! 117: int len=0; ! 118: #ifdef __unix__ ! 119: int istty; ! 120: ! 121: istty=isatty(fileno(stdin)); ! 122: #endif ! 123: while(1) { ! 124: fread(&ch,1,1,stdin); ! 125: #ifdef __unix__ ! 126: if(!istty) { ! 127: printf("%c",ch); ! 128: fflush(stdout); ! 129: } ! 130: #endif ! 131: if(ch=='\r' || ch=='\n') /* enter */ ! 132: break; ! 133: if(ch=='\b' || ch==DEL) { /* backspace */ ! 134: if(len) len--; ! 135: continue; ! 136: } ! 137: if(len<maxlen) ! 138: str[len++]=ch; ! 139: } ! 140: str[len]=0; /* we need The Terminator */ ! 141: ! 142: return(len); ! 143: } ! 144: ! 145: ! 146: /****************************************************************************/ ! 147: /* Local utility function. */ ! 148: /****************************************************************************/ ! 149: static int which(char* prompt, int max) ! 150: { ! 151: char str[41]; ! 152: int i; ! 153: ! 154: while(1) { ! 155: printf("%s which (1-%d): ",prompt,max); ! 156: str[0]=0; ! 157: getstr(str,sizeof(str)-1); ! 158: i=atoi(str); ! 159: if(i>0 && i<=max) ! 160: return(i-1); ! 161: } ! 162: } ! 163: ! 164: /****************************************************************************/ ! 165: /* Truncates white-space chars off end of 'str' */ ! 166: /****************************************************************************/ ! 167: static void truncsp(char *str) ! 168: { ! 169: uint c; ! 170: ! 171: c=strlen(str); ! 172: while(c && (uchar)str[c-1]<=' ') c--; ! 173: str[c]=0; ! 174: } ! 175: ! 176: /****************************************************************************/ ! 177: /* Convert ASCIIZ string to upper case */ ! 178: /****************************************************************************/ ! 179: #if defined(__unix__) ! 180: static char* strupr(char* str) ! 181: { ! 182: char* p=str; ! 183: ! 184: while(*p) { ! 185: *p=toupper(*p); ! 186: p++; ! 187: } ! 188: return(str); ! 189: } ! 190: #endif ! 191: ! 192: /****************************************************************************/ ! 193: /* General menu function, see uifc.h for details. */ ! 194: /****************************************************************************/ ! 195: int ulist(int mode, int left, int top, int width, int *cur, int *bar ! 196: , char *title, char **option) ! 197: { ! 198: char str[128]; ! 199: int i,opts; ! 200: int optnumlen; ! 201: int yesno=0; ! 202: int lines; ! 203: ! 204: for(opts=0;opts<MAX_OPTS;opts++) ! 205: if(option[opts]==NULL || option[opts][0]==0) ! 206: break; ! 207: ! 208: if((*cur)>=opts) ! 209: (*cur)=opts-1; /* returned after scrolled */ ! 210: ! 211: if((*cur)<0) ! 212: (*cur)=0; ! 213: ! 214: if(opts>999) ! 215: optnumlen=4; ! 216: else if(opts>99) ! 217: optnumlen=3; ! 218: else if(opts>9) ! 219: optnumlen=2; ! 220: else ! 221: optnumlen=1; ! 222: while(1) { ! 223: if(opts==2 && !stricmp(option[0],"Yes") && !stricmp(option[1],"No")) { ! 224: yesno=1; ! 225: printf("%s? ",title); ! 226: } else { ! 227: printf("\n[%s]\n",title); ! 228: lines=2; ! 229: for(i=0;i<opts;i++) { ! 230: printf("%*d: %s\n",optnumlen,i+1,option[i]); ! 231: lines++; ! 232: if(!(lines%api->scrn_len)) { ! 233: printf("More? "); ! 234: str[0]=0; ! 235: getstr(str,sizeof(str)-1); ! 236: if(toupper(*str)=='N') ! 237: break; ! 238: } ! 239: } ! 240: str[0]=0; ! 241: if(mode&WIN_GET) ! 242: strcat(str,", Copy"); ! 243: if(mode&WIN_PUT) ! 244: strcat(str,", Paste"); ! 245: if(mode&WIN_INS) ! 246: strcat(str,", Add"); ! 247: if(mode&WIN_DEL) ! 248: strcat(str,", Delete"); ! 249: printf("\nWhich (Help%s or Quit): ",str); ! 250: } ! 251: str[0]=0; ! 252: getstr(str,sizeof(str)-1); ! 253: ! 254: truncsp(str); ! 255: i=atoi(str); ! 256: if(i>0 && i<=opts) { ! 257: *cur=--i; ! 258: return(*cur); ! 259: } ! 260: i=atoi(str+1); ! 261: switch(toupper(*str)) { ! 262: case 0: ! 263: case ESC: ! 264: case 'Q': ! 265: printf("Quit\n"); ! 266: return(-1); ! 267: case 'Y': ! 268: if(!yesno) ! 269: break; ! 270: printf("Yes\n"); ! 271: return(0); ! 272: case 'N': ! 273: if(!yesno) ! 274: break; ! 275: printf("No\n"); ! 276: return(1); ! 277: case 'H': ! 278: case '?': ! 279: printf("Help\n"); ! 280: help(); ! 281: break; ! 282: case 'A': /* Add/Insert */ ! 283: if(!(mode&WIN_INS)) ! 284: break; ! 285: if(!opts) ! 286: return(MSK_INS); ! 287: if(i>0 && i<=opts+1) ! 288: return((i-1)|MSK_INS); ! 289: return(which("Add before",opts+1)|MSK_INS); ! 290: case 'D': /* Delete */ ! 291: if(!(mode&WIN_DEL)) ! 292: break; ! 293: if(!opts) ! 294: break; ! 295: if(i>0 && i<=opts) ! 296: return((i-1)|MSK_DEL); ! 297: if(opts==1) ! 298: return(MSK_DEL); ! 299: return(which("Delete",opts)|MSK_DEL); ! 300: case 'C': /* Copy/Get */ ! 301: if(!(mode&WIN_GET)) ! 302: break; ! 303: if(!opts) ! 304: break; ! 305: if(i>0 && i<=opts) ! 306: return((i-1)|MSK_GET); ! 307: if(opts==1) ! 308: return(MSK_GET); ! 309: return(which("Copy",opts)|MSK_GET); ! 310: case 'P': /* Paste/Put */ ! 311: if(!(mode&WIN_PUT)) ! 312: break; ! 313: if(!opts) ! 314: break; ! 315: if(i>0 && i<=opts) ! 316: return((i-1)|MSK_PUT); ! 317: if(opts==1) ! 318: return(MSK_PUT); ! 319: return(which("Paste",opts)|MSK_PUT); ! 320: } ! 321: } ! 322: } ! 323: ! 324: ! 325: /*************************************************************************/ ! 326: /* This function is a windowed input string input routine. */ ! 327: /*************************************************************************/ ! 328: int uinput(int mode, int left, int top, char *prompt, char *outstr, ! 329: int max, int kmode) ! 330: { ! 331: char str[256]; ! 332: ! 333: while(1) { ! 334: printf("%s (maxlen=%u): ",prompt,max); ! 335: ! 336: getstr(str,max); ! 337: truncsp(str); ! 338: if(strcmp(str,"?")) ! 339: break; ! 340: help(); ! 341: } ! 342: if(strcmp(outstr,str)) ! 343: api->changes=1; ! 344: if(kmode&K_UPPER) /* convert to uppercase? */ ! 345: strupr(str); ! 346: strcpy(outstr,str); ! 347: return(strlen(outstr)); ! 348: } ! 349: ! 350: /****************************************************************************/ ! 351: /* Displays the message 'str' and waits for the user to select "OK" */ ! 352: /****************************************************************************/ ! 353: void umsg(char *str) ! 354: { ! 355: printf("%s\n",str); ! 356: } ! 357: ! 358: /****************************************************************************/ ! 359: /* Status popup/down function, see uifc.h for details. */ ! 360: /****************************************************************************/ ! 361: void upop(char *str) ! 362: { ! 363: if(str==NULL) ! 364: printf("\n"); ! 365: else ! 366: printf("\r%-79s",str); ! 367: } ! 368: ! 369: /****************************************************************************/ ! 370: /* Sets the current help index by source code file and line number. */ ! 371: /****************************************************************************/ ! 372: void sethelp(int line, char* file) ! 373: { ! 374: helpline=line; ! 375: helpfile=file; ! 376: } ! 377: ! 378: /****************************************************************************/ ! 379: /* Help function. */ ! 380: /****************************************************************************/ ! 381: void help() ! 382: { ! 383: char hbuf[HELPBUF_SIZE],str[256]; ! 384: char *p; ! 385: unsigned short line; ! 386: long l; ! 387: FILE *fp; ! 388: ! 389: printf("\n"); ! 390: if(!api->helpbuf) { ! 391: if((fp=fopen(api->helpixbfile,"rb"))==NULL) ! 392: sprintf(hbuf,"ERROR: Cannot open help index: %s" ! 393: ,api->helpixbfile); ! 394: else { ! 395: p=strrchr(helpfile,'/'); ! 396: if(p==NULL) ! 397: p=strrchr(helpfile,'\\'); ! 398: if(p==NULL) ! 399: p=helpfile; ! 400: else ! 401: p++; ! 402: l=-1L; ! 403: while(!feof(fp)) { ! 404: if(!fread(str,12,1,fp)) ! 405: break; ! 406: str[12]=0; ! 407: fread(&line,2,1,fp); ! 408: if(stricmp(str,p) || line!=helpline) { ! 409: fseek(fp,4,SEEK_CUR); ! 410: continue; } ! 411: fread(&l,4,1,fp); ! 412: break; } ! 413: fclose(fp); ! 414: if(l==-1L) ! 415: sprintf(hbuf,"ERROR: Cannot locate help key (%s:%u) in: %s" ! 416: ,p,helpline,api->helpixbfile); ! 417: else { ! 418: if((fp=fopen(api->helpdatfile,"rb"))==NULL) ! 419: sprintf(hbuf,"ERROR: Cannot open help file: %s" ! 420: ,api->helpdatfile); ! 421: else { ! 422: fseek(fp,l,SEEK_SET); ! 423: fread(hbuf,HELPBUF_SIZE,1,fp); ! 424: fclose(fp); ! 425: } ! 426: } ! 427: } ! 428: } ! 429: else ! 430: strcpy(hbuf,api->helpbuf); ! 431: ! 432: puts(hbuf); ! 433: if(strlen(hbuf)>200) { ! 434: printf("Hit enter"); ! 435: getstr(str,sizeof(str)-1); ! 436: } ! 437: } ! 438: ! 439:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.