Annotation of 43BSD/contrib/X/xterm/charproc.c, revision 1.1.1.1

1.1       root        1: #include <X/mit-copyright.h>
                      2: 
                      3: /* Copyright (c) 1985 Massachusetts Institute of Technology            */
                      4: /* Copyright (c) 1985  Digital Equipment Corporation                   */
                      5:  
                      6: /* charproc.c */
                      7:  
                      8: #include <X/Xlib.h>
                      9: #include "ptyx.h"
                     10: #include <stdio.h>
                     11: #include <sgtty.h>
                     12: #include "chartable.h"
                     13: #include "esctable.h"
                     14:  
                     15: #ifndef lint
                     16: static char *rcsid_charproc_c = "$Header: charproc.c,v 10.10 86/02/01 16:05:52 tony Rel $";
                     17: #endif lint
                     18: 
                     19: /* CAUTION: getb "knows" that the variable "c" is receiving the result */
                     20: 
                     21: #define        getb(buf) (--buf_cnt >= 0 ? *buf_ptr++:                         \
                     22:        ((c=fill(buf)), buf_cnt=buf->cnt, buf_ptr=buf->ptr, c))
                     23: 
                     24: #define        peekb(buf)  (buf_cnt >  0 ? *buf_ptr  : -1)
                     25: 
                     26: #define ANSIflush()   { arg = flushbuf(screen, term->flags, text_ptr); \
                     27:                        buffermode = 0;                                 \
                     28:                        text_ptr = text_buf;                            \
                     29:                        text_cnt = TEXT_BUF_SIZE; }
                     30: 
                     31: #define TEKflush()     {       arg = TekFlushBuf(term, text_ptr);      \
                     32:                                buffermode = 0;                         \
                     33:                                text_ptr = text_buf;                    \
                     34:                                text_cnt = TEXT_BUF_SIZE;               \
                     35:                        }
                     36: 
                     37: #define        TEXT_BUF_SIZE   256
                     38: 
                     39: extern TekLink *tb_end_link;
                     40: extern int tb_end;
                     41: 
                     42: unsigned char  text_buf[TEXT_BUF_SIZE];
                     43:  
                     44: unsigned       nri     = 0;
                     45: unsigned       nlf     = 0;
                     46: unsigned       ctotal  = 0;
                     47: unsigned       ntotal  = 0;
                     48:  
                     49: /*
                     50:  * in normal mode, buffer up as large a string of printing characters
                     51:  * as possible before flushing the buffer.  buffer up LF's and RI's
                     52:  * so these can be processed as a block.
                     53:  */
                     54: ANSInormal(term)
                     55: Terminal       *term;
                     56: {
                     57:        register int            c;
                     58:        register unsigned char  *text_ptr;
                     59:        register int            text_cnt;
                     60:        register unsigned char  *buf_ptr;
                     61:        register int            buf_cnt;
                     62:        register unsigned       buffermode;
                     63:        register Screen *screen = &term->screen;
                     64:        register Buffer *trmbuf = &term->buf;
                     65:        int                     arg;
                     66:  
                     67:        buffermode = 0;
                     68:        arg = 0;
                     69:        c = 0;
                     70:        text_ptr = text_buf;
                     71:        text_cnt = TEXT_BUF_SIZE;
                     72:        buf_cnt = trmbuf->cnt;
                     73:        buf_ptr = trmbuf->ptr;
                     74:  
                     75:        if (screen->TekGMode || screen->TekAMode)
                     76:                return (TekMode(term));
                     77: 
                     78:        for (;;) {
                     79:                /*
                     80:                 * if special condition has occurred, c will already
                     81:                 * be set to EOF.  otherwise, pick up a new char.
                     82:                 */
                     83:                if (c >= 0)
                     84:                        c = getb(trmbuf);
                     85: 
                     86:                if (ctable[c] == CPRINTING) {
                     87:                        buffermode = BUFFER_MODE;
                     88:                        if (--text_cnt >= 0)
                     89:                                *text_ptr++ = c;
                     90:                        else {
                     91:                                ANSIflush();
                     92:                                --text_cnt, *text_ptr++ = c;
                     93:                                if (arg)
                     94:                                        c = EOF;
                     95:                        }
                     96:                        continue;
                     97: 
                     98:                }
                     99: 
                    100:                switch (ctable[c]) {
                    101:                case CIGNORE:
                    102:                        break;
                    103: 
                    104: 
                    105:                case CLINEFEED:
                    106:                        if (buffermode || nri) {
                    107:                                ANSIflush();
                    108:                                if (arg)
                    109:                                        c = EOF;
                    110:                        }
                    111:                        ++nlf;
                    112:                        break;
                    113: 
                    114:                case CRETURN:
                    115:                        if (buffermode) {
                    116:                                ANSIflush();
                    117:                                if (arg)
                    118:                                        c = EOF;
                    119:                        }
                    120:                        screen->cur_col = 0;
                    121:                        screen->do_wrap = 0;
                    122:                        break;
                    123: 
                    124:                case CRI:
                    125: RI_kluge:              if (buffermode || nlf) {
                    126:                                ANSIflush();
                    127:                                if (arg)
                    128:                                        c = EOF;
                    129:                        }
                    130:                        ++nri;
                    131:                        break;
                    132: 
                    133:                case FLUSH:
                    134:                        ANSIflush();
                    135:                        trmbuf->cnt = buf_cnt;
                    136:                        trmbuf->ptr = buf_ptr;
                    137:                        return (arg);
                    138: 
                    139:                case CESC:
                    140:                        /* try to intercept RI's so we can buffer them  */
                    141:                        if (peekb(trmbuf) == 'M') {
                    142:                                c = getb(trmbuf);
                    143:                                goto RI_kluge;
                    144:                        }
                    145:                        /* no RI detected; fall into default case       */
                    146: 
                    147:                default:
                    148:                        ANSIflush();
                    149:                        docontrol(term, c);
                    150:        
                    151:                        /*
                    152:                         * if mode changes or event occurs, force a
                    153:                         * cleanup and return by setting char to EOF
                    154:                         */
                    155:                        if (arg 
                    156:                        || screen->mode!=ANSInormal 
                    157:                        || screen->TekGMode 
                    158:                        || screen->TekAMode)
                    159:                                c = EOF;
                    160:                }
                    161:        }
                    162: }
                    163:  
                    164: /*
                    165:  * flush the buffer of printing characters.  first, process any LF's or
                    166:  * RI's that have been buffered.
                    167:  */
                    168: flushbuf(screen, flags, text_ptr)
                    169: register Screen        *screen;
                    170: unsigned       flags;
                    171: register unsigned char *text_ptr;
                    172: {
                    173:        register unsigned char  *s;
                    174:        register unsigned char  *p;
                    175:        int                     arg = 0;
                    176:  
                    177:        if (nri != 0) {
                    178:                ioctl(screen->display->fd, FIONREAD, &arg);
                    179:                RevIndex(screen, nri);
                    180:                nri = 0;
                    181:        }
                    182:        if (nlf != 0) {
                    183:                ioctl(screen->display->fd, FIONREAD, &arg);
                    184:                Index(screen, nlf);
                    185:                if (flags & LINEFEED) {         /* do a carriage return */
                    186:                        screen->cur_col = 0;
                    187:                        screen->do_wrap = 0;
                    188:                }
                    189:                nlf = 0;
                    190:        }
                    191: 
                    192:        s = text_buf;
                    193:        /*
                    194:         * if a single shift is in effect, process 
                    195:         * the one character it affects.
                    196:         */
                    197:        if (screen->curss!=0 && s<text_ptr) {
                    198:                dotext(screen, flags, screen->gsets[screen->curss], s, s+1);
                    199:                ++s;
                    200:                screen->curss = 0;
                    201:        }
                    202: 
                    203:        /*
                    204:         * characters with and without the high bit set must be processed
                    205:         * separately (they select different character sets).  collect them
                    206:         * into groups before processing for as much efficiency as possible.
                    207:         */
                    208:        while (s < text_ptr) {
                    209:                p = s;
                    210:                if (*s < 0x80) {
                    211:                        /* character doesn't have high bit set  */
                    212:                        while (*s<0x80 && s<text_ptr)
                    213:                                ++s;
                    214:                        dotext(screen, flags,
                    215:                                screen->gsets[screen->curgl], p, s);
                    216:                }
                    217:                else {  /* character has high bit set           */
                    218:                        while (*s>=0x80 && s<text_ptr) {
                    219:                                *s &= 0x7f;
                    220:                                ++s;
                    221:                        }
                    222:                        dotext(screen, flags,
                    223:                                screen->gsets[screen->curgr], p, s);
                    224:                }
                    225:        }
                    226: 
                    227:        return (arg || screen->display->qlen!=0);
                    228: }
                    229: 
                    230: /*
                    231:  * process a string of characters according to the character set indicated
                    232:  * by charset.  worry about end of line conditions (wraparound if selected).
                    233:  */
                    234: dotext(screen, flags, charset, buf, ptr)
                    235: register Screen        *screen;
                    236: unsigned       flags;
                    237: char           charset;
                    238: unsigned char  *buf;
                    239: unsigned char  *ptr;
                    240: {
                    241:        register unsigned char  *s;
                    242:        register int    len;
                    243:        register int    n;
                    244:        register int    next_col;
                    245: 
                    246:        switch (charset) {
                    247:        case 'A':       /* United Kingdom set                           */
                    248:                for (s=buf; s<ptr; ++s)
                    249:                        if (*s == '#')
                    250:                                *s = '\036';    /* UK pound sign        */
                    251:                break;
                    252: 
                    253:        case 'B':       /* ASCII set                                    */
                    254:                break;
                    255: 
                    256:        case '0':       /* special graphics (line drawing)              */
                    257:                for (s=buf; s<ptr; ++s)
                    258:                        if (*s>=0x5f && *s<=0x7e)
                    259:                                *s = *s - 0x5f;
                    260:                break;
                    261: 
                    262:        default:        /* any character sets we don't recognize        */
                    263:                return;
                    264:        }
                    265: 
                    266:        len = ptr - buf; 
                    267:        ptr = buf;
                    268:        while (len > 0) {
                    269:                n = screen->max_col-screen->cur_col+1;
                    270:                if (n <= 1) {
                    271:                        if (screen->do_wrap && (flags&WRAPAROUND)) {
                    272:                                Index(screen, 1);
                    273:                                screen->cur_col = 0;
                    274:                                screen->do_wrap = 0;
                    275:                                n = screen->max_col+1;
                    276:                        }
                    277:                        else
                    278:                                n = 1;
                    279:                }
                    280:                if (len < n)
                    281:                        n = len;
                    282:                next_col = screen->cur_col + n;
                    283:                WriteText(screen, ptr, n, flags);
                    284:                /*
                    285:                 * the call to WriteText updates screen->cur_col.
                    286:                 * If screen->cur_col != next_col, we must have
                    287:                 * hit the right margin, so set the do_wrap flag.
                    288:                 */
                    289:                screen->do_wrap = (screen->cur_col < next_col);
                    290:                len -= n;
                    291:                ptr += n;
                    292:        }
                    293: }
                    294:  
                    295: /*
                    296:  * write a string str of length len onto the screen at
                    297:  * the current cursor position.  update cursor position.
                    298:  */
                    299: WriteText(screen, str, len, flags)
                    300: register Screen        *screen;
                    301: register unsigned char *str;
                    302: register int   len;
                    303: unsigned       flags;
                    304: {
                    305:        Font    fnt;
                    306:  
                    307:        fnt = (flags & BOLD ? screen->fnt_bold : screen->fnt_norm);
                    308:        if (flags & INSERT)
                    309:                InsertChar(screen, len);
                    310: #ifdef JUMPSCROLL
                    311:        if (!(AddToRefresh(screen))) {
                    312:                if(screen->scroll_amt)
                    313:                        FlushScroll(screen);
                    314: #endif JUMPSCROLL
                    315:        if (flags & INVERSE)
                    316:                XText(screen->window, CursorX(screen), CursorY(screen),
                    317:                        str, len, fnt, screen->background, screen->foreground);
                    318:        else
                    319:                XText(screen->window, CursorX(screen), CursorY(screen),
                    320:                        str, len, fnt, screen->foreground, screen->background);
                    321:        /*
                    322:         * the following statements compile data to compute the average 
                    323:         * number of characters written on each call to XText.  The data
                    324:         * may be examined via the use of a "hidden" escape sequence.
                    325:         */
                    326:        ctotal += len;
                    327:        ++ntotal;
                    328: #ifdef JUMPSCROLL
                    329:        }
                    330: #endif JUMPSCROLL
                    331:        ScreenWrite(screen, str, flags, len);
                    332:        CursorForward(screen, len);
                    333: }
                    334:  
                    335: /*
                    336:  * in Tek mode (graphics or alpha), buffer up as large a string of printing
                    337:  * characters as possible before flushing buffer.  in graphics mode the
                    338:  * characters are plotted, in alpha mode they are printed.
                    339:  */
                    340: TekMode(term)
                    341: Terminal       *term;
                    342: {
                    343:        register int            c;
                    344:        register unsigned char  *text_ptr;
                    345:        register int            text_cnt;
                    346:        register unsigned char  *buf_ptr;
                    347:        register int            buf_cnt;
                    348:        register unsigned       buffermode;
                    349:        register Screen *screen = &term->screen;
                    350:        register Buffer *trmbuf = &term->buf;
                    351:        int                     arg;
                    352:  
                    353:        c = 0;
                    354:        buffermode = 0;
                    355:        text_ptr = text_buf;
                    356:        text_cnt = TEXT_BUF_SIZE;
                    357:        buf_cnt = trmbuf->cnt;
                    358:        buf_ptr = trmbuf->ptr;
                    359: 
                    360:        for (;;) {
                    361:                /*
                    362:                 * if special condition has occurred, c will already
                    363:                 * be set to EOF.  otherwise, pick up a new char.
                    364:                 */
                    365:                if (c >= 0)
                    366:                        c = getb(trmbuf);
                    367: 
                    368:                if (c > 0)
                    369:                        c &= 0x7f;
                    370: 
                    371:                if (ctable[c]==CPRINTING || (c==DEL && screen->TekGMode)) {
                    372:                        buffermode = BUFFER_MODE;
                    373:                        if (--text_cnt >= 0)
                    374:                                *text_ptr++ = c;
                    375:                        else {
                    376:                                TEKflush();
                    377:                                --text_cnt, *text_ptr++ = c;
                    378:                                if (arg)
                    379:                                        c = EOF;
                    380:                        }
                    381:                        continue;
                    382: 
                    383:                }
                    384: 
                    385:                switch (ctable[c]) {
                    386:                case CIGNORE:
                    387:                        break;
                    388: 
                    389:                case CTEKINIT:
                    390:                        if (buffermode)
                    391:                                TEKflush();
                    392:                        TekInit(term, c);
                    393:                        if (arg)
                    394:                                c = EOF;
                    395:                        break;
                    396: 
                    397:                case FLUSH:
                    398:                        TEKflush();
                    399:                        trmbuf->cnt = buf_cnt;
                    400:                        trmbuf->ptr = buf_ptr;
                    401:                        return (arg);
                    402: 
                    403:                default:        /* BEL, BS, HT, LF, VT, FF, CR, ESC, US */
                    404:                                /* and also SI, SO, CAN, SUB            */
                    405:                        TEKflush();
                    406:                        if (screen->TekGMode)
                    407:                                TekAlph(term, c);
                    408:                        docontrol(term, c);
                    409:        
                    410:                        /*
                    411:                         * if mode changes or event occurs, force a
                    412:                         * cleanup and return by setting char to EOF
                    413:                         */
                    414:                        if (arg || screen->mode!=ANSInormal 
                    415:                        || (screen->TekGMode==0 && screen->TekAMode==0))
                    416:                                c = EOF;
                    417:                }
                    418:        }
                    419: }
                    420:  
                    421: /*
                    422:  * flush the buffer of printing characters.
                    423:  * use TekString, TekPoint, or TekPlot according to current mode.
                    424:  */
                    425: TekFlushBuf(term, text_ptr)
                    426: Terminal       *term;
                    427: register unsigned char *text_ptr;
                    428: {
                    429:        register Screen *screen = &term->screen;
                    430:        register unsigned char  *s;
                    431:  
                    432:        s = text_buf;
                    433:        if (text_ptr != text_buf) {
                    434:                if (screen->TekGMode) {
                    435:                        if (screen->TekIMode)
                    436:                                while (s < text_ptr) {
                    437:                                        TekBufPut(*s);
                    438:                                        TekPoint(term, *s++);
                    439:                                }
                    440:                        else
                    441:                                while (s < text_ptr) {
                    442:                                        TekBufPut(*s);
                    443:                                        TekPlot(term, *s++);
                    444:                                }
                    445:                }
                    446:                else
                    447:                        TekString(term, text_buf, text_ptr-text_buf);
                    448:        }
                    449: 
                    450:        return (screen->display->qlen != 0);
                    451: }
                    452: 
                    453: /*
                    454:  * a string (DCS, OSC, PM, APC) has been encountered in ANSI mode.
                    455:  * all printing characters are ignored until a string terminator
                    456:  * is seen (other possible exits are CAN, SUB, ESC, and C1 controls).
                    457:  */
                    458: ANSIstring(term)
                    459: Terminal       *term;
                    460: {
                    461:        register int    c;
                    462:        register Screen *screen = &term->screen;
                    463:        register Buffer *trmbuf = &term->buf;
                    464:        register unsigned char  *buf_ptr;
                    465:        register int            buf_cnt;
                    466:  
                    467:        buf_cnt = trmbuf->cnt;
                    468:        buf_ptr = trmbuf->ptr;
                    469:        while (screen->mode==ANSIstring && screen->display->qlen==0) {
                    470:                if ((c=getb(trmbuf)) == -1)
                    471:                        break;
                    472:                if ((c=parseseq(c, &screen->ansi, screen->TekEmu)) != -1) {
                    473:                        switch (ctable[c]) {
                    474:                        case CIGNORE:
                    475:                        case CPRINTING:
                    476:                                break;
                    477:                        case CESC:
                    478:                        case CCSI:
                    479:                                screen->mode = ANSInormal;
                    480:                                procseq(term);
                    481:                                break;
                    482:                        case CDCS:
                    483:                                screen->mode = ANSIstring;
                    484:                                procseq(term);
                    485:                                break;
                    486:                        case CCANCEL:
                    487:                                screen->mode = ANSInormal;
                    488:                                break;
                    489:                        default:
                    490:                                break;
                    491:                        }
                    492:                }
                    493:        }
                    494:        trmbuf->cnt = buf_cnt;
                    495:        trmbuf->ptr = buf_ptr;
                    496:        return (screen->display->qlen != 0);
                    497: }
                    498:  
                    499: /*
                    500:  * call parseseq with each new character until the sequence has been
                    501:  * parsed.  once parsed, call procseq to process the sequence.  DEC
                    502:  * standard says C0 controls in the middle of a sequence are acted
                    503:  * on just as if they weren't in the middle of a sequence (ANSI says
                    504:  * this is an error condition, but as always doesn't specify how to
                    505:  * handle the error).
                    506:  */
                    507: ANSIparse(term)
                    508: Terminal       *term;
                    509: {
                    510:        register int    c, ch;
                    511:        register Screen *screen = &term->screen;
                    512:        register Buffer *trmbuf = &term->buf;
                    513:        register unsigned char  *buf_ptr;
                    514:        register int            buf_cnt;
                    515:  
                    516:        c = 0;
                    517:        buf_cnt = trmbuf->cnt;
                    518:        buf_ptr = trmbuf->ptr;
                    519: 
                    520:        for (;;) {
                    521:                /*
                    522:                 * if special condition has occurred, c will already
                    523:                 * be set to EOF.  otherwise, pick up a new char.
                    524:                 */
                    525:                if (c >= 0)
                    526:                        c = getb(trmbuf);
                    527: 
                    528:                if (c == EOF) {
                    529:                        trmbuf->cnt = buf_cnt;
                    530:                        trmbuf->ptr = buf_ptr;
                    531:                        return (screen->display->qlen != 0);
                    532:                }
                    533: 
                    534:                if ((ch=parseseq(c, &screen->ansi, screen->TekEmu)) != -1) {
                    535:                        switch (ctable[ch]) {
                    536:                        case CIGNORE:
                    537:                                break;
                    538: 
                    539:                        case CESC:
                    540:                        case CCSI:
                    541:                                screen->mode = ANSInormal;
                    542:                                procseq(term);
                    543:                                break;
                    544: 
                    545:                        case CDCS:
                    546:                                screen->mode = ANSIstring;
                    547:                                procseq(term);
                    548:                                break;
                    549: 
                    550:                        default:
                    551:                                docontrol(term, ch);
                    552:                                break;
                    553:                        }
                    554:        
                    555:                        /*
                    556:                         * if mode changes or event occurs, force a
                    557:                         * cleanup and return by setting char to EOF
                    558:                         */
                    559:                        if (screen->mode!=ANSIparse || screen->ansi.a_type==0) {
                    560:                                c = EOF;
                    561:                                if (screen->mode==ANSIparse)
                    562:                                        screen->mode = ANSInormal;
                    563:                                screen->ansi.a_type = 0;
                    564:                                screen->ansi.a_pintro = 0;
                    565:                                screen->ansi.a_final = 0;
                    566:                        }
                    567:                        if (screen->display->qlen != 0);
                    568:                                c = EOF;
                    569: 
                    570:                }
                    571:        }
                    572: }
                    573:  
                    574: /*
                    575:  * some sort of ANSI sequence has been parsed.  look through the 
                    576:  * esctable to look for a match.  if found, apply default parameters
                    577:  * and dispatch.
                    578:  */
                    579: procseq(term)
                    580: Terminal       *term;
                    581: {
                    582:        register ANSI   *ap = &term->screen.ansi;
                    583:        register int    i;
                    584:        register long   *p;
                    585:        register long   a_funct;
                    586: #define        SEQKEY          p[0]    /* type, private, & final in a long     */
                    587: #define INTERS         p[1]    /* intermediate(s) in a long            */
                    588: #define        SEQTYPE         p[2]    /* sequence type (dispatch value)       */
                    589: #define        NDEFLT          p[3]    /* number of default parameters         */
                    590: #define DEFAULT(n)     p[4+n]  /* the n'th default parameter (0 origin)*/
                    591: #define FIXEDLEN       4       /* fixed (min) length of table entries  */
                    592:  
                    593:        /*
                    594:         * just return if any error encountered
                    595:         */
                    596:        if (ap->a_nastyf != 0)
                    597:                return;
                    598: 
                    599:        a_funct = (ap->a_final << 16) | (ap->a_pintro << 8) | ap->a_type;
                    600: 
                    601:        /*
                    602:         * step through table, looking for an
                    603:         * entry which matches the current sequence.
                    604:         */
                    605:        for (p=esctable; *p!=0; p+=NDEFLT+FIXEDLEN) {
                    606:                if (SEQKEY==a_funct
                    607:                && (INTERS==ap->a_inters || INTERS==WILD)) {
                    608:                        /*
                    609:                         * we have a match.
                    610:                         * get default values from table.
                    611:                         */
                    612:                        for (i=0; i<NDEFLT; ++i) {
                    613:                                if (ap->a_dflt[i] || i>=ap->a_nparam)
                    614:                                        ap->a_param[i] = DEFAULT(i);
                    615:                        }
                    616:                        if (ap->a_nparam < NDEFLT)
                    617:                                ap->a_nparam = NDEFLT;
                    618:                        /*
                    619:                         * ready to process the sequence.
                    620:                         */
                    621:                        doescape(term, SEQTYPE, ap);
                    622:                        break;
                    623:                }
                    624:        }
                    625: }
                    626:  
                    627: /*
                    628:  * this is a big switch of all the ANSI (and other) sequences
                    629:  * we know how to handle.  the cases of the switch must
                    630:  * have a corresponding entry in the esctable.
                    631:  */
                    632: doescape(term, kind, ap)
                    633: Terminal       *term;
                    634: long           kind;
                    635: ANSI           *ap;
                    636: {
                    637:        register Screen *screen = &term->screen;
                    638:        register        row, col;
                    639:        register        i, top, bot;
                    640:        ANSI            reply;
                    641:        int             bitset(), bitclr();
                    642:        register unsigned char  *text_ptr;
                    643:        register int            text_cnt;
                    644: 
                    645:        switch (kind) {
                    646:        case DECKPAM:
                    647:                term->keyboard.flags |= KYPD_APL;
                    648:                break;
                    649:  
                    650:        case DECKPNM:
                    651:                term->keyboard.flags &= ~KYPD_APL;
                    652:                break;
                    653:  
                    654:        case DECTC1:
                    655:                screen->rx8bit = 0;
                    656:                break;
                    657:  
                    658:        case DECSC:
                    659:                screen->sc.row = screen->cur_row;
                    660:                screen->sc.col = screen->cur_col;
                    661:                screen->sc.flags = term->flags;
                    662:                break;
                    663:  
                    664:        case DECAC1:
                    665:                screen->rx8bit = 1;
                    666:                break;
                    667:  
                    668:        case S7C1T:
                    669:                screen->tx8bit = 0;
                    670:                break;
                    671:  
                    672:        case S8C1T:
                    673:                screen->tx8bit = 1;
                    674:                break;
                    675:  
                    676:        case DECRC:
                    677:                term->flags &= ~(BOLD|INVERSE);
                    678:                term->flags |= screen->sc.flags&(BOLD|INVERSE);
                    679:                CursorSet(screen, screen->sc.row,
                    680:                        screen->sc.col, term->flags);
                    681:                break;
                    682:  
                    683:        case LS2:
                    684:                screen->curgl = 2;
                    685:                break;
                    686:  
                    687:        case LS3:
                    688:                screen->curgl = 3;
                    689:                break;
                    690:  
                    691:        case LS3R:
                    692:                screen->curgr = 3;
                    693:                break;
                    694:  
                    695:        case LS2R:
                    696:                screen->curgr = 2;
                    697:                break;
                    698:  
                    699:        case LS1R:
                    700:                screen->curgr = 1;
                    701:                break;
                    702:  
                    703:        case DESIGNATE:
                    704:                switch (ap->a_inters) {
                    705:                case '(':
                    706:                        screen->gsets[0] = ap->a_final;
                    707:                        break;
                    708:  
                    709:                case ')':
                    710:                        screen->gsets[1] = ap->a_final;
                    711:                        break;
                    712:  
                    713:                case '*':
                    714:                        screen->gsets[2] = ap->a_final;
                    715:                        break;
                    716:  
                    717:                case '+':
                    718:                        screen->gsets[3] = ap->a_final;
                    719:                        break;
                    720: 
                    721:                case '#':               /* special "hidden" sequence    */
                    722:                        if (ap->a_final == '1')
                    723:                                fprintf(stderr, "avg call = %d char\n", 
                    724:                                        ctotal/ntotal);
                    725: 
                    726:                default:
                    727:                        break;
                    728:                }
                    729:                break;
                    730:  
                    731:        case DA1:
                    732:                if (ap->a_param[0]==0) {
                    733:                        reply.a_type   = CSI;
                    734:                        reply.a_pintro = '?';
                    735:                        reply.a_nparam = 1;
                    736:                        reply.a_param[0] = 6;           /* VT102        */
                    737:                        reply.a_inters = 0;
                    738:                        reply.a_final  = 'c';
                    739:                        unparseseq(&reply, screen->tx8bit, screen->respond);
                    740:                }
                    741:                break;
                    742:  
                    743:        case TBC:
                    744:                if (ap->a_param[0]==0)
                    745:                        TabClear(term->tabs, screen->cur_col);
                    746:                else if (ap->a_param[0] == 3)
                    747:                        TabZonk(term->tabs);
                    748:                break;
                    749:  
                    750:        case SET:
                    751:                modes(term, bitset);
                    752:                break;
                    753:  
                    754:        case DECSET:
                    755:                dpmodes(term, bitset);
                    756:                break;
                    757:  
                    758:        case RST:
                    759:                modes(term, bitclr);
                    760:                break;
                    761:  
                    762:        case DECRST:
                    763:                dpmodes(term, bitclr);
                    764:                break;
                    765:  
                    766:        case SGR:
                    767:                for (i=0; i<ap->a_nparam; ++i) {
                    768:                        switch (ap->a_param[i]) {
                    769:                        case 0:
                    770:                                term->flags &= ~(INVERSE|BOLD);
                    771:                                break;
                    772:  
                    773:                        case 1:
                    774:                        case 4:         /* Underscore, really   */
                    775:                        case 5:         /* Blink, really.       */
                    776:                                term->flags |= BOLD;
                    777:                                break;
                    778:  
                    779:                        case 7:
                    780:                                term->flags |= INVERSE;
                    781:                        }
                    782:                }
                    783:                break;
                    784:  
                    785:        case CPR:
                    786:                if (ap->a_param[0]==5) {
                    787:                        reply.a_type = CSI;
                    788:                        reply.a_pintro = 0;
                    789:                        reply.a_nparam = 1;
                    790:                        reply.a_param[0] = 0;
                    791:                        reply.a_inters = 0;
                    792:                        reply.a_final  = 'n';
                    793:                        unparseseq(&reply, screen->tx8bit, screen->respond);
                    794:                        break;
                    795:                }
                    796:                if (ap->a_param[0]==6) {
                    797:                        reply.a_type = CSI;
                    798:                        reply.a_pintro = 0;
                    799:                        reply.a_nparam = 2;
                    800:                        reply.a_param[0] = screen->cur_row+1;
                    801:                        reply.a_param[1] = screen->cur_col+1;
                    802:                        reply.a_inters = 0;
                    803:                        reply.a_final  = 'R';
                    804:                        unparseseq(&reply, screen->tx8bit, screen->respond);
                    805:                        break;
                    806:                }
                    807:                break;
                    808:  
                    809:        case DECSTBM:
                    810:                top = ap->a_param[0];
                    811:                bot = ap->a_param[1];
                    812:                if (top < 1)
                    813:                        top = 1;
                    814:                if (bot > screen->max_row+1)
                    815:                        bot = screen->max_row+1;
                    816:                if (bot > top) {
                    817: #ifdef JUMPSCROLL
                    818:                        if(screen->scroll_amt)
                    819:                                FlushScroll(screen);
                    820: #endif JUMPSCROLL
                    821:                        screen->top_marg = top-1;
                    822:                        screen->bot_marg = bot-1;
                    823:                        CursorSet(screen, 0, 0, term->flags);
                    824:                }
                    825:                break;
                    826:  
                    827:        case ICH:
                    828:                InsertChar(screen, ap->a_param[0]);
                    829:                break;
                    830:  
                    831:        case CUU:
                    832:                CursorUp(screen, ap->a_param[0]);
                    833:                break;
                    834:        
                    835:        case CUD:
                    836:                CursorDown(screen, ap->a_param[0]);
                    837:                break;
                    838:        
                    839:        case CUF:
                    840:                CursorForward(screen, ap->a_param[0]);
                    841:                break;
                    842:        
                    843:        case CUB:
                    844:                CursorBack(screen, ap->a_param[0]);
                    845:                break;
                    846:        
                    847:        case HVP:
                    848:        case CUP:
                    849:                row = ap->a_param[0];
                    850:                col = ap->a_param[1];
                    851:  
                    852:                screen->cur_x = screen->cur_y = 0;
                    853:                screen->TekAMode = 0;
                    854:                CursorSet(screen, row-1, col-1, term->flags);
                    855:                break;
                    856:  
                    857:        case ED:
                    858:                switch (ap->a_param[0]) {
                    859:                case 0: ClearBelow(screen);
                    860:                        break;
                    861: 
                    862:                case 1: ClearAbove(screen);
                    863:                        break;
                    864: 
                    865:                case 2: ClearScreen(screen);
                    866:                        if (screen->TekEmu)
                    867:                                TekErase(term);
                    868:                        break;
                    869:                }
                    870:                break;
                    871:  
                    872:        case EL:
                    873:                switch (ap->a_param[0]) {
                    874:                case 0: ClearRight(screen);
                    875:                        break;
                    876: 
                    877:                case 1: ClearLeft(screen);
                    878:                        break;
                    879: 
                    880:                case 2: ClearLine(screen);
                    881:                        break;
                    882:                }
                    883:                break;
                    884:  
                    885:        case IL:
                    886:                InsertLine(screen, ap->a_param[0]);
                    887:                break;
                    888:  
                    889:        case DL:
                    890:                DeleteLine(screen, ap->a_param[0]);
                    891:                break;
                    892:  
                    893:        case DCH:
                    894:                DeleteChar(screen, ap->a_param[0]);
                    895:                break;
                    896:  
                    897:        case DECALN:
                    898:                text_ptr = text_buf;
                    899:                text_cnt = TEXT_BUF_SIZE;
                    900:                for (i=0; i<256; ++i) {
                    901:                        if (--text_cnt >= 0)
                    902:                                *text_ptr++ = i;
                    903:                        else {
                    904:                                flushbuf(screen, term->flags, text_ptr);
                    905:                                text_ptr = text_buf;
                    906:                                text_cnt = TEXT_BUF_SIZE-1;
                    907:                                *text_ptr++ = i;
                    908:                        }
                    909:                }
                    910:                flushbuf(screen, term->flags, text_ptr);
                    911:                break;
                    912: 
                    913:        case TEKESCFF:
                    914:        case TEKCSIUS:
                    915:                CursorSet(screen, 0, 0, term->flags);
                    916:                ClearScreen(screen);
                    917:                TekErase(term);
                    918:                break;
                    919: 
                    920:        case TEKESCSUB:
                    921:                TekCursor(term);
                    922:                break;
                    923: 
                    924:        case TEKESCINQ:
                    925:                TekInq(term);
                    926:                break;
                    927: 
                    928:        default:
                    929:                Panic("unexpected dispatch (%d) encountered in doescape", kind);
                    930:                break;
                    931:        }
                    932: }
                    933:  
                    934: /*
                    935:  * this is a big switch of all the control characters we know how to handle.
                    936:  * the cases of the switch have a corresponding entry in the ctable.
                    937:  */
                    938: docontrol(term, c)
                    939: Terminal       *term;
                    940: {
                    941:        register Screen *screen = &term->screen;
                    942:  
                    943:        switch (ctable[c]) {
                    944:        case CIGNORE:
                    945:                break;
                    946:  
                    947:        case CBELL:
                    948:                XFeep(0);
                    949:                break;
                    950:  
                    951:        case CBACKSPACE:
                    952:                CursorBack(screen, 1);
                    953:                break;
                    954:  
                    955:        case CTAB:
                    956:                screen->cur_col = TabNext(term->tabs, screen->cur_col);
                    957:                if (screen->cur_col > screen->max_col)
                    958:                        screen->cur_col = screen->max_col;
                    959:                break;
                    960:  
                    961:        case CLINEFEED:         /* actually both VT and LF map here     */
                    962:        case CFORMFEED:
                    963:                if (screen->TekAMode)
                    964:                        TekReset(term);
                    965:                Index(screen, 1);
                    966:                if (term->flags & LINEFEED)
                    967:                        CarriageReturn(screen);
                    968:                break;
                    969:  
                    970:        case CRETURN:
                    971:                if (screen->TekAMode)
                    972:                        TekReset(term);
                    973:                CarriageReturn(screen);
                    974:                break;
                    975:  
                    976:        case CLS1:
                    977:                screen->curgl = 1;
                    978:                break;
                    979:  
                    980:        case CLS0:
                    981:                screen->curgl = 0;
                    982:                break;
                    983:  
                    984:        case CCANCEL:
                    985:                screen->mode = ANSInormal;
                    986:                break;
                    987:  
                    988:        case CESC:
                    989:        case CDCS:
                    990:        case CCSI:
                    991:                screen->ansi.a_type  = c;
                    992:                screen->ansi.a_pintro = 0;
                    993:                screen->ansi.a_final = 0;
                    994:                screen->ansi.a_inters = 0;
                    995:                screen->ansi.a_nparam = 0;
                    996:                screen->ansi.a_nastyf = 0;
                    997:                screen->mode = ANSIparse;
                    998:                break;
                    999:  
                   1000:        case CTEKINIT:          /* come here from FS, GS, or RS         */
                   1001:                if (screen->TekEmu)
                   1002:                        TekInit(term, c);
                   1003:                break;
                   1004:  
                   1005:        case CTEKALPH:          /* US                                   */
                   1006:                break;          /* just ignore; can only get to alpha   */
                   1007:                                /* mode from Tek graphics mode          */
                   1008: 
                   1009:        case CIND:
                   1010:                Index(screen, 1);
                   1011:                break;
                   1012:  
                   1013:        case CNEL:
                   1014:                Index(screen, 1);
                   1015:                CarriageReturn(screen);
                   1016:                break;
                   1017:  
                   1018:        case CRI:
                   1019:                RevIndex(screen, 1);
                   1020:                break;
                   1021:  
                   1022:        case CSS2:
                   1023:                screen->curss = 2;
                   1024:                break;
                   1025:  
                   1026:        case CSS3:
                   1027:                screen->curss = 3;
                   1028:                break;
                   1029:  
                   1030:        default:
                   1031:                Panic("unexpected char (0x%x) encountered in docontrol", c);
                   1032:                break;
                   1033:        }
                   1034: }
                   1035: 
                   1036: /*
                   1037:  * process ANSI modes set, reset
                   1038:  */
                   1039: modes(term, func)
                   1040: Terminal       *term;
                   1041: int            (*func)();
                   1042: {
                   1043:        register Screen *screen = &term->screen;
                   1044:        register ANSI   *ansi;
                   1045:        register int    i;
                   1046: 
                   1047:        ansi = &screen->ansi;
                   1048:        for (i=0; i<ansi->a_nparam; ++i) {
                   1049:                switch (ansi->a_param[i]) {
                   1050:                case 4:                 /* IRM                          */
                   1051:                        (*func)(&term->flags, INSERT);
                   1052:                        break;
                   1053: 
                   1054:                case 20:                /* LNM                          */
                   1055:                        (*func)(&term->flags, LINEFEED);
                   1056:                        break;
                   1057:                }
                   1058:        }
                   1059: }
                   1060: 
                   1061: /*
                   1062:  * process DEC private modes set, reset
                   1063:  */
                   1064: dpmodes(term, func)
                   1065: Terminal       *term;
                   1066: int            (*func)();
                   1067: {
                   1068:        register Screen *screen = &term->screen;
                   1069:        register ANSI   *ap;
                   1070:        register int    i;
                   1071: 
                   1072:        ap = &screen->ansi;
                   1073:        for (i=0; i<ap->a_nparam; ++i) {
                   1074:                switch (ap->a_param[i]) {
                   1075:                case 1:                 /* DECCKM                       */
                   1076:                        (*func)(&term->keyboard.flags, CURSOR_APL);
                   1077:                        break;
                   1078: 
                   1079: #ifdef JUMPSCROLL
                   1080:                case 4:                 /* DECSCLM (slow scroll)        */
                   1081:                        if (func == bitset) {
                   1082:                                screen->jumpscroll = 0;
                   1083:                                if (screen->scroll_amt)
                   1084:                                        FlushScroll(screen);
                   1085:                        } else if (!screen->TekEmu)
                   1086:                                screen->jumpscroll = 1;
                   1087:                        (*func)(&term->flags, SMOOTHSCROLL);
                   1088:                        break;
                   1089: #endif JUMPSCROLL
                   1090:                case 5:                 /* DECSCNM                      */
                   1091:                        i = term->flags;
                   1092:                        (*func)(&term->flags, REVERSE_VIDEO);
                   1093:                        if ((term->flags ^ i) & REVERSE_VIDEO)
                   1094:                                ReverseVideo(term);
                   1095:                        break;
                   1096: 
                   1097:                case 6:                 /* DECOM                        */
                   1098:                        (*func)(&term->flags, ORIGIN);
                   1099:                        CursorSet(screen, 0, 0, term->flags);
                   1100:                        break;
                   1101: 
                   1102:                case 7:                 /* DECAWM                       */
                   1103:                        (*func)(&term->flags, WRAPAROUND);
                   1104:                        break;
                   1105:                case 9:                 /* MIT bogus sequence           */
                   1106:                        (*func)(&screen->send_mouse_pos, 1);
                   1107:                        break;
                   1108:                case 38:                /* DECTEK                       */
                   1109:                        (*func)(&screen->TekEmu, 1);
                   1110:                        /*
                   1111:                         * probably need to do some work here to get
                   1112:                         * into or out of Tek emulation cleanly
                   1113:                         */
                   1114:                        break;
                   1115:                }
                   1116:        }
                   1117: }
                   1118: 
                   1119: /*
                   1120:  * set a bit in a word given a pointer to the word and a mask.
                   1121:  */
                   1122: bitset(p, mask)
                   1123: int    *p;
                   1124: {
                   1125:        *p |= mask;
                   1126: }
                   1127: 
                   1128: /*
                   1129:  * clear a bit in a word given a pointer to the word and a mask.
                   1130:  */
                   1131: bitclr(p, mask)
                   1132: int    *p;
                   1133: {
                   1134:        *p &= ~mask;
                   1135: }
                   1136: 
                   1137: ReverseVideo (term)
                   1138:        Terminal *term;
                   1139: {
                   1140:        register Screen *screen = &term->screen;
                   1141:        int tmp;
                   1142: 
                   1143:        XDefineCursor(screen->window,
                   1144:                      (term->flags & REVERSE_VIDEO) ? screen->rcurs : screen->curs);
                   1145:        tmp = screen->background;
                   1146:        if (screen->cursorcolor == screen->foreground)
                   1147:            screen->cursorcolor = tmp;
                   1148:        screen->background = screen->foreground;
                   1149:        screen->foreground = tmp;
                   1150:        XFreePixmap(screen->bgndtile);
                   1151:        screen->bgndtile = XMakeTile(screen->background);
                   1152:        if (screen->borderwidth &&
                   1153:            screen->background < 2 &&
                   1154:            screen->foreground < 2) {
                   1155:                if (screen->bgndtile == BlackPixmap)
                   1156:                    screen->bordertile = WhitePixmap;
                   1157:                else if (screen->bgndtile == WhitePixmap)
                   1158:                    screen->bordertile = BlackPixmap;
                   1159:            XChangeBorder (screen->window, screen->bordertile);
                   1160:        }
                   1161:        XChangeBackground (screen->window, screen->bgndtile);
                   1162:        XClear (screen->window);
                   1163:        ScrnRefresh (screen, 0, 0, screen->max_row +1, screen->max_col + 1);
                   1164:        if (screen->TekEmu) TekRefresh (term);
                   1165: }

unix.superglobalmegacorp.com

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