Annotation of 43BSDTahoe/new/jove/disp.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 "ctype.h"
                     10: #include "termcap.h"
                     11: 
                     12: 
                     13: #ifdef MAC
                     14: #      include "mac.h"
                     15: #else
                     16: #      include <varargs.h>
                     17: #      include <sys/stat.h>
                     18: #endif
                     19: 
                     20: #include <signal.h>
                     21: 
                     22: #ifdef MAC
                     23: #      undef private
                     24: #      define private
                     25: #endif
                     26: 
                     27: #ifdef LINT_ARGS
                     28: private void
                     29: #ifdef ID_CHAR
                     30:        DeTab(int, char *, char *, int, int),
                     31:        DelChar(int, int, int),
                     32:        InsChar(int, int, int, char *),
                     33: #endif
                     34:        DoIDline(int),
                     35:        do_cl_eol(int),
                     36:        ModeLine(Window *),
                     37:        mode_app(char *),
                     38:        GotoDot(void),
                     39:        UpdLine(int),
                     40:        UpdWindow(Window *, int);
                     41: 
                     42: private int
                     43:        AddLines(int, int),
                     44:        DelLines(int, int),
                     45:        UntilEqual(int);
                     46: #else
                     47: private void
                     48: #ifdef ID_CHAR
                     49:        DeTab(),
                     50:        DelChar(),
                     51:        InsChar(),
                     52: #endif
                     53:        DoIDline(),
                     54:        do_cl_eol(),
                     55:        GotoDot(),
                     56:        ModeLine(),
                     57:        mode_app(),
                     58:        UpdLine(),
                     59:        UpdWindow();
                     60: private int
                     61:        AddLines(),
                     62:        DelLines(),
                     63:        UntilEqual();
                     64: #endif /* LINT_ARGS */
                     65: 
                     66: #ifdef MAC
                     67: #      undef private
                     68: #      define private static
                     69: #endif
                     70: 
                     71: int    DisabledRedisplay = NO;
                     72: 
                     73: /* Kludge windows gets called by the routines that delete lines from the
                     74:    buffer.  If the w->w_line or w->w_top are deleted and this procedure
                     75:    is not called, the redisplay routine will barf. */
                     76: 
                     77: void
                     78: ChkWindows(line1, line2)
                     79: Line   *line1;
                     80: register Line  *line2;
                     81: {
                     82:        register Window *w = fwind;
                     83:        register Line   *lp;
                     84: 
                     85:        do {
                     86:                for (lp = line1->l_next; lp != line2->l_next; lp = lp->l_next) {
                     87:                        if (lp == w->w_top)
                     88:                                w->w_flags |= W_TOPGONE;
                     89:                        if (lp == w->w_line)
                     90:                                w->w_flags |= W_CURGONE;
                     91:                }
                     92:                w = w->w_next;
                     93:        } while (w != fwind);
                     94: }
                     95: 
                     96: extern int     RingBell;
                     97: 
                     98: void
                     99: redisplay()
                    100: {
                    101:        extern int      AbortCnt;
                    102:        register Window *w = fwind;
                    103:        int     lineno,
                    104:                done_ID = NO,
                    105:                i;
                    106:        register struct scrimage        *des_p,
                    107:                                        *phys_p;
                    108: 
                    109:        if (DisabledRedisplay == YES)
                    110:                return;
                    111:        curwind->w_line = curwind->w_bufp->b_dot;
                    112:        curwind->w_char = curwind->w_bufp->b_char;
                    113: #ifdef MAC
                    114:        InputPending = 0;
                    115: #else  
                    116:        if (InputPending = charp())     /* calls CheckEvent, which could */
                    117:                return; /* result in a call to rediplay(). We don't want that. */
                    118: #endif
                    119: #ifdef JOB_CONTROL
                    120:        if (UpdFreq)
                    121:                sighold(SIGALRM);
                    122: #endif
                    123:        if (RingBell) {
                    124:                dobell(1);
                    125:                RingBell = 0;
                    126:        }
                    127:        AbortCnt = BufSize;             /* initialize this now */
                    128:        if (UpdMesg)
                    129:                DrawMesg(YES);
                    130: 
                    131:        for (lineno = 0, w = fwind; lineno < ILI; w = w->w_next) {
                    132:                UpdWindow(w, lineno);
                    133:                lineno += w->w_height;
                    134:        }
                    135: 
                    136:        UpdModLine = 0; /* Now that we've called update window, we can
                    137:                           assume that the modeline will be updated.  But
                    138:                           if while redrawing the modeline the user types
                    139:                           a character, ModeLine() is free to set this on
                    140:                           again so that the modeline will be fully drawn
                    141:                           at the next redisplay. */
                    142: 
                    143:        des_p = DesiredScreen;
                    144:        phys_p = PhysScreen;
                    145:        for (i = 0; i < ILI; i++, des_p++, phys_p++) {
                    146:                if (!done_ID && (des_p->s_id != phys_p->s_id)) {
                    147:                        DoIDline(i);
                    148:                        done_ID = YES;
                    149:                }
                    150:                if ((des_p->s_flags & (DIRTY | L_MOD)) ||
                    151:                    (des_p->s_id != phys_p->s_id) ||
                    152:                    (des_p->s_vln != phys_p->s_vln) ||
                    153:                    (des_p->s_offset != phys_p->s_offset))
                    154:                        UpdLine(i);
                    155:                if (InputPending)
                    156:                        goto ret;
                    157:        }
                    158: 
                    159: 
                    160:        if (Asking) {
                    161:                Placur(LI - 1, min(CO - 2, calc_pos(mesgbuf, Asking)));
                    162:                        /* Nice kludge */
                    163:                flusho();
                    164:        } else
                    165:                GotoDot();
                    166: ret:
                    167: #ifdef JOB_CONTROL
                    168:        if (UpdFreq)
                    169:                sigrelse(SIGALRM);
                    170: #else
                    171:        ;       /* yuck */
                    172: #endif
                    173: #ifdef MAC
                    174:        if(Windchange) docontrols();
                    175: #endif /* MAC */
                    176: }
                    177: 
                    178: #ifndef IBMPC
                    179: private void
                    180: dobell(n)
                    181: {
                    182:        while (--n >= 0) {
                    183: #ifndef MAC
                    184:                if (VisBell && VB)
                    185:                        putstr(VB);
                    186:                else
                    187:                        putpad(BL, 1);
                    188: #else
                    189:                SysBeep(5);
                    190: #endif
                    191:        }
                    192:        flusho();
                    193: }
                    194: #endif /* IBMPC */
                    195: 
                    196: /* find_pos() returns the position on the line, that C_CHAR represents
                    197:    in LINE */
                    198: 
                    199: int
                    200: find_pos(line, c_char)
                    201: Line   *line;
                    202: {
                    203:        return calc_pos(lcontents(line), c_char);
                    204: }
                    205: 
                    206: int
                    207: calc_pos(lp, c_char)
                    208: register char  *lp;
                    209: register int   c_char;
                    210: {
                    211:        register int    pos = 0;
                    212:        register int    c;
                    213: 
                    214: 
                    215:        while ((--c_char >= 0) && ((c = *lp++) & CHARMASK) != 0) {
                    216:                if (c == '\t')
                    217:                        pos += (tabstop - (pos % tabstop));
                    218:                else if (isctrl(c))
                    219:                        pos += 2;
                    220:                else
                    221:                        pos += 1;
                    222:        }
                    223:        return pos;
                    224: }
                    225: 
                    226: int    UpdModLine = 0,
                    227:        UpdMesg = 0,
                    228:        CanScroll = 0;
                    229: 
                    230: private void
                    231: DoIDline(start)
                    232: {
                    233:        register struct scrimage        *des_p = &DesiredScreen[start];
                    234:        struct scrimage *phys_p = &PhysScreen[start];
                    235:        register int    i,
                    236:                        j;
                    237: 
                    238:        /* Some changes have been made.  Try for insert or delete lines.
                    239:           If either case has happened, Addlines and/or DelLines will do
                    240:           necessary scrolling, also CONVERTING PhysScreen to account for the
                    241:           physical changes.  The comparison continues from where the
                    242:           insertion/deletion takes place; this doesn't happen very often,
                    243:           usually it happens with more than one window with the same
                    244:           buffer. */
                    245: 
                    246:        if (!CanScroll)
                    247:                return;         /* We should never have been called! */
                    248: 
                    249:        for (i = start; i < ILI; i++, des_p++, phys_p++)
                    250:                if (des_p->s_id != phys_p->s_id)
                    251:                        break;
                    252: 
                    253:        for (; i < ILI; i++) {
                    254:                for (j = i + 1; j < ILI; j++) {
                    255:                        des_p = &DesiredScreen[j];
                    256:                        phys_p = &PhysScreen[j];
                    257:                        if (des_p->s_id != 0 && des_p->s_id == phys_p->s_id)
                    258:                                break;
                    259:                        if (des_p->s_id == PhysScreen[i].s_id) {
                    260:                                if (des_p->s_id == 0)
                    261:                                        continue;
                    262:                                if (AddLines(i, j - i)) {
                    263:                                        DoIDline(j);
                    264:                                        return;
                    265:                                }
                    266:                                break;
                    267:                        }
                    268:                        if ((des_p = &DesiredScreen[i])->s_id == phys_p->s_id) {
                    269:                                if (des_p->s_id == 0)
                    270:                                        continue;
                    271:                                if (DelLines(i, j - i)) {
                    272:                                        DoIDline(i);
                    273:                                        return;
                    274:                                }
                    275:                                break;
                    276:                        }
                    277:                }
                    278:        }
                    279: }
                    280: 
                    281: /* Make DesiredScreen reflect what the screen should look like when we are done
                    282:    with the redisplay.  This deals with horizontal scrolling.  Also makes
                    283:    sure the current line of the Window is in the window. */
                    284: 
                    285: int    ScrollAll = NO;
                    286: 
                    287: private void
                    288: UpdWindow(w, start)
                    289: register Window        *w;
                    290: {
                    291:        Line    *lp;
                    292:        int     i,
                    293:                upper,          /* top of window */
                    294:                lower,          /* bottom of window */
                    295:                strt_col,       /* starting print column of current line */
                    296:                ntries = 0;     /* # of tries at updating window */
                    297:        register struct scrimage        *des_p,
                    298:                                        *phys_p;
                    299:        Buffer  *bp = w->w_bufp;
                    300: 
                    301: retry:
                    302:        if (w->w_flags & W_CURGONE) {
                    303:                w->w_line = bp->b_dot;
                    304:                w->w_char = bp->b_char;
                    305:        }
                    306:        if (w->w_flags & W_TOPGONE)
                    307:                CentWind(w);    /* reset topline of screen */
                    308:        w->w_flags &= ~(W_CURGONE | W_TOPGONE);
                    309: 
                    310:        /* make sure that the current line is in the window */
                    311:        upper = start;
                    312:        lower = upper + w->w_height - 1;        /* don't include modeline */
                    313:        for (i = upper, lp = w->w_top; i < lower && lp != 0; lp = lp->l_next, i++)
                    314:                if (lp == w->w_line)
                    315:                        break;
                    316:        if (i == lower || lp == 0) {
                    317:                ntries += 1;
                    318:                if (ntries == 1) {
                    319:                        CalcWind(w);
                    320:                        goto retry;
                    321:                } else if (ntries == 2) {
                    322:                        w->w_top = w->w_line = w->w_bufp->b_first;
                    323:                        printf("\rERROR in redisplay: I got hopelessly lost!");
                    324:                        dobell(2);
                    325:                        goto retry;
                    326:                } else if (ntries == 3) {
                    327:                        printf("\n\rOops, still lost, quitting ...\r\n");
                    328:                        finish(1);
                    329:                }
                    330:        }
                    331: 
                    332:        /* first do some calculations for the current line */
                    333:        {
                    334:                int     diff = (w->w_flags & W_NUMLINES) ? 8 : 0,
                    335:                        end_col;
                    336: 
                    337:                strt_col = (ScrollAll == YES) ? w->w_LRscroll :
                    338:                           PhysScreen[i].s_offset;
                    339:                end_col = strt_col + (CO - 2) - diff;
                    340:                /* Right now we are displaying from strt_col to
                    341:                   end_col of the buffer line.  These are PRINT
                    342:                   columns, not actual characters. */
                    343:                w->w_dotcol = find_pos(w->w_line, w->w_char);
                    344:                /* if the new dotcol is out of range, reselect
                    345:                   a horizontal window */
                    346:                if ((PhysScreen[i].s_offset == -1) ||
                    347:                    (w->w_dotcol < strt_col) ||
                    348:                    (w->w_dotcol >= end_col)) {
                    349:                        if (w->w_dotcol < ((CO - 2) - diff))
                    350:                                strt_col = 0;
                    351:                        else
                    352:                                strt_col = w->w_dotcol - (CO / 2);
                    353:                        if (ScrollAll == YES) {
                    354:                                if (w->w_LRscroll != strt_col)
                    355:                                        UpdModLine = YES;
                    356:                                w->w_LRscroll = strt_col;
                    357:                        }
                    358:                }
                    359:                w->w_dotline = i;
                    360:                w->w_dotcol += diff;
                    361:        }
                    362: 
                    363:        des_p = &DesiredScreen[upper];
                    364:        phys_p = &PhysScreen[upper];
                    365:        for (i = upper, lp = w->w_top; lp != 0 && i < lower; i++, des_p++, phys_p++, lp = lp->l_next) {
                    366:                des_p->s_window = w;
                    367:                des_p->s_lp = lp;
                    368:                des_p->s_id = lp->l_dline & ~DIRTY;
                    369:                des_p->s_flags = isdirty(lp) ? L_MOD : 0;
                    370:                if (w->w_flags & W_NUMLINES)
                    371:                        des_p->s_vln = w->w_topnum + (i - upper);
                    372:                else
                    373:                        des_p->s_vln = 0;
                    374: 
                    375:                if (lp == w->w_line)
                    376:                        des_p->s_offset = strt_col;
                    377:                else
                    378:                        des_p->s_offset = w->w_LRscroll;
                    379:        }
                    380: 
                    381:        /* Is structure assignment faster than copy each field separately? */
                    382:        if (i < lower) {
                    383:                static struct scrimage  dirty_plate = { 0, DIRTY, 0, 0, 0, 0 },
                    384:                                        clean_plate = { 0, 0, 0, 0, 0, 0 };
                    385: 
                    386:                for (; i < lower; i++, des_p++, phys_p++)
                    387:                        if (phys_p->s_id != 0)
                    388:                                *des_p = dirty_plate;
                    389:                        else
                    390:                                *des_p = clean_plate;
                    391:        }
                    392: 
                    393:        des_p->s_window = w;
                    394:        des_p->s_flags = 0;
                    395:        if (((des_p->s_id = (int) w->w_bufp) != phys_p->s_id) || UpdModLine)
                    396:                des_p->s_flags = MODELINE | DIRTY;
                    397: #ifdef MAC
                    398:        if(UpdModLine) Modechange = 1;
                    399:        if(w == curwind && w->w_control) SetScrollBar(w->w_control);
                    400: #endif
                    401: }
                    402: 
                    403: /* Write whatever is in mesgbuf (maybe we are Asking, or just printed
                    404:    a message).  Turns off the UpdateMesg line flag. */
                    405: 
                    406: void
                    407: DrawMesg(abortable)
                    408: {
                    409: #ifndef MAC            /* same reason as in redisplay() */
                    410:        if (charp())
                    411:                return;
                    412: #endif
                    413:        i_set(ILI, 0);
                    414:        if (swrite(mesgbuf, NO, abortable)) {
                    415:                cl_eol();
                    416:                UpdMesg = 0;
                    417:        }
                    418:        flusho();
                    419: }
                    420: 
                    421: /* Goto the current position in the current window.  Presumably redisplay()
                    422:    has already been called, and curwind->{w_dotline,w_dotcol} have been set
                    423:    correctly. */
                    424: 
                    425: private void
                    426: GotoDot()
                    427: {
                    428:        if (InputPending)
                    429:                return;
                    430:        Placur(curwind->w_dotline, curwind->w_dotcol -
                    431:                                PhysScreen[curwind->w_dotline].s_offset);
                    432:        flusho();
                    433: }
                    434: 
                    435: private int
                    436: UntilEqual(start)
                    437: register int   start;
                    438: {
                    439:        register struct scrimage        *des_p = &DesiredScreen[start],
                    440:                                        *phys_p = &PhysScreen[start];
                    441: 
                    442:        while ((start < ILI) && (des_p->s_id != phys_p->s_id)) {
                    443:                des_p += 1;
                    444:                phys_p += 1;
                    445:                start += 1;
                    446:        }
                    447: 
                    448:        return start;
                    449: }
                    450: 
                    451: /* Calls the routine to do the physical changes, and changes PhysScreen to
                    452:    reflect those changes. */
                    453: 
                    454: private int
                    455: AddLines(at, num)
                    456: register int   at,
                    457:                num;
                    458: {
                    459:        register int    i;
                    460:        int     bottom = UntilEqual(at + num);
                    461: 
                    462:        if (num == 0 || num >= ((bottom - 1) - at))
                    463:                return NO;                              /* we did nothing */
                    464:        v_ins_line(num, at, bottom - 1);
                    465: 
                    466:        /* Now change PhysScreen to account for the physical change. */
                    467: 
                    468:        for (i = bottom - 1; i - num >= at; i--)
                    469:                PhysScreen[i] = PhysScreen[i - num];
                    470:        for (i = 0; i < num; i++)
                    471:                PhysScreen[at + i].s_id = 0;
                    472:        return YES;                                     /* we did something */
                    473: }
                    474: 
                    475: private int
                    476: DelLines(at, num)
                    477: register int   at,
                    478:                num;
                    479: {
                    480:        register int    i;
                    481:        int     bottom = UntilEqual(at + num);
                    482: 
                    483:        if (num == 0 || num >= ((bottom - 1) - at))
                    484:                return NO;
                    485:        v_del_line(num, at, bottom - 1);
                    486: 
                    487:        for (i = at; num + i < bottom; i++)
                    488:                PhysScreen[i] = PhysScreen[num + i];
                    489:        for (i = bottom - num; i < bottom; i++)
                    490:                PhysScreen[i].s_id = 0;
                    491:        return YES;
                    492: }
                    493: 
                    494: /* Update line linenum in window w.  Only set PhysScreen to DesiredScreen
                    495:    if the swrite or cl_eol works, that is nothing is interupted by 
                    496:    characters typed. */ 
                    497: 
                    498: private void
                    499: UpdLine(linenum)
                    500: register int   linenum;
                    501: {
                    502:        register struct scrimage        *des_p = &DesiredScreen[linenum];
                    503:        register Window *w = des_p->s_window;
                    504: 
                    505:        i_set(linenum, 0);
                    506:        if (des_p->s_flags & MODELINE)
                    507:                ModeLine(w);
                    508:        else if (des_p->s_id) {
                    509:                des_p->s_lp->l_dline &= ~DIRTY;
                    510:                des_p->s_flags &= ~(DIRTY | L_MOD);
                    511: #ifdef ID_CHAR
                    512:                if (!UseIC && (w->w_flags & W_NUMLINES))
                    513: #else
                    514:                if (w->w_flags & W_NUMLINES)
                    515: #endif
                    516:                        (void) swrite(sprint("%6d  ", des_p->s_vln), NO, YES);
                    517: 
                    518: #ifdef ID_CHAR
                    519:                if (UseIC) {
                    520:                        char    outbuf[MAXCOLS],
                    521:                                *lptr;
                    522:                        int     fromcol = (w->w_flags & W_NUMLINES) ? 8 : 0;
                    523: 
                    524:                        if (w->w_flags & W_NUMLINES)
                    525:                                sprintf(outbuf, "%6d  ", des_p->s_vln);
                    526:                        lptr = lcontents(des_p->s_lp);
                    527:                        DeTab(des_p->s_offset, lptr, outbuf + fromcol,
                    528:                                (sizeof outbuf) - 1 - fromcol,
                    529:                                des_p->s_window->w_flags & W_VISSPACE);
                    530:                        if (IDchar(outbuf, linenum, 0))
                    531:                                PhysScreen[linenum] = *des_p;
                    532:                        else if (i_set(linenum, 0), swrite(outbuf, NO, YES))
                    533:                                do_cl_eol(linenum);
                    534:                        else
                    535:                                PhysScreen[linenum].s_id = -1;
                    536:                } else
                    537: #endif /* ID_CHAR */
                    538:                    if (BufSwrite(linenum))
                    539:                        do_cl_eol(linenum);
                    540:                else
                    541:                        PhysScreen[linenum].s_id = -1;
                    542:        } else if (PhysScreen[linenum].s_id)    /* not the same ... make sure */
                    543:                do_cl_eol(linenum);
                    544: }
                    545: 
                    546: private void
                    547: do_cl_eol(linenum)
                    548: register int   linenum;
                    549: {
                    550:        cl_eol();
                    551:        PhysScreen[linenum] = DesiredScreen[linenum];
                    552: }
                    553: 
                    554: #ifdef ID_CHAR
                    555: 
                    556: /* From here to the end of the file is code that tries to utilize the
                    557:    insert/delete character feature on some terminals.  It is very confusing
                    558:    and not so well written code, AND there is a lot of it.  You may want
                    559:    to use the space for something else. */
                    560: 
                    561: extern struct screenline       *Screen;
                    562: int    IN_INSmode = 0;
                    563: 
                    564: int    UseIC;
                    565: 
                    566: int    DClen,
                    567:        MDClen,
                    568:        IClen,
                    569:        MIClen,
                    570:        IMlen,
                    571:        CElen;
                    572: 
                    573: void
                    574: disp_opt_init()
                    575: {
                    576:        DClen = DC ? strlen(DC) : 0;
                    577:        MDClen = M_DC ? strlen(M_DC) : 9999;
                    578:        IClen = IC ? strlen(IC) : 0;
                    579:        MIClen = M_IC ? strlen(M_IC) : 9999;
                    580:        IMlen = IM ? strlen(IM) : 0;
                    581:        CElen = CE ? strlen(CE) : 0;
                    582: 
                    583:        UseIC = (IC || IM || M_IC);
                    584: }
                    585: 
                    586: void
                    587: INSmode(on)
                    588: {
                    589:        if (on && !IN_INSmode) {
                    590:                putpad(IM, 1);
                    591:                IN_INSmode = YES;
                    592:        } else if (!on && IN_INSmode) {
                    593:                putpad(EI, 1);
                    594:                IN_INSmode = NO;
                    595:        }
                    596: }
                    597: 
                    598: private void
                    599: DeTab(s_offset, buf, outbuf, limit, visspace)
                    600: register char  *buf;
                    601: char   *outbuf;
                    602: {
                    603:        register char   *phys_p = outbuf,
                    604:                        c;
                    605:        register int    pos = 0;
                    606:        char            *limitp = &outbuf[limit];
                    607: 
                    608: #define OkayOut(ch)    if ((pos++ >= s_offset) && (phys_p < limitp))\
                    609:                                *phys_p++ = ch;\
                    610:                        else
                    611: 
                    612:        while (c = *buf++) {
                    613:                if (c == '\t') {
                    614:                        int     nchars = (tabstop - (pos % tabstop));
                    615: 
                    616:                        if (visspace) {
                    617:                                OkayOut('>');
                    618:                                nchars -= 1;
                    619:                        }
                    620:                        while (--nchars >= 0)
                    621:                                OkayOut(' ');
                    622: 
                    623:                } else if (isctrl(c)) {
                    624:                        OkayOut('^');
                    625:                        OkayOut(c == 0177 ? '?' : c + '@');
                    626:                } else {
                    627:                        if (visspace && c == ' ')
                    628:                                c = '_';
                    629:                        OkayOut(c);
                    630:                }
                    631:                if (pos - s_offset >= CO) {
                    632:                        phys_p = &outbuf[CO - 1];
                    633:                        *phys_p++ = '!';
                    634:                        break;
                    635:                }                       
                    636:        }
                    637:        *phys_p = 0;
                    638: }
                    639: 
                    640: /* ID character routines full of special cases and other fun stuff like that.
                    641:    It actually works though ... 
                    642: 
                    643:        Returns Non-Zero if you are finished (no differences left). */
                    644: 
                    645: private int
                    646: IDchar(new, lineno, col)
                    647: register char  *new;
                    648: {
                    649:        register int    i;
                    650:        int     j,
                    651:                oldlen,
                    652:                NumSaved;
                    653:        register struct screenline      *sline = &Screen[lineno];
                    654: 
                    655:        oldlen = sline->s_length - sline->s_line;
                    656: 
                    657:        for (i = col; i < oldlen && new[i] != 0; i++)
                    658:                if (sline->s_line[i] != new[i])
                    659:                        break;
                    660:        if (new[i] == 0 || i == oldlen)
                    661:                return (new[i] == 0 && i == oldlen);
                    662: 
                    663:        for (j = i + 1; j < oldlen && new[j]; j++) {
                    664:                if (new[j] == sline->s_line[i]) {
                    665:                        NumSaved = IDcomp(new + j, sline->s_line + i,
                    666:                                        strlen(new)) + NumSimilar(new + i,
                    667:                                                sline->s_line + i, j - i);
                    668:                        if (OkayInsert(NumSaved, j - i)) {
                    669:                                InsChar(lineno, i, j - i, new);
                    670:                                return(IDchar(new, lineno, j));
                    671:                        }
                    672:                }
                    673:        }
                    674: 
                    675:        for (j = i + 1; j < oldlen && new[i]; j++) {
                    676:                if (new[i] == sline->s_line[j]) {
                    677:                        NumSaved = IDcomp(new + i, sline->s_line + j,
                    678:                                        oldlen - j);
                    679:                        if (OkayDelete(NumSaved, j - i, new[oldlen] == 0)) {
                    680:                                DelChar(lineno, i, j - i);
                    681:                                return(IDchar(new, lineno, j));
                    682:                        }
                    683:                }
                    684:        }
                    685:        return 0;
                    686: }
                    687: 
                    688: private int
                    689: NumSimilar(s, t, n)
                    690: register char  *s,
                    691:                *t;
                    692: {
                    693:        register int    num = 0;
                    694: 
                    695:        while (n--)
                    696:                if (*s++ == *t++)
                    697:                        num += 1;
                    698:        return num;
                    699: }
                    700: 
                    701: private int
                    702: IDcomp(s, t, len)
                    703: register char  *s,
                    704:                *t;
                    705: {
                    706:        register int    i;
                    707:        int     num = 0,
                    708:                nonspace = 0;
                    709:        char    c;
                    710: 
                    711:        for (i = 0; i < len; i++) {
                    712:                if ((c = *s++) != *t++)
                    713:                        break;
                    714:                if (c != ' ')
                    715:                        nonspace++;
                    716:                if (nonspace)
                    717:                        num += 1;
                    718:        }
                    719: 
                    720:        return num;
                    721: }
                    722: 
                    723: private int
                    724: OkayDelete(Saved, num, samelength)
                    725: {
                    726:        /* If the old and the new are the same length, then we don't
                    727:         * have to clear to end of line.  We take that into consideration.
                    728:         */
                    729:        return ((Saved + (!samelength ? CElen : 0))
                    730:                > min(MDClen, DClen * num));
                    731: }
                    732: 
                    733: private int
                    734: OkayInsert(Saved, num)
                    735: {
                    736:        register int    n = 0;
                    737: 
                    738:        if (IC)         /* Per character prefixes */
                    739:                n = min(num * IClen, MIClen);
                    740: 
                    741:        if (IM && !IN_INSmode) {        
                    742:                /* Good terminal.  Fewer characters in this case */
                    743:                n += IMlen;
                    744:        }
                    745: 
                    746:        n += num;       /* The characters themselves */
                    747: 
                    748:        return Saved > n;
                    749: }
                    750: 
                    751: extern int     CapCol;
                    752: extern char    *cursend;
                    753: extern struct screenline       *Curline;
                    754: 
                    755: private void
                    756: DelChar(lineno, col, num)
                    757: {
                    758:        register char   *from,
                    759:                        *to;
                    760:        register int    i;
                    761:        struct screenline *sp = (&Screen[lineno]);
                    762: 
                    763:        Placur(lineno, col);
                    764:        if (M_DC && num > 1) {
                    765:                char    minibuf[16];
                    766: 
                    767:                sprintf(minibuf, M_DC, num);
                    768:                putpad(minibuf, num);
                    769:        } else {
                    770:                for (i = num; --i >= 0; )
                    771:                        putpad(DC, 1);
                    772:        }
                    773: 
                    774:        to = sp->s_line + col;
                    775:        from = to + num;
                    776: 
                    777:        byte_copy(from, to, sp->s_length - from + 1);
                    778:        clrline(sp->s_length - num, sp->s_length);
                    779:        sp->s_length -= num;
                    780: }
                    781: 
                    782: private void
                    783: InsChar(lineno, col, num, new)
                    784: char   *new;
                    785: {
                    786:        register char   *sp1,
                    787:                        *sp2,   /* To push over the array. */
                    788:                        *sp3;   /* Last character to push over. */
                    789:        int     i;
                    790: 
                    791:        i_set(lineno, 0);
                    792:        sp2 = Curline->s_length + num;
                    793: 
                    794:        if (sp2 >= cursend) {
                    795:                i_set(lineno, CO - num - 1);
                    796:                cl_eol();
                    797:                sp2 = cursend - 1;
                    798:        }
                    799:        Curline->s_length = sp2;
                    800:        sp1 = sp2 - num;
                    801:        sp3 = Curline->s_line + col;
                    802: 
                    803:        while (sp1 >= sp3)
                    804:                *sp2-- = *sp1--;
                    805: 
                    806:        new += col;
                    807:        byte_copy(new, sp3, num);
                    808:        /* The internal screen is correct, and now we have to do
                    809:           the physical stuff. */
                    810: 
                    811:        Placur(lineno, col);
                    812:        if (IM) {
                    813:                if (!IN_INSmode)
                    814:                        INSmode(1);
                    815:        } else if (M_IC && num > 1) {
                    816:                char    minibuf[16];
                    817: 
                    818:                sprintf(minibuf, M_IC, num);
                    819:                putpad(minibuf, num);
                    820:        } else if (IC) {
                    821:                for (i = 0; i < num; i++)
                    822:                        putpad(IC, 1);
                    823:        }
                    824:        for (i = 0; i < num; i++) {
                    825:                putchar(new[i]);
                    826:                if (IN_INSmode)
                    827:                        putpad(IP, 1);
                    828:        }
                    829:        CapCol += num;
                    830: }
                    831: 
                    832: #endif /* ID_CHAR */
                    833: 
                    834: #ifdef UNIX            /* obviously ... no mail today if not Unix*/
                    835: 
                    836: /* chkmail() returns nonzero if there is new mail since the
                    837:    last time we checked. */
                    838: 
                    839: char   Mailbox[FILESIZE];      /* initialized in main */
                    840: int    MailInt = 60;   /* check no more often than 60 seconds */
                    841: #ifdef BIFF
                    842: int    BiffChk = NO;   /* whether or not to turn off biff while in JOVE */
                    843: #endif
                    844: 
                    845: int
                    846: chkmail(force)
                    847: {
                    848:        time_t  now;
                    849:        static time_t   last_chk = 0;
                    850:        static int      value = FALSE;
                    851:        static off_t    last_size = 0;
                    852:        struct stat     stbuf;
                    853:        int     last_val;
                    854:        static time_t   last_time = 0;
                    855: 
                    856:        time(&now);
                    857:        if (!force && (now < last_chk + MailInt))
                    858:                return value;
                    859:        last_chk = now;
                    860:        if (force)
                    861:                last_time = now;
                    862:        if (stat(Mailbox, &stbuf) < 0) {
                    863:                value = FALSE;
                    864:                return FALSE;
                    865:        }
                    866:        last_val = value;
                    867:        value = ((stbuf.st_mtime > last_time) &&
                    868:                 (stbuf.st_size > 0) &&
                    869:                 (stbuf.st_size >= last_size) &&
                    870:                 (stbuf.st_mtime + 5 > stbuf.st_atime));
                    871:        if (value == TRUE &&
                    872:                      ((value != last_val) || (stbuf.st_size != last_size)))
                    873:                dobell(3);
                    874:        if (stbuf.st_size < last_size)
                    875:                last_time = now;
                    876:        last_size = stbuf.st_size;
                    877:        return value;
                    878: }
                    879: 
                    880: #endif /* UNIX */
                    881: 
                    882: /* Print the mode line. */
                    883: 
                    884: private char   *mode_p,
                    885:                *mend_p;
                    886: int    BriteMode = 1;          /* modeline should standout */
                    887: 
                    888: private void
                    889: mode_app(str)
                    890: register char  *str;
                    891: {
                    892:        if (mode_p >= mend_p)
                    893:                return;
                    894:        while ((mode_p < mend_p) && (*mode_p++ = *str++))
                    895:                ;
                    896:        mode_p -= 1;    /* back over the null */
                    897: }
                    898: 
                    899: char   ModeFmt[120] = "%3c %w %[%sJOVE (%M)   Buffer: %b  \"%f\" %]%s%m*- %((%t)%s%)%e";
                    900: 
                    901: private void
                    902: ModeLine(w)
                    903: register Window        *w;
                    904: {
                    905:        extern int      i_line;
                    906:        extern char     *pwd();
                    907:        int     n,
                    908:                ign_some = NO;
                    909:        char    line[MAXCOLS],
                    910:                *fmt = ModeFmt,
                    911:                fillc,
                    912:                c;
                    913:        register Buffer *thisbuf = w->w_bufp;
                    914:        register Buffer *bp;
                    915: 
                    916:        mode_p = line;
                    917:        mend_p = &line[(sizeof line) - 1];
                    918: 
                    919: #if defined(UNIX) || (defined (MSDOS) && !defined(IBMPC))
                    920:        if (BriteMode != 0 && SO == 0)
                    921:                BriteMode = 0;
                    922:        fillc = BriteMode ? ' ' : '-';
                    923: #endif /* UNIX */
                    924: #ifdef IBMPC           /* very subtle - don't mess up attributes too much */
                    925:        fillc = '-'; /*BriteMode ? ' ' : '-';*/
                    926: #endif /* IBMPC */
                    927: #ifdef MAC
                    928:        fillc = '_';    /* looks better on a Mac */
                    929: #endif /* MAC */
                    930: 
                    931:        while (c = *fmt++) {
                    932:                if (c != '%') {
                    933:                        if (c == '\\')
                    934:                                if ((c = *fmt++) == '\0')
                    935:                                        break;
                    936:                        if (!ign_some)
                    937:                                *mode_p++ = c;
                    938:                        continue;
                    939:                }
                    940:                if ((c = *fmt++) == '\0')       /* char after the '%' */
                    941:                        break;
                    942:                if (ign_some && c != ')')
                    943:                        continue;
                    944:                n = 1;
                    945:                if (c >= '0' && c <= '9') {
                    946:                        n = 0;
                    947:                        while (c >= '0' && c <= '9') {
                    948:                                n = n * 10 + (c - '0');
                    949:                                c = *fmt++;
                    950:                        }
                    951:                }
                    952:                switch (c) {
                    953:                case '(':
                    954:                        if (w->w_next != fwind) /* Not bottom window. */
                    955:                                ign_some = YES;
                    956:                        break;
                    957: 
                    958:                case ')':
                    959:                        ign_some = NO;
                    960:                        break;
                    961: 
                    962:                case '[':
                    963:                case ']':
                    964:                    {
                    965:                        char    *strs = (c == '[') ? "[[[[[[[[[[" : "]]]]]]]]]]";
                    966: 
                    967:                        mode_app(strs + 10 - RecDepth);
                    968:                        break;
                    969:                    }
                    970:                        
                    971: #ifdef UNIX
                    972:                case 'C':       /* check mail here */
                    973:                        if (chkmail(NO))
                    974:                                mode_app("[New mail]");
                    975:                        break;
                    976: 
                    977: #endif /* UNIX */
                    978: 
                    979:                case 'M':
                    980:                    {
                    981:                        static char     *mmodes[] = {
                    982:                                "Fundamental ",
                    983:                                "Text ",
                    984:                                "C ",
                    985: #ifdef LISP
                    986:                                "Lisp ",
                    987: #endif
                    988:                                0
                    989:                        };
                    990: 
                    991:                        mode_app(mmodes[thisbuf->b_major]);
                    992: 
                    993:                        if (BufMinorMode(thisbuf, Fill))
                    994:                                mode_app("Fill ");
                    995:                        if (BufMinorMode(thisbuf, Abbrev))
                    996:                                mode_app("Abbrev ");
                    997:                        if (BufMinorMode(thisbuf, OverWrite))
                    998:                                mode_app("OvrWt ");
                    999:                        if (BufMinorMode(thisbuf, Indent))
                   1000:                                mode_app("AI ");
                   1001:                        if (InMacDefine)
                   1002:                                mode_app("Def ");
                   1003:                        mode_p -= 1;    /* Back over the extra space. */
                   1004:                        break;
                   1005:                    }
                   1006: 
                   1007:                case 'c':
                   1008:                        while (--n >= 0)
                   1009:                                *mode_p++ = fillc;
                   1010:                        break;
                   1011: 
                   1012: #ifdef CHDIR
                   1013:                case 'd':       /* print working directory */
                   1014:                        mode_app(pr_name(pwd(), YES));
                   1015:                        break;
                   1016: #endif
                   1017:                        
                   1018:                case 'e':
                   1019:                    {
                   1020:                        /* 2 space pad pluss padding for magic cookies */
                   1021:                        char    *last_p = &line[CO - 2 - (2 * SG)];
                   1022: 
                   1023:                        while (mode_p < last_p)
                   1024:                                *mode_p++ = fillc;
                   1025: 
                   1026:                        goto outahere;          /* %e means we're done! */
                   1027:                    }
                   1028: 
                   1029:                case 'b':
                   1030:                        mode_app(thisbuf->b_name);
                   1031:                        break;
                   1032: 
                   1033:                case 'f':
                   1034:                case 'F':
                   1035:                        if (thisbuf->b_fname == 0)
                   1036:                                mode_app("[No file]");
                   1037:                        else {
                   1038:                                if (c == 'f')
                   1039:                                        mode_app(pr_name(thisbuf->b_fname, YES));
                   1040:                                else
                   1041:                                        mode_app(basename(thisbuf->b_fname));
                   1042:                        }
                   1043:                        break;
                   1044: 
                   1045: #ifdef LOAD_AV
                   1046:                case 'l':
                   1047:                    {
                   1048:                        double  theavg;
                   1049:                        char    minibuf[10];
                   1050: 
                   1051:                        get_la(&theavg);
                   1052:                        theavg += .005; /* round to nearest .01 */
                   1053:                        sprintf(minibuf, "%d.%02d",
                   1054:                               (int) theavg,
                   1055:                               (int)((theavg - (int) theavg) * 100));
                   1056:                        mode_app(minibuf);
                   1057:                        break;
                   1058:                    }
                   1059: #endif
                   1060: 
                   1061:                case 'm':
                   1062:                        if (IsModified(w->w_bufp))
                   1063:                                *mode_p++ = fmt[0];
                   1064:                        else
                   1065:                                *mode_p++ = fmt[1];
                   1066:                        fmt += 2;       /* skip two characters */
                   1067:                        break;
                   1068: 
                   1069:                case 'n':
                   1070:                    {
                   1071:                        char    tmp[16];
                   1072:                        for (bp = world, n = 1; bp != 0; bp = bp->b_next, n++)
                   1073:                                if (bp == thisbuf)
                   1074:                                        break;
                   1075: 
                   1076:                        sprintf(tmp, "%d", n);
                   1077:                        mode_app(tmp);
                   1078:                        break;
                   1079:                    }
                   1080: 
                   1081: #ifdef IPROCS
                   1082:                case 'p':
                   1083:                    if (thisbuf->b_type == B_PROCESS) {
                   1084:                        char    tmp[40];
                   1085: 
                   1086:                        sprintf(tmp, "(%s)", (thisbuf->b_process == 0) ?
                   1087:                                             "No process" :
                   1088:                                             pstate(thisbuf->b_process));
                   1089:                        mode_app(tmp);
                   1090:                        break;
                   1091:                    }
                   1092: #endif
                   1093: 
                   1094:                case 's':
                   1095:                        if (mode_p[-1] == ' ')
                   1096:                                continue;
                   1097:                        *mode_p++ = ' ';
                   1098:                        break;
                   1099: 
                   1100:                case 't':
                   1101:                    {
                   1102:                        char    timestr[12];
                   1103: 
                   1104:                        mode_app(get_time((time_t *) 0, timestr, 11, 16));
                   1105:                        break;
                   1106:                    }
                   1107: 
                   1108:                case 'w':
                   1109:                        if (w->w_LRscroll > 0) 
                   1110:                                mode_app(">");
                   1111:                }
                   1112:        }
                   1113: 
                   1114: outahere:
                   1115:        *mode_p = 0;
                   1116: 
                   1117:        /* Highlight mode line. */
                   1118:        if (BriteMode) {
                   1119: #ifdef ID_CHAR
                   1120:                if (IN_INSmode)
                   1121:                        INSmode(0);
                   1122: #endif
                   1123: #ifdef TERMCAP
                   1124:                putpad(SO, 1);
                   1125: #else 
                   1126:                SO_on();
                   1127: #endif /* TERMCAP */
                   1128:        }
                   1129:        if (swrite(line, BriteMode, YES))
                   1130:                do_cl_eol(i_line);
                   1131:        else
                   1132:                UpdModLine = 1;
                   1133:        if (BriteMode)
                   1134: #ifdef TERMCAP
                   1135:                putpad(SE, 1);
                   1136: #else 
                   1137:                SO_off();
                   1138: #endif /* TERMCAP */
                   1139: }
                   1140: 
                   1141: /* This tries to place the current line of the current window in the
                   1142:    center of the window, OR to place it at the arg'th line of the window.
                   1143:    This also causes the horizontal position of the line to be centered,
                   1144:    if the line needs scrolling, or moved all the way back to the left,
                   1145:    if that's possible. */
                   1146: void
                   1147: RedrawDisplay()
                   1148: {
                   1149:        int     line;
                   1150:        Line    *newtop = prev_line((curwind->w_line = curline), is_an_arg() ?
                   1151:                                arg_value() : HALF(curwind));
                   1152: 
                   1153:        if ((line = in_window(curwind, curwind->w_line)) != -1)
                   1154:                PhysScreen[line].s_offset = -1;
                   1155:        if (newtop == curwind->w_top)
                   1156:                v_clear(FLine(curwind), FLine(curwind) + SIZE(curwind));
                   1157:        else
                   1158:                SetTop(curwind, newtop);
                   1159: }
                   1160: 
                   1161: void
                   1162: v_clear(line1, line2)
                   1163: register int   line1;
                   1164: {
                   1165:        register struct scrimage        *phys_p, *des_p;
                   1166: 
                   1167:        phys_p = &PhysScreen[line1];
                   1168:        des_p = &DesiredScreen[line1];
                   1169: 
                   1170:        while (line1 <= line2) {
                   1171:                i_set(line1, 0);
                   1172:                cl_eol();
                   1173:                phys_p->s_id = des_p->s_id = 0;
                   1174:                phys_p += 1;
                   1175:                des_p += 1;
                   1176:                line1 += 1;
                   1177:        }
                   1178: }
                   1179: 
                   1180: void
                   1181: ClAndRedraw()
                   1182: {
                   1183:        cl_scr(YES);
                   1184: }
                   1185: 
                   1186: void
                   1187: NextPage()
                   1188: {
                   1189:        Line    *newline;
                   1190: 
                   1191:        if (Asking)
                   1192:                return;
                   1193:        if (arg_value() < 0) {
                   1194:                negate_arg_value();
                   1195:                PrevPage();
                   1196:                return;
                   1197:        }
                   1198:        if (arg_type() == YES)
                   1199:                UpScroll();
                   1200:        else {
                   1201:                if (in_window(curwind, curwind->w_bufp->b_last) != -1) {
                   1202:                        rbell();
                   1203:                        return;
                   1204:                }
                   1205:                newline = next_line(curwind->w_top, max(1, SIZE(curwind) - 1));
                   1206:                SetTop(curwind, curwind->w_line = newline);
                   1207:                if (curwind->w_bufp == curbuf)
                   1208:                        SetLine(newline);
                   1209:        }
                   1210: }
                   1211: 
                   1212: #ifdef MSDOS           /* kg */
                   1213: 
                   1214: void
                   1215: PageScrollUp()
                   1216: {
                   1217:        int i, n;
                   1218: 
                   1219:     n = max(1, SIZE(curwind) - 1);
                   1220:        for (i=0; i<n; i++) {
                   1221:            UpScroll();
                   1222:            redisplay();
                   1223:        }
                   1224: }
                   1225: 
                   1226: void
                   1227: PageScrollDown()
                   1228: {
                   1229:        int i, n;
                   1230: 
                   1231:        n = max(1, SIZE(curwind) - 1);
                   1232:        for (i=0; i<n; i++) {
                   1233:            DownScroll();
                   1234:            redisplay();
                   1235:        }
                   1236: }
                   1237: #endif /* MSDOS */
                   1238: 
                   1239: void
                   1240: PrevPage()
                   1241: {
                   1242:        Line    *newline;
                   1243: 
                   1244:        if (Asking)
                   1245:                return;
                   1246:        if (arg_value() < 0) {
                   1247:                negate_arg_value();
                   1248:                NextPage();
                   1249:                return;
                   1250:        }
                   1251:        if (arg_type() == YES)
                   1252:                DownScroll();
                   1253:        else {
                   1254:                newline = prev_line(curwind->w_top, max(1, SIZE(curwind) - 1));
                   1255:                SetTop(curwind, curwind->w_line = newline);
                   1256:                if (curwind->w_bufp == curbuf)
                   1257:                        SetLine(newline);
                   1258:        }
                   1259: }
                   1260: 
                   1261: void
                   1262: UpScroll()
                   1263: {
                   1264:        SetTop(curwind, next_line(curwind->w_top, arg_value()));
                   1265:        if ((curwind->w_bufp == curbuf) &&
                   1266:            (in_window(curwind, curline) == -1))
                   1267:                SetLine(curwind->w_top);
                   1268: }
                   1269: 
                   1270: void
                   1271: DownScroll()
                   1272: {
                   1273:        SetTop(curwind, prev_line(curwind->w_top, arg_value()));
                   1274:        if ((curwind->w_bufp == curbuf) &&
                   1275:            (in_window(curwind, curline) == -1))
                   1276:                SetLine(curwind->w_top);
                   1277: }
                   1278: 
                   1279: int    VisBell = NO,
                   1280:        RingBell = NO;  /* So if we have a lot of errors ...
                   1281:                           ring the bell only ONCE */
                   1282: void
                   1283: rbell()
                   1284: {
                   1285:        RingBell = YES;
                   1286: }
                   1287: 
                   1288: /* Message prints the null terminated string onto the bottom line of the
                   1289:    terminal. */
                   1290: 
                   1291: void
                   1292: message(str)
                   1293: char   *str;
                   1294: {
                   1295:        if (InJoverc)
                   1296:                return;
                   1297:        UpdMesg = YES;
                   1298:        errormsg = NO;
                   1299:        if (str != mesgbuf)
                   1300:                null_ncpy(mesgbuf, str, (sizeof mesgbuf) - 1);
                   1301: }
                   1302: 
                   1303: /* End of Window */
                   1304: 
                   1305: void
                   1306: Eow()
                   1307: {
                   1308:        if (Asking)
                   1309:                return;
                   1310:        SetLine(next_line(curwind->w_top, SIZE(curwind) - 1 -
                   1311:                        min(SIZE(curwind) - 1, arg_value() - 1)));
                   1312:        if (!is_an_arg())
                   1313:                Eol();
                   1314: }
                   1315: 
                   1316: /* Beginning of Window */
                   1317: 
                   1318: void
                   1319: Bow()
                   1320: {
                   1321:        if (Asking)
                   1322:                return;
                   1323:        SetLine(next_line(curwind->w_top, min(SIZE(curwind) - 1, arg_value() - 1)));
                   1324: }
                   1325: 
                   1326: private int    LineNo,
                   1327:                last_col,
                   1328:                DoAutoNL;
                   1329: private Window *old_wind;      /* save the window we were in BEFORE
                   1330:                                   before we were called, if UseBuffers
                   1331:                                   is nonzero */
                   1332: 
                   1333: int    UseBuffers = FALSE;
                   1334: int    TOabort = 0;
                   1335: 
                   1336: /* This initializes the typeout.  If send-typeout-to-buffers is set
                   1337:    the buffer NAME is created (emptied if it already exists) and output
                   1338:    goes to the buffer.  Otherwise output is drawn on the screen and
                   1339:    erased by TOstop() */
                   1340: 
                   1341: void
                   1342: TOstart(name, auto_newline)
                   1343: char   *name;
                   1344: {
                   1345:        if (UseBuffers) {
                   1346:                old_wind = curwind;
                   1347:                pop_wind(name, YES, B_SCRATCH);
                   1348:        } else
                   1349:                DisabledRedisplay = YES;
                   1350:        TOabort = LineNo = last_col = 0;
                   1351:        DoAutoNL = auto_newline;
                   1352: }
                   1353: 
                   1354: /* VARARGS1 */
                   1355: 
                   1356: void
                   1357: Typeout(fmt, va_alist)
                   1358: char   *fmt;
                   1359: va_dcl
                   1360: {
                   1361:        if (TOabort)
                   1362:                return;
                   1363: 
                   1364:        if (!UseBuffers && (LineNo == ILI - 1)) {
                   1365:                register int    c;
                   1366: 
                   1367:                LineNo = 0;
                   1368:                last_col = 0;
                   1369:                f_mess("--more--");
                   1370:                if ((c = getchar()) != ' ') {
                   1371:                        TOabort = YES;
                   1372:                        if (c != AbortChar && c != RUBOUT)
                   1373:                                Ungetc(c);
                   1374:                        f_mess(NullStr);
                   1375:                        return;
                   1376:                }
                   1377:                f_mess(NullStr);
                   1378:        }
                   1379: 
                   1380:        if (fmt) {
                   1381:                extern int      i_col;
                   1382:                char    string[132];
                   1383:                va_list ap;
                   1384: 
                   1385:                va_start(ap);
                   1386:                format(string, sizeof string, fmt, ap);
                   1387:                va_end(ap);
                   1388:                if (UseBuffers)
                   1389:                        ins_str(string, NO);
                   1390:                else {
                   1391:                        i_set(LineNo, last_col);
                   1392:                        (void) swrite(string, NO, YES);
                   1393:                        last_col = i_col;
                   1394:                }
                   1395:        }
                   1396:        if (!UseBuffers) {
                   1397:                PhysScreen[LineNo].s_id = -1;
                   1398:                if (fmt == 0 || DoAutoNL == YES) {
                   1399:                        cl_eol();
                   1400:                        flusho();
                   1401:                        LineNo += 1;
                   1402:                        last_col = 0;
                   1403:                }
                   1404:        } else if (fmt == 0 || DoAutoNL != 0)
                   1405:                ins_str("\n", NO);
                   1406: }
                   1407: 
                   1408: void
                   1409: TOstop()
                   1410: {
                   1411:        int     c;
                   1412: 
                   1413:        if (UseBuffers) {
                   1414:                ToFirst();
                   1415:                SetWind(old_wind);
                   1416:        } else {
                   1417:                if (TOabort) {
                   1418:                        DisabledRedisplay = NO;
                   1419:                        return;
                   1420:                }
                   1421:                if (last_col != 0)
                   1422:                        Typeout((char *) 0);
                   1423:                Typeout("----------");
                   1424:                cl_eol();
                   1425:                flusho();
                   1426:                c = getchar();
                   1427:                if (c != ' ')
                   1428:                        Ungetc(c);
                   1429:                DisabledRedisplay = NO;
                   1430:        }
                   1431: }

unix.superglobalmegacorp.com

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