Annotation of sbbs/src/sbbs3/con_out.cpp, revision 1.1.1.1

1.1       root        1: /* con_out.cpp */
                      2: 
                      3: /* Synchronet console output routines */
                      4: 
                      5: /* $Id: con_out.cpp,v 1.51 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: 
                     39: /**********************************************************************/
                     40: /* Functions that pertain to console i/o - color, strings, chars etc. */
                     41: /* Called from functions everywhere                                   */
                     42: /**********************************************************************/
                     43: 
                     44: #include "sbbs.h"
                     45: 
                     46: /***************************************************/
                     47: /* Seven bit table for EXASCII to ASCII conversion */
                     48: /***************************************************/
                     49: static const char *sbtbl="CUeaaaaceeeiiiAAEaAooouuyOUcLYRfaiounNao?--24!<>"
                     50:                        "###||||++||++++++--|-+||++--|-+----++++++++##[]#"
                     51:                        "abrpEout*ono%0ENE+><rj%=o..+n2* ";
                     52: 
                     53: /****************************************************************************/
                     54: /* Convert string from IBM extended ASCII to just ASCII                                                */
                     55: /****************************************************************************/
                     56: char* DLLCALL ascii_str(uchar* str)
                     57: {
                     58:        size_t i;
                     59: 
                     60:        for(i=0;str[i];i++)
                     61:                if(str[i]&0x80)
                     62:                        str[i]=sbtbl[str[i]^0x80];  /* seven bit table */
                     63:                else if(str[i]==CTRL_A          /* ctrl-a */
                     64:                        && str[i+1]!=0)                         /* valid */
                     65:                        i++;                                            /* skip the attribute code */
                     66: 
                     67:        return((char*)str);
                     68: }
                     69: 
                     70: /****************************************************************************/
                     71: /* Outputs a NULL terminated string locally and remotely (if applicable)    */
                     72: /* Handles ctrl-a characters                                                */
                     73: /****************************************************************************/
                     74: int sbbs_t::bputs(char *str)
                     75: {
                     76:        int i;
                     77:     ulong l=0;
                     78: 
                     79:        if(online==ON_LOCAL && console&CON_L_ECHO)      /* script running as event */
                     80:                return(eprintf(LOG_INFO,"%s",str));
                     81: 
                     82:        while(str[l]) {
                     83:                if(str[l]==CTRL_A               /* ctrl-a */
                     84:                        && str[l+1]!=0) {               /* valid */
                     85:                        ctrl_a(str[++l]);       /* skip the ctrl-a */
                     86:                        l++;                                    /* skip the attribute code */
                     87:                        continue; 
                     88:                }
                     89:                if(str[l]=='@') {           /* '@' */
                     90:                        if(str==mnestr                  /* Mnemonic string or */
                     91:                                || (str>=text[0]        /* Straight out of TEXT.DAT */
                     92:                                        && str<=text[TOTAL_TEXT-1])) {
                     93:                                i=show_atcode(str+l);   /* return 0 if not valid @ code */
                     94:                                l+=i;                                   /* i is length of code string */
                     95:                                if(i)                                   /* if valid string, go to top */
                     96:                                        continue; 
                     97:                        }
                     98:                        for(i=0;i<TOTAL_TEXT;i++)
                     99:                                if(str==text[i])
                    100:                                        break;
                    101:                        if(i<TOTAL_TEXT) {              /* Replacement text */
                    102:                                i=show_atcode(str+l);
                    103:                                l+=i;
                    104:                                if(i)
                    105:                                        continue; 
                    106:                        } 
                    107:                }
                    108:                outchar(str[l++]); 
                    109:        }
                    110:        return(l);
                    111: }
                    112: 
                    113: /****************************************************************************/
                    114: /* Outputs a NULL terminated string locally and remotely (if applicable)    */
                    115: /* Does not expand ctrl-a characters (raw)                                  */
                    116: /* Max length of str is 64 kbytes                                           */
                    117: /****************************************************************************/
                    118: int sbbs_t::rputs(char *str)
                    119: {
                    120:     ulong l=0;
                    121: 
                    122:        if(online==ON_LOCAL && console&CON_L_ECHO)      /* script running as event */
                    123:                return(eprintf(LOG_INFO,"%s",str));
                    124: 
                    125:        while(str[l])
                    126:                outchar(str[l++]);
                    127:        return(l);
                    128: }
                    129: 
                    130: /****************************************************************************/
                    131: /* Performs printf() using bbs bputs function                                                          */
                    132: /****************************************************************************/
                    133: int sbbs_t::bprintf(char *fmt, ...)
                    134: {
                    135:        va_list argptr;
                    136:        char sbuf[4096];
                    137: 
                    138:        if(strchr(fmt,'%')==NULL)
                    139:                return(bputs(fmt));
                    140:        va_start(argptr,fmt);
                    141:        vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
                    142:        sbuf[sizeof(sbuf)-1]=0; /* force termination */
                    143:        va_end(argptr);
                    144:        return(bputs(sbuf));
                    145: }
                    146: 
                    147: /****************************************************************************/
                    148: /* Performs printf() using bbs rputs function                                                          */
                    149: /****************************************************************************/
                    150: int sbbs_t::rprintf(char *fmt, ...)
                    151: {
                    152:        va_list argptr;
                    153:        char sbuf[4096];
                    154: 
                    155:        va_start(argptr,fmt);
                    156:        vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
                    157:        sbuf[sizeof(sbuf)-1]=0; /* force termination */
                    158:        va_end(argptr);
                    159:        return(rputs(sbuf));
                    160: }
                    161: 
                    162: /****************************************************************************/
                    163: /* Outputs destructive backspace locally and remotely (if applicable),         */
                    164: /****************************************************************************/
                    165: void sbbs_t::backspace(void)
                    166: {
                    167:        int             oldconsole;
                    168: 
                    169:        oldconsole=console;
                    170:        console &= ~(CON_R_ECHOX|CON_L_ECHOX);
                    171:        outchar('\b');
                    172:        outchar(' ');
                    173:        outchar('\b');
                    174:        console=oldconsole;
                    175: }
                    176: 
                    177: /****************************************************************************/
                    178: /* Returns true if the user (or the yet-to-be-logged-in client) supports       */
                    179: /* all of the specified terminal 'cmp_flags' (e.g. ANSI, COLOR, RIP).          */
                    180: /* If no flags specified, returns all terminal flag bits supported                     */
                    181: /****************************************************************************/
                    182: long sbbs_t::term_supports(long cmp_flags)
                    183: {
                    184:        long flags = sys_status&SS_USERON ? useron.misc : autoterm;
                    185: 
                    186:        return(cmp_flags ? ((flags&cmp_flags)==cmp_flags) : (flags&TERM_FLAGS));
                    187: }
                    188: 
                    189: /****************************************************************************/
                    190: /* Outputs character locally and remotely (if applicable), preforming echo  */
                    191: /* translations (X's and r0dent emulation) if applicable.                                      */
                    192: /****************************************************************************/
                    193: void sbbs_t::outchar(char ch)
                    194: {
                    195:        int             i;
                    196: 
                    197:        if(console&CON_ECHO_OFF)
                    198:                return;
                    199:        if(ch==ESC)
                    200:                outchar_esc=1;
                    201:        else if(outchar_esc==1) {
                    202:                if(ch=='[')
                    203:                        outchar_esc++;
                    204:                else
                    205:                        outchar_esc=0;
                    206:        }
                    207:        else if(outchar_esc==2) {
                    208:                if((ch>='@' && ch<='Z') || (ch>='a' && ch<='z'))
                    209:                        outchar_esc++;
                    210:        }
                    211:        else
                    212:                outchar_esc=0;
                    213:        if(term_supports(NO_EXASCII) && ch&0x80)
                    214:                ch=sbtbl[(uchar)ch^0x80];  /* seven bit table */
                    215:        if(ch==FF && lncntr>1 && !tos) {
                    216:                lncntr=0;
                    217:                CRLF;
                    218:                if(!(sys_status&SS_PAUSEOFF)) {
                    219:                        pause();
                    220:                        while(lncntr && online && !(sys_status&SS_ABORT))
                    221:                                pause(); 
                    222:                        sys_status&=~SS_ABORT;
                    223:                }
                    224:        }
                    225: #if 0
                    226:        if(sys_status&SS_CAP    /* Writes to Capture File */
                    227:                && (sys_status&SS_ANSCAP || (ch!=ESC /* && !lclaes() */)))
                    228:                fwrite(&ch,1,1,capfile);
                    229: #endif
                    230: #if 0 
                    231:        if(console&CON_L_ECHO) {
                    232:                if(console&CON_L_ECHOX && (uchar)ch>=' ')
                    233:                        putch(password_char);
                    234:                else if(cfg.node_misc&NM_NOBEEP && ch==BEL);     /* Do nothing if beep */
                    235:                else if(ch==BEL) {
                    236:                                sbbs_beep(2000,110);
                    237:                                nosound(); 
                    238:                }
                    239:                else putch(ch); 
                    240:        }
                    241: #endif
                    242: 
                    243:        if(online==ON_REMOTE && console&CON_R_ECHO) {
                    244:                if(console&CON_R_ECHOX && (uchar)ch>=' ' && !outchar_esc) {
                    245:                        ch=text[YN][3];
                    246:                        if(text[YN][2]==0 || ch==0) ch='X';
                    247:                }
                    248:                if(ch==FF && term_supports(ANSI)) {
                    249:                        putcom("\x1b[2J\x1b[H");        /* clear screen, home cursor */
                    250:                }
                    251:                else {
                    252:                        if(ch==(char)TELNET_IAC && !(telnet_mode&TELNET_MODE_OFF))
                    253:                                outcom(TELNET_IAC);     /* Must escape Telnet IAC char (255) */
                    254:                        i=0;
                    255:                        while(outcom(ch)&TXBOF && i<1440) { /* 3 minute pause delay */
                    256:                                if(!online)
                    257:                                        break;
                    258:                                i++;
                    259:                                if(sys_status&SS_SYSPAGE)
                    260:                                        sbbs_beep(i,80);
                    261:                                else
                    262:                                        mswait(80); 
                    263:                        }
                    264:                        if(i==1440) {                                                   /* timeout - beep flush outbuf */
                    265:                                i=rioctl(TXBC);
                    266:                                lprintf(LOG_NOTICE,"timeout(outchar) %04X %04X\r\n",i,rioctl(IOFO));
                    267:                                outcom(BEL);
                    268:                                rioctl(IOCS|PAUSE); 
                    269:                        } 
                    270:                } 
                    271:        }
                    272:        if(ch==LF) {
                    273:                lncntr++;
                    274:                lbuflen=0;
                    275:                tos=0;
                    276:        } else if(ch==FF) {
                    277:                lncntr=0;
                    278:                lbuflen=0;
                    279:                tos=1;
                    280:        } else {
                    281:                if(!lbuflen)
                    282:                        latr=curatr;
                    283:                if(lbuflen<LINE_BUFSIZE)
                    284:                        lbuf[lbuflen++]=ch; 
                    285:        }
                    286:        if(outchar_esc==3)
                    287:                outchar_esc=0;
                    288: 
                    289:        if(lncntr==rows-1 && ((useron.misc&UPAUSE) || sys_status&SS_PAUSEON) 
                    290:                && !(sys_status&SS_PAUSEOFF)) {
                    291:                lncntr=0;
                    292:                pause(); 
                    293:        }
                    294: }
                    295: 
                    296: void sbbs_t::center(char *instr)
                    297: {
                    298:        char str[256];
                    299:        int i,j;
                    300: 
                    301:        SAFECOPY(str,instr);
                    302:        truncsp(str);
                    303:        j=bstrlen(str);
                    304:        for(i=0;i<(cols-j)/2;i++)
                    305:                outchar(' ');
                    306:        bputs(str);
                    307:        CRLF;
                    308: }
                    309: 
                    310: void sbbs_t::clearline(void)
                    311: {
                    312:        int i;
                    313: 
                    314:        outchar(CR);
                    315:        if(term_supports(ANSI))
                    316:                rputs("\x1b[K");
                    317:        else {
                    318:                for(i=0;i<cols-1;i++)
                    319:                        outchar(' ');
                    320:                outchar(CR); 
                    321:        }
                    322: }
                    323: 
                    324: void sbbs_t::cursor_home(void)
                    325: {
                    326:        if(term_supports(ANSI))
                    327:                rputs("\x1b[H");
                    328:        else
                    329:                outchar(FF);
                    330: }
                    331: 
                    332: void sbbs_t::cursor_up(int count)
                    333: {
                    334:        if(count<1)
                    335:                return;
                    336:        if(!term_supports(ANSI))
                    337:                return;
                    338:        if(count>1)
                    339:                rprintf("\x1b[%dA",count);
                    340:        else
                    341:                rputs("\x1b[A");
                    342: }
                    343: 
                    344: void sbbs_t::cursor_down(int count)
                    345: {
                    346:        if(count<1)
                    347:                return;
                    348:        if(!term_supports(ANSI))
                    349:                return;
                    350:        if(count>1)
                    351:                rprintf("\x1b[%dB",count);
                    352:        else
                    353:                rputs("\x1b[B");
                    354: }
                    355: 
                    356: void sbbs_t::cursor_right(int count)
                    357: {
                    358:        if(count<1)
                    359:                return;
                    360:        if(term_supports(ANSI)) {
                    361:                if(count>1)
                    362:                        rprintf("\x1b[%dC",count);
                    363:                else
                    364:                        rputs("\x1b[C");
                    365:        } else {
                    366:                for(int i=0;i<count;i++)
                    367:                        outchar(' ');
                    368:        }
                    369: }
                    370: 
                    371: void sbbs_t::cursor_left(int count)
                    372: {
                    373:        if(count<1)
                    374:                return;
                    375:        if(term_supports(ANSI)) {
                    376:                if(count>1)
                    377:                        rprintf("\x1b[%dD",count);
                    378:                else
                    379:                        rputs("\x1b[D");
                    380:        } else {
                    381:                for(int i=0;i<count;i++)
                    382:                        outchar('\b');
                    383:        }
                    384: }
                    385: 
                    386: void sbbs_t::cleartoeol(void)
                    387: {
                    388:        if(term_supports(ANSI))
                    389:                rputs("\x1b[K");
                    390: #if 0
                    391:        else {
                    392:                i=j=lclwx();    /* commented out */
                    393:                while(i++<79)
                    394:                        outchar(' ');
                    395:                while(j++<79)
                    396:                        outchar(BS); 
                    397:        }
                    398: #endif                
                    399: }
                    400: 
                    401: /****************************************************************************/
                    402: /* performs the correct attribute modifications for the Ctrl-A code                    */
                    403: /****************************************************************************/
                    404: void sbbs_t::ctrl_a(char x)
                    405: {
                    406:        char    tmp1[128],atr=curatr;
                    407:        struct  tm tm;
                    408: 
                    409:        if(x && (uchar)x<=CTRL_Z) {    /* Ctrl-A through Ctrl-Z for users with MF only */
                    410:                if(!(useron.flags1&FLAG(x+64)))
                    411:                        console^=(CON_ECHO_OFF);
                    412:                return; 
                    413:        }
                    414:        if((uchar)x>0x7f) {
                    415:                cursor_right((uchar)x-0x7f);
                    416:                return; 
                    417:        }
                    418:        switch(toupper(x)) {
                    419:                case '!':   /* level 10 or higher */
                    420:                        if(useron.level<10)
                    421:                                console^=CON_ECHO_OFF;
                    422:                        break;
                    423:                case '@':   /* level 20 or higher */
                    424:                        if(useron.level<20)
                    425:                                console^=CON_ECHO_OFF;
                    426:                        break;
                    427:                case '#':   /* level 30 or higher */
                    428:                        if(useron.level<30)
                    429:                                console^=CON_ECHO_OFF;
                    430:                        break;
                    431:                case '$':   /* level 40 or higher */
                    432:                        if(useron.level<40)
                    433:                                console^=CON_ECHO_OFF;
                    434:                        break;
                    435:                case '%':   /* level 50 or higher */
                    436:                        if(useron.level<50)
                    437:                                console^=CON_ECHO_OFF;
                    438:                        break;
                    439:                case '^':   /* level 60 or higher */
                    440:                        if(useron.level<60)
                    441:                                console^=CON_ECHO_OFF;
                    442:                        break;
                    443:                case '&':   /* level 70 or higher */
                    444:                        if(useron.level<70)
                    445:                                console^=CON_ECHO_OFF;
                    446:                        break;
                    447:                case '*':   /* level 80 or higher */
                    448:                        if(useron.level<80)
                    449:                                console^=CON_ECHO_OFF;
                    450:                        break;
                    451:                case '(':   /* level 90 or higher */
                    452:                        if(useron.level<90)
                    453:                                console^=CON_ECHO_OFF;
                    454:                        break;
                    455:                case ')':   /* turn echo back on */
                    456:                        console&=~CON_ECHO_OFF;
                    457:                        break;
                    458:                case '+':       /* push current attribte */
                    459:                        if(attr_sp<(int)sizeof(attr_stack))
                    460:                                attr_stack[attr_sp++]=curatr;
                    461:                        break;
                    462:                case '-':       /* pop current attribute OR optimized "normal" */
                    463:                        if(attr_sp>0)
                    464:                                attr(attr_stack[--attr_sp]);
                    465:                        else                                                                    /* turn off all attributes if */
                    466:                                if(atr&(HIGH|BLINK|BG_LIGHTGRAY))       /* high intensity, blink or */
                    467:                                        attr(LIGHTGRAY);                                /* background bits are set */
                    468:                        break;
                    469:                case '_':                                                               /* turn off all attributes if */
                    470:                        if(atr&(BLINK|BG_LIGHTGRAY))            /* blink or background is set */
                    471:                                attr(LIGHTGRAY);
                    472:                        break;
                    473:                case 'P':       /* Pause */
                    474:                        pause();
                    475:                        break;
                    476:                case 'Q':   /* Pause reset */
                    477:                        lncntr=0;
                    478:                        break;
                    479:                case 'T':   /* Time */
                    480:                        now=time(NULL);
                    481:                        localtime_r(&now,&tm);
                    482:                        bprintf("%02d:%02d %s"
                    483:                                ,tm.tm_hour==0 ? 12
                    484:                                : tm.tm_hour>12 ? tm.tm_hour-12
                    485:                                : tm.tm_hour, tm.tm_min, tm.tm_hour>11 ? "pm":"am");
                    486:                        break;
                    487:                case 'D':   /* Date */
                    488:                        now=time(NULL);
                    489:                        bputs(unixtodstr(&cfg,now,tmp1));
                    490:                        break;
                    491:                case ',':   /* Delay 1/10 sec */
                    492:                        mswait(100);
                    493:                        break;
                    494:                case ';':   /* Delay 1/2 sec */
                    495:                        mswait(500);
                    496:                        break;
                    497:                case '.':   /* Delay 2 secs */
                    498:                        mswait(2000);
                    499:                        break;
                    500:                case 'S':   /* Synchronize */
                    501:                        ASYNC;
                    502:                        break;
                    503:                case 'L':       /* CLS (form feed) */
                    504:                        CLS;
                    505:                        break;
                    506:                case '>':   /* CLREOL */
                    507:                        cleartoeol();
                    508:                        break;
                    509:                case '<':   /* Non-destructive backspace */
                    510:                        outchar(BS);
                    511:                        break;
                    512:                case '[':   /* Carriage return */
                    513:                        outchar(CR);
                    514:                        break;
                    515:                case ']':   /* Line feed */
                    516:                        outchar(LF);
                    517:                        break;
                    518:                case 'A':   /* Ctrl-A */
                    519:                        outchar(CTRL_A);
                    520:                        break;
                    521:                case 'H':       /* High intensity */
                    522:                        atr|=HIGH;
                    523:                        attr(atr);
                    524:                        break;
                    525:                case 'I':       /* Blink */
                    526:                        atr|=BLINK;
                    527:                        attr(atr);
                    528:                        break;
                    529:                case 'N':       /* Normal */
                    530:                        attr(LIGHTGRAY);
                    531:                        break;
                    532:                case 'R':
                    533:                        atr=(atr&0xf8)|RED;
                    534:                        attr(atr);
                    535:                        break;
                    536:                case 'G':
                    537:                        atr=(atr&0xf8)|GREEN;
                    538:                        attr(atr);
                    539:                        break;
                    540:                case 'B':
                    541:                        atr=(atr&0xf8)|BLUE;
                    542:                        attr(atr);
                    543:                        break;
                    544:                case 'W':       /* White */
                    545:                        atr=(atr&0xf8)|LIGHTGRAY;
                    546:                        attr(atr);
                    547:                        break;
                    548:                case 'C':
                    549:                        atr=(atr&0xf8)|CYAN;
                    550:                        attr(atr);
                    551:                        break;
                    552:                case 'M':
                    553:                        atr=(atr&0xf8)|MAGENTA;
                    554:                        attr(atr);
                    555:                        break;
                    556:                case 'Y':   /* Yellow */
                    557:                        atr=(atr&0xf8)|BROWN;
                    558:                        attr(atr);
                    559:                        break;
                    560:                case 'K':       /* Black */
                    561:                        atr=(atr&0xf8)|BLACK;
                    562:                        attr(atr);
                    563:                        break;
                    564:                case '0':       /* Black Background */
                    565:                        atr=(atr&0x8f);
                    566:                        attr(atr);
                    567:                        break;
                    568:                case '1':       /* Red Background */
                    569:                        atr=(atr&0x8f)|(uchar)BG_RED;
                    570:                        attr(atr);
                    571:                        break;
                    572:                case '2':       /* Green Background */
                    573:                        atr=(atr&0x8f)|(uchar)BG_GREEN;
                    574:                        attr(atr);
                    575:                        break;
                    576:                case '3':       /* Yellow Background */
                    577:                        atr=(atr&0x8f)|(uchar)BG_BROWN;
                    578:                        attr(atr);
                    579:                        break;
                    580:                case '4':       /* Blue Background */
                    581:                        atr=(atr&0x8f)|(uchar)BG_BLUE;
                    582:                        attr(atr);
                    583:                        break;
                    584:                case '5':       /* Magenta Background */
                    585:                        atr=(atr&0x8f)|(uchar)BG_MAGENTA;
                    586:                        attr(atr);
                    587:                        break;
                    588:                case '6':       /* Cyan Background */
                    589:                        atr=(atr&0x8f)|(uchar)BG_CYAN;
                    590:                        attr(atr);
                    591:                        break;
                    592:                case '7':       /* White Background */
                    593:                        atr=(atr&0x8f)|(uchar)BG_LIGHTGRAY;
                    594:                        attr(atr);
                    595:                        break; 
                    596:        }
                    597: }
                    598: 
                    599: /***************************************************************************/
                    600: /* Changes local and remote text attributes accounting for monochrome      */
                    601: /***************************************************************************/
                    602: /****************************************************************************/
                    603: /* Sends ansi codes to change remote ansi terminal's colors                 */
                    604: /* Only sends necessary codes - tracks remote terminal's current attributes */
                    605: /* through the 'curatr' variable                                            */
                    606: /****************************************************************************/
                    607: void sbbs_t::attr(int atr)
                    608: {
                    609:        char    str[16];
                    610: 
                    611:        if(!term_supports(ANSI))
                    612:                return;
                    613:        if(!term_supports(COLOR)) {  /* eliminate colors if user doesn't have them */
                    614:                if(atr&LIGHTGRAY)       /* if any foreground bits set, set all */
                    615:                        atr|=LIGHTGRAY;
                    616:                if(atr&BG_LIGHTGRAY)  /* if any background bits set, set all */
                    617:                        atr|=BG_LIGHTGRAY;
                    618:                if(atr&LIGHTGRAY && atr&BG_LIGHTGRAY)
                    619:                        atr&=~LIGHTGRAY;    /* if background is solid, foreground is black */
                    620:                if(!atr)
                    621:                        atr|=LIGHTGRAY;         /* don't allow black on black */
                    622:        }
                    623:        if(curatr==atr) /* text hasn't changed. don't send codes */
                    624:                return;
                    625: 
                    626: #if 1
                    627:        strcpy(str,"\033[");
                    628:        if((!(atr&HIGH) && curatr&HIGH) || (!(atr&BLINK) && curatr&BLINK)
                    629:                || atr==LIGHTGRAY) {
                    630:                strcat(str,"0;");
                    631:                curatr=LIGHTGRAY;
                    632:        }
                    633:        if(atr&BLINK) {                     /* special attributes */
                    634:                if(!(curatr&BLINK))
                    635:                        strcat(str,"5;");
                    636:        }
                    637:        if(atr&HIGH) {
                    638:                if(!(curatr&HIGH))
                    639:                        strcat(str,"1;"); 
                    640:        }
                    641:        if((atr&0x07) != (curatr&0x07)) {
                    642:                switch(atr&0x07) {
                    643:                        case BLACK:
                    644:                                strcat(str,"30;");
                    645:                                break;
                    646:                        case RED:
                    647:                                strcat(str,"31;");
                    648:                                break;
                    649:                        case GREEN:
                    650:                                strcat(str,"32;");
                    651:                                break;
                    652:                        case BROWN:
                    653:                                strcat(str,"33;");
                    654:                                break;
                    655:                        case BLUE:
                    656:                                strcat(str,"34;");
                    657:                                break;
                    658:                        case MAGENTA:
                    659:                                strcat(str,"35;");
                    660:                                break;
                    661:                        case CYAN:
                    662:                                strcat(str,"36;");
                    663:                                break;
                    664:                        case LIGHTGRAY:
                    665:                                strcat(str,"37;");
                    666:                                break;
                    667:                }
                    668:        }
                    669:        if((atr&0x70) != (curatr&0x70)) {
                    670:                switch(atr&0x70) {
                    671:                        /* The BG_BLACK macro is 0x200, so isn't in the mask */
                    672:                        case 0 /* BG_BLACK */:  
                    673:                                strcat(str,"40;");
                    674:                                break;
                    675:                        case BG_RED:
                    676:                                strcat(str,"41;");
                    677:                                break;
                    678:                        case BG_GREEN:
                    679:                                strcat(str,"42;");
                    680:                                break;
                    681:                        case BG_BROWN:
                    682:                                strcat(str,"43;");
                    683:                                break;
                    684:                        case BG_BLUE:
                    685:                                strcat(str,"44;");
                    686:                                break;
                    687:                        case BG_MAGENTA:
                    688:                                strcat(str,"45;");
                    689:                                break;
                    690:                        case BG_CYAN:
                    691:                                strcat(str,"46;");
                    692:                                break;
                    693:                        case BG_LIGHTGRAY:
                    694:                                strcat(str,"47;");
                    695:                                break;
                    696:                }
                    697:        }
                    698:        if(strlen(str)==2)
                    699:                return;
                    700:        str[strlen(str)-1]='m';
                    701:        rputs(str);
                    702: #else
                    703:        if((!(atr&HIGH) && curatr&HIGH) || (!(atr&BLINK) && curatr&BLINK)
                    704:                || atr==LIGHTGRAY) {
                    705:                rputs(ansi(ANSI_NORMAL));
                    706:                curatr=LIGHTGRAY; 
                    707:        }
                    708: 
                    709:        if(atr==LIGHTGRAY)                  /* no attributes */
                    710:                return;
                    711: 
                    712:        if(atr&BLINK) {                     /* special attributes */
                    713:                if(!(curatr&BLINK))
                    714:                        rputs(ansi(BLINK)); 
                    715:        }
                    716:        if(atr&HIGH) {
                    717:                if(!(curatr&HIGH))
                    718:                        rputs(ansi(HIGH)); 
                    719:        }
                    720: 
                    721:        if((atr&0x7)==BLACK) {              /* foreground colors */
                    722:                if((curatr&0x7)!=BLACK)
                    723:                        rputs(ansi(BLACK)); 
                    724:        }
                    725:        else if((atr&0x7)==RED) {
                    726:                if((curatr&0x7)!=RED)
                    727:                        rputs(ansi(RED)); 
                    728:        }
                    729:        else if((atr&0x7)==GREEN) {
                    730:                if((curatr&0x7)!=GREEN)
                    731:                        rputs(ansi(GREEN)); 
                    732:        }
                    733:        else if((atr&0x7)==BROWN) {
                    734:                if((curatr&0x7)!=BROWN)
                    735:                        rputs(ansi(BROWN)); 
                    736:        }
                    737:        else if((atr&0x7)==BLUE) {
                    738:                if((curatr&0x7)!=BLUE)
                    739:                        rputs(ansi(BLUE)); 
                    740:        }
                    741:        else if((atr&0x7)==MAGENTA) {
                    742:                if((curatr&0x7)!=MAGENTA)
                    743:                        rputs(ansi(MAGENTA)); 
                    744:        }
                    745:        else if((atr&0x7)==CYAN) {
                    746:                if((curatr&0x7)!=CYAN)
                    747:                        rputs(ansi(CYAN)); 
                    748:        }
                    749:        else if((atr&0x7)==LIGHTGRAY) {
                    750:                if((curatr&0x7)!=LIGHTGRAY)
                    751:                        rputs(ansi(LIGHTGRAY)); 
                    752:        }
                    753: 
                    754:        if((atr&0x70)==0) {        /* background colors */
                    755:                if((curatr&0x70)!=0)
                    756:                        rputs(ansi(BG_BLACK)); 
                    757:        }
                    758:        else if((atr&0x70)==BG_RED) {
                    759:                if((curatr&0x70)!=BG_RED)
                    760:                        rputs(ansi(BG_RED)); 
                    761:        }
                    762:        else if((atr&0x70)==BG_GREEN) {
                    763:                if((curatr&0x70)!=BG_GREEN)
                    764:                        rputs(ansi(BG_GREEN)); 
                    765:        }
                    766:        else if((atr&0x70)==BG_BROWN) {
                    767:                if((curatr&0x70)!=BG_BROWN)
                    768:                        rputs(ansi(BG_BROWN)); 
                    769:        }
                    770:        else if((atr&0x70)==BG_BLUE) {
                    771:                if((curatr&0x70)!=BG_BLUE)
                    772:                        rputs(ansi(BG_BLUE)); 
                    773:        }
                    774:        else if((atr&0x70)==BG_MAGENTA) {
                    775:                if((curatr&0x70)!=BG_MAGENTA)
                    776:                        rputs(ansi(BG_MAGENTA)); 
                    777:        }
                    778:        else if((atr&0x70)==BG_CYAN) {
                    779:                if((curatr&0x70)!=BG_CYAN)
                    780:                        rputs(ansi(BG_CYAN)); 
                    781:        }
                    782:        else if((atr&0x70)==BG_LIGHTGRAY) {
                    783:                if((curatr&0x70)!=BG_LIGHTGRAY)
                    784:                        rputs(ansi(BG_LIGHTGRAY)); 
                    785:        }
                    786: #endif
                    787: 
                    788:        curatr=atr;
                    789: }
                    790: 
                    791: /****************************************************************************/
                    792: /* Checks to see if user has hit Pause or Abort. Returns 1 if user aborted. */
                    793: /* If the user hit Pause, waits for a key to be hit.                        */
                    794: /* Emulates remote XON/XOFF flow control on local console                   */
                    795: /* Preserves SS_ABORT flag state, if already set.                           */
                    796: /* Called from various listing procedures that wish to check for abort      */
                    797: /****************************************************************************/
                    798: bool sbbs_t::msgabort()
                    799: {
                    800:        static ulong counter;
                    801: 
                    802:        if(sys_status&SS_SYSPAGE && !(++counter%100)) 
                    803:                sbbs_beep(sbbs_random(800),1);
                    804: 
                    805:        checkline();
                    806:        if(sys_status&SS_ABORT)
                    807:                return(true);
                    808:        if(!online)
                    809:                return(true);
                    810:        return(false);
                    811: }
                    812: 
                    813: 

unix.superglobalmegacorp.com

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