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

1.1     ! root        1: /* getkey.cpp */
        !             2: 
        !             3: /* Synchronet single-key console functions */
        !             4: 
        !             5: /* $Id: getkey.cpp,v 1.37 2006/08/23 01:45:05 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 2006 Rob Swindell - http://www.synchro.net/copyright.html         *
        !            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]);
        !           281:                                        logline(nulstr,"Inactive");
        !           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: /****************************************************************************/
        !           302: void sbbs_t::mnemonics(char *str)
        !           303: {
        !           304:     char *ctrl_a_codes;
        !           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 {
        !           337:                        if(str[l]==CTRL_A           /* ctrl-a */
        !           338:                                && str[l+1]!=0) {               /* valid */
        !           339:                                ctrl_a(str[++l]);       /* skip the ctrl-a */
        !           340:                                l++;                    /* skip the attribute code */
        !           341:                        } else
        !           342:                                outchar(str[l++]); 
        !           343:                } 
        !           344:        }
        !           345:        if(!ctrl_a_codes)
        !           346:                attr(cfg.color[clr_mnecmd]);
        !           347: }
        !           348: 
        !           349: /****************************************************************************/
        !           350: /* Prompts user for Y or N (yes or no) and CR is interpreted as a Y         */
        !           351: /* Returns 1 for Y or 0 for N                                               */
        !           352: /* Called from quite a few places                                           */
        !           353: /****************************************************************************/
        !           354: bool sbbs_t::yesno(char *str)
        !           355: {
        !           356:     char ch;
        !           357: 
        !           358:        strcpy(question,str);
        !           359:        SYNC;
        !           360:        if(useron.misc&WIP) {
        !           361:                strip_ctrl(question);
        !           362:                menu("yesno"); 
        !           363:        }
        !           364:        else
        !           365:                bprintf(text[YesNoQuestion],str);
        !           366:        while(online) {
        !           367:                if(sys_status&SS_ABORT)
        !           368:                        ch=text[YN][1];
        !           369:                else
        !           370:                        ch=getkey(K_UPPER|K_COLD);
        !           371:                if(ch==text[YN][0] || ch==CR) {
        !           372:                        if(bputs(text[Yes]))
        !           373:                                CRLF;
        !           374:                        lncntr=0;
        !           375:                        return(true); 
        !           376:                }
        !           377:                if(ch==text[YN][1]) {
        !           378:                        if(bputs(text[No]))
        !           379:                                CRLF;
        !           380:                        lncntr=0;
        !           381:                        return(false); 
        !           382:                } 
        !           383:        }
        !           384:        return(true);
        !           385: }
        !           386: 
        !           387: /****************************************************************************/
        !           388: /* Prompts user for N or Y (no or yes) and CR is interpreted as a N         */
        !           389: /* Returns 1 for N or 0 for Y                                               */
        !           390: /* Called from quite a few places                                           */
        !           391: /****************************************************************************/
        !           392: bool sbbs_t::noyes(char *str)
        !           393: {
        !           394:     char ch;
        !           395: 
        !           396:        strcpy(question,str);
        !           397:        SYNC;
        !           398:        if(useron.misc&WIP) {
        !           399:                strip_ctrl(question);
        !           400:                menu("noyes"); 
        !           401:        }
        !           402:        else
        !           403:                bprintf(text[NoYesQuestion],str);
        !           404:        while(online) {
        !           405:                if(sys_status&SS_ABORT)
        !           406:                        ch=text[YN][1];
        !           407:                else
        !           408:                        ch=getkey(K_UPPER|K_COLD);
        !           409:                if(ch==text[YN][1] || ch==CR) {
        !           410:                        if(bputs(text[No]))
        !           411:                                CRLF;
        !           412:                        lncntr=0;
        !           413:                        return(true); 
        !           414:                }
        !           415:                if(ch==text[YN][0]) {
        !           416:                        if(bputs(text[Yes]))
        !           417:                                CRLF;
        !           418:                        lncntr=0;
        !           419:                        return(false); 
        !           420:                } 
        !           421:        }
        !           422:        return(true);
        !           423: }
        !           424: 
        !           425: /****************************************************************************/
        !           426: /* Waits for remote or local user to hit a key that is contained inside str.*/
        !           427: /* 'str' should contain uppercase characters only. When a valid key is hit, */
        !           428: /* it is echoed (upper case) and is the return value.                       */
        !           429: /* Called from quite a few functions                                        */
        !           430: /****************************************************************************/
        !           431: long sbbs_t::getkeys(char *keys, ulong max)
        !           432: {
        !           433:        char    str[81];
        !           434:        uchar   ch,n=0,c=0;
        !           435:        ulong   i=0;
        !           436: 
        !           437:        SAFECOPY(str,keys);
        !           438:        strupr(str);
        !           439:        while(online) {
        !           440:                ch=getkey(K_UPPER);
        !           441:                if(max && ch>0x7f)  /* extended ascii chars are digits to isdigit() */
        !           442:                        continue;
        !           443:                if(sys_status&SS_ABORT) {   /* return -1 if Ctrl-C hit */
        !           444:                        attr(LIGHTGRAY);
        !           445:                        CRLF;
        !           446:                        lncntr=0;
        !           447:                        return(-1); 
        !           448:                }
        !           449:                if(ch && !n && (strchr(str,ch))) {  /* return character if in string */
        !           450:                        outchar(ch);
        !           451:                        if(useron.misc&COLDKEYS && ch>' ') {
        !           452:                                while(online && !(sys_status&SS_ABORT)) {
        !           453:                                        c=getkey(0);
        !           454:                                        if(c==CR || c==BS || c==DEL)
        !           455:                                                break; 
        !           456:                                }
        !           457:                                if(sys_status&SS_ABORT) {
        !           458:                                        CRLF;
        !           459:                                        return(-1); 
        !           460:                                }
        !           461:                                if(c==BS || c==DEL) {
        !           462:                                        backspace();
        !           463:                                        continue; 
        !           464:                                } 
        !           465:                        }
        !           466:                        attr(LIGHTGRAY);
        !           467:                        CRLF;
        !           468:                        lncntr=0;
        !           469:                        return(ch); 
        !           470:                }
        !           471:                if(ch==CR && max) {             /* return 0 if no number */
        !           472:                        attr(LIGHTGRAY);
        !           473:                        CRLF;
        !           474:                        lncntr=0;
        !           475:                        if(n)
        !           476:                                return(i|0x80000000L);           /* return number plus high bit */
        !           477:                        return(0)        !           478:                }
        !           479:                if((ch==BS || ch==DEL) && n) {
        !           480:                        backspace();
        !           481:                        i/=10;
        !           482:                        n--; 
        !           483:                }
        !           484:                else if(max && isdigit(ch) && (i*10)+(ch&0xf)<=max && (ch!='0' || n)) {
        !           485:                        i*=10;
        !           486:                        n++;
        !           487:                        i+=ch&0xf;
        !           488:                        outchar(ch);
        !           489:                        if(i*10>max && !(useron.misc&COLDKEYS)) {
        !           490:                                attr(LIGHTGRAY);
        !           491:                                CRLF;
        !           492:                                lncntr=0;
        !           493:                                return(i|0x80000000L); 
        !           494:                        } 
        !           495:                } 
        !           496:        }
        !           497:        return(-1);
        !           498: }
        !           499: 
        !           500: /****************************************************************************/
        !           501: /* Prints PAUSE message and waits for a key stoke                           */
        !           502: /****************************************************************************/
        !           503: void sbbs_t::pause()
        !           504: {
        !           505:        char    ch;
        !           506:        uchar   tempattrs=curatr; /* was lclatr(-1) */
        !           507:     int                i,j;
        !           508:        long    l=K_UPPER;
        !           509: 
        !           510:        if(sys_status&SS_ABORT)
        !           511:                return;
        !           512:        lncntr=0;
        !           513:        if(online==ON_REMOTE)
        !           514:                rioctl(IOFI);
        !           515:        bputs(text[Pause]);
        !           516:        j=bstrlen(text[Pause]);
        !           517:        if(sys_status&SS_USERON && !(useron.misc&(WIP|NOPAUSESPIN))
        !           518:                && !(cfg.node_misc&NM_NOPAUSESPIN))
        !           519:                l|=K_SPIN;
        !           520:        ch=getkey(l);
        !           521:        if(ch==text[YN][1] || ch=='Q')
        !           522:                sys_status|=SS_ABORT;
        !           523:        else if(ch==LF) // down arrow == display one more line
        !           524:                lncntr=rows-2;
        !           525:        if(text[Pause][0]!='@')
        !           526:                for(i=0;i<j;i++)
        !           527:                        backspace();
        !           528:        getnodedat(cfg.node_num,&thisnode,0);
        !           529:        nodesync();
        !           530:        attr(tempattrs);
        !           531: }
        !           532: 
        !           533: /****************************************************************************/
        !           534: /* Puts a character into the input buffer                                   */
        !           535: /****************************************************************************/
        !           536: void sbbs_t::ungetkey(char ch)
        !           537: {
        !           538: #if 0  /* this way breaks ansi_getxy() */
        !           539:        RingBufWrite(&inbuf,(uchar*)&ch,sizeof(uchar));
        !           540: #else
        !           541:        keybuf[keybuftop++]=ch;   
        !           542:        if(keybuftop==KEY_BUFSIZE)   
        !           543:                keybuftop=0; 
        !           544: #endif
        !           545: }

unix.superglobalmegacorp.com

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