Annotation of 43BSD/contrib/X/xterm/charproc.c, revision 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.