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

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

unix.superglobalmegacorp.com

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