Annotation of sbbs/src/sbbs3/getkey.cpp, revision 1.1.1.2

1.1       root        1: /* getkey.cpp */
                      2: 
                      3: /* Synchronet single-key console functions */
                      4: 
1.1.1.2 ! root        5: /* $Id: getkey.cpp,v 1.42 2009/11/09 02:54:55 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 2009 Rob Swindell - http://www.synchro.net/copyright.html         *
1.1       root       12:  *                                                                                                                                                     *
                     13:  * This program is free software; you can redistribute it and/or                       *
                     14:  * modify it under the terms of the GNU 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 General Public License for more details: gpl.txt or                     *
                     18:  * http://www.fsf.org/copyleft/gpl.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 "sbbs.h"
                     39: #include "telnet.h"    // TELNET_GA
                     40: 
                     41: /****************************************************************************/
                     42: /* Waits for remote or local user to hit a key. Inactivity timer is checked */
                     43: /* and hangs up if inactive for 4 minutes. Returns key hit, or uppercase of */
                     44: /* key hit if mode&K_UPPER or key out of KEY BUFFER. Does not print key.    */
                     45: /* Called from functions all over the place.                                */
                     46: /****************************************************************************/
                     47: char sbbs_t::getkey(long mode)
                     48: {
                     49:        char    ch,coldkey,c=0,spin=sbbs_random(5);
                     50:        time_t  last_telnet_cmd=0;
                     51: 
                     52:        if(!online || !input_thread_running) {
                     53:                YIELD();        // just in case someone is looping on getkey() when they shouldn't
                     54:                return(0);
                     55:        }
                     56:        sys_status&=~SS_ABORT;
                     57:        if((sys_status&SS_USERON || action==NODE_DFLT) && !(mode&(K_GETSTR|K_NOSPIN)))
                     58:                mode|=(useron.misc&SPIN);
                     59:        lncntr=0;
                     60:        timeout=time(NULL);
                     61:        if(mode&K_SPIN)
                     62:                outchar(' ');
                     63: 
                     64:        do {
                     65:                if(sys_status&SS_ABORT) {
                     66:                        if(mode&K_SPIN) /* back space once if on spinning cursor */
                     67:                                backspace();
                     68:                        return(0); 
                     69:                }
                     70: 
                     71:                if(mode&K_SPIN) {
                     72:                        if(useron.misc&NO_EXASCII) {
                     73:                                switch(c++) {
                     74:                                        case 0:
                     75:                                                outchar(BS);
                     76:                                                outchar('|');
                     77:                                                break;
                     78:                                        case 1:
                     79:                                                outchar(BS);
                     80:                                                outchar('/');
                     81:                                                break;
                     82:                                        case 2:
                     83:                                                outchar(BS);
                     84:                                                outchar('-');
                     85:                                                break;
                     86:                                        case 3:
                     87:                                                outchar(BS);
                     88:                                                outchar('\\');
                     89:                                                c=0;
                     90:                                                break;
                     91:                                }
                     92:                        } else {
                     93:                                switch(spin) {
                     94:                                        case 0:
                     95:                                                switch(c++) {
                     96:                                                        case 0:
                     97:                                                                outchar(BS);
                     98:                                                                outchar('�');
                     99:                                                                break;
                    100:                                                        case 1:
                    101:                                                                outchar(BS);
                    102:                                                                outchar('/');
                    103:                                                                break;
                    104:                                                        case 2:
                    105:                                                                outchar(BS);
                    106:                                                                outchar('�');
                    107:                                                                break;
                    108:                                                        case 3:
                    109:                                                                outchar(BS);
                    110:                                                                outchar('\\');
                    111:                                                                c=0;
                    112:                                                                break;
                    113:                                                }
                    114:                                                break;
                    115:                                        case 1:
                    116:                                                switch(c++) {
                    117:                                                        case 0:
                    118:                                                                outchar(BS);
                    119:                                                                outchar('�');
                    120:                                                                break;
                    121:                                                        case 1:
                    122:                                                                outchar(BS);
                    123:                                                                outchar('�');
                    124:                                                                break;
                    125:                                                        case 2:
                    126:                                                                outchar(BS);
                    127:                                                                outchar('�');
                    128:                                                                break;
                    129:                                                        case 3:
                    130:                                                                outchar(BS);
                    131:                                                                outchar('�');
                    132:                                                                break;
                    133:                                                        case 4:
                    134:                                                                outchar(BS);
                    135:                                                                outchar('�');
                    136:                                                                break;
                    137:                                                        case 5:
                    138:                                                                outchar(BS);
                    139:                                                                outchar('�');
                    140:                                                                c=0;
                    141:                                                                break;
                    142:                                                }
                    143:                                                break;
                    144:                                        case 2:
                    145:                                                switch(c++) {
                    146:                                                        case 0:
                    147:                                                                outchar(BS);
                    148:                                                                outchar('-');
                    149:                                                                break;
                    150:                                                        case 1:
                    151:                                                                outchar(BS);
                    152:                                                                outchar('=');
                    153:                                                                break;
                    154:                                                        case 2:
                    155:                                                                outchar(BS);
                    156:                                                                outchar('�');
                    157:                                                                break;
                    158:                                                        case 3:
                    159:                                                                outchar(BS);
                    160:                                                                outchar('=');
                    161:                                                                c=0;
                    162:                                                                break;
                    163:                                                }
                    164:                                                break;
                    165:                                        case 3:
                    166:                                                switch(c++) {
                    167:                                                        case 0:
                    168:                                                                outchar(BS);
                    169:                                                                outchar('�');
                    170:                                                                break;
                    171:                                                        case 1:
                    172:                                                                outchar(BS);
                    173:                                                                outchar('�');
                    174:                                                                break;
                    175:                                                        case 2:
                    176:                                                                outchar(BS);
                    177:                                                                outchar('�');
                    178:                                                                break;
                    179:                                                        case 3:
                    180:                                                                outchar(BS);
                    181:                                                                outchar('�');
                    182:                                                                c=0;
                    183:                                                                break;
                    184:                                                }
                    185:                                                break;
                    186:                                        case 4:
                    187:                                                switch(c++) {
                    188:                                                        case 0:
                    189:                                                                outchar(BS);
                    190:                                                                outchar('�');
                    191:                                                                break;
                    192:                                                        case 1:
                    193:                                                                outchar(BS);
                    194:                                                                outchar('�');
                    195:                                                                break;
                    196:                                                        case 2:
                    197:                                                                outchar(BS);
                    198:                                                                outchar('�');
                    199:                                                                break;
                    200:                                                        case 3:
                    201:                                                                outchar(BS);
                    202:                                                                outchar('�');
                    203:                                                                c=0;
                    204:                                                                break;
                    205:                                                }
                    206:                                                break; 
                    207:                                }
                    208:                        }
                    209:                }
                    210:                ch=inkey(mode,mode&K_SPIN ? 250:1000);
                    211:                if(sys_status&SS_ABORT)
                    212:                        return(0);
                    213:                now=time(NULL);
                    214:                if(ch) {
                    215:                        if(mode&K_NUMBER && isprint(ch) && !isdigit(ch))
                    216:                                continue;
                    217:                        if(mode&K_ALPHA && isprint(ch) && !isalpha(ch))
                    218:                                continue;
                    219:                        if(mode&K_NOEXASC && ch&0x80)
                    220:                                continue;
                    221:                        if(mode&K_SPIN)
                    222:                                backspace();
                    223:                        if(mode&K_COLD && ch>' ' && useron.misc&COLDKEYS) {
                    224:                                if(mode&K_UPPER)
                    225:                                        outchar(toupper(ch));
                    226:                                else
                    227:                                        outchar(ch);
                    228:                                while((coldkey=inkey(mode,1000))==0 && online && !(sys_status&SS_ABORT))
                    229:                                        ;
                    230:                                backspace();
                    231:                                if(coldkey==BS || coldkey==DEL)
                    232:                                        continue;
                    233:                                if(coldkey>' ')
                    234:                                        ungetkey(coldkey); 
                    235:                        }
                    236:                        if(mode&K_UPPER)
                    237:                                return(toupper(ch));
                    238:                        return(ch); 
                    239:                }
                    240:                if(sys_status&SS_USERON && !(sys_status&SS_LCHAT)) gettimeleft();
                    241:                else if(online && now-answertime>SEC_LOGON && !(sys_status&SS_LCHAT)) {
                    242:                        console&=~(CON_R_ECHOX|CON_L_ECHOX);
                    243:                        console|=(CON_R_ECHO|CON_L_ECHO);
                    244:                        bputs(text[TakenTooLongToLogon]);
                    245:                        hangup(); 
                    246:                }
                    247:                if(sys_status&SS_USERON && online && (timeleft/60)<(5-timeleft_warn)
                    248:                        && !SYSOP && !(sys_status&SS_LCHAT)) {
                    249:                        timeleft_warn=5-(timeleft/60);
                    250:                        SAVELINE;
                    251:                        attr(LIGHTGRAY);
                    252:                        bprintf(text[OnlyXminutesLeft]
                    253:                                ,((ushort)timeleft/60)+1,(timeleft/60) ? "s" : nulstr);
                    254:                        RESTORELINE; 
                    255:                }
                    256: 
                    257:                if(!(startup->options&BBS_OPT_NO_TELNET_GA)
                    258:                        && now!=last_telnet_cmd && now-timeout>=60 && !((now-timeout)%60)) {
                    259:                        // Let's make sure the socket is up
                    260:                        // Sending will trigger a socket d/c detection
                    261:                        send_telnet_cmd(TELNET_GA,0);
                    262:                        last_telnet_cmd=now;
                    263:                }
                    264:                        
                    265:                if(online==ON_REMOTE && !(console&CON_NO_INACT)
                    266:                        && now-timeout>=cfg.sec_warn) {                                         /* warning */
                    267:                        if(sys_status&SS_USERON && cfg.sec_warn!=cfg.sec_hangup) {
                    268:                                SAVELINE;
                    269:                                bputs(text[AreYouThere]); 
                    270:                        }
                    271:                        else
                    272:                                bputs("\7\7");
                    273:                        while(!inkey(K_NONE,100) && online && now-timeout>=cfg.sec_warn) {
                    274:                                now=time(NULL);
                    275:                                if(now-timeout>=cfg.sec_hangup) {
                    276:                                        if(online==ON_REMOTE) {
                    277:                                                console|=CON_R_ECHO;
                    278:                                                console&=~CON_R_ECHOX; 
                    279:                                        }
                    280:                                        bputs(text[CallBackWhenYoureThere]);
1.1.1.2 ! root      281:                                        logline(LOG_NOTICE,nulstr,"Inactive");
1.1       root      282:                                        hangup();
                    283:                                        return(0); 
                    284:                                }
                    285:                        }
                    286:                        if(sys_status&SS_USERON && cfg.sec_warn!=cfg.sec_hangup) {
                    287:                                bputs("\r\1n\1>");
                    288:                                RESTORELINE; 
                    289:                        }
                    290:                        timeout=now; 
                    291:                }
                    292: 
                    293:        } while(online);
                    294: 
                    295:        return(0);
                    296: }
                    297: 
                    298: 
                    299: /****************************************************************************/
                    300: /* Outputs a string highlighting characters preceeded by a tilde            */
                    301: /****************************************************************************/
1.1.1.2 ! root      302: void sbbs_t::mnemonics(const char *str)
1.1       root      303: {
1.1.1.2 ! root      304:     const char *ctrl_a_codes;
1.1       root      305:     long l;
                    306: 
                    307:        if(!strchr(str,'~')) {
                    308:                mnestr=str;
                    309:                bputs(str);
                    310:                return; 
                    311:        }
                    312:        ctrl_a_codes=strchr(str,1);
                    313:        if(!ctrl_a_codes) {
                    314:                if(str[0]=='@' && str[strlen(str)-1]=='@' && !strchr(str,' ')) {
                    315:                        mnestr=str;
                    316:                        bputs(str);
                    317:                        return; 
                    318:                }
                    319:                attr(cfg.color[clr_mnelow]); 
                    320:        }
                    321:        l=0L;
                    322:        while(str[l]) {
                    323:                if(str[l]=='~' && str[l+1]!=0) {
                    324:                        if(!term_supports(ANSI))
                    325:                                outchar('(');
                    326:                        l++;
                    327:                        if(!ctrl_a_codes)
                    328:                                attr(cfg.color[clr_mnehigh]);
                    329:                        outchar(str[l]);
                    330:                        l++;
                    331:                        if(!term_supports(ANSI))
                    332:                                outchar(')');
                    333:                        if(!ctrl_a_codes)
                    334:                                attr(cfg.color[clr_mnelow]); 
                    335:                }
                    336:                else {
1.1.1.2 ! root      337:                        if(str[l]==CTRL_A && str[l+1]!=0) {
        !           338:                                l++;
        !           339:                                if(toupper(str[l])=='Z')        /* EOF */
        !           340:                                        break;
        !           341:                                ctrl_a(str[l++]);
1.1       root      342:                        } else
                    343:                                outchar(str[l++]); 
                    344:                } 
                    345:        }
                    346:        if(!ctrl_a_codes)
                    347:                attr(cfg.color[clr_mnecmd]);
                    348: }
                    349: 
                    350: /****************************************************************************/
                    351: /* Prompts user for Y or N (yes or no) and CR is interpreted as a Y         */
                    352: /* Returns 1 for Y or 0 for N                                               */
                    353: /* Called from quite a few places                                           */
                    354: /****************************************************************************/
1.1.1.2 ! root      355: bool sbbs_t::yesno(const char *str)
1.1       root      356: {
                    357:     char ch;
                    358: 
1.1.1.2 ! root      359:        SAFECOPY(question,str);
1.1       root      360:        SYNC;
1.1.1.2 ! root      361:        bprintf(text[YesNoQuestion],str);
1.1       root      362:        while(online) {
                    363:                if(sys_status&SS_ABORT)
                    364:                        ch=text[YN][1];
                    365:                else
                    366:                        ch=getkey(K_UPPER|K_COLD);
                    367:                if(ch==text[YN][0] || ch==CR) {
                    368:                        if(bputs(text[Yes]))
                    369:                                CRLF;
                    370:                        lncntr=0;
                    371:                        return(true); 
                    372:                }
                    373:                if(ch==text[YN][1]) {
                    374:                        if(bputs(text[No]))
                    375:                                CRLF;
                    376:                        lncntr=0;
                    377:                        return(false); 
                    378:                } 
                    379:        }
                    380:        return(true);
                    381: }
                    382: 
                    383: /****************************************************************************/
                    384: /* Prompts user for N or Y (no or yes) and CR is interpreted as a N         */
                    385: /* Returns 1 for N or 0 for Y                                               */
                    386: /* Called from quite a few places                                           */
                    387: /****************************************************************************/
1.1.1.2 ! root      388: bool sbbs_t::noyes(const char *str)
1.1       root      389: {
                    390:     char ch;
                    391: 
1.1.1.2 ! root      392:        SAFECOPY(question,str);
1.1       root      393:        SYNC;
1.1.1.2 ! root      394:        bprintf(text[NoYesQuestion],str);
1.1       root      395:        while(online) {
                    396:                if(sys_status&SS_ABORT)
                    397:                        ch=text[YN][1];
                    398:                else
                    399:                        ch=getkey(K_UPPER|K_COLD);
                    400:                if(ch==text[YN][1] || ch==CR) {
                    401:                        if(bputs(text[No]))
                    402:                                CRLF;
                    403:                        lncntr=0;
                    404:                        return(true); 
                    405:                }
                    406:                if(ch==text[YN][0]) {
                    407:                        if(bputs(text[Yes]))
                    408:                                CRLF;
                    409:                        lncntr=0;
                    410:                        return(false); 
                    411:                } 
                    412:        }
                    413:        return(true);
                    414: }
                    415: 
                    416: /****************************************************************************/
                    417: /* Waits for remote or local user to hit a key that is contained inside str.*/
                    418: /* 'str' should contain uppercase characters only. When a valid key is hit, */
                    419: /* it is echoed (upper case) and is the return value.                       */
                    420: /* Called from quite a few functions                                        */
                    421: /****************************************************************************/
1.1.1.2 ! root      422: long sbbs_t::getkeys(const char *keys, ulong max)
1.1       root      423: {
                    424:        char    str[81];
                    425:        uchar   ch,n=0,c=0;
                    426:        ulong   i=0;
                    427: 
                    428:        SAFECOPY(str,keys);
                    429:        strupr(str);
                    430:        while(online) {
                    431:                ch=getkey(K_UPPER);
                    432:                if(max && ch>0x7f)  /* extended ascii chars are digits to isdigit() */
                    433:                        continue;
                    434:                if(sys_status&SS_ABORT) {   /* return -1 if Ctrl-C hit */
                    435:                        attr(LIGHTGRAY);
                    436:                        CRLF;
                    437:                        lncntr=0;
                    438:                        return(-1); 
                    439:                }
                    440:                if(ch && !n && (strchr(str,ch))) {  /* return character if in string */
                    441:                        outchar(ch);
                    442:                        if(useron.misc&COLDKEYS && ch>' ') {
                    443:                                while(online && !(sys_status&SS_ABORT)) {
                    444:                                        c=getkey(0);
                    445:                                        if(c==CR || c==BS || c==DEL)
                    446:                                                break; 
                    447:                                }
                    448:                                if(sys_status&SS_ABORT) {
                    449:                                        CRLF;
                    450:                                        return(-1); 
                    451:                                }
                    452:                                if(c==BS || c==DEL) {
                    453:                                        backspace();
                    454:                                        continue; 
                    455:                                } 
                    456:                        }
                    457:                        attr(LIGHTGRAY);
                    458:                        CRLF;
                    459:                        lncntr=0;
                    460:                        return(ch); 
                    461:                }
                    462:                if(ch==CR && max) {             /* return 0 if no number */
                    463:                        attr(LIGHTGRAY);
                    464:                        CRLF;
                    465:                        lncntr=0;
                    466:                        if(n)
                    467:                                return(i|0x80000000L);           /* return number plus high bit */
                    468:                        return(0); 
                    469:                }
                    470:                if((ch==BS || ch==DEL) && n) {
                    471:                        backspace();
                    472:                        i/=10;
                    473:                        n--; 
                    474:                }
                    475:                else if(max && isdigit(ch) && (i*10)+(ch&0xf)<=max && (ch!='0' || n)) {
                    476:                        i*=10;
                    477:                        n++;
                    478:                        i+=ch&0xf;
                    479:                        outchar(ch);
                    480:                        if(i*10>max && !(useron.misc&COLDKEYS)) {
                    481:                                attr(LIGHTGRAY);
                    482:                                CRLF;
                    483:                                lncntr=0;
                    484:                                return(i|0x80000000L); 
                    485:                        } 
                    486:                } 
                    487:        }
                    488:        return(-1);
                    489: }
                    490: 
                    491: /****************************************************************************/
                    492: /* Prints PAUSE message and waits for a key stoke                           */
                    493: /****************************************************************************/
                    494: void sbbs_t::pause()
                    495: {
                    496:        char    ch;
                    497:        uchar   tempattrs=curatr; /* was lclatr(-1) */
                    498:     int                i,j;
                    499:        long    l=K_UPPER;
                    500: 
                    501:        if(sys_status&SS_ABORT)
                    502:                return;
                    503:        lncntr=0;
                    504:        if(online==ON_REMOTE)
                    505:                rioctl(IOFI);
                    506:        bputs(text[Pause]);
                    507:        j=bstrlen(text[Pause]);
1.1.1.2 ! root      508:        if(sys_status&SS_USERON && !(useron.misc&(HTML|WIP|NOPAUSESPIN))
1.1       root      509:                && !(cfg.node_misc&NM_NOPAUSESPIN))
                    510:                l|=K_SPIN;
                    511:        ch=getkey(l);
                    512:        if(ch==text[YN][1] || ch=='Q')
                    513:                sys_status|=SS_ABORT;
                    514:        else if(ch==LF) // down arrow == display one more line
                    515:                lncntr=rows-2;
                    516:        if(text[Pause][0]!='@')
                    517:                for(i=0;i<j;i++)
                    518:                        backspace();
                    519:        getnodedat(cfg.node_num,&thisnode,0);
                    520:        nodesync();
                    521:        attr(tempattrs);
                    522: }
                    523: 
                    524: /****************************************************************************/
                    525: /* Puts a character into the input buffer                                   */
                    526: /****************************************************************************/
                    527: void sbbs_t::ungetkey(char ch)
                    528: {
                    529: #if 0  /* this way breaks ansi_getxy() */
                    530:        RingBufWrite(&inbuf,(uchar*)&ch,sizeof(uchar));
                    531: #else
                    532:        keybuf[keybuftop++]=ch;   
                    533:        if(keybuftop==KEY_BUFSIZE)   
                    534:                keybuftop=0; 
                    535: #endif
                    536: }

unix.superglobalmegacorp.com

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