Annotation of sbbs/sbbs3/getkey.cpp, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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