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

1.1     ! root        1: /*************************************************************************
        !             2:  * This program is copyright (C) 1985, 1986 by Jonathan Payne.  It is    *
        !             3:  * provided to you without charge for use only on a licensed Unix        *
        !             4:  * system.  You may copy JOVE provided that this notice is included with *
        !             5:  * the copy.  You may not sell copies of this program or versions        *
        !             6:  * modified for use on microcomputer systems, unless the copies are      *
        !             7:  * included with a Unix system distribution and the source is provided.  *
        !             8:  *************************************************************************/
        !             9: 
        !            10: #include "jove.h"
        !            11: #include "io.h"
        !            12: #include "ctype.h"
        !            13: #include "temp.h"
        !            14: #include "termcap.h"
        !            15: 
        !            16: extern int     BufSize;
        !            17: 
        !            18: int    OkayAbort,
        !            19:        tabstop = 8;
        !            20: 
        !            21: int    (*TTins_line)(),
        !            22:        (*TTdel_line)();
        !            23: 
        !            24: struct scrimage
        !            25:        *DesiredScreen = 0,
        !            26:        *PhysScreen = 0;
        !            27: 
        !            28: struct screenline      *Screen = 0,    /* the screen (a bunch of screenline) */
        !            29:                        *Savelines = 0, /* another bunch (LI of them) */
        !            30:                        *Curline = 0;   /* current line */
        !            31: char   *cursor,                        /* offset into current Line */
        !            32:        *cursend;
        !            33: 
        !            34: int    CapCol,
        !            35:        CapLine,
        !            36: 
        !            37:        i_line,
        !            38:        i_col;
        !            39: 
        !            40: make_scr()
        !            41: {
        !            42:        register int    i;
        !            43:        register struct screenline      *ns;
        !            44:        register char   *nsp;
        !            45: 
        !            46: #ifdef RESHAPING
        !            47:        /* In case we are RESHAPING the window! */
        !            48:        if (DesiredScreen)
        !            49:                free((char *) DesiredScreen);
        !            50:        if (PhysScreen)
        !            51:                free((char *) PhysScreen);
        !            52:        if (Savelines)
        !            53:                free((char *) Savelines);
        !            54:        if (Screen) {
        !            55:                ns = Screen;
        !            56:                for (i = 0; i < LI; i++)
        !            57:                        free((ns++)->s_line);
        !            58:                free((char *) Screen);
        !            59:        }
        !            60: #endif RESHAPING
        !            61: 
        !            62:        DesiredScreen = (struct scrimage *) malloc((unsigned) LI * sizeof (struct scrimage));
        !            63:        PhysScreen = (struct scrimage *) malloc((unsigned) LI * sizeof (struct scrimage));
        !            64: 
        !            65:        Savelines = (struct screenline *)
        !            66:                        malloc((unsigned) LI * sizeof(struct screenline));
        !            67:        ns = Screen = (struct screenline *)
        !            68:                        malloc((unsigned) LI * sizeof(struct screenline));
        !            69: 
        !            70:        nsp = (char *) malloc((unsigned)CO * LI);
        !            71:        if (nsp == 0) {
        !            72:                printf("\n\rCannot malloc screen!\n");
        !            73:                finish(1);
        !            74:        }
        !            75: 
        !            76:        for (i = 0; i < LI; i++) {
        !            77:                ns->s_line = nsp;
        !            78:                nsp += CO;
        !            79:                ns->s_length = nsp - 1;         /* End of Line */
        !            80:                ns++;
        !            81:        }
        !            82:        cl_scr(0);
        !            83: }
        !            84: 
        !            85: clrline(cp1, cp2)
        !            86: register char  *cp1,
        !            87:                *cp2;
        !            88: {
        !            89:        while (cp1 <= cp2)
        !            90:                *cp1++ = ' ';
        !            91: }
        !            92: 
        !            93: #define sputc(c)       ((*cursor != (char) (c)) ? dosputc(c) : (cursor++, i_col++))
        !            94: #define soutputc(c)    if (--n <= 0) break; else sputc(c)
        !            95: 
        !            96: cl_eol()
        !            97: {
        !            98:        if (cursor > cursend)
        !            99:                return;
        !           100: 
        !           101:        if (cursor < Curline->s_length) {
        !           102:                if (CE) {
        !           103:                        Placur(i_line, i_col);
        !           104:                        putpad(CE, 1);
        !           105:                        clrline(cursor, Curline->s_length);
        !           106:                } else {
        !           107:                /* Ugh.  The slow way for dumb terminals. */
        !           108:                        register char *savecp = cursor;
        !           109: 
        !           110:                        while (cursor <= Curline->s_length)
        !           111:                                sputc(' ');
        !           112:                        cursor = savecp;
        !           113:                }
        !           114:                Curline->s_length = cursor;
        !           115:        }
        !           116: }
        !           117: 
        !           118: cl_scr(doit)
        !           119: {
        !           120:        register int    i;
        !           121:        register struct screenline      *sp = Screen;
        !           122: 
        !           123:        for (i = 0; i < LI; i++, sp++) {
        !           124:                clrline(sp->s_line, sp->s_length);
        !           125:                sp->s_length = sp->s_line;
        !           126:                PhysScreen[i].s_id = 0;
        !           127:        }
        !           128:        if (doit) {
        !           129:                putpad(CL, LI);
        !           130:                CapCol = CapLine = 0;
        !           131:                UpdMesg++;
        !           132:        }
        !           133: }
        !           134: 
        !           135: #ifdef ID_CHAR
        !           136: extern int     IN_INSmode;
        !           137: #endif
        !           138: 
        !           139: /* Output one character (if necessary) at the current position */
        !           140: 
        !           141: dosputc(c)
        !           142: register char  c;
        !           143: {
        !           144:        if (*cursor != c) {
        !           145: #ifdef ID_CHAR
        !           146:                if (IN_INSmode)
        !           147:                        INSmode(0);
        !           148: #endif
        !           149:                if (i_line != CapLine || i_col != CapCol)
        !           150:                        Placur(i_line, i_col);
        !           151:                if (UL && (c & 0177) == '_' && (*cursor & 0177) != ' ')
        !           152:                        putstr(" \b");          /* Erase so '_' looks right. */
        !           153:                *cursor++ = c;
        !           154:                putchar(c & 0177);
        !           155:                CapCol++;
        !           156:                i_col++;
        !           157:        } else {
        !           158:                cursor++;
        !           159:                i_col++;
        !           160:        }
        !           161: }
        !           162: 
        !           163: /* Write `line' at the current position of `cursor'.  Stop when we
        !           164:    reach the end of the screen.  Aborts if there is a character
        !           165:    waiting.  */
        !           166: 
        !           167: swrite(line, inversep, abortable)
        !           168: register char  *line;
        !           169: register int   abortable;
        !           170: {
        !           171:        register int    c;
        !           172:        int     col = i_col,
        !           173:                aborted = 0;
        !           174:        register int    n = cursend - cursor;
        !           175:        int     or_byte = inversep ? 0200 : 0,
        !           176:                thebyte;
        !           177: 
        !           178:        if (n <= 0)
        !           179:                return 1;
        !           180: 
        !           181:        OkayAbort = 0;
        !           182:        while (c = *line++) {
        !           183:                if (abortable && OkayAbort) {
        !           184:                        OkayAbort = NO;
        !           185:                        if (InputPending = charp()) {
        !           186:                                aborted = 1;
        !           187:                                break;
        !           188:                        }
        !           189:                }
        !           190:                if (c == '\t') {
        !           191:                        int     nchars;
        !           192: 
        !           193:                        nchars = (tabstop - (col % tabstop));
        !           194:                        col += nchars;
        !           195: 
        !           196:                        thebyte = (' ' | or_byte);
        !           197:                        while (nchars--)
        !           198:                                soutputc(thebyte);
        !           199:                        if (n <= 0)
        !           200:                                break;
        !           201:                } else if (isctrl(c)) {
        !           202:                        thebyte = ('^' | or_byte);
        !           203:                        soutputc(thebyte);
        !           204:                        thebyte = (((c == '\177') ? '?' : c + '@') | or_byte);
        !           205:                        soutputc(thebyte);
        !           206:                        col += 2;
        !           207:                } else {
        !           208:                        thebyte = (c | or_byte);
        !           209:                        soutputc(thebyte);
        !           210:                        col++;
        !           211:                }
        !           212:        }
        !           213:        if (n <= 0) {
        !           214:                thebyte = ('!' | or_byte);
        !           215:                sputc(thebyte);
        !           216:        }
        !           217:        if (cursor > Curline->s_length)
        !           218:                Curline->s_length = cursor;
        !           219:        return !aborted;
        !           220: }
        !           221: 
        !           222: /* This is for writing a buffer line to the screen.  This is to
        !           223:    minimize the amount of copying from one buffer to another buffer.
        !           224:    This gets the info directly from the disk buffers. */
        !           225: 
        !           226: BufSwrite(linenum)
        !           227: {
        !           228:        char    *bp;
        !           229:        register int    n = cursend - cursor,
        !           230:                        col = 0,
        !           231:                        c;
        !           232:        int     StartCol = DesiredScreen[linenum].s_offset,
        !           233:                visspace = DesiredScreen[linenum].s_window->w_visspace,
        !           234:                aborted = 0;
        !           235: 
        !           236:        bp = lcontents(DesiredScreen[linenum].s_lp);
        !           237:        if (*bp) for (;;) {
        !           238:                if (col >= StartCol) {
        !           239:                        DesiredScreen[linenum].s_offset = col;
        !           240:                        break;
        !           241:                }
        !           242: 
        !           243:                c = *bp++ & 0177;
        !           244:                if (c == '\t')
        !           245:                        col += (tabstop - (col % tabstop));
        !           246:                else if (isctrl(c))
        !           247:                        col += 2;
        !           248:                else
        !           249:                        col++;
        !           250:        }
        !           251: 
        !           252:        OkayAbort = 0;
        !           253:        while (c = (*bp++ & 0177)) {
        !           254:                if (OkayAbort) {
        !           255:                        OkayAbort = NO;
        !           256:                        if (InputPending = charp()) {
        !           257:                                aborted = 1;
        !           258:                                break;
        !           259:                        }
        !           260:                }
        !           261:                if (c == '\t') {
        !           262:                        int     nchars = (tabstop - (col % tabstop));
        !           263: 
        !           264:                        col += nchars;
        !           265:                        if (visspace) {
        !           266:                                soutputc('>');
        !           267:                                nchars--;
        !           268:                        }
        !           269:                        while (--nchars >= 0)
        !           270:                                soutputc(' ');
        !           271:                        if (n <= 0)
        !           272:                                break;
        !           273:                } else if (isctrl(c)) {
        !           274:                        soutputc('^');
        !           275:                        soutputc((c == '\177') ? '?' : c + '@');
        !           276:                        col += 2;
        !           277:                } else {
        !           278:                        if (visspace && c == ' ')
        !           279:                                c = '_';
        !           280:                        soutputc(c);
        !           281:                        col++;
        !           282:                }
        !           283:        }
        !           284:        if (n <= 0)
        !           285:                sputc('!');
        !           286:        if (cursor > Curline->s_length)
        !           287:                Curline->s_length = cursor;
        !           288:        return !aborted;                /* Didn't abort */
        !           289: }
        !           290: 
        !           291: i_set(nline, ncol)
        !           292: register int   nline,
        !           293:                ncol;
        !           294: {
        !           295:        Curline = &Screen[nline];
        !           296:        cursor = Curline->s_line + ncol;
        !           297:        cursend = &Curline->s_line[CO - 1];
        !           298:        i_line = nline;
        !           299:        i_col = ncol;
        !           300: }
        !           301: 
        !           302: /* Insert `num' lines a top, but leave all the lines BELOW `bottom'
        !           303:    alone (at least they won't look any different when we are done).
        !           304:    This changes the screen array AND does the physical changes. */
        !           305: 
        !           306: v_ins_line(num, top, bottom)
        !           307: {
        !           308:        register int    i;
        !           309: 
        !           310:        /* Save the screen pointers. */
        !           311: 
        !           312:        for(i = 0; i < num && top + i <= bottom; i++)
        !           313:                Savelines[i] = Screen[bottom - i];
        !           314: 
        !           315:        /* Num number of bottom lines will be lost.
        !           316:           Copy everything down num number of times. */
        !           317: 
        !           318:        for (i = bottom; i > top && i-num >= 0; i--)
        !           319:                Screen[i] = Screen[i - num];
        !           320: 
        !           321:        /* Restore the saved ones, making them blank. */
        !           322: 
        !           323:        for (i = 0; i < num; i++) {
        !           324:                Screen[top + i] = Savelines[i];
        !           325:                clrline(Screen[top + i].s_line, Screen[top + i].s_length);
        !           326:                Screen[top + i].s_length = Screen[top + i].s_line;
        !           327:        }
        !           328: 
        !           329:        (*TTins_line)(top, bottom, num);
        !           330: }
        !           331: 
        !           332: /* Delete `num' lines starting at `top' leaving the lines below `bottom'
        !           333:    alone.  This updates the internal image as well as the physical image.  */
        !           334: 
        !           335: v_del_line(num, top, bottom)
        !           336: {
        !           337:        register int    i,
        !           338:                        bot;
        !           339: 
        !           340:        bot = bottom;
        !           341: 
        !           342:        /* Save the lost lines. */
        !           343: 
        !           344:        for (i = 0; i < num && top + i <= bottom; i++)
        !           345:                Savelines[i] = Screen[top + i];
        !           346: 
        !           347:        /* Copy everything up num number of lines. */
        !           348: 
        !           349:        for (i = top; num + i <= bottom; i++)
        !           350:                Screen[i] = Screen[i + num];
        !           351: 
        !           352:        /* Restore the lost ones, clearing them. */
        !           353: 
        !           354:        for (i = 0; i < num; i++) {
        !           355:                Screen[bottom - i] = Savelines[i];
        !           356:                clrline(Screen[bot].s_line, Screen[bot].s_length);
        !           357:                Screen[bot].s_length = Screen[bot].s_line;
        !           358:                bot--;
        !           359:        }
        !           360: 
        !           361:        (*TTdel_line)(top, bottom, num);
        !           362: }
        !           363: 
        !           364: 
        !           365: /* The cursor optimization happens here.  You may decide that this
        !           366:    is going too far with cursor optimization, or perhaps it should
        !           367:    limit the amount of checking to when the output speed is slow.
        !           368:    What ever turns you on ...   */
        !           369: 
        !           370: private struct cursaddr {
        !           371:        int     c_numchars,
        !           372:                (*c_proc)();
        !           373: };
        !           374: 
        !           375: private char   *Cmstr;
        !           376: private struct cursaddr        *HorMin,
        !           377:                        *VertMin,
        !           378:                        *DirectMin;
        !           379: 
        !           380: private ForMotion(),
        !           381:        ForTab(),
        !           382:        BackMotion(),
        !           383:        RetTab(),
        !           384:        DownMotion(),
        !           385:        UpMotion(),
        !           386:        GoDirect(),
        !           387:        HomeGo(),
        !           388:        BottomUp();
        !           389:        
        !           390: 
        !           391: private struct cursaddr        WarpHor[] = {
        !           392:        0,      ForMotion,
        !           393:        0,      ForTab,
        !           394:        0,      BackMotion,
        !           395:        0,      RetTab
        !           396: };
        !           397: 
        !           398: private struct cursaddr        WarpVert[] = {
        !           399:        0,      DownMotion,
        !           400:        0,      UpMotion
        !           401: };
        !           402: 
        !           403: private struct cursaddr        WarpDirect[] = {
        !           404:        0,      GoDirect,
        !           405:        0,      HomeGo,
        !           406:        0,      BottomUp
        !           407: };
        !           408: 
        !           409: #undef FORWARD
        !           410: #define        FORWARD         0       /* Move forward */
        !           411: #define FORTAB         1       /* Forward using tabs */
        !           412: #undef BACKWARD
        !           413: #define        BACKWARD        2       /* Move backward */
        !           414: #define RETFORWARD     3       /* Beginning of line and then tabs */
        !           415: #define NUMHOR         4
        !           416: 
        !           417: #define DOWN           0       /* Move down */
        !           418: #define UPMOVE         1       /* Move up */
        !           419: #define NUMVERT                2
        !           420: 
        !           421: #define DIRECT         0       /* Using CM */
        !           422: #define HOME           1       /* HOME */
        !           423: #define LOWER          2       /* Lower Line */
        !           424: #define NUMDIRECT      3
        !           425: 
        !           426: #define        home()          Placur(0, 0)
        !           427: #define LowLine()      putpad(LL, 1), CapLine = ILI, CapCol = 0
        !           428: #define PrintHo()      putpad(HO, 1), CapLine = CapCol = 0
        !           429: 
        !           430: int    phystab = 8;
        !           431: 
        !           432: private
        !           433: GoDirect(line, col)
        !           434: register int   line,
        !           435:                col;
        !           436: {
        !           437:        putpad(Cmstr, 1);
        !           438:        CapLine = line;
        !           439:        CapCol = col;
        !           440: }
        !           441: 
        !           442: private
        !           443: RetTab(col)
        !           444: register int   col;
        !           445: {
        !           446:        putchar('\r');
        !           447:        CapCol = 0;
        !           448:        ForTab(col);
        !           449: }
        !           450: 
        !           451: private
        !           452: HomeGo(line, col)
        !           453: {
        !           454:        PrintHo();
        !           455:        DownMotion(line);
        !           456:        ForTab(col);
        !           457: }
        !           458: 
        !           459: private
        !           460: BottomUp(line, col)
        !           461: register int   line,
        !           462:                col;
        !           463: {
        !           464:        LowLine();
        !           465:        UpMotion(line);
        !           466:        ForTab(col);
        !           467: }
        !           468: 
        !           469: /* Tries to move forward using tabs (if possible).  It tabs to the
        !           470:    closest tabstop which means it may go past 'destcol' and backspace
        !           471:    to it. */
        !           472: 
        !           473: private
        !           474: ForTab(destcol)
        !           475: int    destcol;
        !           476: {
        !           477:        register int    tabgoal,
        !           478:                        ntabs,
        !           479:                        tabstp = phystab;
        !           480: 
        !           481:        if (TABS && (tabstp > 0)) {
        !           482:                tabgoal = destcol + (tabstp / 2);
        !           483:                tabgoal -= (tabgoal % tabstp);
        !           484: 
        !           485:                /* Don't tab to last place or else it is likely to screw up. */
        !           486:                if (tabgoal >= CO)
        !           487:                        tabgoal -= tabstp;
        !           488: 
        !           489:                ntabs = (tabgoal / tabstp) - (CapCol / tabstp);
        !           490:                while (--ntabs >= 0)
        !           491:                        putchar('\t');
        !           492:                CapCol = tabgoal;
        !           493:        }
        !           494:        if (CapCol > destcol)
        !           495:                BackMotion(destcol);
        !           496:        else if (CapCol < destcol)
        !           497:                ForMotion(destcol);
        !           498: }
        !           499: 
        !           500: private
        !           501: ForMotion(destcol)
        !           502: register int   destcol;
        !           503: {
        !           504:        register int    nchars = destcol - CapCol;
        !           505:        register char   *cp = &Screen[CapLine].s_line[CapCol];
        !           506: 
        !           507:        while (--nchars >= 0)
        !           508:                putchar(*cp++ & 0177);
        !           509:        CapCol = destcol;
        !           510: }
        !           511: 
        !           512: private
        !           513: BackMotion(destcol)
        !           514: register int   destcol;
        !           515: {
        !           516:        register int    nchars = CapCol - destcol;
        !           517: 
        !           518:        if (BC)
        !           519:                while (--nchars >= 0)
        !           520:                        putpad(BC, 1);
        !           521:        else
        !           522:                while (--nchars >= 0)
        !           523:                        putchar('\b');
        !           524:        CapCol = destcol;
        !           525: }
        !           526: 
        !           527: private
        !           528: DownMotion(destline)
        !           529: register int   destline;
        !           530: {
        !           531:        register int    nlines = destline - CapLine;
        !           532: 
        !           533:        while (--nlines >= 0)
        !           534:                putchar('\n');
        !           535:        CapLine = destline;
        !           536: }
        !           537: 
        !           538: private
        !           539: UpMotion(destline)
        !           540: register int   destline;
        !           541: {
        !           542:        register int    nchars = CapLine - destline;
        !           543: 
        !           544:        while (--nchars >= 0)
        !           545:                putpad(UP, 1);
        !           546:        CapLine = destline;
        !           547: }
        !           548: 
        !           549: #ifdef ID_CHAR
        !           550: static int     EIlen;
        !           551: #endif
        !           552: extern int     IMlen;
        !           553: 
        !           554: InitCM()
        !           555: {
        !           556:        HOlen = HO ? strlen(HO) : 1000;
        !           557:        LLlen = LL ? strlen(LL) : 1000;
        !           558:        UPlen = UP ? strlen(UP) : 1000;
        !           559: #ifdef ID_CHAR
        !           560:        if (EI)
        !           561:                EIlen = strlen(EI);
        !           562: #endif
        !           563: }
        !           564: 
        !           565: Placur(line, col)
        !           566: {
        !           567:        int     dline,          /* Number of lines to move */
        !           568:                dcol;           /* Number of columns to move */
        !           569:        register int    best,
        !           570:                        i;
        !           571:        register struct cursaddr        *cp;
        !           572:        int     xtracost = 0;   /* Misc addition to cost. */
        !           573: 
        !           574: #define CursMin(which,addrs,max) \
        !           575:        for (best = 0, cp = &addrs[1], i = 1; i < max; i++, cp++) \
        !           576:                if (cp->c_numchars < addrs[best].c_numchars) \
        !           577:                        best = i; \
        !           578:        which = &addrs[best];
        !           579: 
        !           580:        if (line == CapLine && col == CapCol)
        !           581:                return;         /* We are already there. */
        !           582: 
        !           583:        dline = line - CapLine;
        !           584:        dcol = col - CapCol;
        !           585: #ifdef ID_CHAR
        !           586:        if (IN_INSmode && MI)
        !           587:                xtracost = EIlen + IMlen;
        !           588:        /* If we're already in insert mode, it is likely that we will
        !           589:           want to be in insert mode again, after the insert. */
        !           590: #endif
        !           591: 
        !           592:        /* Number of characters to move horizontally for each case.
        !           593:           1: Just move forward by typing the right character on the screen.
        !           594:           2: Print the correct number of back spaces.
        !           595:           3: Try tabbing to the correct place.
        !           596:           4: Try going to the beginning of the line, and then tab. */
        !           597: 
        !           598:        if (dcol == 1 || dcol == 0) {           /* Most common case. */
        !           599:                HorMin = &WarpHor[FORWARD];
        !           600:                HorMin->c_numchars = dcol + xtracost;
        !           601:        } else {
        !           602:                WarpHor[FORWARD].c_numchars = dcol >= 0 ? dcol + xtracost : 1000;
        !           603:                WarpHor[BACKWARD].c_numchars = dcol < 0 ? -(dcol + xtracost) : 1000;
        !           604:                WarpHor[FORTAB].c_numchars = dcol >= 0 && TABS ?
        !           605:                                ForNum(CapCol, col) + xtracost : 1000;
        !           606:                WarpHor[RETFORWARD].c_numchars = (xtracost + 1 + (TABS ? ForNum(0, col) : col));
        !           607: 
        !           608:                /* Which is the shortest of the bunch */
        !           609: 
        !           610:                CursMin(HorMin, WarpHor, NUMHOR);
        !           611:        }
        !           612: 
        !           613:        /* Moving vertically is more simple. */
        !           614: 
        !           615:        WarpVert[DOWN].c_numchars = dline >= 0 ? dline : 1000;
        !           616:        WarpVert[UPMOVE].c_numchars = dline < 0 ? ((-dline) * UPlen) : 1000;
        !           617: 
        !           618:        /* Which of these is simpler */
        !           619:        CursMin(VertMin, WarpVert, NUMVERT);
        !           620: 
        !           621:        /* Homing first and lowering first are considered 
        !           622:           direct motions.
        !           623:           Homing first's total is the sum of the cost of homing
        !           624:           and the sum of tabbing (if possible) to the right. */
        !           625:        
        !           626:        if (VertMin->c_numchars + HorMin->c_numchars <= 3) {
        !           627:                DirectMin = &WarpDirect[DIRECT];        /* A dummy ... */
        !           628:                DirectMin->c_numchars = 100;
        !           629:        } else {
        !           630:                WarpDirect[DIRECT].c_numchars = CM ?
        !           631:                                strlen(Cmstr = tgoto(CM, col, line)) : 1000;
        !           632:                WarpDirect[HOME].c_numchars = HOlen + line +
        !           633:                                WarpHor[RETFORWARD].c_numchars;
        !           634:                WarpDirect[LOWER].c_numchars = LLlen + ((ILI - line) * UPlen) +
        !           635:                                WarpHor[RETFORWARD].c_numchars;
        !           636:                CursMin(DirectMin, WarpDirect, NUMDIRECT);
        !           637:        }
        !           638: 
        !           639:        if (HorMin->c_numchars + VertMin->c_numchars < DirectMin->c_numchars) {
        !           640:                if (line != CapLine)
        !           641:                        (*VertMin->c_proc)(line);
        !           642:                if (col != CapCol) {
        !           643: #ifdef ID_CHAR
        !           644:                        if (IN_INSmode) /* We may use real characters ... */
        !           645:                                INSmode(0);
        !           646: #endif
        !           647:                        (*HorMin->c_proc)(col);
        !           648:                }
        !           649:        } else {
        !           650: #ifdef ID_CHAR
        !           651:                if (IN_INSmode && !MI)
        !           652:                        INSmode(0);
        !           653: #endif
        !           654:                (*DirectMin->c_proc)(line, col);
        !           655:        }
        !           656: }
        !           657: 
        !           658: #define abs(x) ((x) >= 0 ? (x) : -(x))
        !           659: 
        !           660: ForNum(from, to)
        !           661: register int   from;
        !           662: {
        !           663:        register int    tabgoal,
        !           664:                        tabstp = phystab;
        !           665:        int             numchars = 0;
        !           666: 
        !           667:        if (from >= to)
        !           668:                return from - to;
        !           669:        if (TABS && (tabstp > 0)) {
        !           670:                tabgoal = to + (tabstp / 2);
        !           671:                tabgoal -= (tabgoal % tabstp);
        !           672:                if (tabgoal >= CO)
        !           673:                        tabgoal -= tabstp;
        !           674:                numchars = (tabgoal / tabstop) - (from / tabstp);
        !           675:                from = tabgoal;
        !           676:        }
        !           677:        return numchars + abs(from - to);
        !           678: }
        !           679: 
        !           680: #ifdef WIRED_TERMS
        !           681: 
        !           682: BGi_lines(top, bottom, num)
        !           683: {
        !           684:        printf("\033[%d;%dr\033[%dL\033[r", top + 1, bottom + 1, num);
        !           685:        CapCol = CapLine = 0;
        !           686: }
        !           687: 
        !           688: SUNi_lines(top, bottom, num)
        !           689: {
        !           690:        Placur(bottom - num + 1, 0);
        !           691:        printf("\033[%dM", num);
        !           692:        Placur(top, 0);
        !           693:        printf("\033[%dL", num);
        !           694: }
        !           695: 
        !           696: C100i_lines(top, bottom, num)
        !           697: {
        !           698:        if (num <= 1) {
        !           699:                GENi_lines(top, bottom, num);
        !           700:                return;
        !           701:        }
        !           702:        printf("\033v%c%c%c%c", ' ', ' ', ' ' + bottom + 1, ' ' + CO);
        !           703:        CapLine = CapCol = 0;
        !           704:        Placur(top, 0);
        !           705:        while (num--)
        !           706:                putpad(AL, ILI - CapLine);
        !           707:        printf("\033v%c%c%c%c", ' ', ' ', ' ' + LI, ' ' + CO);
        !           708:        CapLine = CapCol = 0;
        !           709: }
        !           710: 
        !           711: #endif WIRED_TERMS
        !           712: 
        !           713: GENi_lines(top, bottom, num)
        !           714: {
        !           715:        register int    i;
        !           716: 
        !           717:        if (CS) {
        !           718:                printf(tgoto(CS, bottom, top));
        !           719:                CapCol = CapLine = 0;
        !           720:                Placur(top, 0);
        !           721:                for (i = 0; i < num; i++)
        !           722:                        putpad(SR, bottom - top);
        !           723:                printf(tgoto(CS, ILI, 0));
        !           724:                CapCol = CapLine = 0;
        !           725:        } else {
        !           726:                Placur(bottom - num + 1, 0);
        !           727:                if (M_DL && (num > 1)) {
        !           728:                        char    minibuf[16];
        !           729: 
        !           730:                        sprintf(minibuf, M_DL, num);
        !           731:                        putpad(minibuf, ILI - CapLine);
        !           732:                } else {
        !           733:                        for (i = 0; i < num; i++)
        !           734:                                putpad(DL, ILI - CapLine);
        !           735:                }
        !           736:                Placur(top, 0);
        !           737:                if (M_AL && (num > 1)) {
        !           738:                        char    minibuf[16];
        !           739: 
        !           740:                        sprintf(minibuf, M_AL, num);
        !           741:                        putpad(minibuf, ILI - CapLine);
        !           742:                } else {
        !           743:                        for (i = 0; i < num; i++)
        !           744:                                putpad(AL, ILI - CapLine);
        !           745:                }
        !           746:        }
        !           747: }
        !           748: 
        !           749: #ifdef WIRED_TERMS
        !           750: 
        !           751: BGd_lines(top, bottom, num)
        !           752: {
        !           753:        printf("\033[%d;%dr\033[%dM\033[r", top + 1, bottom + 1, num);
        !           754:        CapCol = CapLine = 0;
        !           755: }
        !           756: 
        !           757: SUNd_lines(top, bottom, num)
        !           758: {
        !           759:        Placur(top, 0);
        !           760:        printf("\033[%dM", num);
        !           761:        Placur(bottom + 1 - num, 0);
        !           762:        printf("\033[%dL", num);
        !           763: }
        !           764: 
        !           765: C100d_lines(top, bottom, num)
        !           766: {
        !           767:        if (num <= 1) {
        !           768:                GENd_lines(top, bottom, num);
        !           769:                return;
        !           770:        }
        !           771:        printf("\033v%c%c%c%c", ' ', ' ', ' ' + bottom + 1, ' ' + CO);
        !           772:        CapLine = CapCol = 0;
        !           773:        Placur(top, 0);
        !           774:        while (num--)
        !           775:                putpad(DL, ILI - CapLine);
        !           776:        printf("\033v%c%c%c%c", ' ', ' ', ' ' + LI, ' ' + CO);
        !           777:        CapLine = CapCol = 0;
        !           778: }
        !           779: 
        !           780: #endif WIRED_TERMS
        !           781: 
        !           782: GENd_lines(top, bottom, num)
        !           783: {
        !           784:        register int    i;
        !           785: 
        !           786:        if (CS) {
        !           787:                printf(tgoto(CS, bottom, top));
        !           788:                CapCol = CapLine = 0;
        !           789:                Placur(bottom, 0);
        !           790:                for (i = 0; i < num; i++)
        !           791:                        putpad(SF, bottom - top);
        !           792:                printf(tgoto(CS, ILI, 0));
        !           793:                CapCol = CapLine = 0;
        !           794:        } else {
        !           795:                Placur(top, 0);
        !           796:                if (M_DL && (num > 1)) {
        !           797:                        char    minibuf[16];
        !           798: 
        !           799:                        sprintf(minibuf, M_DL, num);
        !           800:                        putpad(minibuf, ILI - top);
        !           801:                } else {
        !           802:                        for (i = 0; i < num; i++)
        !           803:                                putpad(DL, ILI - top);
        !           804:                }
        !           805:                Placur(bottom + 1 - num, 0);
        !           806:                if (M_AL && (num > 1)) {
        !           807:                        char    minibuf[16];
        !           808: 
        !           809:                        sprintf(minibuf, M_AL, num);
        !           810:                        putpad(minibuf, ILI - CapLine);
        !           811:                } else {
        !           812:                        for (i = 0; i < num; i++)
        !           813:                                putpad(AL, ILI - CapLine);
        !           814:                }
        !           815:        }
        !           816: }
        !           817: 
        !           818: struct ID_lookup {
        !           819:        char    *ID_name;
        !           820:        int     (*I_proc)();    /* proc to insert lines */
        !           821:        int     (*D_proc)();    /* proc to delete lines */
        !           822: } ID_trms[] = {
        !           823:        "generic",      GENi_lines,     GENd_lines,     /* This should stay here */
        !           824: #ifdef WIRED_TERMS
        !           825:        "sun",          SUNi_lines,     SUNd_lines,
        !           826:        "bg",           BGi_lines,      BGd_lines,
        !           827:        "c1",           C100i_lines,    C100d_lines,
        !           828: #endif WIRED_TERMS
        !           829:        0,              0,              0
        !           830: };
        !           831: 
        !           832: IDline_setup(tname)
        !           833: char   *tname;
        !           834: {
        !           835:        register struct ID_lookup       *idp;
        !           836: 
        !           837:        for (idp = &ID_trms[1]; idp->ID_name; idp++)
        !           838:                if (strncmp(idp->ID_name, tname, strlen(idp->ID_name)) == 0)
        !           839:                        break;
        !           840:        if (idp->ID_name == 0)
        !           841:                idp = &ID_trms[0];
        !           842:        TTins_line = idp->I_proc;
        !           843:        TTdel_line = idp->D_proc;
        !           844: }

unix.superglobalmegacorp.com

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