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

1.1       root        1: /* uifcx.c */
                      2: 
                      3: /* Standard I/O Implementation of UIFC (user interface) library */
                      4: 
1.1.1.2 ! root        5: /* $Id: uifcx.c,v 1.25 2010/02/27 04:02:25 rswindell Exp $ */
1.1       root        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:  *                                                                                                                                                     *
1.1.1.2 ! root       11:  * Copyright 2010 Rob Swindell - http://www.synchro.net/copyright.html         *
1.1       root       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: 
1.1.1.2 ! root      378: static void uputs(char* ptr)
        !           379: {
        !           380:        while(*ptr) {
        !           381:                if(*ptr>2)
        !           382:                        putchar(*ptr);
        !           383:                ptr++;
        !           384:        }
        !           385:        putchar('\n');
        !           386: }
        !           387: 
1.1       root      388: /****************************************************************************/
                    389: /* Help function.                                                                                                                      */
                    390: /****************************************************************************/
                    391: void help()
                    392: {
                    393:        char hbuf[HELPBUF_SIZE],str[256];
                    394:     char *p;
                    395:        unsigned short line;
                    396:        long l;
                    397:        FILE *fp;
                    398: 
                    399:     printf("\n");
                    400:     if(!api->helpbuf) {
                    401:         if((fp=fopen(api->helpixbfile,"rb"))==NULL)
                    402:             sprintf(hbuf,"ERROR: Cannot open help index: %s"
                    403:                 ,api->helpixbfile);
                    404:         else {
                    405:             p=strrchr(helpfile,'/');
                    406:             if(p==NULL)
                    407:                 p=strrchr(helpfile,'\\');
                    408:             if(p==NULL)
                    409:                 p=helpfile;
                    410:             else
                    411:                 p++;
                    412:             l=-1L;
                    413:             while(!feof(fp)) {
                    414:                 if(!fread(str,12,1,fp))
                    415:                     break;
                    416:                 str[12]=0;
                    417:                 fread(&line,2,1,fp);
                    418:                 if(stricmp(str,p) || line!=helpline) {
                    419:                     fseek(fp,4,SEEK_CUR);
                    420:                     continue; }
                    421:                 fread(&l,4,1,fp);
                    422:                 break; }
                    423:             fclose(fp);
                    424:             if(l==-1L)
                    425:                 sprintf(hbuf,"ERROR: Cannot locate help key (%s:%u) in: %s"
                    426:                     ,p,helpline,api->helpixbfile);
                    427:             else {
                    428:                 if((fp=fopen(api->helpdatfile,"rb"))==NULL)
                    429:                     sprintf(hbuf,"ERROR: Cannot open help file: %s"
                    430:                         ,api->helpdatfile);
                    431:                 else {
                    432:                     fseek(fp,l,SEEK_SET);
                    433:                     fread(hbuf,HELPBUF_SIZE,1,fp);
                    434:                     fclose(fp); 
                    435:                                } 
                    436:                        } 
                    437:                } 
                    438:        }
                    439:     else
                    440:         strcpy(hbuf,api->helpbuf);
                    441: 
1.1.1.2 ! root      442:     uputs(hbuf);
1.1       root      443:     if(strlen(hbuf)>200) {
                    444:         printf("Hit enter");
                    445:         getstr(str,sizeof(str)-1);
                    446:     }
                    447: }
                    448: 
                    449: 

unix.superglobalmegacorp.com

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