Annotation of sbbs/uifc/uifcx.c, revision 1.1.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.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: 

unix.superglobalmegacorp.com

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