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

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

unix.superglobalmegacorp.com

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