Annotation of sbbs/src/uifc/uifcx.c, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.