Annotation of 43BSDReno/contrib/jove/screen.c, revision 1.1

1.1     ! root        1: /***************************************************************************
        !             2:  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
        !             3:  * is provided to you without charge, and with no warranty.  You may give  *
        !             4:  * away copies of JOVE, including sources, provided that this notice is    *
        !             5:  * included in all the files.                                              *
        !             6:  ***************************************************************************/
        !             7: 
        !             8: #include "jove.h"
        !             9: #include "fp.h"
        !            10: #include "ctype.h"
        !            11: #include "termcap.h"
        !            12: #include "disp.h"
        !            13: 
        !            14: int    AbortCnt,
        !            15:        CanScroll = 0,
        !            16:        tabstop = 8;
        !            17: 
        !            18: #if !(defined(IBMPC) || defined(MAC))
        !            19: private void
        !            20:        (*TTins_line) proto((int, int, int)),
        !            21:        (*TTdel_line) proto((int, int, int));
        !            22: #endif /* (defined(IBMPC) || defined(MAC)) */
        !            23: 
        !            24: struct scrimage
        !            25:        *DesiredScreen = 0,
        !            26:        *PhysScreen = 0;
        !            27: 
        !            28: struct screenline      *Screen = 0,    /* the screen (a bunch of screenline) */
        !            29:                        *Curline = 0;   /* current line */
        !            30: 
        !            31: private struct screenline   *Savelines = 0;    /* another bunch (LI of them) */
        !            32: 
        !            33: 
        !            34: private char   *cursor;                        /* offset into current Line */
        !            35: 
        !            36: char   *cursend;
        !            37: 
        !            38: int    CapCol,
        !            39:        CapLine,
        !            40: 
        !            41:        i_line,
        !            42:        i_col;
        !            43: 
        !            44: #ifdef IBMPC
        !            45: extern unsigned char   CHPL;
        !            46: extern void            near normfun(),
        !            47:                        near scr_win(),
        !            48:                        near clr_page(),
        !            49:                        near clr_eoln();
        !            50: 
        !            51: #endif
        !            52: 
        !            53: void
        !            54: make_scr()
        !            55: {
        !            56:        register int    i;
        !            57:        register struct screenline      *ns;
        !            58:        register char   *nsp;
        !            59: 
        !            60: #ifdef RESHAPING
        !            61:        /* In case we are RESHAPING the window! */
        !            62:        if (DesiredScreen)
        !            63:                free((char *) DesiredScreen);
        !            64:        if (PhysScreen)
        !            65:                free((char *) PhysScreen);
        !            66:        if (Savelines)
        !            67:                free((char *) Savelines);
        !            68:        if (Screen) {
        !            69:                free(Screen->s_line);   /* free all the screen data */
        !            70:                free((char *) Screen);
        !            71:        }
        !            72: #endif /* RESHAPING */
        !            73: 
        !            74:        DesiredScreen = (struct scrimage *) malloc((unsigned) LI * sizeof (struct scrimage));
        !            75:        PhysScreen = (struct scrimage *) malloc((unsigned) LI * sizeof (struct scrimage));
        !            76: 
        !            77:        Savelines = (struct screenline *)
        !            78:                        malloc((unsigned) LI * sizeof(struct screenline));
        !            79:        ns = Screen = (struct screenline *)
        !            80:                        malloc((unsigned) LI * sizeof(struct screenline));
        !            81: 
        !            82:        nsp = (char *) malloc((unsigned)CO * LI);
        !            83:        if (nsp == 0) {
        !            84:                writef("\n\rCannot malloc screen!\n");
        !            85:                finish(1);
        !            86:        }
        !            87: 
        !            88:        for (i = 0; i < LI; i++) {
        !            89:                ns->s_line = nsp;
        !            90:                nsp += CO;
        !            91:                ns->s_length = nsp - 1;         /* End of Line */
        !            92:                ns += 1;
        !            93:        }
        !            94:        cl_scr(0);
        !            95: }
        !            96: 
        !            97: void
        !            98: clrline(cp1, cp2)
        !            99: register char  *cp1,
        !           100:                *cp2;
        !           101: {
        !           102:        while (cp1 <= cp2)
        !           103:                *cp1++ = ' ';
        !           104: }
        !           105: 
        !           106: #if !(defined(IBMPC) || defined(MAC))
        !           107: # define sputc(c)      ((*cursor != (char) (c)) ? dosputc((c)) : (cursor++, i_col++))
        !           108: #endif /* (defined(IBMPC) || defined(MAC)) */
        !           109: 
        !           110: #ifdef IBMPC
        !           111: int force = 0;
        !           112: # define sputc(c)      dosputc((c))
        !           113: #endif /* IBMPC */
        !           114: 
        !           115: #ifdef MAC
        !           116: # define sputc(c)      bufputc((c))    /* line buffered for mac display */
        !           117: #endif /* MAC */
        !           118: 
        !           119: #define soutputc(c)    { if (--n <= 0) break; else sputc((c)); }
        !           120: 
        !           121: void
        !           122: cl_eol()
        !           123: {
        !           124:        if (cursor > cursend)
        !           125:                return;
        !           126: 
        !           127:        if (cursor < Curline->s_length) {
        !           128: #if !(defined(IBMPC) || defined(MAC))
        !           129:                if (CE) {
        !           130: #endif /* (defined(IBMPC) || defined(MAC)) */
        !           131:                        Placur(i_line, i_col);
        !           132: #ifdef TERMCAP
        !           133:                        putpad(CE, 1);
        !           134: #else
        !           135:                clr_eoln();
        !           136: #endif /* TERMCAP */
        !           137:                        clrline(cursor, Curline->s_length);
        !           138: #if !(defined(IBMPC) || defined(MAC))
        !           139:                } else {
        !           140:                /* Ugh.  The slow way for dumb terminals. */
        !           141:                        register char *savecp = cursor;
        !           142: 
        !           143:                        while (cursor <= Curline->s_length)
        !           144:                                sputc(' ');
        !           145:                        cursor = savecp;
        !           146:                }
        !           147: #endif /* (defined(IBMPC) || defined(MAC)) */
        !           148:                Curline->s_length = cursor;
        !           149:        }
        !           150: }
        !           151: 
        !           152: void
        !           153: cl_scr(doit)
        !           154: int doit;
        !           155: {
        !           156:        register int    i;
        !           157:        register struct screenline      *sp = Screen;
        !           158: 
        !           159:        for (i = 0; i < LI; i++, sp++) {
        !           160:                clrline(sp->s_line, sp->s_length);
        !           161:                sp->s_length = sp->s_line;
        !           162:                PhysScreen[i].s_id = 0;
        !           163:        }
        !           164:        if (doit) {
        !           165: #ifdef TERMCAP
        !           166:                putpad(CL, LI);
        !           167: #else
        !           168:                clr_page();
        !           169: #endif /* TERMCAP */
        !           170:                CapCol = CapLine = 0;
        !           171:                UpdMesg = YES;
        !           172:        }
        !           173: }
        !           174: 
        !           175: /* Output one character (if necessary) at the current position */
        !           176: 
        !           177: #ifndef MAC
        !           178: int            /* only for lints sake */
        !           179: dosputc(c)
        !           180: register int   c;
        !           181: {
        !           182: #ifndef IBMPC
        !           183:        if (*cursor != c) {
        !           184: # ifdef ID_CHAR
        !           185:                if (IN_INSmode)
        !           186:                        INSmode(0);
        !           187: # endif
        !           188: #else /* IBMPC */
        !           189:        if ((force) || (*cursor != c)) {
        !           190: #endif /* IBMPC */
        !           191:                if (i_line != CapLine || i_col != CapCol)
        !           192:                        Placur(i_line, i_col);
        !           193: #ifndef IBMPC
        !           194:                if (UL && (c & CHARMASK) == '_' && (*cursor & CHARMASK) != ' ')
        !           195:                        putstr(" \b");          /* Erase so '_' looks right. */
        !           196: #endif /* IBMPC */
        !           197:                *cursor++ = c;
        !           198: #ifndef IBMPC
        !           199:                jputchar(c & CHARMASK);
        !           200: #else /* IBMPC */
        !           201:                normfun((char) c);
        !           202: #endif /* IBMPC */
        !           203:                AbortCnt -= 1;
        !           204:                CapCol += 1;
        !           205:                i_col += 1;
        !           206:        } else {
        !           207:                cursor += 1;
        !           208:                i_col += 1;
        !           209:        }
        !           210:        return 0;   /* useless result */
        !           211: }
        !           212: #else /* MAC */
        !           213: 
        !           214: /* Character output to bit-mapped screen is very expensive. It makes
        !           215:    much more sense to write the entire line at once. So, we print all
        !           216:    the characters, whether already there or not, once the line is
        !           217:    complete.  */
        !           218: 
        !           219: #define BUFFLUSH (char) 0
        !           220: #define BUFSTART (char) 1
        !           221: 
        !           222: bufputc(c)
        !           223: register char c;
        !           224: {
        !           225:        static char buf[256];
        !           226:        static int len = 0;
        !           227: 
        !           228:        if(c == BUFSTART) {
        !           229: /*             if (i_line != CapLine || i_col != CapCol)*/
        !           230:                        NPlacur(i_line, i_col);
        !           231:                len = 0;
        !           232:                return;
        !           233:        }
        !           234:        if(c == BUFFLUSH) {
        !           235:                buf[0] = (unsigned char) len;
        !           236:                writechr(buf);
        !           237:                len = 0;
        !           238:        }
        !           239:        else {
        !           240:                if(len > 255) return;
        !           241:                *cursor++ = c;
        !           242:                if(c == '0') buf[++len] = 0xAF; /* slashed zero */
        !           243:                else buf[++len] = c;
        !           244:                CapCol++;
        !           245:                i_col++;
        !           246:        }
        !           247:        return;
        !           248: }
        !           249: #endif /* MAC */
        !           250: 
        !           251: /* Write `line' at the current position of `cursor'.  Stop when we
        !           252:    reach the end of the screen.  Aborts if there is a character
        !           253:    waiting.  */
        !           254: 
        !           255: #ifdef MAC             /* This was getting too complicated with ifdefs ... */
        !           256: int
        !           257: swrite(line, inversep, abortable)
        !           258: register char  *line;
        !           259: register int   abortable;
        !           260: {
        !           261:        register int    c;
        !           262:        int     col = i_col,
        !           263:                aborted = 0;
        !           264:        register int    n = cursend - cursor;
        !           265: 
        !           266:        if (n <= 0)
        !           267:                return 1;
        !           268:        sputc(BUFSTART);        /* Okay, because no interruption possible */
        !           269: 
        !           270:        while (c = *line++) {
        !           271:                if (abortable && AbortCnt < 0) {
        !           272:                        AbortCnt = BufSize;
        !           273:                        if (InputPending = charp()) {
        !           274:                                aborted = 1;
        !           275:                                break;
        !           276:                        }
        !           277:                }
        !           278:                if (c == '\t') {
        !           279:                        int     nchars;
        !           280: 
        !           281:                        nchars = (tabstop - (col % tabstop));
        !           282:                        col += nchars;
        !           283: 
        !           284:                        while (nchars--)
        !           285:                                soutputc(' ');
        !           286:                        if (n <= 0)
        !           287:                                break;
        !           288:                } else if (isctrl(c)) {
        !           289:                        soutputc('^');
        !           290:                        c = ((c == '\177') ? '?' : c + '@');
        !           291:                        soutputc(c);
        !           292:                        col += 2;
        !           293:                } else {
        !           294:                        soutputc(c);
        !           295:                        col += 1;
        !           296:                }
        !           297:        }
        !           298:        if (n <= 0) {
        !           299:                if ((*line == '\0') && (c != '\t') && !isctrl(c))
        !           300:                        sputc(c);
        !           301:                        sputc('!');
        !           302:        }
        !           303:        if (cursor > Curline->s_length)
        !           304:                Curline->s_length = cursor;
        !           305:        sputc(BUFFLUSH);
        !           306:        return !aborted;
        !           307: }
        !           308: 
        !           309: #else /* MAC */
        !           310: 
        !           311: int
        !           312: swrite(line, inversep, abortable)
        !           313: register char  *line;
        !           314: int    inversep;
        !           315: register int   abortable;
        !           316: {
        !           317:        register int    c;
        !           318:        int     col = i_col,
        !           319:                aborted = 0;
        !           320:        register int    n = cursend - cursor;
        !           321: #ifndef IBMPC
        !           322:        int     or_byte = inversep ? 0200 : 0,
        !           323:                thebyte;
        !           324: #else
        !           325:        int     thebyte;
        !           326: #endif /* IBMPC */
        !           327: 
        !           328: #ifdef IBMPC
        !           329:        force = inversep? 1: 0;  /* to force a redraw of the modeline */
        !           330: #endif /* IBMPC */
        !           331: 
        !           332:        if (n <= 0)
        !           333:                return 1;
        !           334:        while ((c = *line++) != '\0') {
        !           335:                if (abortable && AbortCnt < 0) {
        !           336:                        AbortCnt = BufSize;
        !           337:                        if ((InputPending = charp()) != '\0') {
        !           338:                                aborted = 1;
        !           339:                                break;
        !           340:                        }
        !           341:                }
        !           342:                if (c == '\t') {
        !           343:                        int     nchars;
        !           344: 
        !           345:                        nchars = (tabstop - (col % tabstop));
        !           346:                        col += nchars;
        !           347: 
        !           348: #ifndef IBMPC
        !           349:                        thebyte = (' ' | or_byte);
        !           350: #endif /* IBMPC */
        !           351:                        while (nchars--)
        !           352: #ifndef IBMPC
        !           353:                                soutputc(thebyte);
        !           354: #else /* IBMPC */
        !           355:                                soutputc(' ');
        !           356: #endif /* IBMPC */
        !           357:                        if (n <= 0)
        !           358:                                break;
        !           359:                } else if (isctrl(c)) {
        !           360: #ifndef IBMPC
        !           361:                        thebyte = ('^' | or_byte);
        !           362:                        soutputc(thebyte);
        !           363:                        thebyte = (((c == '\177') ? '?' : c + '@') | or_byte);
        !           364:                        soutputc(thebyte);
        !           365: #else /* IBMPC */
        !           366:                        soutputc('^');
        !           367:                        c = ((c == '\177') ? '?' : c + '@');
        !           368:                        soutputc(c);
        !           369: #endif /* IBMPC */
        !           370:                        col += 2;
        !           371: #ifdef TERMCAP
        !           372:                } else if (HZ && c == '~') {
        !           373:                        thebyte = ('`' | or_byte);
        !           374:                        soutputc(thebyte);
        !           375:                        col += 1;
        !           376: #endif
        !           377:                } else {
        !           378: #ifndef IBMPC
        !           379:                        thebyte = (c | or_byte);
        !           380:                        soutputc(thebyte);
        !           381: #else /* IBMPC */
        !           382:                    if (c == 255) c = 1;
        !           383:                        if (c == ' ' && inversep) c = 255;
        !           384:                        soutputc(c);
        !           385: #endif /* IBMPC */
        !           386:                        col += 1;
        !           387:                }
        !           388:        }
        !           389:        if (n <= 0) {
        !           390:                if ((*line == '\0') && (c != '\t') && !isctrl(c))
        !           391: #ifndef IBMPC
        !           392:                        sputc(c|or_byte);
        !           393: #else /* IBMPC */
        !           394:                        sputc(c);
        !           395: #endif /* IBMPC */
        !           396:                else
        !           397: #ifndef IBMPC
        !           398:                        sputc('!'|or_byte);
        !           399: #else /* IBMPC */
        !           400:                        sputc('!');
        !           401: #endif /* IBMPC */
        !           402:        }
        !           403:        if (cursor > Curline->s_length)
        !           404:                Curline->s_length = cursor;
        !           405: #ifdef IBMPC
        !           406:        force = 0;
        !           407: #endif
        !           408:        return !aborted;
        !           409: }
        !           410: #endif /* MAC */
        !           411: 
        !           412: /* This is for writing a buffer line to the screen.  This is to
        !           413:    minimize the amount of copying from one buffer to another buffer.
        !           414:    This gets the info directly from the disk buffers. */
        !           415: 
        !           416: int
        !           417: BufSwrite(linenum)
        !           418: int linenum;
        !           419: {
        !           420:        register int    n = cursend - cursor,
        !           421:                        col = 0,
        !           422:                        c = -1;
        !           423:        register char   *bp;
        !           424:        int     StartCol = DesiredScreen[linenum].s_offset,
        !           425:                visspace = DesiredScreen[linenum].s_window->w_flags & W_VISSPACE,
        !           426:                aborted = 0;
        !           427: 
        !           428:        bp = lcontents(DesiredScreen[linenum].s_lp);
        !           429:        if (*bp) for (;;) {
        !           430:                if (col >= StartCol) {
        !           431:                        DesiredScreen[linenum].s_offset = col;
        !           432:                        break;
        !           433:                }
        !           434: 
        !           435:                c = *bp++ & CHARMASK;
        !           436:                if (c == '\0')
        !           437:                        break;
        !           438:                if (c == '\t')
        !           439:                        col += (tabstop - (col % tabstop));
        !           440:                else if (isctrl(c))
        !           441:                        col += 2;
        !           442:                else
        !           443:                        col += 1;
        !           444:        }
        !           445: #ifdef MAC
        !           446:        sputc(BUFSTART);        /* Okay because we can't be interrupted */
        !           447: #endif
        !           448: 
        !           449:        if (c != '\0') while ((c = *bp++) != '\0') {
        !           450:                if (AbortCnt < 0) {
        !           451:                        AbortCnt = BufSize;
        !           452:                        if ((InputPending = charp()) != '\0') {
        !           453:                                aborted = 1;
        !           454:                                break;
        !           455:                        }
        !           456:                }
        !           457:                if (c == '\t') {
        !           458:                        int     nchars = (tabstop - (col % tabstop));
        !           459: 
        !           460:                        col += nchars;
        !           461:                        if (visspace) {
        !           462:                                soutputc('>');
        !           463:                                nchars -= 1;
        !           464:                        }
        !           465:                        while (--nchars >= 0)
        !           466:                                soutputc(' ');
        !           467:                        if (n <= 0)
        !           468:                                break;
        !           469:                } else if (isctrl(c)) {
        !           470:                        soutputc('^');
        !           471:                        soutputc((c == '\177') ? '?' : c + '@');
        !           472:                        col += 2;
        !           473: #ifdef TERMCAP
        !           474:                } else if (HZ && c == '~') {
        !           475:                        soutputc('`');
        !           476:                        col += 1;
        !           477: #endif
        !           478:                } else {
        !           479:                        if (c == ' ' && visspace)
        !           480:                                c = '_';
        !           481: #ifdef IBMPC
        !           482:                        if (c == 255)
        !           483:                           c = 1;
        !           484: #endif /* IBMPC */
        !           485:                        soutputc(c);
        !           486:                        col += 1;
        !           487:                }
        !           488:        }
        !           489:        if (n <= 0) {
        !           490:                if ((*bp == '\0') && (c != '\t') && !isctrl(c))
        !           491:                        sputc(c);
        !           492:                else
        !           493:                        sputc('!');
        !           494:        }
        !           495:        if (cursor > Curline->s_length)
        !           496:                Curline->s_length = cursor;
        !           497: #ifdef MAC
        !           498:        sputc(BUFFLUSH);
        !           499: #endif
        !           500:        return !aborted;                /* Didn't abort */
        !           501: }
        !           502: 
        !           503: void
        !           504: i_set(nline, ncol)
        !           505: register int   nline,
        !           506:                ncol;
        !           507: {
        !           508:        Curline = &Screen[nline];
        !           509:        cursor = Curline->s_line + ncol;
        !           510:        cursend = &Curline->s_line[CO - 1];
        !           511:        i_line = nline;
        !           512:        i_col = ncol;
        !           513: }
        !           514: 
        !           515: #if !(defined(MAC) || defined(IBMPC))
        !           516: void
        !           517: SO_on()
        !           518: {
        !           519:        /* If there are magic cookies, then WHERE the SO string is
        !           520:           printed decides where the SO actually starts on the screen.
        !           521:           So it's important to make sure the cursor is positioned there
        !           522:           anyway.  I think this is right. */
        !           523:        if (SG != 0) {
        !           524:                Placur(i_line, i_col);
        !           525:                i_col += SG;
        !           526:                CapCol += SG;
        !           527:        }
        !           528:        putpad(SO, 1);
        !           529: }
        !           530: 
        !           531: void
        !           532: SO_off()
        !           533: {
        !           534:        /* see comment in SO_on() */
        !           535:        if (SG != 0) {
        !           536:                Placur(i_line, i_col);
        !           537:                i_col += SG;
        !           538:                CapCol += SG;
        !           539:        }
        !           540:        putpad(SE, 1);
        !           541: }
        !           542: #endif
        !           543: 
        !           544: /* Insert `num' lines a top, but leave all the lines BELOW `bottom'
        !           545:    alone (at least they won't look any different when we are done).
        !           546:    This changes the screen array AND does the physical changes. */
        !           547: 
        !           548: void
        !           549: v_ins_line(num, top, bottom)
        !           550: int num,
        !           551:     top,
        !           552:     bottom;
        !           553: {
        !           554:        register int    i;
        !           555: 
        !           556:        /* Save the screen pointers. */
        !           557: 
        !           558:        for(i = 0; i < num && top + i <= bottom; i++)
        !           559:                Savelines[i] = Screen[bottom - i];
        !           560: 
        !           561:        /* Num number of bottom lines will be lost.
        !           562:           Copy everything down num number of times. */
        !           563: 
        !           564:        for (i = bottom; i > top && i-num >= 0; i--)
        !           565:                Screen[i] = Screen[i - num];
        !           566: 
        !           567:        /* Restore the saved ones, making them blank. */
        !           568: 
        !           569:        for (i = 0; i < num; i++) {
        !           570:                Screen[top + i] = Savelines[i];
        !           571:                clrline(Screen[top + i].s_line, Screen[top + i].s_length);
        !           572:                Screen[top + i].s_length = Screen[top + i].s_line;
        !           573:        }
        !           574: 
        !           575: #if !(defined(IBMPC) || defined(MAC))
        !           576:        (*TTins_line)(top, bottom, num);
        !           577: #endif
        !           578: 
        !           579: #ifdef MAC
        !           580:        i_lines(top, bottom, num);
        !           581: #endif
        !           582: 
        !           583: #ifdef IBMPC
        !           584:        scr_win((int) -num, (unsigned char) top, 0, (unsigned char) bottom, CHPL-1);
        !           585: #endif
        !           586: }
        !           587: 
        !           588: /* Delete `num' lines starting at `top' leaving the lines below `bottom'
        !           589:    alone.  This updates the internal image as well as the physical image.  */
        !           590: 
        !           591: void
        !           592: v_del_line(num, top, bottom)
        !           593: int num,
        !           594:     top,
        !           595:     bottom;
        !           596: {
        !           597:        register int    i,
        !           598:                        bot;
        !           599: 
        !           600:        bot = bottom;
        !           601: 
        !           602:        /* Save the lost lines. */
        !           603: 
        !           604:        for (i = 0; i < num && top + i <= bottom; i++)
        !           605:                Savelines[i] = Screen[top + i];
        !           606: 
        !           607:        /* Copy everything up num number of lines. */
        !           608: 
        !           609:        for (i = top; num + i <= bottom; i++)
        !           610:                Screen[i] = Screen[i + num];
        !           611: 
        !           612:        /* Restore the lost ones, clearing them. */
        !           613: 
        !           614:        for (i = 0; i < num; i++) {
        !           615:                Screen[bottom - i] = Savelines[i];
        !           616:                clrline(Screen[bot].s_line, Screen[bot].s_length);
        !           617:                Screen[bot].s_length = Screen[bot].s_line;
        !           618:                bot -= 1;
        !           619:        }
        !           620: 
        !           621: #if !(defined(IBMPC) || defined(MAC))
        !           622:        (*TTdel_line)(top, bottom, num);
        !           623: #endif
        !           624: 
        !           625: #ifdef MAC
        !           626:        d_lines(top, bottom, num);
        !           627: #endif
        !           628: 
        !           629: #ifdef IBMPC
        !           630:        scr_win(num, (unsigned char) top, 0, (unsigned char) bottom, CHPL-1);
        !           631: #endif
        !           632: 
        !           633: }
        !           634: 
        !           635: #if !(defined(MAC) || defined(IBMPC))  /* remainder of this file */
        !           636: 
        !           637: /* The cursor optimization happens here.  You may decide that this
        !           638:    is going too far with cursor optimization, or perhaps it should
        !           639:    limit the amount of checking to when the output speed is slow.
        !           640:    What ever turns you on ...   */
        !           641: 
        !           642: struct cursaddr {
        !           643:        int     cm_numchars;
        !           644:        void    (*cm_proc) ();
        !           645: };
        !           646: 
        !           647: private char   *Cmstr;
        !           648: private struct cursaddr        *HorMin,
        !           649:                        *VertMin,
        !           650:                        *DirectMin;
        !           651: 
        !           652: private void
        !           653:        GENi_lines proto((int, int, int)),
        !           654:        GENd_lines proto((int, int, int)),
        !           655:        ForMotion proto((int)),
        !           656:        ForTab proto((int)),
        !           657:        BackMotion proto((int)),
        !           658:        RetTab proto((int)),
        !           659:        DownMotion proto((int)),
        !           660:        UpMotion proto((int)),
        !           661:        GoDirect proto((int, int)),
        !           662:        HomeGo proto((int, int)),
        !           663:        BottomUp proto((int, int));
        !           664: 
        !           665: 
        !           666: private struct cursaddr        WarpHor[] = {
        !           667:        0,      ForMotion,
        !           668:        0,      ForTab,
        !           669:        0,      BackMotion,
        !           670:        0,      RetTab
        !           671: };
        !           672: 
        !           673: private struct cursaddr        WarpVert[] = {
        !           674:        0,      DownMotion,
        !           675:        0,      UpMotion
        !           676: };
        !           677: 
        !           678: private struct cursaddr        WarpDirect[] = {
        !           679:        0,      GoDirect,
        !           680:        0,      HomeGo,
        !           681:        0,      BottomUp
        !           682: };
        !           683: 
        !           684: #undef FORWARD
        !           685: #define        FORWARD         0       /* Move forward */
        !           686: #define FORTAB         1       /* Forward using tabs */
        !           687: #undef BACKWARD
        !           688: #define        BACKWARD        2       /* Move backward */
        !           689: #define RETFORWARD     3       /* Beginning of line and then tabs */
        !           690: #define NUMHOR         4
        !           691: 
        !           692: #define DOWN           0       /* Move down */
        !           693: #define UPMOVE         1       /* Move up */
        !           694: #define NUMVERT                2
        !           695: 
        !           696: #define DIRECT         0       /* Using CM */
        !           697: #define HOME           1       /* HOME */
        !           698: #define LOWER          2       /* Lower Line */
        !           699: #define NUMDIRECT      3
        !           700: 
        !           701: #define        home()          Placur(0, 0)
        !           702: #define LowLine()      { putpad(LL, 1); CapLine = ILI; CapCol = 0; }
        !           703: #define PrintHo()      { putpad(HO, 1); CapLine = CapCol = 0; }
        !           704: 
        !           705: int    phystab = 8;
        !           706: 
        !           707: private void
        !           708: GoDirect(line, col)
        !           709: register int   line,
        !           710:                col;
        !           711: {
        !           712:        putpad(Cmstr, 1);
        !           713:        CapLine = line;
        !           714:        CapCol = col;
        !           715: }
        !           716: 
        !           717: private void
        !           718: RetTab(col)
        !           719: register int   col;
        !           720: {
        !           721:        jputchar('\r');
        !           722:        CapCol = 0;
        !           723:        ForTab(col);
        !           724: }
        !           725: 
        !           726: private void
        !           727: HomeGo(line, col)
        !           728: int line,
        !           729:     col;
        !           730: {
        !           731:        PrintHo();
        !           732:        DownMotion(line);
        !           733:        ForTab(col);
        !           734: }
        !           735: 
        !           736: private void
        !           737: BottomUp(line, col)
        !           738: register int   line,
        !           739:                col;
        !           740: {
        !           741:        LowLine();
        !           742:        UpMotion(line);
        !           743:        ForTab(col);
        !           744: }
        !           745: 
        !           746: /* Tries to move forward using tabs (if possible).  It tabs to the
        !           747:    closest tabstop which means it may go past 'destcol' and backspace
        !           748:    to it. */
        !           749: 
        !           750: private void
        !           751: ForTab(destcol)
        !           752: int    destcol;
        !           753: {
        !           754:        register int    tabgoal,
        !           755:                        ntabs,
        !           756:                        tabstp = phystab;
        !           757: 
        !           758:        if (TABS && (tabstp > 0)) {
        !           759:                tabgoal = destcol + (tabstp / 2);
        !           760:                tabgoal -= (tabgoal % tabstp);
        !           761: 
        !           762:                /* Don't tab to last place or else it is likely to screw up. */
        !           763:                if (tabgoal >= CO)
        !           764:                        tabgoal -= tabstp;
        !           765: 
        !           766:                ntabs = (tabgoal / tabstp) - (CapCol / tabstp);
        !           767:                while (--ntabs >= 0)
        !           768:                        jputchar('\t');
        !           769:                CapCol = tabgoal;
        !           770:        }
        !           771:        if (CapCol > destcol)
        !           772:                BackMotion(destcol);
        !           773:        else if (CapCol < destcol)
        !           774:                ForMotion(destcol);
        !           775: }
        !           776: 
        !           777: private void
        !           778: ForMotion(destcol)
        !           779: register int   destcol;
        !           780: {
        !           781:        register int    nchars = destcol - CapCol;
        !           782:        register char   *cp = &Screen[CapLine].s_line[CapCol];
        !           783: 
        !           784:        while (--nchars >= 0)
        !           785:                jputchar(*cp++ & CHARMASK);
        !           786:        CapCol = destcol;
        !           787: }
        !           788: 
        !           789: private void
        !           790: BackMotion(destcol)
        !           791: register int   destcol;
        !           792: {
        !           793:        register int    nchars = CapCol - destcol;
        !           794: 
        !           795:        if (BC)
        !           796:                while (--nchars >= 0)
        !           797:                        putpad(BC, 1);
        !           798:        else
        !           799:                while (--nchars >= 0)
        !           800:                        jputchar('\b');
        !           801:        CapCol = destcol;
        !           802: }
        !           803: 
        !           804: private void
        !           805: DownMotion(destline)
        !           806: register int   destline;
        !           807: {
        !           808:        register int    nlines = destline - CapLine;
        !           809: 
        !           810:        while (--nlines >= 0)
        !           811:                putpad(DO, 1);
        !           812:        CapLine = destline;
        !           813: }
        !           814: 
        !           815: private void
        !           816: UpMotion(destline)
        !           817: register int   destline;
        !           818: {
        !           819:        register int    nchars = CapLine - destline;
        !           820: 
        !           821:        while (--nchars >= 0)
        !           822:                putpad(UP, 1);
        !           823:        CapLine = destline;
        !           824: }
        !           825: 
        !           826: #ifdef ID_CHAR
        !           827: static int     EIlen;
        !           828: #endif
        !           829: 
        !           830: #ifndef IBMPC
        !           831: 
        !           832: void
        !           833: InitCM()
        !           834: {
        !           835:        HOlen = HO ? strlen(HO) : 1000;
        !           836:        LLlen = LL ? strlen(LL) : 1000;
        !           837:        UPlen = UP ? strlen(UP) : 1000;
        !           838: #ifdef ID_CHAR
        !           839:        if (EI)
        !           840:                EIlen = strlen(EI);
        !           841: #endif
        !           842: }
        !           843: 
        !           844: private int ForNum proto((int from, int to));
        !           845: 
        !           846: void
        !           847: Placur(line, col)
        !           848: int line,
        !           849:     col;
        !           850: {
        !           851:        int     dline,          /* Number of lines to move */
        !           852:                dcol;           /* Number of columns to move */
        !           853:        register int    best,
        !           854:                        i;
        !           855:        register struct cursaddr        *cp;
        !           856:        int     xtracost = 0;   /* Misc addition to cost. */
        !           857: 
        !           858: #define CursMin(which,addrs,max)       { \
        !           859:        for (best = 0, cp = &(addrs)[1], i = 1; i < (max); i++, cp++) \
        !           860:                if (cp->cm_numchars < (addrs)[best].cm_numchars) \
        !           861:                        best = i; \
        !           862:        (which) = &(addrs)[best]; \
        !           863: }
        !           864: 
        !           865:        if (line == CapLine && col == CapCol)
        !           866:                return;         /* We are already there. */
        !           867: 
        !           868:        dline = line - CapLine;
        !           869:        dcol = col - CapCol;
        !           870: #ifdef ID_CHAR
        !           871:        if (IN_INSmode && MI)
        !           872:                xtracost = EIlen + IMlen;
        !           873:        /* If we're already in insert mode, it is likely that we will
        !           874:           want to be in insert mode again, after the insert. */
        !           875: #endif
        !           876: 
        !           877:        /* Number of characters to move horizontally for each case.
        !           878:           1: Just move forward by typing the right character on the screen.
        !           879:           2: Print the correct number of back spaces.
        !           880:           3: Try tabbing to the correct place.
        !           881:           4: Try going to the beginning of the line, and then tab. */
        !           882: 
        !           883:        if (dcol == 1 || dcol == 0) {           /* Most common case. */
        !           884:                HorMin = &WarpHor[FORWARD];
        !           885:                HorMin->cm_numchars = dcol + xtracost;
        !           886:        } else {
        !           887:                WarpHor[FORWARD].cm_numchars = dcol >= 0 ? dcol + xtracost : 1000;
        !           888:                WarpHor[BACKWARD].cm_numchars = dcol < 0 ? -(dcol + xtracost) : 1000;
        !           889:                WarpHor[FORTAB].cm_numchars = dcol >= 0 && TABS ?
        !           890:                                ForNum(CapCol, col) + xtracost : 1000;
        !           891:                WarpHor[RETFORWARD].cm_numchars = (xtracost + 1 + (TABS ? ForNum(0, col) : col));
        !           892: 
        !           893:                /* Which is the shortest of the bunch */
        !           894: 
        !           895:                CursMin(HorMin, WarpHor, NUMHOR);
        !           896:        }
        !           897: 
        !           898:        /* Moving vertically is more simple. */
        !           899: 
        !           900:        WarpVert[DOWN].cm_numchars = dline >= 0 ? dline : 1000;
        !           901:        WarpVert[UPMOVE].cm_numchars = dline < 0 ? ((-dline) * UPlen) : 1000;
        !           902: 
        !           903:        /* Which of these is simpler */
        !           904:        CursMin(VertMin, WarpVert, NUMVERT);
        !           905: 
        !           906:        /* Homing first and lowering first are considered
        !           907:           direct motions.
        !           908:           Homing first's total is the sum of the cost of homing
        !           909:           and the sum of tabbing (if possible) to the right. */
        !           910: 
        !           911:        if (VertMin->cm_numchars + HorMin->cm_numchars <= 3) {
        !           912:                DirectMin = &WarpDirect[DIRECT];        /* A dummy ... */
        !           913:                DirectMin->cm_numchars = 100;
        !           914:        } else {
        !           915:                WarpDirect[DIRECT].cm_numchars = CM ?
        !           916:                                strlen(Cmstr = tgoto(CM, col, line)) : 1000;
        !           917:                WarpDirect[HOME].cm_numchars = HOlen + line +
        !           918:                                WarpHor[RETFORWARD].cm_numchars;
        !           919:                WarpDirect[LOWER].cm_numchars = LLlen + ((ILI - line) * UPlen) +
        !           920:                                WarpHor[RETFORWARD].cm_numchars;
        !           921:                CursMin(DirectMin, WarpDirect, NUMDIRECT);
        !           922:        }
        !           923: 
        !           924:        if (HorMin->cm_numchars + VertMin->cm_numchars < DirectMin->cm_numchars) {
        !           925:                if (line != CapLine)
        !           926:                        (*VertMin->cm_proc)(line);
        !           927:                if (col != CapCol) {
        !           928: #ifdef ID_CHAR
        !           929:                        if (IN_INSmode) /* We may use real characters ... */
        !           930:                                INSmode(0);
        !           931: #endif
        !           932:                        (*HorMin->cm_proc)(col);
        !           933:                }
        !           934:        } else {
        !           935: #ifdef ID_CHAR
        !           936:                if (IN_INSmode && !MI)
        !           937:                        INSmode(0);
        !           938: #endif
        !           939:                (*DirectMin->cm_proc)(line, col);
        !           940:        }
        !           941: }
        !           942: 
        !           943: #endif /* IBMPC */
        !           944: 
        !           945: #define abs(x) ((x) >= 0 ? (x) : -(x))
        !           946: 
        !           947: private int
        !           948: ForNum(from, to)
        !           949: register int   from;
        !           950: int to;
        !           951: {
        !           952:        register int    tabgoal,
        !           953:                        tabstp = phystab;
        !           954:        int             numchars = 0;
        !           955: 
        !           956:        if (from >= to)
        !           957:                return from - to;
        !           958:        if (TABS && (tabstp > 0)) {
        !           959:                tabgoal = to + (tabstp / 2);
        !           960:                tabgoal -= (tabgoal % tabstp);
        !           961:                if (tabgoal >= CO)
        !           962:                        tabgoal -= tabstp;
        !           963:                numchars = (tabgoal / tabstop) - (from / tabstp);
        !           964:                from = tabgoal;
        !           965:        }
        !           966:        return numchars + abs(from - to);
        !           967: }
        !           968: 
        !           969: #ifdef WIRED_TERMS
        !           970: 
        !           971: private void
        !           972: BGi_lines(top, bottom, num)
        !           973: int top,
        !           974:     bottom,
        !           975:     num;
        !           976: {
        !           977:        writef("\033[%d;%dr\033[%dL\033[r", top + 1, bottom + 1, num);
        !           978:        CapCol = CapLine = 0;
        !           979: }
        !           980: 
        !           981: private void
        !           982: SUNi_lines(top, bottom, num)
        !           983: int top,
        !           984:     bottom,
        !           985:     num;
        !           986: {
        !           987:        Placur(bottom - num + 1, 0);
        !           988:        writef("\033[%dM", num);
        !           989:        Placur(top, 0);
        !           990:        writef("\033[%dL", num);
        !           991: }
        !           992: 
        !           993: private void
        !           994: C100i_lines(top, bottom, num)
        !           995: int top,
        !           996:     bottom,
        !           997:     num;
        !           998: {
        !           999:        if (num <= 1) {
        !          1000:                GENi_lines(top, bottom, num);
        !          1001:                return;
        !          1002:        }
        !          1003:        writef("\033v%c%c%c%c", ' ', ' ', ' ' + bottom + 1, ' ' + CO);
        !          1004:        CapLine = CapCol = 0;
        !          1005:        Placur(top, 0);
        !          1006:        while (num--)
        !          1007:                putpad(AL, ILI - CapLine);
        !          1008:        writef("\033v%c%c%c%c", ' ', ' ', ' ' + LI, ' ' + CO);
        !          1009:        CapLine = CapCol = 0;
        !          1010: }
        !          1011: 
        !          1012: #endif /* WIRED_TERMS */
        !          1013: 
        !          1014: private void
        !          1015: GENi_lines(top, bottom, num)
        !          1016: int top,
        !          1017:     bottom,
        !          1018:     num;
        !          1019: {
        !          1020:        register int    i;
        !          1021: 
        !          1022:        if (CS) {
        !          1023:                putpad(tgoto(CS, bottom, top), 1);
        !          1024:                CapCol = CapLine = 0;
        !          1025:                Placur(top, 0);
        !          1026:                for (i = 0; i < num; i++)
        !          1027:                        putpad(SR, bottom - top);
        !          1028:                putpad(tgoto(CS, ILI, 0), 1);
        !          1029:                CapCol = CapLine = 0;
        !          1030:        } else {
        !          1031:                Placur(bottom - num + 1, 0);
        !          1032:                if (M_DL && (num > 1)) {
        !          1033:                        putargpad(M_DL, num, ILI - CapLine);
        !          1034:                } else {
        !          1035:                        for (i = 0; i < num; i++)
        !          1036:                                putpad(DL, ILI - CapLine);
        !          1037:                }
        !          1038:                Placur(top, 0);
        !          1039:                if (M_AL && (num > 1)) {
        !          1040:                        putargpad(M_AL, num, ILI - CapLine);
        !          1041:                } else {
        !          1042:                        for (i = 0; i < num; i++)
        !          1043:                                putpad(AL, ILI - CapLine);
        !          1044:                }
        !          1045:        }
        !          1046: }
        !          1047: 
        !          1048: #ifdef WIRED_TERMS
        !          1049: 
        !          1050: private void
        !          1051: BGd_lines(top, bottom, num)
        !          1052: int top,
        !          1053:     bottom,
        !          1054:     num;
        !          1055: {
        !          1056:        writef("\033[%d;%dr\033[%dM\033[r", top + 1, bottom + 1, num);
        !          1057:        CapCol = CapLine = 0;
        !          1058: }
        !          1059: 
        !          1060: private void
        !          1061: SUNd_lines(top, bottom, num)
        !          1062: int top,
        !          1063:     bottom,
        !          1064:     num;
        !          1065: {
        !          1066:        Placur(top, 0);
        !          1067:        writef("\033[%dM", num);
        !          1068:        Placur(bottom + 1 - num, 0);
        !          1069:        writef("\033[%dL", num);
        !          1070: }
        !          1071: 
        !          1072: private void
        !          1073: C100d_lines(top, bottom, num)
        !          1074: int top,
        !          1075:     bottom,
        !          1076:     num;
        !          1077: {
        !          1078:        if (num <= 1) {
        !          1079:                GENd_lines(top, bottom, num);
        !          1080:                return;
        !          1081:        }
        !          1082:        writef("\033v%c%c%c%c", ' ', ' ', ' ' + bottom + 1, ' ' + CO);
        !          1083:        CapLine = CapCol = 0;
        !          1084:        Placur(top, 0);
        !          1085:        while (num--)
        !          1086:                putpad(DL, ILI - CapLine);
        !          1087:        writef("\033v%c%c%c%c", ' ', ' ', ' ' + LI, ' ' + CO);
        !          1088:        CapLine = CapCol = 0;
        !          1089: }
        !          1090: 
        !          1091: #endif /* WIRED_TERMS */
        !          1092: 
        !          1093: private void
        !          1094: GENd_lines(top, bottom, num)
        !          1095: int top,
        !          1096:     bottom,
        !          1097:     num;
        !          1098: {
        !          1099:        register int    i;
        !          1100: 
        !          1101:        if (CS) {
        !          1102:                putpad(tgoto(CS, bottom, top), 1);
        !          1103:                CapCol = CapLine = 0;
        !          1104:                Placur(bottom, 0);
        !          1105:                for (i = 0; i < num; i++)
        !          1106:                        putpad(SF, bottom - top);
        !          1107:                putpad(tgoto(CS, ILI, 0), 1);
        !          1108:                CapCol = CapLine = 0;
        !          1109:        } else {
        !          1110:                Placur(top, 0);
        !          1111:                if (M_DL && (num > 1)) {
        !          1112:                        putargpad(M_DL, num, ILI - top);
        !          1113:                } else {
        !          1114:                        for (i = 0; i < num; i++)
        !          1115:                                putpad(DL, ILI - top);
        !          1116:                }
        !          1117:                Placur(bottom + 1 - num, 0);
        !          1118:                if (M_AL && (num > 1)) {
        !          1119:                        putargpad(M_AL, num, ILI - CapLine);
        !          1120:                } else {
        !          1121:                        for (i = 0; i < num; i++)
        !          1122:                                putpad(AL, ILI - CapLine);
        !          1123:                }
        !          1124:        }
        !          1125: }
        !          1126: 
        !          1127: private const struct ID_lookup {
        !          1128:        char    *ID_name;
        !          1129:        void    (*I_proc) proto((int, int, int));       /* proc to insert lines */
        !          1130:        void    (*D_proc) proto((int, int, int));       /* proc to delete lines */
        !          1131: } ID_trms[] = {
        !          1132:        "generic",      GENi_lines,     GENd_lines,     /* This should stay here */
        !          1133: #ifdef WIRED_TERMS
        !          1134:        "sun",          SUNi_lines,     SUNd_lines,
        !          1135:        "bg",           BGi_lines,      BGd_lines,
        !          1136:        "c1",           C100i_lines,    C100d_lines,
        !          1137: #endif /* WIRED_TERMS */
        !          1138:        0,              0,              0
        !          1139: };
        !          1140: 
        !          1141: void
        !          1142: IDline_setup(tname)
        !          1143: char   *tname;
        !          1144: {
        !          1145:        register const struct ID_lookup *idp;
        !          1146: 
        !          1147:        for (idp = &ID_trms[1]; idp->ID_name; idp++)
        !          1148:                if (strncmp(idp->ID_name, tname, strlen(idp->ID_name)) == 0)
        !          1149:                        break;
        !          1150:        if (idp->ID_name == 0)
        !          1151:                idp = &ID_trms[0];
        !          1152: #ifndef IBMPC
        !          1153:        TTins_line = idp->I_proc;
        !          1154:        TTdel_line = idp->D_proc;
        !          1155: #endif
        !          1156: }
        !          1157: 
        !          1158: #endif /* MAC */

unix.superglobalmegacorp.com

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