Annotation of 43BSDReno/contrib/jove/screen.c, revision 1.1.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.