Annotation of researchv9/cmd/emacs/emacs_disp.c, revision 1.1

1.1     ! root        1: /* EMACS_MODES: c !fill */
        !             2: 
        !             3: #include "emacs_io.h"
        !             4: #include "emacs_gb.h"
        !             5: #include "emacs_disp.h"
        !             6: #ifdef TERMINFO
        !             7: #include <sys/types.h>
        !             8: #include <sys/termio.h>
        !             9: #define SGTTY struct termio
        !            10: #include <term.h>
        !            11: #endif
        !            12: 
        !            13: /* character insert */
        !            14: 
        !            15: /* inserts count occurances of the character c in the file */
        !            16: 
        !            17: 
        !            18: 
        !            19: insertc(count,c)
        !            20: 
        !            21: register char c;
        !            22: register int count;
        !            23: 
        !            24: {
        !            25: 
        !            26:        if (count < 0) return;                  /* Reject bad count */
        !            27:        while (count--) {
        !            28:                if ((OVERW) && (c != EOL) && (clptr[column] != EOL)) {
        !            29: 
        !            30:                        clptr[column] = c;
        !            31:                        sputl(curln,column,curln);      /* fix this line */
        !            32:                        modify(curln);
        !            33:                        column++;
        !            34:                } else {
        !            35:                        if(put(c)==0) break;
        !            36:                }
        !            37:        }
        !            38: }
        !            39: 
        !            40: /* insert one character into the file at current position */
        !            41: 
        !            42: put(c)
        !            43: 
        !            44: register char c;
        !            45: /* Keywords: commands:10 insertion line-representation:50 */
        !            46: {
        !            47: 
        !            48:        register char tc;
        !            49:        register int xcol;
        !            50:        
        !            51:        if (c == EOL) {
        !            52:                nl(1);
        !            53:                return(1);
        !            54:        }
        !            55:        xcol=column;
        !            56:        while (c!= EOL) {
        !            57:                tc = clptr[xcol];
        !            58:                clptr[xcol++] = c;
        !            59:                c = tc;
        !            60:        }
        !            61:        modify(curln);
        !            62:        clptr = ckline(curln,xcol);
        !            63:        if (clptr == NULL) {
        !            64:                clptr = mkline(curln);
        !            65:                *(clptr+xcol-1) = EOL;
        !            66:                return(0);
        !            67:        }
        !            68:        clptr[xcol] = EOL;
        !            69:        sputl(curln,column,curln);      /* fix this line */
        !            70:        move(curln,column+1);
        !            71:        return(1);
        !            72: }
        !            73: 
        !            74: /* tabc -- tab command */
        !            75: /* inserts a tab unless notabs mode is on, in which case */
        !            76: /* it inserts spaces up to next tabstop. */
        !            77: 
        !            78: tabc(count,arg)
        !            79: 
        !            80: register int count;
        !            81: int arg;
        !            82: 
        !            83: /* Keywords: commands insertion */
        !            84: {
        !            85:        if (infrn >= 0) {               /* no dice in macro */
        !            86:                if (NOTABS) {
        !            87:                        while (count--) {
        !            88:                                do {
        !            89:                                        put(' ');
        !            90:                                } while (column%TABSTOP);
        !            91:                        }
        !            92:                } else {
        !            93:                        insertc(count,arg);
        !            94:                }
        !            95:        }
        !            96:        return(1);
        !            97: }
        !            98: 
        !            99: /* mvc -- move with checking for c<=length(l) */
        !           100: 
        !           101: 
        !           102: 
        !           103: mvc(l,c)
        !           104: register int l;
        !           105: register int c;
        !           106: 
        !           107: /* Keywords: commands:40 movement */
        !           108: {
        !           109:        register int x;
        !           110: 
        !           111:        if ((x = leng(l)) < c) move(l,x);
        !           112:        else move (l,c);
        !           113: }
        !           114: /* move to new position in the file */
        !           115: 
        !           116: move (newln,newcol)
        !           117: register int newln;
        !           118: register int newcol;
        !           119: 
        !           120: {
        !           121: /* Keywords: movement buffer-allocation:20 */
        !           122:        
        !           123:        if (newln < 1) newln = 1;
        !           124:        if (newln >= NPTRS) {
        !           125:                if (!growbuf(newln)) {
        !           126:                        newln = NPTRS-1;
        !           127:                }
        !           128:        }
        !           129:        curln = newln;
        !           130:        clptr = mkline(curln);
        !           131:        column = newcol;
        !           132:        return;
        !           133: }
        !           134: 
        !           135: /* move both the display matrix pointer and the actual display to the
        !           136:  * specified line and column */
        !           137: 
        !           138: mgo(x,y)
        !           139: 
        !           140: register int x,y;
        !           141: 
        !           142: {
        !           143: 
        !           144:        sgo(mline = x,mcol = y);
        !           145: }
        !           146: 
        !           147: 
        !           148: /* move the display cursor to the specified destination.  sgo attempts
        !           149:  * to optimize the movement, using single character or absolute
        !           150:  * positioning */
        !           151: #ifdef PC
        !           152: sgo(x,y)
        !           153: register int x,y;
        !           154: {
        !           155: 
        !           156:        video(REG(POS_CUR,0),REG(PAGE_0,0),0,REG(x,y));
        !           157:        
        !           158: }
        !           159: #else
        !           160: sgo(x,y)
        !           161: /* Keywords: screen-handling the-screen-cursor */
        !           162: register int x,y;
        !           163: 
        !           164: {
        !           165:        int mx,my;
        !           166:        int xcost;              /* cost with all relative movement */
        !           167:        int ycost;              /* cost with carriage return */
        !           168:                                /* acost is cost of absolute positioning */
        !           169:        
        !           170: /* calculate relative costs of various movements.  cost functions  */
        !           171: /* automatically indicate that un-doable motions have infinite cost */
        !           172:        
        !           173:        
        !           174:        if (umode) unline();            /* out of "underline mode" */
        !           175: 
        !           176:        /* calculate xcost and ycost */
        !           177: 
        !           178:        mx = x-scrlin;
        !           179:        if (mx<0) {
        !           180:                mx = -mx;
        !           181:                xcost = mx*lUP;
        !           182:        } else xcost = mx*lDOWN;
        !           183: 
        !           184:        ycost = y + xcost + lCR;
        !           185:        
        !           186:        my = y-scrcol;
        !           187:        if (my<0) {
        !           188:                my = -my;
        !           189:                xcost +=my*lBAK;
        !           190:        } else xcost += my;
        !           191: 
        !           192:        if (xcost == 0) return;         /* Catch spurious calls to sgo */
        !           193: 
        !           194:        if (acost < ycost) {
        !           195:                if (acost < xcost) {
        !           196:                                        /* do absolute positioning */
        !           197:                        if (CURAD) {
        !           198:                                absmove(x,y);
        !           199:                        } else {        /* have relative addrs */
        !           200:                                if (x>scrlin) eprintf (RELDOWN,mx);
        !           201:                                if (x<scrlin) eprintf (RELUP,mx);
        !           202:                                if (y>scrcol) eprintf (RELFORW,my);
        !           203:                                if (y<scrcol) eprintf (RELBACK,my);
        !           204:                        }
        !           205:                        scrlin=x;
        !           206:                        scrcol=y;
        !           207:                        return;
        !           208:                }                       /* else relative is cheap, do it */
        !           209:        } else {
        !           210:                if (osert && (MI == 0)) {
        !           211:                        unsert();       /* LEAVE insert character mode */
        !           212:                }
        !           213:                if (ycost < xcost) {
        !           214:                                        /* do carriage return processing */
        !           215:                        PUTS(CR);               /* carriage return */
        !           216:                        scrcol = 0;
        !           217: 
        !           218:                        /* fall through to finish with relative motion */
        !           219:                }
        !           220:        }
        !           221: 
        !           222:        while (x != scrlin) {
        !           223:                if (x < scrlin) {
        !           224:                        PUTS(UP);
        !           225:                        scrlin--;
        !           226:                } else {
        !           227:                        PUTS(DOWN);
        !           228:                        scrlin++;
        !           229:                }
        !           230:        }
        !           231: 
        !           232:        /* now correct row */
        !           233: 
        !           234:        while (y != scrcol) {
        !           235:                if (y < scrcol) {
        !           236:                        PUTS(BACK);
        !           237:                        scrcol--;
        !           238:                } else {
        !           239:                        if ((FORWARD == NULL)|| (FORWARD[1] && (osert==0)))  {
        !           240:                                if (osert) {
        !           241:                                        unsert();
        !           242:                                }
        !           243:                                x = cmap[scrlin] [scrcol];
        !           244:                                if (x == 0) x=cmap[scrlin] [scrcol] = ' ';
        !           245:                                if (x & 0200) pu(x); /* underlined character */
        !           246:                                else {
        !           247:                                        if (umode) unline();
        !           248:                                        putchar(x); /* re-write to move; */
        !           249:                                }
        !           250:                        } else {
        !           251:                                PUTS(FORWARD);
        !           252:                        }
        !           253:                        scrcol++;
        !           254:                }
        !           255:        };
        !           256:        return;
        !           257: }
        !           258: 
        !           259: /* unsert -- LEAVE insert character mode */
        !           260: 
        !           261: unsert()
        !           262: {
        !           263: /* Keywords: screen-handling terminal-parameters insertion character-at-a-time */
        !           264:        PUTS(OSERTC); /* can't stay inserting */
        !           265:        osert = 0;
        !           266: }
        !           267: 
        !           268: unline()
        !           269: {
        !           270: /* Keywords: screen-handling terminal-parameters underlining */
        !           271:        PUTS(UEND);
        !           272:        umode = 0;
        !           273: }
        !           274: 
        !           275: /* vshift -- shift the display image from top to bottom (inclusive) by x */
        !           276: 
        !           277: 
        !           278: vshift(top,bottom,x)
        !           279: /* Keywords: scrolling the-screen-map terminal-parameters:20 display-update:80 */
        !           280: int top;
        !           281: int bottom;
        !           282: int x;
        !           283: 
        !           284: {
        !           285:        register int i;
        !           286:        register int j;
        !           287:        char *cp1;
        !           288:        char *cp2;
        !           289:        int *jnkptr;
        !           290:        int *mapptr;
        !           291:        int start;
        !           292:        int stop;
        !           293:        register int off;
        !           294:        
        !           295:        if (x > 0) {
        !           296:                off = 1;
        !           297:                start = top;
        !           298:                stop = bottom+1;
        !           299:        } else {
        !           300:                off = -1;
        !           301:                start = bottom;
        !           302:                stop = top-1;
        !           303:        }
        !           304:        for (i = start,mapptr = scrmap+i,jnkptr = scrjnk+i; i != stop-x; i+=off,mapptr+=off,jnkptr+=off) {
        !           305:                *jnkptr = *(jnkptr+x);
        !           306:                *mapptr = *(mapptr+x);
        !           307:                cp1 = cmap[i];
        !           308:                cp2 = cmap[i+x];
        !           309:                for (j = 0; j < *jnkptr; j++) {
        !           310:                        *cp1++ = *cp2++;
        !           311:                }
        !           312:        }
        !           313:        while (i != stop) {
        !           314:                if (off > 0) {
        !           315:                        *mapptr++ = *jnkptr++ = 0;
        !           316:                        i++;
        !           317:                } else {
        !           318:                        *mapptr-- = *jnkptr-- = 0;
        !           319:                        i--;
        !           320:                }
        !           321:        }
        !           322: }
        !           323:        
        !           324: /* adjust vertical position of line -- open (or close) lines on */
        !           325: /* the screen  argument is the number of lines to add (or drop). */
        !           326: 
        !           327: vadjust(x,xline)
        !           328: 
        !           329: register int x;
        !           330: int xline;
        !           331: /* Keywords: display-update:90 deletion:50 insertion:50 terminal-parameters:90 the-screen-map scrolling:20 screen-lines screen-handling */
        !           332: {
        !           333:        register int i;
        !           334:        register int j;
        !           335:        int oldx;
        !           336: 
        !           337:        
        !           338:        oldx = xline;
        !           339:        TRACE(VADJUST);
        !           340:        TRACE(curln);
        !           341:        TRACE(x);
        !           342:        if (x<0) {
        !           343:                x = -x;
        !           344:                i = 1;
        !           345:        } else i = 0;
        !           346:        if (((j = lastln-xline-x) <= 0)||
        !           347:         ((x*VCOST)>(j*ttywarp*CFILL))) return; /* nothing to save */
        !           348:        SREGION=SCRLINES-oldx;          /* effected region */
        !           349:        if (i) {                        /* if deleting lines */
        !           350:                sgo(xline,0);
        !           351:                
        !           352:                if (SCREG && CURAD) {           /*if vt100 stype scrolling */
        !           353:                        PUTS(TPARM(SCREG,oldx+XBASE,SCRLINES+XBASE-1)); /*define region*/
        !           354:                        absmove(0,0);
        !           355:                        sgo(SCRLINES-1,0);
        !           356:                        do_n(CLSCROLL,SSCROLL,x); /* Scroll up x lines */
        !           357:                        PUTS(TPARM(SCREG,XBASE,REALBOT+XBASE-1));
        !           358:                        absmove(oldx,0);
        !           359:                } else {
        !           360:                        do_n(CLDEL,LDEL,x);
        !           361:                        sgo(SCRLINES-x,0);
        !           362:                        do_n(CLOPEN,LOPEN,x);
        !           363:                }
        !           364:                sgo(oldx,0);
        !           365:                vshift (oldx,SCRLINES-1,x);
        !           366:        } else {
        !           367:                if (SCREG && CURAD && RSCROLL) {                /* if vt100 style scrolling */
        !           368: 
        !           369:                        PUTS(TPARM(SCREG,oldx+XBASE,SCRLINES+XBASE-1)); /*define region */
        !           370:                        absmove(xline,0);
        !           371:                        do_n(CRSCROLL,RSCROLL,x);
        !           372:                        PUTS(TPARM(SCREG,XBASE,REALBOT+XBASE-1));
        !           373:                        absmove(oldx,0);
        !           374:                } else {
        !           375:                        sgo(SCRLINES-x,0);
        !           376:                        do_n(CLDEL,LDEL,x);
        !           377:                        sgo(oldx,0);
        !           378:                        do_n(CLOPEN,LOPEN,x);
        !           379:                }
        !           380:                mgo(oldx,0);
        !           381:                
        !           382:                vshift(oldx,SCRLINES-1,-x);
        !           383:        }
        !           384:        SREGION=1;
        !           385: }
        !           386: 
        !           387: do_n(mulcap,sincap,n)
        !           388: char *mulcap;
        !           389: register char *sincap;
        !           390: register int n;
        !           391: 
        !           392: /* Keywords: scrolling:20 screen-lines:40 terminal-parameters argument-processing screen-handling */
        !           393: 
        !           394: {
        !           395:        if (mulcap && (n>1)) {
        !           396:                                        /* If we can do all at once */
        !           397: #ifdef TERMINFO
        !           398:                putpad(tparm(mulcap,n));
        !           399: #else
        !           400:                PUTS(mulcap,n);
        !           401: #endif         
        !           402:        } else {
        !           403:                while (n--) PUTS(sincap);
        !           404:        }
        !           405: }
        !           406: 
        !           407: absmove(x, y)
        !           408: int    x;
        !           409: int    y;
        !           410: {
        !           411: /* Keywords: terminal-parameters the-screen-cursor screen-handling */
        !           412:        
        !           413: #ifdef TERMINFO
        !           414:        putpad(tparm(CURAD, x, y));
        !           415: #else
        !           416: #ifdef TERMCAP
        !           417:        putpad(tgoto(CURAD, y, x));
        !           418: #else
        !           419:        if (SRCADD) {
        !           420:                eprintf(CURAD,x+XBASE,y+YBASE);
        !           421:        } else {
        !           422:                eprintf(CURAD,y+YBASE,x+XBASE);
        !           423:        }
        !           424: #endif
        !           425: #endif
        !           426:        scrlin=x;
        !           427:        scrcol=y;
        !           428: }
        !           429: 
        !           430: /* sscroll -- try to fix display by scrolling */
        !           431: 
        !           432: sscroll(x)
        !           433: 
        !           434: register int x;
        !           435: /* Keywords: terminal-parameters scrolling screen-handling */
        !           436: {
        !           437:        register int i;
        !           438: 
        !           439:        
        !           440:        if (SSCROLL == NULL || twowind || (SCRLINES-x < 3) || (curbf != disbuf[cwind])) return;
        !           441: 
        !           442: 
        !           443:        sgo(REALBOT-1,0);                       /* to bottom */
        !           444:        SREGION=REALBOT;                        /* number of lines effected */
        !           445:        do_n(CLSCROLL,SSCROLL,x);
        !           446:        SREGION=1;
        !           447:        vshift (0,SCRNLIN-1,x);
        !           448:        if (timemd) disptime = 1;       /* Wiped out time display */
        !           449: }
        !           450: 
        !           451: #endif PC
        !           452: 
        !           453: /* delete chars -- delete characters starting at . */
        !           454: 
        !           455: /* all characters must be on the same line */
        !           456: 
        !           457: delc(count)
        !           458: 
        !           459: register int count;
        !           460: 
        !           461: /* Keywords: deletion line-representation killstack:50 stacking:50 commands:20 */
        !           462: 
        !           463: {
        !           464:        register char *cp1;
        !           465:        register char *cp2;
        !           466: 
        !           467:        undel();
        !           468:        killstk(curln,column,curln,column+count); /* stack even on 0 */
        !           469:        if (count == 0) {
        !           470:                beep();
        !           471:                return(0);                      /* nothing to modify */
        !           472:        }
        !           473:        cp1 = clptr+column;
        !           474:        cp2 = cp1+count;
        !           475:        if (NODEL) {
        !           476:                while (cp1<cp2) *cp1++=' ';
        !           477:        } else {
        !           478:                while ((*cp1++ = *cp2++) != EOL);
        !           479:        }
        !           480:        sputl(curln,column,curln);
        !           481:        modify(curln);
        !           482:        move(curln,column);
        !           483:        return(1);
        !           484: }
        !           485: 
        !           486: /* open up count blank lines in the file */
        !           487: 
        !           488: openl(count)
        !           489: 
        !           490: register int count;
        !           491: 
        !           492: 
        !           493: /* Keywords: insertion line-representation memory-allocation:30 text-lines the-screen-map:20 screen-lines:50 */
        !           494: 
        !           495: {
        !           496: 
        !           497:        register int i;
        !           498:        register char *lp;
        !           499:        char *lp1;
        !           500:        char *lp2;
        !           501:        int oldcol;
        !           502:        int oldln;
        !           503: 
        !           504:        /* first fix the file */
        !           505: 
        !           506:        if (nlines+count >= NPTRS) {
        !           507:                if (!growbuf(nlines+count)) {
        !           508:                        return;
        !           509:                }
        !           510:        }
        !           511:        if (curln<nlines) {
        !           512:                for (i = fbkno; i < NBLOCK; i++) {
        !           513:                        if (hipt[i]>curln) hipt[i]+=count;
        !           514:                        if (lowpt[i]>curln) lowpt[i]+=count;
        !           515:                }
        !           516:                for (i = nlines; i > curln; i--) {
        !           517:                        ptrs[i+count] = ptrs[i];
        !           518:                }
        !           519:        }
        !           520:        nlines += count;
        !           521:        for (i = curln+1; i <= curln+count; i++) ptrs[i] = 0;
        !           522:        if (clptr[column] != EOL) {
        !           523:                if(ckline(curln+count,leng(curln)-column)!=NULL) {
        !           524:                        holdin(curln,curln+count);
        !           525:                        lp1 = mkline(curln+count);
        !           526:                        lp2 = lp = mkline(curln) + column;
        !           527:                        while ((*lp1++ = *lp++)!= EOL);
        !           528:                        *lp2 = EOL;
        !           529:                }
        !           530:        }
        !           531:        modify(curln);
        !           532:        modify(curln+count);
        !           533: 
        !           534:        /* now fix the display */
        !           535: 
        !           536:        oldln = curln;
        !           537:        oldcol = column;
        !           538:        if (TABMD && (RARE == 0)) {
        !           539:                tabjust(curln+count);
        !           540:        }
        !           541:        if (disbuf[cwind] == curbf) {
        !           542: 
        !           543: /* Adjust scrmap to reflect the change.  All lines past oldln in the
        !           544:  * current buffer that show on the screen are bumped up by count.  The
        !           545:  * current line is bumped only if the whole line moved */
        !           546:                
        !           547:                for (i = wbase; i < SCRLINES; i++) {
        !           548:                        if ((scrmap[i]) && ((nln = scrmap[i]&SCRMSK) >= oldln)) {
        !           549:                                if ((nln != oldln) || (oldcol == 0)) scrmap[i] += count;
        !           550:                        }
        !           551:                }
        !           552:        }
        !           553:        sputl(oldln,oldcol,REST);
        !           554:        move(oldln,oldcol);
        !           555: }
        !           556: 
        !           557: 
        !           558: /* getname prompts for a string, using ps, and inputs a string */
        !           559: 
        !           560: /* rubout and @ can be used to edit the string as enterred, and  causes
        !           561:  * a quit, returning no input string
        !           562:  * ^Y causes the current buffer name to be brought out
        !           563:  */
        !           564: 
        !           565: char *
        !           566: getname(ps)
        !           567: 
        !           568: register char *ps;
        !           569: 
        !           570: /* Keywords: user-interface prompting key-bindings:50 reading:50 filenames:50 commands:20 text-lines:40 the-screen-cursor:30 macro-hooks:10 */
        !           571: 
        !           572: {
        !           573:        register int i;
        !           574:        register char c;
        !           575:        int cnt = 1;
        !           576:        char *xp;
        !           577: 
        !           578:        if (infrn < 0) {                /* if in macro */
        !           579:                if(retrvs(fnbuf,FNLEN)>=0){
        !           580:                        return(fnbuf);
        !           581:                } else return(NULL);
        !           582:        }
        !           583:        if (hooks[Read_Name_Hook]) {
        !           584:                stkstr(ps);
        !           585:                if (hook(Read_Name_Hook) && (retrvs(fnbuf,FNLEN) >= 0)) {
        !           586:                        return(fnbuf);
        !           587:                }else return(NULL);
        !           588:        }
        !           589:        fnbuf[i=0] = 0; 
        !           590:        for (;;) {
        !           591:                if (infrn == 0 ){
        !           592:                        prompt(ECHOL,"%s%s",ps,fnbuf); /* display prompt */
        !           593:                        if (c=fnbuf[i]) { /* If there is stuff past the cursor */
        !           594: 
        !           595: /* UGH,  To find out where the cursor goes, we must  duplicate a lot */
        !           596: /* of ugly code out of prompt! */
        !           597:                                
        !           598:                                char pbuf[256];
        !           599:                                mline = ECHOL;
        !           600:                                mcol = 0;
        !           601:                                fnbuf[i]=0;
        !           602:                                seprintf(pbuf,"%s%s",ps,fnbuf);
        !           603:                                fnbuf[i]=c;
        !           604:                                xputl(pbuf,0);
        !           605:                        }
        !           606:                        mgo(mline,mcol);
        !           607:                }
        !           608:                cnt = 1;
        !           609: getbak:                donttime=1;             /* Avoid time & mail */
        !           610:                c = getchar();
        !           611:                donttime=0;             /* Restore time display */
        !           612:                switch(map_it[c]) {
        !           613: 
        !           614:                case CQUOTE:                    
        !           615:                        c = getchar();
        !           616:                        goto regchar;
        !           617: 
        !           618:                case CCTLU:
        !           619:                        cnt*=4;
        !           620:                        goto getbak; /* Bypass re-initilizing cnt! */
        !           621:                        
        !           622:                case CEQUIT:
        !           623:                case CEXIT:
        !           624:                        beep();
        !           625:                        unprompt();
        !           626:                        return(NULL);
        !           627:                case CCTLX:
        !           628:                        xp = mkline(curln);
        !           629:                        goto wrdin;
        !           630:                case CYANK:
        !           631:                        xp = fname();
        !           632: wrdin:                 while ((*xp!= 0) && (*xp != EOL)&& (i<FNLEN-1)) {
        !           633:                                cram(fnbuf,i++,*xp++);
        !           634:                        }
        !           635:                        continue;
        !           636:                default:
        !           637: 
        !           638: 
        !           639: /* anything that isn't otherwise mapped comes here.  Most just insert,  */
        !           640: /* but we do check for '@' */
        !           641:                
        !           642:                        if (c == '@') {
        !           643:                                fnbuf[0]=0;
        !           644:                                i = 0;
        !           645:                                continue;
        !           646:                        }
        !           647:                        
        !           648:                        if (c>=' ') {
        !           649: regchar:                       if (i<FNLEN-1) cram(fnbuf,i++,c);
        !           650:                                continue;
        !           651:                        } else {
        !           652:                                if ((c != CTRLJ) && (c != CTRLM)) {
        !           653:                                        beep;
        !           654:                                        continue;
        !           655:                                }
        !           656:                        }
        !           657:                        
        !           658: /* Fall through to handle newlines re-mapped by the user */
        !           659:                                
        !           660:                case CNEWLINE:
        !           661:                case CMETA:
        !           662:                        unprompt();
        !           663:                        if (infrn == 0) mflush(stdout); /* Indicate that we got it */
        !           664:                        return(fnbuf);
        !           665:                case CREFRESH:
        !           666:                        clear();
        !           667:                        continue;
        !           668:                case CBDEL:
        !           669:                        while (cnt--) {
        !           670:                                if (i) {
        !           671:                                        i--;
        !           672:                                        mstrcpy(fnbuf+i,fnbuf+i+1);
        !           673:                                } else beep();
        !           674:                        }
        !           675:                        continue;
        !           676:                case CFDEL:
        !           677:                        while (cnt--) {
        !           678:                                if (fnbuf[i]) {
        !           679:                                        mstrcpy(fnbuf+i,fnbuf+i+1);
        !           680:                                } else beep();
        !           681:                        }
        !           682:                        continue;
        !           683:                case CXPOSE:
        !           684:                        if (fnbuf[i] && fnbuf[i+1]) {
        !           685:                                c = fnbuf[i];
        !           686:                                fnbuf[i]=fnbuf[i+1];
        !           687:                                fnbuf[++i] = c;
        !           688:                        }
        !           689:                        break;
        !           690:                case CFORW:
        !           691:                        while (cnt--) {
        !           692:                                if (fnbuf[i]) {
        !           693:                                        i++;
        !           694:                                } else beep();
        !           695:                        }
        !           696:                        continue;
        !           697:                case CBEGIN:
        !           698:                        i = 0;
        !           699:                        continue;
        !           700:                case CENDL:
        !           701:                        i = lng(fnbuf);
        !           702:                        continue;
        !           703:                case CBACK:
        !           704:                        i-=cnt;
        !           705:                        if (i<0) {
        !           706:                                beep();
        !           707:                                i=0;
        !           708:                        }
        !           709:                        continue;
        !           710:                case CEKILL:
        !           711:                        fnbuf[i]=0;
        !           712:                        continue;
        !           713:                }
        !           714:        }
        !           715: }
        !           716: 
        !           717: /* Cram character into the middle of a filename string */
        !           718: 
        !           719: cram(sp,pos,cchar)
        !           720: register char *sp;
        !           721: register int pos,cchar;
        !           722: /* Keywords: user-interface prompting string-handling:40 */
        !           723: 
        !           724: {
        !           725: 
        !           726:        int nc;
        !           727:        
        !           728:        while (cchar) {
        !           729:                if (pos == FNLEN-1) {
        !           730:                        beep();
        !           731:                        break;
        !           732:                }
        !           733:                nc = sp[pos];
        !           734:                sp[pos]=cchar;
        !           735:                pos++;
        !           736:                cchar=nc;
        !           737:        }
        !           738:        sp[pos]=0;
        !           739: }
        !           740: 
        !           741: /* gechar: get EMACS character: */
        !           742: /* returns 0200+c for meta chars, 0400+c for ^X chars */
        !           743: 
        !           744: 
        !           745: gechar(ps)
        !           746: register char *ps;
        !           747: /* Keywords: user-interface character-at-a-time prompting:40 ^-and-M-processing:70 */
        !           748: {
        !           749:        register int c;
        !           750:        
        !           751:        prompt1("%s: ",ps);
        !           752:        c = getchar();
        !           753:        if (map_it[c] == CMETA) {
        !           754:                prompt1("%s: M-",ps);
        !           755:                c = 0200+getchar();
        !           756:        }
        !           757:        if (map_it[c] == CCTLX) {
        !           758:                prompt1("%s: ^X",ps);
        !           759:                c = 0400+getchar();
        !           760:        }
        !           761:        unprompt();
        !           762:        return(c);
        !           763: }
        !           764: /* putout outputs a string (like eprintf) at the current position */
        !           765: 
        !           766: /* position is advanced by one line.  If the position overflows the screen
        !           767:  * -MORE- is printed, and input  is read.  Any character except ^G
        !           768:  * continues the display, ^G quits by returning -1 */
        !           769: 
        !           770: /*VARARGS1*/
        !           771: 
        !           772: putout(string,arg1)
        !           773: char *string;
        !           774: /* Keywords: prompting:10 informational-displays MORE-processing  */
        !           775: {
        !           776:        if (mline>=SCRLINES) {
        !           777:                prompt1("--  MORE --");
        !           778:                if ((infrn == 0) && ((getchar()) == CTRLG)) return(-1);
        !           779:                unprompt();
        !           780:                mline=0;                /* TOP */
        !           781:        }
        !           782:        prompt2(mline,string,&arg1);
        !           783:        clrl();
        !           784:        mgo(++mline,0);
        !           785:        return(0);
        !           786: }
        !           787: 
        !           788: /* put out a string on ECHOL */
        !           789: /*VARARGS1*/
        !           790: 
        !           791: prompt1(string,arg1)
        !           792: char *string;
        !           793: /* Keywords: prompting */
        !           794: 
        !           795: {
        !           796:        if (infrn) return;              /* prompt only if input from stdin */
        !           797:        prompt2(ECHOL,string,&arg1);
        !           798:        if (mcol) sgo(mline,mcol);      /* Move cursor only if something is there! */
        !           799: }
        !           800: 
        !           801: /* Keywords: informational-displays time-processing:50 mail-processing:50 */
        !           802: 
        !           803: prompt3(string,arg1)
        !           804: char *string;
        !           805: {
        !           806:        if (infrn) return;
        !           807:        prompt2(ECHOL-1,string,&arg1);
        !           808:        scrmap[ECHOL-1] = ECHOHACK;     /* Flag for next unprompt */
        !           809: }
        !           810: /* put out a string at a specified line */
        !           811: 
        !           812: /*VARARGS2*/
        !           813: 
        !           814: prompt(ecl,string,arg1)
        !           815: int ecl;
        !           816: char *string;
        !           817: int arg1;
        !           818: /* Keywords: informational-displays mode-line user-interface:20 */
        !           819: {
        !           820:        prompt2(ecl,string,&arg1);
        !           821: }
        !           822: 
        !           823: /* Internal subroutine for all prompting */
        !           824: 
        !           825: prompt2(ecl,string,argl)
        !           826: char *string;
        !           827: register int ecl;
        !           828: unsigned int *argl;
        !           829: 
        !           830: /* Keywords: prompting informational-displays the-screen-map:40 */
        !           831: 
        !           832: {
        !           833:        char pbuf[256];
        !           834: 
        !           835:        mline = ecl;
        !           836:        scrmap[mline] = 0;              /* wipe out previous display */
        !           837:        mcol = 0;
        !           838:        sxprintf(pbuf,string,argl);
        !           839:        xputl(pbuf,0);
        !           840:        psx = mline;
        !           841:        psy = mcol;
        !           842:        clrl();
        !           843: 
        !           844: }
        !           845:        
        !           846: /* clear out prompt */
        !           847: 
        !           848: unprompt()
        !           849: /* Keywords: prompting informational-displays the-screen-map:40 deletion:10 */
        !           850: {
        !           851:        if (infrn) return;              /* unprompt only if input from termial */
        !           852:        mline = ECHOL;
        !           853:        mcol = 0;
        !           854:        clrl();
        !           855:        if (scrmap[ECHOL-1] == ECHOHACK) {
        !           856:                mline = ECHOL-1;
        !           857:                clrl();
        !           858:        }
        !           859:        if (timemd) disptime = 1;       /* put time back */
        !           860: }
        !           861: 
        !           862: /* multi-line deleter */
        !           863: 
        !           864: /* deletes the text between current position, and kline, kcol */
        !           865: /* all deleted text is stacked */
        !           866: 
        !           867: tkill()
        !           868: /* Keywords: deletion picture-mode:50 killstack:50 stacking:50 the-screen-map:60 */
        !           869:        /* arguments are kline,kcol */
        !           870: {
        !           871:        int oldcol;
        !           872:        register int x;
        !           873:        register int y;
        !           874:        register char *cp;
        !           875:        char *cp1;
        !           876: 
        !           877:        if (kline < 1) kline = 1;
        !           878:        if (kline >nlines) {
        !           879:                kline = nlines;
        !           880:                kcol = leng(kline);
        !           881:        }
        !           882:        if ((kline < curln) || ((kline == curln) && (kcol < column))) {
        !           883:                x = curln;
        !           884:                y = column;
        !           885:                move (kline, kcol);
        !           886:                kcol = y;
        !           887:                kline = x;
        !           888:        }
        !           889: 
        !           890: 
        !           891:        if (kline == curln) {
        !           892:                return(delc (kcol-column));             /* cheap out */
        !           893:        }
        !           894:        oldcol = column;
        !           895:        undel();
        !           896:        killstk(curln,column,kline,kcol);
        !           897:        if (PICMODE) {
        !           898:                int mincol;
        !           899:                int maxcol;
        !           900:                int ln;
        !           901:                register int c;
        !           902: 
        !           903:                ln = curln;
        !           904:                if (kcol<column) {
        !           905:                        mincol=kcol;
        !           906:                        maxcol=column;
        !           907:                } else {
        !           908:                        mincol=column;
        !           909:                        maxcol=kcol;
        !           910:                }
        !           911:                while (ln<=kline) {
        !           912:                        cp = mkline(ln);
        !           913:                        c = 0;
        !           914:                        if (NODEL) {
        !           915:                                while (c<maxcol) {
        !           916:                                        if (cp[c]==EOL) break;
        !           917:                                        if (c>=mincol) cp[c] = ' ';
        !           918:                                        c++;
        !           919:                                }
        !           920:                        } else {
        !           921:                                int lln;
        !           922:                                
        !           923:                                lln = leng(ln);
        !           924:                                if (lln > mincol) {
        !           925:                                        if (lln < maxcol) {
        !           926:                                                cp[mincol]=EOL;
        !           927:                                        } else {
        !           928:                                                c = mincol;
        !           929:                                                while (1) {
        !           930:                                                        cp[c]=(*(cp+c+maxcol-mincol));
        !           931:                                                        if (*(cp+(c++))==EOL) break;
        !           932:                                                }
        !           933:                                        }
        !           934:                                }
        !           935:                        }
        !           936:                        modify(ln);
        !           937:                        ln++;
        !           938:                }
        !           939:                sputl(curln,column,REST);
        !           940:                mvc(curln,column);
        !           941:                return(1);
        !           942:        }
        !           943:        if(ckline(curln,column+leng(kline)-kcol) == NULL) return(0);
        !           944:        holdin(curln,kline);
        !           945:        cp1 = mkline(curln)+column;
        !           946:        cp = mkline(kline)+kcol;
        !           947:        while ((*cp1++ = *cp++)!= EOL) column++;
        !           948:        modify(curln);
        !           949: 
        !           950:        /* current line is fixed, fix rest */
        !           951: 
        !           952:        x = kline-curln;
        !           953: 
        !           954: /* Adjust block ranges to account for movement in lines.  high point
        !           955:  * shifts if its above the deleted region.  Low point shifts if it's
        !           956:  * in or above */
        !           957:        
        !           958:        if (curln+x<nlines) {
        !           959:                for (y = fbkno; y < NBLOCK; y++) {
        !           960:                        if (hipt[y]>curln+x) hipt[y]-=x;
        !           961:                        if (lowpt[y]>curln) lowpt[y]-=x;
        !           962:                }
        !           963:        }
        !           964:        
        !           965:        for (y = curln+1+x; y <= nlines; y++) {
        !           966:                ptrs[y-x] = ptrs[y];
        !           967:        }
        !           968:        nlines -= x;
        !           969: 
        !           970:        if (disbuf[cwind] == curbf) {
        !           971: 
        !           972: /* Adjust scrmap to reflect the change.  All lines past oldln in the
        !           973:  * current buffer that show on the screen are bumped up by count.  The
        !           974:  * current line is bumped only if the whole line moved */
        !           975:                
        !           976:                for (y = wbase; y < SCRLINES; y++) {
        !           977:                        if ((scrmap[y]) && ((nln = scrmap[y]&SCRMSK) >= curln)) {
        !           978:                                if ((nln == curln) && oldcol) continue; /* dont wipe out curln */
        !           979:                                if (nln >= (curln+x)) scrmap[y]-=x; /* map down for lines past the deletion */
        !           980:                                else scrmap[y] = 0; /* this line has been killed */
        !           981:                        }
        !           982:                }
        !           983:        }
        !           984: 
        !           985:        sputl(curln,oldcol,REST);
        !           986:        move(curln,oldcol);
        !           987:        return(1);
        !           988: }
        !           989: 
        !           990: /* refresh the screen */
        !           991: 
        !           992: /* clear and force refresh */
        !           993: 
        !           994: refresh(arg)
        !           995: 
        !           996: register unsigned arg;
        !           997: /* Keywords: display-update commands the-screen-cursor:40 windows:20 */
        !           998: {
        !           999: 
        !          1000:        
        !          1001:        if (numarg) dspage(curln-arg,0);
        !          1002:        else clear();
        !          1003: }
        !          1004: 
        !          1005: /* mark a region of the displayy for fixing.  Arguments are the  */
        !          1006: /* first line and (file) character position to fix, and the last line */
        !          1007: 
        !          1008: sputl(from, col, to)
        !          1009: 
        !          1010: int col;
        !          1011: register int from;
        !          1012: int to;
        !          1013: {
        !          1014: /* Keywords: screen-handling:60 commands:30 display-update:30 deletion:50 insertion:50 */
        !          1015:        register int *fmp;
        !          1016:        int wwid;
        !          1017:        
        !          1018:        if (disbuf[cwind] != curbf) return; /* not in this window */
        !          1019:        from -= minln;
        !          1020:        wwid = SCRLINES-wbase;
        !          1021:        fmp = fmap;
        !          1022:        to -= minln;
        !          1023:        if (to > wwid) to = wwid;
        !          1024:        if ((from >= 0) && (from <= wwid)) {
        !          1025:                if (fmp[from] > col) fmp[from]= col;
        !          1026:        }
        !          1027:        while (++from<=to) if (from >= 0) fmp[from]=0;
        !          1028:        return;
        !          1029: }
        !          1030: 
        !          1031: /* Display output routines.  This is probably less clean than the
        !          1032:  * previous version, but handles underlining and also does a better
        !          1033:  * job with insert/delete character. */
        !          1034: 
        !          1035: /* The functions are:
        !          1036: 
        !          1037:        cflush(buf,n) -- put n-mcol characters starting at buf+mcol on the
        !          1038:                        screen at current mline,mcol.  This is
        !          1039:                        assumed not to overflow one line.
        !          1040:                        
        !          1041:        xputl(line,flag,col) -- The hard work.  Maps a string to one
        !          1042:                        or more screen lines.  The exact nature of
        !          1043:                        the mapping is different for buffer lines
        !          1044:                        than for strings, as indicated by flag.
        !          1045: */
        !          1046: 
        !          1047: 
        !          1048: /* Cflush is the main vehicle for the escape of characters.  All
        !          1049:  * charcters that actaually print (as opposed to terminal
        !          1050:  * control) go through here.  The general strategy is that if the
        !          1051:  * desired character is by some odd chance there already, nothing
        !          1052:  * happens.  If the desired character is a space and the terminal is
        !          1053:  * beyond the end of the line, nothing happens.  If insert or delete
        !          1054:  * characters will help bring cp into line with what's on the
        !          1055:  * screen, then it will use them as necessary.  Underlining is
        !          1056:  * handled, including the pain of making it work on various
        !          1057:  * brain-damaged terminals. */
        !          1058: 
        !          1059: /* These general principals followed in a way that is optimized for
        !          1060:  * common cases, including:  display of a whole line that is already
        !          1061:  * on the screen.  Display of a whole line that does not correspond
        !          1062:  * to what's on the screen, and display of one new character. */
        !          1063: 
        !          1064: 
        !          1065: #ifdef PC
        !          1066: #define EOM 0                          /* End of string marker */
        !          1067: #else
        !          1068: #define EOM '\337'                     /* End of line marker */
        !          1069: #endif PC
        !          1070: 
        !          1071: cflush(cp,n)
        !          1072: 
        !          1073: register char *cp;
        !          1074: int n;
        !          1075: 
        !          1076: /* Keywords: character-at-a-time:40 insertion:30 deletion:30 character-output screen-handling terminal-parameters:20 */
        !          1077: {
        !          1078:        register char *mp;
        !          1079:        register int x;
        !          1080:        register int y;
        !          1081:        int z;
        !          1082:        int jnk;
        !          1083:        int stop;
        !          1084:        
        !          1085:        cp[n] = EOM;                    /* Mark end of line */
        !          1086: 
        !          1087: 
        !          1088: #ifdef PC
        !          1089:        mcol += vout(mline,mcol,cp+mcol);
        !          1090:        if (scrjnk[mline]< mcol) scrjnk[mline]=mcol;
        !          1091: #else  
        !          1092:        mp = cmap[mline];               /* character map pointer */
        !          1093:        x = jnk = scrjnk[mline];
        !          1094:        while (x < n) mp[x++] = BLANK; /* Clear out the spaces we will write */
        !          1095:        x = mcol;                       /* Get mcol into a register */
        !          1096:        stop = 0;
        !          1097:        while (1) {
        !          1098:                while (mp[x]== cp[x]) x++; /* skip rapidly over same stuff */
        !          1099:                if ((mp[x] == 0) && (cp[x] == ' ')) {
        !          1100:                        x++;
        !          1101:                        continue;
        !          1102:                }
        !          1103:                if ((cp[x] == EOM)) {
        !          1104:                        mcol = x;
        !          1105:                        if (x < jnk) x = jnk;
        !          1106:                        scrjnk[mline] = x;
        !          1107: 
        !          1108:                        if ((scrcol > REALWID) && SCRWRAP) {
        !          1109:                                scrlin++;
        !          1110:                                scrcol=0;
        !          1111:                        }
        !          1112:                        return;
        !          1113:                }
        !          1114:                
        !          1115: /* Character was not there, we must do some work here! */
        !          1116: 
        !          1117:                nmput++;                        /* count for stats */
        !          1118:                if ((x != scrcol) || (mline != scrlin)) sgo(mline,x);
        !          1119: 
        !          1120: /* First, see if we have enough left to worry about insert/delete */
        !          1121:                
        !          1122:                if (jnk-x >= lDELC) {
        !          1123:                        if (stop == 0) {
        !          1124: 
        !          1125:                                /* Find the last matching position */
        !          1126:                                
        !          1127:                                stop = n-1;
        !          1128:                                if (stop >= jnk) stop = jnk;
        !          1129:                                while ((mp[stop] == 0) && (cp[stop] == ' ')) stop--;
        !          1130:                                while (mp[stop] == cp[stop]) stop--;
        !          1131:                                stop++;
        !          1132:                        }
        !          1133:                        
        !          1134: /* Try to use DELC.  Must have at least lDELC characters match within
        !          1135:  * DLOOK characters of the current position. */
        !          1136:   
        !          1137: /* Note:   If there are ANY nulls in the characters to be deleted, we */
        !          1138: /*        Can't use DELC, since the concept-style terminals won't delete*/
        !          1139:                        
        !          1140: 
        !          1141:                        if (DELC&& mp[x]) {
        !          1142:        
        !          1143:                                y = 1;
        !          1144:                                while (y < DLOOK && mp[x+y]) {
        !          1145:                                        if (mp[x+y] == cp[x] ) {
        !          1146:                                                z = dccost * y;
        !          1147:                                                if (y+z+x >stop) goto NoDEL;
        !          1148:                                                if (strncmp(cp+x,mp+x+y,z)) goto NoDEL;
        !          1149:                 /* Should be next_del, but this is faster */
        !          1150:                
        !          1151:                                                /* Delete y characters from under the cursor */
        !          1152:        
        !          1153:                                                SREGION=SCRWID-x; /* number of char's gobbled */
        !          1154:                                                if ((DELMODE==1) && (osert == 0)) {
        !          1155:                                                        PUTS(INSERTM);  /* enter "delete mode, UGH!!!" */
        !          1156:                                                        osert = 1;
        !          1157:                                                }
        !          1158:                                                if ((DELMODE==2) && osert) {
        !          1159:                                                        unsert();  /* Must not be in insert mode */
        !          1160:                                                }
        !          1161:                                                if (x > jnk) jnk = x;
        !          1162:                                                while (y--) {
        !          1163:        
        !          1164:                                                        PUTS(DELC);     /*clobber next char */
        !          1165:                                                        jnk = lshift(scrlin,x,jnk-1);
        !          1166:                                                }
        !          1167:                                                stop = 0;       /* Don't know where to stop any more */
        !          1168:                                                SREGION=1;
        !          1169:                                                x += z;         /* This many matched */
        !          1170:                                                goto donec;     /* Process next character */
        !          1171:                                        }
        !          1172: next_del:                              y++;
        !          1173:                                }
        !          1174:                        }
        !          1175: 
        !          1176: 
        !          1177: /* Now see if insertion will help.  It will be used if lINSC
        !          1178:  * characters can be matched within ILOOK characters of the cursor. */
        !          1179: 
        !          1180: NoDEL:         
        !          1181:                        if ((INSERTC || INSERTM) && (stop > x+lINSC) && ((cp[x] & 0200) == 0)) {
        !          1182:                                y = 1;
        !          1183:                                while ((y<ILOOK) && (x+y < stop) && ((cp[x+y]&0200) == 0)) {
        !          1184:                                        if (cp[x+y] == mp[x]) {
        !          1185: 
        !          1186: /* Found a match, now figure out how much we should have to see before inserting */
        !          1187:                                                
        !          1188:                                                if (INSERTC) z = y * iccost;
        !          1189: /* If inserting is per-character, then each one costs iccost */
        !          1190: /* Otherwise, it costs iccost to go into and out of icmode */
        !          1191:                                                
        !          1192:                                                else {
        !          1193:                                                        if (osert) z = 0;
        !          1194:                                                        else z = iccost;
        !          1195:                                                }
        !          1196: /* After a successful insert, we will need cursor motion, so add that too. */
        !          1197:                                                z += acost;
        !          1198:                                                if ((x+y+z)>stop) goto NOINS;
        !          1199:                                                if (strncmp(cp+x+y,mp+x,z)) goto NOINS;
        !          1200: 
        !          1201: 
        !          1202: 
        !          1203: /* Now insert y characters at point, taking from cp and putting out to
        !          1204:  * screen.  Note that underscores and overstrikes are rejected
        !          1205:  * above, so that nothing here will overstrike.  We just blast out
        !          1206:  * the characters. */
        !          1207:                                                if (x > jnk) jnk = x;
        !          1208:                                                SREGION=jnk-x; /* number of char's moved */
        !          1209:                                                if (umode) unline();
        !          1210:                                                if ((osert == 0) && INSERTM) {
        !          1211:                                                        PUTS(INSERTM); /* insert mode */
        !          1212:                                                        osert++;
        !          1213:                                                }
        !          1214: 
        !          1215:                                                while (y--) {
        !          1216:                                                        if (INSERTC) PUTS(INSERTC); /* insert prepare */
        !          1217:                                                        putchar(cp[x]);
        !          1218:                                                        if (INSERTP) PUTS(INSERTP); /* insert pad */
        !          1219:                                                        jnk = rshift(scrlin,scrcol+1,mp[scrcol]);
        !          1220:                                                        mp[scrcol++] = cp[x++];
        !          1221:                                                }
        !          1222:                                                x+= z;
        !          1223:                                                SREGION=1;
        !          1224:                                                stop = 0;       /* Stop is no good any more */
        !          1225:                                                goto donec;             /* process next character */
        !          1226:                                        }
        !          1227: next_ins:                      y++;
        !          1228:                                }
        !          1229:                        }
        !          1230:                }
        !          1231: NOINS: if (osert) {
        !          1232:                        unsert();
        !          1233:                }
        !          1234: 
        !          1235: /* Underscore processing.  relevant variables are EOVER and ULINE. 
        !          1236:  * EOVER should be one if writing over an underlined position clears
        !          1237:  * it, otherwise, make it zero, and we will clear the line to get
        !          1238:  * rid of unwanted underscores.  ULINE is a string parameter that
        !          1239:  * contains whatever is needed to print the character with an
        !          1240:  * underline.  If the terminal underscores naturally, then ULINE is
        !          1241:  * %c<BS>_.  If the terminal has an underscore character mode,
        !          1242:  * then ULINE is underscore mode on, %c, underscore mode off.  If
        !          1243:  * the terminal has an underscore single character command, then
        !          1244:  * ULINE is underscore character %c.  This is inefficient in
        !          1245:  * underscoring giant blocks of text, but this should be rare */
        !          1246: 
        !          1247: 
        !          1248:                if (cp[x]&0200){
        !          1249:                        pu(cp[x]); /* underlined character */
        !          1250:                } else {
        !          1251:                        if (umode) unline();
        !          1252:                        if ((mp[x]&0200)&& (!EOVER)) { /* If re-writing won't erase */
        !          1253:                                PUTS(CLINE); /* wipe line */
        !          1254:                                while (jnk > scrcol) mp[--jnk] = BLANK; /* Wipeout array */
        !          1255:                        }
        !          1256:                        putchar(cp[x]);
        !          1257:                }
        !          1258:                mp[scrcol++] = cp[x++];
        !          1259: donec: continue;               
        !          1260:        }
        !          1261: }
        !          1262: 
        !          1263: /* print an underscored character.  */
        !          1264: 
        !          1265: 
        !          1266: pu(c)
        !          1267: register char c;
        !          1268: {
        !          1269: /* Keywords: screen-handling:20 underlining character-output:40 */
        !          1270:        
        !          1271:        register int oc;
        !          1272:        if (osert) unsert();
        !          1273:        c &= 0177;
        !          1274:        if ((c == 0)|| (c == 040)) {
        !          1275:                                        /* bare underscore */
        !          1276:                oc = cmap[mline][mcol]&0137;  /* Map space to null */
        !          1277:                if (EOVER && (UEND || (oc == 0))) {
        !          1278:                        if (umode) unline();
        !          1279:                        putchar ('_');
        !          1280:                        return;         /* just put out the underscore */
        !          1281:                }
        !          1282:                c = ' ';                /* make sure that we blank over whats there */
        !          1283:        }
        !          1284:        if (UEND == 0) {
        !          1285:                eprintf(ULINE,c);
        !          1286:        } else {
        !          1287:                if (umode == 0) eprintf(ULINE); /* enter "underscore mode" */
        !          1288:                putchar(c);
        !          1289:                umode = 1;
        !          1290:        }
        !          1291: }
        !          1292: 
        !          1293: 
        !          1294: 
        !          1295: /* lshift -- left shift the screen to account for delete character */
        !          1296: 
        !          1297: lshift (line,col,limit)
        !          1298: int line;
        !          1299: register int col; 
        !          1300: register int limit; 
        !          1301: 
        !          1302: /* Keywords: character-output the-screen-map deletion */
        !          1303: {
        !          1304:        register char *lp;
        !          1305:        int x;
        !          1306:        
        !          1307:        lp = cmap[line];
        !          1308:        while (col < limit) {
        !          1309:                if ((lp[col]=lp[col+1]) == 0) break;
        !          1310:                col++;
        !          1311:        }
        !          1312:        lp[col] = 0;
        !          1313:        if (IN && (col == SCRWID)) {
        !          1314:                x = lp[col] = cmap[++line] [0];
        !          1315:                limit++;
        !          1316:                if (x) scrjnk[line] = lshift(line,0,scrjnk[line]-1);
        !          1317:        }
        !          1318:        return(limit);
        !          1319: }
        !          1320: 
        !          1321: /* rshift -- right shift the screen to account for insert character */
        !          1322: 
        !          1323: rshift (line,col,x)
        !          1324: int line;                      /* effected line */
        !          1325: int col;                       /* column to start in */
        !          1326: register int x;                        /* displaced character that goes in col */
        !          1327: {
        !          1328: /* Keywords: character-output the-screen-map insertion */
        !          1329:        
        !          1330:        int y;
        !          1331:        int jnk;
        !          1332:        register char *stop;
        !          1333:        register char *lp;
        !          1334:        
        !          1335:        lp = cmap[line];
        !          1336:        jnk = scrjnk[line];
        !          1337:        if (jnk <=SCRWID) lp[jnk] = 0;
        !          1338:        
        !          1339:        stop = lp+SCRWID;
        !          1340:        lp += col;
        !          1341:        
        !          1342:        while (x  && (lp<= stop)) {
        !          1343:                y = *lp;
        !          1344:                *lp++ = x;
        !          1345:                x = y;
        !          1346:        }
        !          1347:        if (IN) {
        !          1348:                y = lp - cmap[line];
        !          1349:                if (y > jnk) jnk = y;
        !          1350:                if (x) rshift(line+1,0,x);
        !          1351:        } else {
        !          1352:                if (jnk < SCRWID) jnk++;
        !          1353:        }
        !          1354:        scrjnk[line] = jnk;
        !          1355:        return(jnk);
        !          1356: #endif
        !          1357: }
        !          1358: 
        !          1359: /* put a "logical line" of characters on the screen at the current position */
        !          1360: 
        !          1361: /* NOTE:  This is not very clean, but seems necessary to handle all of the
        !          1362:  * various strange possibilities for displaying characters.  We must
        !          1363:  * process a line at a time in order to handle things like
        !          1364:  * underscoring, by which multiple characters map to a single
        !          1365:  * display position.  The general principals here are:  that there
        !          1366:  * two ways of calling it, one with a C string to be printed, and
        !          1367:  * one with a buffer string to be printed.  C strings end in nulls,
        !          1368:  * and cause a special character to be mapped to embedded newlines. 
        !          1369:  * Buffer strings end in newlines, and map normally.  Underscoring
        !          1370:  * is inidicated by the presence of the meta (0200) bit on
        !          1371:  * characters in the display map, so that mapping is done here.  To
        !          1372:  * do this, a whole line is buffered for cput.  Underscoring will
        !          1373:  * work fine so long as the underscores are done one at a time, or
        !          1374:  * the underscores don't wrap lines.  Control and meta characters
        !          1375:  * map to their special emacs equivalents.
        !          1376:  */
        !          1377: 
        !          1378: 
        !          1379: xputl(cp,flg,col)
        !          1380: 
        !          1381: register char *cp;                     /* string pointer */
        !          1382: int flg;                               /* disposition flag */
        !          1383: int col;
        !          1384: 
        !          1385: /* Keywords: character-output the-screen-map:20 screen-handling conversions:50 underlining:20 the-screen-cursor:10 ^-and-M-processing:40 */
        !          1386: 
        !          1387: {
        !          1388:        char cbuf[256];                 /* line buffer */
        !          1389:        register int i;
        !          1390:        register int b;
        !          1391:        int mb;
        !          1392:        int a;
        !          1393: 
        !          1394:        mb = b = mcol;                          /* buffer pointer */
        !          1395: 
        !          1396:        while (1) {
        !          1397:                if (b > mb) mb = b;
        !          1398:                if (b > SCRWID) {
        !          1399: 
        !          1400: /* Line has wrapped.  Put a ! on the end, and wrap anything that is left
        !          1401:  * over to the next line */
        !          1402: 
        !          1403:                        i = cbuf[SCRWID];
        !          1404:                        a = cbuf[SCRWID+1];
        !          1405: 
        !          1406: /* i is the character overwritten by the !, a is the character */
        !          1407: /* overwritten by the EOM in cflush */
        !          1408: 
        !          1409:                        if (mline>=SCRNLIN-1) {
        !          1410: 
        !          1411: /* Wrap from last line on screen, fold back up and don't write in
        !          1412:  * the last position! */
        !          1413:                                cflush(cbuf,SCRWID);
        !          1414:                                mline--; /* don't run overboard */
        !          1415:                        } else {
        !          1416:                                cbuf[SCRWID]='!';
        !          1417:                                cflush(cbuf,SCRWID+1);
        !          1418:                                if (flg && PICMODE) {
        !          1419:                                        if (col>0) hrem = 1+column-col;
        !          1420:                                        return;
        !          1421:                                }
        !          1422:                                mline++;
        !          1423:                                scrmap[mline] = scrow+SCRCNL; /* mark continuation */
        !          1424:                        }
        !          1425:                        mcol = 0;
        !          1426:                        b = 0; 
        !          1427:                        while(b < LNOMOD*LNOWID) cbuf[b++] = ' ';
        !          1428:                        cbuf[b++] = i;
        !          1429:                        i = SCRWID+2;
        !          1430:                        if (SCRWID+1<mb) cbuf[b++] = a;
        !          1431:                        while (i < mb) {
        !          1432:                                cbuf[b++] = cbuf[i++];
        !          1433:                        }
        !          1434:                        mb = b;         /* RESET */
        !          1435:                }
        !          1436: 
        !          1437: /* Process Next character */
        !          1438:                
        !          1439:                i = (*cp++)&0377;               /* next char */
        !          1440:                
        !          1441:                if (flg) {              /* if buffer invocation */
        !          1442:                        if (col++ == column) {
        !          1443:                                nln = mline;
        !          1444:                                ncol = b;
        !          1445:                        }
        !          1446:                        if (i == EOL) {
        !          1447:                                cflush(cbuf,mb);
        !          1448:                                return; /* done */
        !          1449:                        }
        !          1450:                } else {
        !          1451:                        if (i == 0) {
        !          1452:                                cflush(cbuf,mb);
        !          1453:                                return; /* done */
        !          1454:                        }
        !          1455:                        if (i == NEWLINE) { /* embedded newline */
        !          1456:                                cflush(cbuf,b);
        !          1457:                                clrl();
        !          1458:                                mb = b = 0;
        !          1459:                                if (mline < SCRNLIN) mline++; /* don't overflow */
        !          1460:                                scrmap[mline] = 0;
        !          1461:                                mcol = 0;
        !          1462:                                continue; /* re-loop */
        !          1463:                        }
        !          1464:                }
        !          1465:                
        !          1466:                if ((i & META)&& (bit8== 0))  {
        !          1467:                        cbuf[b++] ='M';
        !          1468:                        cbuf[b++] = '-';
        !          1469:                        if (b>mb) mb=b;
        !          1470:                        i-= META;
        !          1471:                }
        !          1472: reswitch:      switch(ctype[i&0177]) {
        !          1473:                case UL:
        !          1474:                        if (ULINE) i = 0200; /* terminal underlines */
        !          1475: 
        !          1476:                        /* else just a plain old character */
        !          1477:                        
        !          1478:                case PLAIN:
        !          1479:                        if ((b < mb) && ((i & 0200) || (cbuf[b] & 0200))){
        !          1480:                                i |= cbuf[b]; /* overstrike */
        !          1481:                        }
        !          1482:                        cbuf[b++] = i;
        !          1483:                        break;
        !          1484: 
        !          1485:                case BACKSP:
        !          1486:                        if (b>mcol) b--;
        !          1487:                        break;
        !          1488:                        
        !          1489:        /*Fall through to handle backspace in normal mode */
        !          1490:                        
        !          1491:                case CONTRL:
        !          1492:                        
        !          1493:                        cbuf[b++] = '^';
        !          1494:                        i = i^0100;
        !          1495:                        goto reswitch; /* Handle things like ^_ correctly! */
        !          1496:                case TAB:
        !          1497:                        i = TABSTOP-((b-(LNOMOD*LNOWID))%TABSTOP);
        !          1498:                        while (i--) {
        !          1499:                                cbuf[b++] = ' ';
        !          1500:                        }
        !          1501:                        break;
        !          1502:                }
        !          1503:        }
        !          1504: }
        !          1505: 
        !          1506: /* cput -- put a character in the file, like xputl */
        !          1507: 
        !          1508: 
        !          1509: cput(c)
        !          1510: register int c;
        !          1511: /* Keywords: insertion help-messages ^-and-M-processing */
        !          1512: {
        !          1513:        c &= 0377;
        !          1514:        if (c & META) {
        !          1515:                put('M');
        !          1516:                put('-');
        !          1517:                c-= META;
        !          1518:        }
        !          1519:        switch(ctype[c]) {
        !          1520: 
        !          1521:        case UL:
        !          1522:        case PLAIN:
        !          1523:                put(c);
        !          1524:                break;
        !          1525:        default:
        !          1526:                put('^');
        !          1527:                put(c^0100);
        !          1528:                break;
        !          1529:        }
        !          1530: }
        !          1531: 
        !          1532: 
        !          1533: 
        !          1534: /* clear the rest of the line, checking to see if the line previously
        !          1535:  * displayed corresponds to the one displayed here now */
        !          1536: 
        !          1537: clrl()
        !          1538: /* Keywords: prompting:10 display-format:20 informational-displays:30 screen-lines clearing */
        !          1539: {
        !          1540:        register int x;
        !          1541:        register int y;
        !          1542:        register int z;
        !          1543:        char *xln;
        !          1544:        int xcol;
        !          1545: #ifdef PC
        !          1546:        char buf[130];
        !          1547: #endif
        !          1548:        x = mline;
        !          1549:        z = mcol;
        !          1550:        y = scrjnk[mline] - mcol;
        !          1551:        if (y > 0) {
        !          1552: #ifdef PC
        !          1553:                buf[y]=0;
        !          1554:                for (x = 0; x < y; x++) buf[x] = ' ';
        !          1555:                x = mline;
        !          1556:                vout(mline,mcol,buf);
        !          1557: #else
        !          1558:                sgo(mline,mcol);                        /* go for real */
        !          1559:                if (CLINE) {
        !          1560:                        PUTS(CLINE);
        !          1561:                } else {
        !          1562:                        xln = cmap[mline];
        !          1563:                        xcol = mcol;
        !          1564:                        while (y--) {
        !          1565:                                if (xln[xcol] && xln[xcol] != ' ') {
        !          1566:                                        sgo(mline,xcol);
        !          1567:                                        putchar(' '); /* wipe line */
        !          1568:                                        if ((scrcol++ >= REALWID) && SCRWRAP) {
        !          1569:                                                scrlin++;
        !          1570:                                                scrcol=0;
        !          1571:                                        }
        !          1572:                                }
        !          1573:                                xcol++;
        !          1574:                        }
        !          1575:                }
        !          1576: #endif         
        !          1577:                scrjnk[x] = z;
        !          1578:        }
        !          1579: }
        !          1580: 
        !          1581: /* findline -- find a line on the screen */
        !          1582: 
        !          1583: /* findline makes no judgement as to whether or not the line is correct  */
        !          1584: /* whether or not the screen is OK up to the line */
        !          1585: 
        !          1586: findline(line)
        !          1587: register int line;
        !          1588: 
        !          1589: /* Keywords: the-screen-cursor screen-lines screen-handling the-screen-map:10 */
        !          1590: 
        !          1591: {
        !          1592:        register int i;
        !          1593:        
        !          1594:        if (disbuf[cwind] == curbf) {
        !          1595:                for (i = wbase; i < SCRLINES; i++) {
        !          1596:                        if (scrmap[i] == line) {
        !          1597:                                nln = i;
        !          1598:                                return(1);
        !          1599:                        }
        !          1600:                }
        !          1601:        }
        !          1602:        return(0);
        !          1603: }
        !          1604: 
        !          1605: /* find the screen address of a file */
        !          1606: 
        !          1607: /* The result is to set mcol and mline and return 1 if found
        !          1608:  * found, otherwise 0 is returned */
        !          1609: 
        !          1610: 
        !          1611: findpos(line,col)
        !          1612: 
        !          1613: register char *line;
        !          1614: register int col;
        !          1615: 
        !          1616: /* Keywords: the-screen-cursor ^-and-M-processing:50 screen-lines screen-handling the-screen-map:10 picture-mode:10 */
        !          1617: {
        !          1618:        register int i;
        !          1619:        char c;
        !          1620:        
        !          1621:        mcol = LNOMOD*LNOWID;
        !          1622:        i = 0;
        !          1623:        while (i < hcol) if (line[i++] == EOL) return(0);
        !          1624:        for (i = hcol; i < col; i++) {
        !          1625:                if ((c= line[i]) == EOL) return(0);
        !          1626:                if (c & META) mcol += metal;
        !          1627:                switch(ctype[c&0177]) {
        !          1628: 
        !          1629:                case PLAIN:
        !          1630:                case UL:
        !          1631:                        mcol++;
        !          1632:                        break;
        !          1633:                case BACKSP:
        !          1634:                        if (mcol) mcol--;
        !          1635:                        break;
        !          1636:                case CONTRL:
        !          1637:                        mcol+=2;
        !          1638:                        break;
        !          1639:                case TAB:
        !          1640:                        mcol = mcol+TABSTOP-((mcol-(LNOMOD*LNOWID))%TABSTOP);
        !          1641:                        break;
        !          1642:                }
        !          1643:                if (mcol>SCRWID) {
        !          1644:                        if (PICMODE) {
        !          1645:                                hrem = col-i;
        !          1646:                                return(0);
        !          1647:                        }
        !          1648:                        if (++mline>SCRLINES) return(0);
        !          1649:                        mcol = mcol-SCRWID;
        !          1650:                        if (LNOMOD) mcol+= LNOWID;
        !          1651:                }
        !          1652:        }
        !          1653:        return(1);
        !          1654: }
        !          1655: 
        !          1656: /* The following function scans the text above "line" to compute
        !          1657:  * it's physical size.  The scan continues until either hstop physical
        !          1658:  * screen lines are found or the line lstop is reached.  The line at
        !          1659:  * which the scan stopped is returned, and the screen area is left
        !          1660:  * in the global "dsize" */
        !          1661: 
        !          1662: areal(line,hstop,lstop)
        !          1663: /* Keywords: screen-lines display-update:30 screen-handling */
        !          1664: 
        !          1665: 
        !          1666: int line;
        !          1667: int hstop;
        !          1668: int lstop;
        !          1669: 
        !          1670: {
        !          1671:        register char *lp;
        !          1672:        register int col;
        !          1673:        register int c;
        !          1674:        
        !          1675:        dsize = 0;
        !          1676:        while ((line > lstop) && (dsize < hstop)) {
        !          1677:                --line;
        !          1678:                dsize++;
        !          1679:                if (PICMODE) continue; /* Picture mode gets one line/line */
        !          1680:                
        !          1681:                lp = mkline(line);
        !          1682:                col = LNOMOD*LNOWID;
        !          1683:                while ((c = *lp++) != EOL) {
        !          1684:                        if (c & META) col += metal;
        !          1685:                        switch(ctype[c&0177]) {
        !          1686:        
        !          1687:                        case PLAIN:
        !          1688:                        case UL:
        !          1689:                                col++;
        !          1690:                                break;
        !          1691:                        case BACKSP:
        !          1692:                                if (col) col--;
        !          1693:                                break;
        !          1694:                        case CONTRL:
        !          1695:                                col+=2;
        !          1696:                                break;
        !          1697:                        case TAB:
        !          1698:                                col = col+TABSTOP-((col-(LNOMOD*LNOWID))%TABSTOP);
        !          1699:                                break;
        !          1700:                        }
        !          1701:                        if (col>SCRWID) {
        !          1702:                                dsize++;
        !          1703:                                col = col-SCRWID;
        !          1704:                                if (LNOMOD) col+= LNOWID;
        !          1705:                        }
        !          1706:                }
        !          1707:        }
        !          1708:        return(line);
        !          1709: }
        !          1710: 
        !          1711: /* print a line number(x) */
        !          1712: 
        !          1713: lnumb(x)
        !          1714: 
        !          1715: /* Keywords: line-numbers informational-displays screen-handling */
        !          1716: {
        !          1717:        register int i;
        !          1718:        char tbuf[8];
        !          1719:        
        !          1720:        for (i=0; i<8; i++) tbuf[i]=0;
        !          1721:        seprintf(tbuf,"%d",x);
        !          1722:        mcol = 0;                                               /* make sure were at start of line */
        !          1723:        
        !          1724:        for (i=0; i<LNOWID; i++) {
        !          1725:                if (tbuf[i] == 0) tbuf[i] = ' ';
        !          1726:        }
        !          1727:        cflush(tbuf,LNOWID);            /* output to terminal */
        !          1728: }
        !          1729: /* putin -- insert string into file */
        !          1730: 
        !          1731: 
        !          1732: putin(xp)
        !          1733: 
        !          1734: register char *xp;
        !          1735: 
        !          1736: /* Keywords: informational-displays help-messages:50 error-messages:50 screen-handling */
        !          1737: {
        !          1738:        register int c;
        !          1739:        RARE = 1;
        !          1740:        while (c = *xp++) {
        !          1741:                if (c == NEWLINE) {     /* Note that NEWLINE != '\n' */
        !          1742:                        nl(1);
        !          1743:                        put('   ');
        !          1744:                }
        !          1745:                else put(c);
        !          1746:        }
        !          1747:        RARE = 0;
        !          1748: }
        !          1749: 
        !          1750: /* dspage  -- re-position display with (line) first.  If  */
        !          1751: /* the move argument is non-zero, the cursor is moved into the middle */
        !          1752: /* of the new display */
        !          1753: 
        !          1754: dspage(line,moves)
        !          1755: int line;
        !          1756: int moves;
        !          1757: 
        !          1758: /* Keywords: commands display-update:30 the-screen-cursor scrolling */
        !          1759: {
        !          1760:        if (line<1) {
        !          1761:                if (minln > 1) line=1;
        !          1762:                else {
        !          1763:                        beep();
        !          1764:                        return(0);
        !          1765:                }
        !          1766:        }
        !          1767:        if (line > nlines) {
        !          1768:                if (maxln < nlines) line = nlines;
        !          1769:                else {
        !          1770:                        beep();
        !          1771:                        return(0);
        !          1772:                }
        !          1773:        }
        !          1774:        fclear();                       /* just blew up file */
        !          1775:        if (disbuf[cwind] != curbf) {
        !          1776:                
        !          1777: /* NOTE:  This is a pain!  display is out of date because we were
        !          1778:  * called from a macro, If we don't do something here, disup will pick
        !          1779:  * a new window when we change buffers.  What we do is not very
        !          1780:  * good, but it works?
        !          1781:  */
        !          1782: 
        !          1783:                if (junked || ((twowind == 0) && (CLINE == 0))) {
        !          1784:                        clear();        /* dumb terminal or command */
        !          1785:                } else {
        !          1786:                        xclear();       /* others, just clobber map */
        !          1787:                }
        !          1788:                disbuf[cwind] = curbf;          /* avoid reset in disup */
        !          1789:        }
        !          1790:        minln = line;
        !          1791:        maxln = line+SCRLINES-wbase; /* This is just a guess, but should make it to disup all right. */
        !          1792:        if (maxln > nlines) maxln = nlines;
        !          1793:        if (moves) move((minln+maxln)/2,0);
        !          1794:        return(0);
        !          1795: }
        !          1796: /* nxtpag -- move to next page */
        !          1797: 
        !          1798: nxtpage(count)
        !          1799: 
        !          1800: register int count;
        !          1801: 
        !          1802: /* Keywords: display-update:20 the-screen-cursor:30 movement commands forwards paging */
        !          1803: 
        !          1804: {
        !          1805: 
        !          1806:        return(dspage((maxln+1+((count-1)*(SCRLINES-wbase)))-keepg,1));
        !          1807: }
        !          1808: 
        !          1809: /* move to top of page (current line becomes first line)  */
        !          1810: 
        !          1811: toppage()
        !          1812: 
        !          1813: /* Keywords: display-update:20 the-screen-cursor:30 movement scrolling commands backwards */
        !          1814: {
        !          1815:        dspage(curln,0);
        !          1816: }
        !          1817: 
        !          1818: /* move to previous page */
        !          1819: 
        !          1820: lstpage(count)
        !          1821: 
        !          1822: register int count;
        !          1823: 
        !          1824: /* Keywords: display-update:20 the-screen-cursor:30 movement commands backwards upward-movement:50 paging */
        !          1825: {
        !          1826:        return(dspage((minln-count*(SCRLINES-wbase))+keepg,1));
        !          1827: }
        !          1828: 
        !          1829: clear()
        !          1830: /* Keywords: clearing screen-handling the-screen-map:40 terminal-parameters:20 terminal-initialization:30 */
        !          1831: {
        !          1832:        register int i;
        !          1833: #ifdef PC
        !          1834: 
        !          1835:        video(REG(SCRL_UP,0),REG(NORMATB,0),0,REG(SCRNLIN,SCRWID));
        !          1836: #else
        !          1837:        PUTS(CLEAR);
        !          1838: #endif
        !          1839:        for (i = 0; i < SCRNLIN; i++) scrmap[i] = scrjnk[i] = 0;
        !          1840:        scrlin = scrcol = mline = mcol = 0;
        !          1841:        disbuf[0]=disbuf[1]= -1;
        !          1842:        junked = minln = maxln = 0;
        !          1843:        if (timemd) disptime = 1;       /* Wiped out time display */
        !          1844: }
        !          1845: 
        !          1846: 
        !          1847: /* didle (display idle) update display and idle for the specified time */
        !          1848: 
        !          1849: didle(count)
        !          1850: 
        !          1851: int count;
        !          1852: {
        !          1853: /* Keywords: macro-programming display-update:10 time-processing:20 screen-handling */
        !          1854:        
        !          1855:        if (count > 100) count = 100;   /* limit to 10 seconds */
        !          1856:        pushin(NULL);                   /* make sure we will update */
        !          1857:        disup();
        !          1858:        mflush(stdout);
        !          1859: #ifndef PC
        !          1860:        while (count--) PUTS (WAIT1);
        !          1861: #endif
        !          1862:        inpop();
        !          1863: }
        !          1864: 
        !          1865: /* disup() update display.  disup should be called whenever you want the */
        !          1866: /* to be up to date.  disup does not update if there is more input */
        !          1867: /* available from the current input source. */
        !          1868: 
        !          1869: /* This is the high level display algorithm, which translates the
        !          1870:  * buffer into a screen image.  The pparameters affecting the algorithm are
        !          1871:  * 
        !          1872:  * scrmap[SCRNLIN]     map from the display line to the file line on
        !          1873:  *                     that line of the display.
        !          1874:  * fmap[SCRNLIN]       map from the file indicating what the smallest
        !          1875:  *                     column in the file containing undisplayed changes
        !          1876:  *                     is.  A special value (LGOOD) indicates that
        !          1877:  *                     the whole line is good.  This avoids looking at
        !          1878:  *                     the lines in the file that are known to be ok.
        !          1879:  * minln               The file line appearing at the top of the current
        !          1880:  *                     window.
        !          1881:  * maxln               The last file line appearing in this window.
        !          1882:  * lastln              The screen line on which maxln is displayed.
        !          1883:  * curbf[2]            The buffer displayed in each window.
        !          1884:  * dahead              Flag indicating that we are displaying the line 
        !          1885:  *                     with the cursor ahead of schedule.
        !          1886:  * 
        !          1887:  * The basic algorithm is to firsst check to see if the window is properly
        !          1888:  * positioned to hold the cursor.  If not, a new window is chosen and minln
        !          1889:  * reset.  Then, each line that should be displayed is examined for
        !          1890:  * changes.  Any lines needing updating are redisplay.  A side effect of
        !          1891:  * the scan is to find the screen address of the current line.  If the
        !          1892:  * screen address is found, the mode line and window splitting line are
        !          1893:  * updated (if necessary), and any other lines are blanked.  If the cursor
        !          1894:  * wasn't found, it tries once again to display starting with the current 
        !          1895:  * line.  This can happen only if the line before the current line or the 
        !          1896:  * current line is gigantic, wrapping lots of times around the screen.  
        !          1897:  * Repeated failures signal a fatal error and indicate a bug or an 
        !          1898:  * enormous current line.
        !          1899:  */
        !          1900: 
        !          1901: /* status display */
        !          1902: 
        !          1903: char mdchar[2] = {'=', '>'};
        !          1904: 
        !          1905: 
        !          1906: disup()                                /* force update display */
        !          1907: 
        !          1908: {
        !          1909: 
        !          1910: /* Keywords: clearing:5 screen-handling display-update scrolling:10 insertion:10 deletion:10 */
        !          1911: 
        !          1912: /* Keywords: lookahead:20 the-screen-cursor:20 the-screen-map:20 screen-lines:10 mode-line:20 macro-hooks:10 */
        !          1913:        register int col;
        !          1914:        int fixed;
        !          1915:        register char *cp;
        !          1916:        long pm;        
        !          1917:        int *fmp;
        !          1918:        int dahead;
        !          1919:        char pmbuf[10];
        !          1920:        char hcbuf[10];
        !          1921:        char smap[NSCRLIN];
        !          1922:        int smapped;
        !          1923:        
        !          1924:        if (MOREIN) return;
        !          1925:        fixed = smapped = 0 ;
        !          1926:        dahead = 0;
        !          1927:        nln = ncol = hrem = -1;
        !          1928: 
        !          1929: /* Check to see if what is on the screen is from the same buffer.  If
        !          1930:  * not, don't try to re-use it
        !          1931:  */
        !          1932:        if (disbuf[cwind] != curbf) {
        !          1933:                minln = 0;              /* force repositioning */
        !          1934:                if (CLINE || twowind) {
        !          1935:                        xclear();       /* force redisplay */
        !          1936:                } else {
        !          1937:                        clear();        /* try to optimize dumb terminal */
        !          1938:                }
        !          1939:                disbuf[cwind] = curbf;          /* mark buffer up to date */
        !          1940:        }
        !          1941: 
        !          1942: /* See if the current line is on the screen.  The check is not absolutely
        !          1943:  * perfect.  If the current line is not on the screen, a new position
        !          1944:  * is picked.  Mis-guessing will be caught eventually.
        !          1945:  */
        !          1946: 
        !          1947: 
        !          1948:        if ((minln == 0) ||(curln <minln) || ((curln> maxln) && (curln-maxln+lastln>=SCRLINES))) {
        !          1949: 
        !          1950:                                        /* display position is bad */
        !          1951: 
        !          1952:                if (junked) {
        !          1953:                        clear();
        !          1954:                        disbuf[cwind] = curbf;          /* mark buffer up to date */
        !          1955:                }
        !          1956: badpos:
        !          1957:                if (hrem>0) {
        !          1958:                        hcol = hcol+4+(hrem-hrem%4);
        !          1959:                        hrem = -1;
        !          1960:                        fclear();
        !          1961:                        goto retry;
        !          1962:                }
        !          1963:                if(fixed++) {
        !          1964:                        if (fixed > 2) error(FATAL,42); /* can't find cursor */
        !          1965:                        minln = curln;
        !          1966:                } else {
        !          1967:                        minln = areal(curln,(SCRLINES-wbase)/2,1);
        !          1968:                }
        !          1969:                fclear();               /* file bad */
        !          1970:                if (SCREG || LOPEN) {
        !          1971:                        if ((minln > 1) && (minln < curln)) dahead = wbase+dsize;
        !          1972:                }
        !          1973:                maxln = curln;
        !          1974:        }
        !          1975: 
        !          1976:        if (column<hcol) {
        !          1977:                hcol = column-column%4;
        !          1978:                dispmod();
        !          1979:                fclear();
        !          1980:        }
        !          1981:        
        !          1982: /* Now for the real work, check all of the lines.  A line can be bad if
        !          1983:  * scrmap indicates that its not in the right place on the display
        !          1984:  * or if fmap indicates that it may have changed since being put up.
        !          1985:  */
        !          1986: 
        !          1987: retry: fmp = &fmap[-minln];
        !          1988:        mcol = 0;
        !          1989:        for (scrow = minln, mline = wbase; (scrow <= nlines) && (mline < SCRLINES);scrow++) {
        !          1990:                if (scrmap[mline] != scrow) {
        !          1991: 
        !          1992: /* line is bad, first try to bring it into position by scrolling or by
        !          1993:  * inserting/deleting lines.  This could result in the display being
        !          1994:  * corrected.
        !          1995:  */
        !          1996: #ifndef PC
        !          1997:                        if ((smapped == 0) && (LOPEN || (SSCROLL && (mline == 0)))) {
        !          1998:                                
        !          1999: 
        !          2000: /* There is some hope for scrolling, build the display map. */
        !          2001: /* We scan remaining screen lines for ones that may be of use.   */
        !          2002:                                
        !          2003: /*     smap[line-minln] = screen line (if any)  */
        !          2004: /*     scrmap[line] = 0 if known to be useless */
        !          2005: 
        !          2006:                                register int x;
        !          2007: 
        !          2008:                                for (x = 0; x < SCRLINES; x++) smap[x] = 0;
        !          2009:                                smapped = scrow+SCRLINES-mline-1;
        !          2010:                                for (x = mline+1; x < SCRLINES; x++) {
        !          2011:                                        col = scrmap[x];
        !          2012:                                        if ((col & SCRCNL) == 0) {
        !          2013:                                                if ((col<scrow) || (col > smapped)) {
        !          2014:                                                        scrmap[x] = 0; /* Useless */
        !          2015:                                                } else {
        !          2016:                                                        smap[col-minln] = x;
        !          2017:                                                }
        !          2018:                                        }
        !          2019:                                }
        !          2020:                        }
        !          2021:                        
        !          2022:        /* try to scroll the screen up with newlines */
        !          2023:                                
        !          2024:                        if ((mline == 0) && SSCROLL && (col=smap[scrow-minln])) {
        !          2025:                                sscroll(col);
        !          2026:                                smapped = 0;
        !          2027:                        } else if(LOPEN) {
        !          2028:                                
        !          2029:                                /* try to adjust screen by
        !          2030:                                 * opening and closing lines */
        !          2031:                                
        !          2032:                                if (col=smap[scrow-minln]) {
        !          2033:                                        vadjust(mline-col,mline);
        !          2034:                                        smapped = 0;
        !          2035:                                } else if (((col=scrmap[mline]&SCRMSK)>scrow) && (col <= nlines)) {
        !          2036:                                        smapped = areal(col,SCRLINES-mline,scrow);
        !          2037:                                        vadjust(dsize,mline);
        !          2038:                                        smapped = 0;
        !          2039:                                }
        !          2040:                        }
        !          2041: 
        !          2042: #endif
        !          2043:                        goto fixline;
        !          2044:                }
        !          2045:                if (fmp[scrow] < LGOOD)  {
        !          2046: 
        !          2047: fixline: 
        !          2048: 
        !          2049: /* Check for display-ahead.  If we are on the first line, jump ahead
        !          2050:  * to the current line and show it first, being careful to return
        !          2051:  * when appropriate */
        !          2052: 
        !          2053: 
        !          2054:                        if (dahead>0) {
        !          2055: 
        !          2056: /* Pick line for display ahead.  Note that in some cases, the
        !          2057:  * current line is on the screen, in which case we just use it.  If
        !          2058:  * not, we try the middle of the screen.  If this is marked as
        !          2059:  * belonging to some other line, we just ignore dahead. */
        !          2060: 
        !          2061:                                if (findline(curln)) mline = nln;
        !          2062:                                else {
        !          2063:                                        if (scrmap[dahead]) {
        !          2064:                                                dahead = 0;
        !          2065:                                                goto disline; 
        !          2066:                                        }
        !          2067:                                        if ((scrmap[dahead-1]&SCRMSK) != curln-1) {
        !          2068:                                                mgo(dahead-1,0);
        !          2069:                                                scrmap[mline]=0;
        !          2070:                                                clrl();
        !          2071:                                        }
        !          2072:                                        if ((scrmap[dahead+1]&SCRMSK) != curln+1) {                                     
        !          2073:                                                mgo(dahead+1,0);
        !          2074:                                                scrmap[mline]=0;
        !          2075:                                                clrl();
        !          2076:                                        }
        !          2077:                                        mline = dahead;
        !          2078:                                }
        !          2079:                                dahead = -1;
        !          2080:                                scrow = curln;
        !          2081:                        }
        !          2082: disline:
        !          2083: 
        !          2084: /* Now fix the display of this line.  fmap indicates where we start */
        !          2085: 
        !          2086: 
        !          2087:                        cp = mkline(scrow);
        !          2088:                        if ((scrmap[mline] == scrow) && (col =fmp[scrow])) {
        !          2089:                                if (col == LGOOD) goto skipit;
        !          2090:                                if ((scrow == curln) && (col > column)) {
        !          2091:                                        col = column;
        !          2092: 
        !          2093:                                }
        !          2094: 
        !          2095: /* Note that if we have backspace mode on, then we can't start the
        !          2096:  * line in the middle, because the line may have backspaces that
        !          2097:  * span the cursor, or have had them in its previous form.  The only
        !          2098:  * safe thing to do is re-format the whole thing and let cflush
        !          2099:  * throw most of it away. */
        !          2100: 
        !          2101:                                if ((col == 0) || BACKP) goto numbline;
        !          2102:                                if (col<hcol) col=hcol;
        !          2103:                                if (findpos(cp,col)==0) goto badpos;
        !          2104:                                cp +=col;
        !          2105:                        } else {
        !          2106:                                scrmap[mline] = scrow; /* mark line */
        !          2107: numbline:                      if(LNOMOD) lnumb(scrow);
        !          2108:                                col = 0;
        !          2109:                                while (col < hcol) {
        !          2110:                                        if (*cp==EOL) break;
        !          2111:                                        cp++;
        !          2112:                                        col++;
        !          2113:                                }
        !          2114:                        }
        !          2115:                        xputl(cp,1,((curln==scrow)?col:-1000)); /* process line */
        !          2116:                        clrl();
        !          2117:                        mline++;
        !          2118:                        mcol = 0;
        !          2119:                        fmp[scrow] = LGOOD;
        !          2120: 
        !          2121: /* if we have NDELAY I/O available, see if there is any type ahead */
        !          2122:                        
        !          2123:                        if (((int) _stdout._cnt *ttywarp) > PATIENCE) {
        !          2124:                                ttfill(); /* try to fill tty buffer */
        !          2125:                                if (MOREIN) {
        !          2126:                                        clptr = mkline(curln);
        !          2127:                                        if (maxln < scrow) maxln = scrow;
        !          2128:                                        return;
        !          2129:                                }
        !          2130:                        }
        !          2131: 
        !          2132:                } else {
        !          2133: 
        !          2134: /* line on the screen is OK, see if the current cursor position is in it */
        !          2135:                        
        !          2136: 
        !          2137: skipit:                        if (scrow == curln) {
        !          2138:                                cp = mkline(curln);
        !          2139:                                if (findpos(cp,column)) {
        !          2140:                                        nln = mline;
        !          2141:                                        ncol = mcol;
        !          2142:                                } else {
        !          2143:                                        goto badpos;
        !          2144:                                }
        !          2145:                        }
        !          2146:                        mline++;
        !          2147:                        while ((scrmap[mline]) == (scrow|SCRCNL)) mline++;
        !          2148:                        mcol = 0;
        !          2149:                }
        !          2150:                if (dahead<0) {
        !          2151:                        dahead = 0;
        !          2152:                        nln = -1;       /* Make sure we find this line later */
        !          2153:                        mline = wbase;
        !          2154:                        scrow = minln;
        !          2155:                        goto disline; /* If displaying ahead, return to finish display */
        !          2156:                }
        !          2157: /* done re-creating the display, now clean up the rest of the lines */
        !          2158: 
        !          2159:        }
        !          2160:        maxln = scrow-1;                /* last line on the screen */
        !          2161:        wminln[cwind] = minln;
        !          2162:        wmaxln[cwind] = maxln;
        !          2163:        lastln = mline-1;               /* last display line used */
        !          2164: 
        !          2165:        if (twowind && (mline == SCRLINES) && (cwind == 0)) {
        !          2166:                prompt(mline,endput);
        !          2167:                scrmap[mline]=0;
        !          2168:        }
        !          2169:        if ((scrow > nlines) || (mline == SCRLINES)) {
        !          2170:                while (mline < SCRLINES+1) {
        !          2171:                        if ((twowind == 0) || (mline < SCRLINES) || cwind) {
        !          2172:                                if (scrjnk[mline])clrl();
        !          2173:                                scrmap[mline++]=0;
        !          2174:                        } else mline++;
        !          2175:                }
        !          2176:        }
        !          2177:        if (nln < 0) {
        !          2178:                goto badpos;            /* oops, blew it agaiin */
        !          2179:        }
        !          2180:        if ((scrmap[MODLN] != MODHACK)||PMODE) {
        !          2181: 
        !          2182: /* Pre-format sections for display-percent mode and horizontal scrolling */
        !          2183: 
        !          2184:                if (hcol) {
        !          2185:                        seprintf(hcbuf,"<%d ",hcol);
        !          2186:                } else hcbuf[0] = 0;
        !          2187:                if (PMODE) {
        !          2188:                        pm = (nlines == 1)?1:nlines-1;
        !          2189:                        pm = (100L*((long) curln-1))/pm;
        !          2190:                        seprintf (pmbuf," %D%%",pm);
        !          2191:                } else pmbuf[0] = 0;
        !          2192:                if (hooks[Mode_Line_Hook]) {
        !          2193:                        hook(Mode_Line_Hook);
        !          2194:                        retrvs(fnbuf,FNLEN);
        !          2195:                        prompt(MODLN,"%s",fnbuf);
        !          2196:                } else {
        !          2197:                        
        !          2198:                        prompt(MODLN,"%s%s %s  (%d) %s %c %s%s",hcbuf,myname,version,bfnumb(),bname(),mdchar[modded()], fname(),pmbuf);
        !          2199:                }
        !          2200:                if (lgripe && (infrn == 0)) {
        !          2201:                        prompt(ECHOL,"I can only use %d lines by %d columns of your screen",SCRNLIN,SCRWID+1);
        !          2202:                        lgripe = 0;
        !          2203:                }
        !          2204:                scrmap[MODLN] = MODHACK;
        !          2205:                if (twowind) {
        !          2206:                        col = w1base-1;
        !          2207:                        prompt(col,endput);
        !          2208:                        scrmap[col] = 0; /* SPPML */
        !          2209:                }
        !          2210:                mgo(nln,ncol);          /* Restore cursor */
        !          2211:        }
        !          2212:        clptr = mkline(curln);          /* make sure we get this one */
        !          2213:        mgo(nln,ncol);
        !          2214: }
        !          2215: 
        !          2216: /* Initialize screen size */
        !          2217: 
        !          2218: setsize()
        !          2219: /* Keywords: modes:50 screen-handling display-format terminal-initialization:10 */
        !          2220: {
        !          2221:        
        !          2222: /* Set safe defaults for height and width, and set dependent parameters */
        !          2223: 
        !          2224:        if (SCRNLIN<=4) SCRNLIN=5;
        !          2225:        if (SCRNLIN>NSCRLIN) {
        !          2226:                SCRNLIN=NSCRLIN;
        !          2227:                lgripe++;
        !          2228:        }
        !          2229:        if (SCRWID>NSCRCOL-1) {
        !          2230:                lgripe++;
        !          2231:                SCRWID=NSCRCOL-1;
        !          2232:        }
        !          2233:        if (SCRWID > REALWID) {
        !          2234:                lgripe++;
        !          2235:                SCRWID = REALWID;
        !          2236:        }
        !          2237:        SCRLINES=SCRNLIN-4;
        !          2238:        ECHOL = SCRNLIN-1;
        !          2239:        MODLN = SCRNLIN-3;
        !          2240: }
        !          2241: 
        !          2242: /* display the mode line */
        !          2243: 
        !          2244: dispmod()
        !          2245: /* Keywords: mode-line */
        !          2246: {
        !          2247:        scrmap[MODLN] = 0;
        !          2248: }
        !          2249: 
        !          2250: 
        !          2251: ttype()                /* set terminal type */
        !          2252: 
        !          2253: {
        !          2254: /* Keywords: commands terminal-initialization terminal-modes:20 terminal-parameters:50 */
        !          2255:        
        !          2256:        register char *mp;
        !          2257: #ifndef PC
        !          2258:        mp = expenv(getname("Terminal Type? "));
        !          2259:        if (mp == NULL) return;
        !          2260:        sttype(mp);
        !          2261: #endif
        !          2262: }
        !          2263: #if defined(TERMCAP) || defined(TERMINFO)
        !          2264:  /* Like putchar but a function which can be passed to putpad */
        !          2265:  pchar(c)
        !          2266: {
        !          2267:        putchar(c);
        !          2268: }
        !          2269:  /*
        !          2270:   * Print out string str with padding.
        !          2271:   */
        !          2272:  putpad(str)
        !          2273:  char *str;
        !          2274:  {
        !          2275:        if (str) {
        !          2276:                tputs(str, SREGION, pchar);
        !          2277:        }
        !          2278: }
        !          2279: 
        !          2280: #endif
        !          2281: #if defined(TERMINFO)
        !          2282: 
        !          2283: sttype(mp)
        !          2284: register char *mp;
        !          2285: {
        !          2286: #ifndef SINGLE
        !          2287:        extern struct term _first_term; /* statically allocated terminal structure */
        !          2288: #endif 
        !          2289:        char tbuf[1024];
        !          2290:        static char bufspace[512];
        !          2291:        char *xp;
        !          2292:        char *pt = bufspace;
        !          2293:        int     rc =  1;
        !          2294: 
        !          2295:        cur_term = 0;                   /* Force setupterm to use default */
        !          2296:        if (mp == NULL) mp = dumbterm;
        !          2297:        setupterm(mp,  1, &rc);
        !          2298:        if (rc != 1)  {
        !          2299:                if (mp == dumbterm) {
        !          2300:                        write(1,"\n\r\n\rI Can't understand your terminal type\n\r",43);
        !          2301:                        quit();
        !          2302:                }
        !          2303:                cur_term = & _first_term; /* Restore terminal pointer */
        !          2304:                IGNORE(error(WARN,86,mp,em_dir));
        !          2305:                return;
        !          2306:        }
        !          2307:        UP      = cursor_up;
        !          2308:        RELUP   = parm_up_cursor;
        !          2309:        DOWN    = cursor_down;
        !          2310:        if (DOWN == NULL)
        !          2311:                DOWN = "\n";
        !          2312:        RELDOWN = parm_down_cursor;
        !          2313:        BACK    = cursor_left;
        !          2314:        RELBACK = parm_left_cursor;
        !          2315:        FORWARD = cursor_right;
        !          2316:        RELFORW = parm_right_cursor;
        !          2317:        CLEAR   = clear_screen;
        !          2318:        CLINE   = clr_eol;
        !          2319:        BELL    = bell;
        !          2320:        CURAD   = cursor_address;
        !          2321:        NOP     = pad_char;
        !          2322:        LOPEN   = insert_line;
        !          2323:        CLOPEN  = parm_insert_line;
        !          2324:        LDEL    = delete_line;
        !          2325:        CLDEL   = parm_delete_line;
        !          2326:        INSERTC = insert_character;
        !          2327:        INSERTM = enter_insert_mode;
        !          2328:        OSERTC  = exit_insert_mode;
        !          2329:        INSERTP = insert_padding;
        !          2330:        IN      = insert_null_glitch;
        !          2331:        /*
        !          2332:        DELMODE = enter_delete_mode; /* Note that DM is a flag in emacs * /
        !          2333:        */
        !          2334:        DELC    = delete_character;
        !          2335:        RSCROLL = scroll_reverse;
        !          2336:        SSCROLL = scroll_forward;
        !          2337:        CLSCROLL= parm_index;
        !          2338:        CRSCROLL= parm_rindex;
        !          2339:        if ((SSCROLL == NULL) && (!eat_newline_glitch)) SSCROLL = "\n";
        !          2340:        SCREG   = change_scroll_region;
        !          2341: 
        !          2342:        /* UNDERLINING */
        !          2343: 
        !          2344:        if (transparent_underline) {
        !          2345:                ULINE = "%c_"; /* underline this way */
        !          2346:                EOVER = erase_overstrike;
        !          2347:        }
        !          2348:        else if (underline_char) {
        !          2349:                /* underscore by magic word */
        !          2350:                ULINE = pt;
        !          2351:                pt = strcpy(pt,"%c");
        !          2352:                pt = strcpy(pt,underline_char);
        !          2353:                EOVER = !ceol_standout_glitch;
        !          2354:                pt++;
        !          2355:        } else if (xp = enter_underline_mode) { /* underscore mode */
        !          2356:                ULINE=xp;
        !          2357:                UEND= exit_underline_mode;
        !          2358:                EOVER = !ceol_standout_glitch;
        !          2359:        }
        !          2360:        CR      = carriage_return;
        !          2361:        SCINIT  = enter_ca_mode;
        !          2362:        VEXIT   = exit_ca_mode;
        !          2363:        MI      = move_insert_mode;
        !          2364:        if ((CURAD == NULL) && (CURAD = cursor_mem_address)) SSCROLL=NULL;
        !          2365: 
        !          2366:        /* Use memory addressing and no scrolling if forced  */
        !          2367: 
        !          2368:        SCRWID  = columns - 1;
        !          2369:        SCRNLIN = lines;
        !          2370:        SCRWRAP = auto_right_margin;
        !          2371: #ifdef JWINSIZE
        !          2372: 
        !          2373:        /*
        !          2374:         * Courtesy of Mark Horton - CDB
        !          2375:         *
        !          2376:         * ioctls for Blit - you may need to #include <jioctl.h>
        !          2377:         * This ioctl defines the window size and overrides what
        !          2378:         * it says in the terminal description file.
        !          2379:         */
        !          2380:        {
        !          2381:                struct jwinsize w;
        !          2382: 
        !          2383:                if (ioctl(1, JWINSIZE, &w) != -1) {
        !          2384:                        SCRNLIN = w.bytesy;
        !          2385:                        SCRWID = w.bytesx - 1;
        !          2386:                }
        !          2387:        }
        !          2388:        if (getenv ("LINES"))
        !          2389:                IGNORE (nscan (getenv ("LINES"), &SCRNLIN));
        !          2390:        if (getenv ("COLUMNS"))
        !          2391:        {
        !          2392:                IGNORE (nscan (getenv ("COLUMNS"), &SCRWID));
        !          2393:                SCRWID--;
        !          2394:        }
        !          2395: 
        !          2396: #endif
        !          2397:        REALWID=SCRWID;
        !          2398:        REALBOT=SCRNLIN;
        !          2399:        setsize();
        !          2400:        if (IN) BLANK= 0;
        !          2401:        else BLANK= ' ';
        !          2402:        if (VCOST == 0) VCOST = 1;
        !          2403:        if (CURAD) {
        !          2404:                acost = dcost(CURAD);
        !          2405:        } else {
        !          2406:                acost = dcost(RELUP)+dcost(RELFORW);
        !          2407:        }
        !          2408:        dccost = dcost(DELC);
        !          2409:        if (INSERTM) iccost = dcost(INSERTM)+dcost(OSERTC);
        !          2410:        else iccost = dcost (INSERTC);
        !          2411:        lUP = dcost(UP);
        !          2412:        lDOWN = dcost(DOWN);
        !          2413:        lBAK = dcost(BACK);
        !          2414:        lCR = dcost(CR);
        !          2415:        if ((NOP == NULL) || (*NOP == 0)) NOP = "\200"; /* null pads get lost */
        !          2416:        if (ULINE) BACKP = 1;           /* Set backspace mode if terminal underscores */
        !          2417:        vinit();
        !          2418:        TERMIQ = 0;             /* Compute terminal's IQ */
        !          2419:        if (CURAD) TERMIQ += 1;
        !          2420:        if (CLINE) TERMIQ += 2;
        !          2421:        if (LOPEN || SCREG) TERMIQ += 4;
        !          2422:        if (INSERTC || INSERTM) TERMIQ += 8; 
        !          2423:        clear();
        !          2424: }
        !          2425: 
        !          2426: /* for costing out terminfo capabilities */
        !          2427: static int TIcount;
        !          2428: /*ARGSUSED*/
        !          2429: 
        !          2430: int TIcost(c)
        !          2431:        char    c;
        !          2432: {
        !          2433:        ++TIcount;
        !          2434: }
        !          2435: #else
        !          2436: #ifdef TERMCAP
        !          2437: 
        !          2438: char PC;
        !          2439: char *BC;
        !          2440: char *TE;
        !          2441: 
        !          2442: sttype(mp)
        !          2443: register char *mp;
        !          2444:  {
        !          2445:        char tbuf[1024];
        !          2446:        static char bufspace[512];
        !          2447:        char *xp;
        !          2448:        char *pt = bufspace;
        !          2449:        char *tgetstr();
        !          2450:        if (mp == NULL) mp = dumbterm;
        !          2451:        if (tgetent(tbuf, mp) < 1) {
        !          2452:                if (mp == dumbterm) {
        !          2453:                        write(1,"\n\r\n\rI Can't understand your terminal type\n\r",43);
        !          2454:                        quit();
        !          2455:                }
        !          2456:                IGNORE(error(WARN,86,mp,em_dir));
        !          2457:                return;
        !          2458:        }
        !          2459:        UP      = tgetstr("up", &pt);
        !          2460:        DOWN    = tgetstr("do", &pt);
        !          2461:        if (DOWN == NULL)
        !          2462:                DOWN = "\n";
        !          2463:        BACK    = tgetstr("bc", &pt);
        !          2464:        if (BACK == NULL && tgetflag("bs"))
        !          2465:                BACK = "\b";
        !          2466:        BC = BACK;
        !          2467:        FORWARD = tgetstr("nd", &pt);
        !          2468:        CLEAR   = tgetstr("cl", &pt);
        !          2469:        CLINE   = tgetstr("ce", &pt);
        !          2470:        BELL    = "\7";
        !          2471:        CURAD   = tgetstr("cm", &pt);
        !          2472:        NOP     = tgetstr("pc", &pt);
        !          2473:        if(NOP != NULL) PC = *NOP;
        !          2474:        LOPEN   = tgetstr("al", &pt);
        !          2475:        CLOPEN  = tgetstr("AL", &pt);
        !          2476:        LDEL    = tgetstr("dl", &pt);
        !          2477:        CLDEL   = tgetstr("DL", &pt);
        !          2478:        INSERTC = tgetstr("ic", &pt);
        !          2479:        INSERTM = tgetstr("im", &pt);
        !          2480:        OSERTC  = tgetstr("ei", &pt);
        !          2481:        INSERTP = tgetstr("ip", &pt);
        !          2482:        IN      = tgetflag("in", &pt);
        !          2483:        DELMODE = (tgetstr("dm", &pt)==NULL); /* Note that DM is a flag in emacs */
        !          2484:        DELC    = tgetstr("dc", &pt);
        !          2485:        RSCROLL = tgetstr("sr", &pt);
        !          2486:        SSCROLL = tgetstr("nl", &pt);
        !          2487:        CLSCROLL = tgetstr("SF", &pt);  
        !          2488:        if (SSCROLL == NULL) SSCROLL = tgetstr("sf",&pt);
        !          2489:        if ((SSCROLL == NULL) && (tgetflag("xn")== NULL)) SSCROLL = "\n";
        !          2490:        SCREG   = tgetstr("cs", &pt);
        !          2491: 
        !          2492: /* UNDERLINING */
        !          2493: 
        !          2494:        if (tgetflag("ul")) {
        !          2495:                ULINE = "%c_"; /* underline this way */
        !          2496:                EOVER = tgetflag("eo");
        !          2497:        }
        !          2498:        else if (xp = tgetstr("uc",&pt)) {
        !          2499:                                        /* underscore by magic word */
        !          2500:                ULINE = pt;
        !          2501:                pt = mstrcpy(pt,"%c");
        !          2502:                pt = mstrcpy(pt,xp);
        !          2503:                EOVER = (tgetflag("xs") == 0);
        !          2504:                pt++;
        !          2505:        } else if (xp = tgetstr("us",&pt)) { /* underscore mode */
        !          2506:                ULINE=xp;
        !          2507:                UEND= tgetstr("ue",&pt);
        !          2508:                EOVER = (tgetflag("xs") == 0);
        !          2509:        }
        !          2510:        CR      = tgetstr("cr", &pt);
        !          2511:        if (CR == NULL) {
        !          2512:                if (tgetflag("nc") == 0)  CR = "\015";
        !          2513:        }
        !          2514:        SCINIT  = tgetstr("ti", &pt);
        !          2515:        TE      = tgetstr("up", &pt);
        !          2516:        MI      = tgetflag("mi", &pt);
        !          2517:        SCRWID  = tgetnum("co") - 1;
        !          2518:        SCRNLIN = tgetnum("li");
        !          2519:        SCRWRAP = tgetflag("am");
        !          2520: #ifdef JWINSIZE
        !          2521: 
        !          2522:        /*
        !          2523:         * Courtesy of Mark Horton - CDB
        !          2524:         *
        !          2525:         * ioctls for Blit - you may need to #include <jioctl.h>
        !          2526:         * This ioctl defines the window size and overrides what
        !          2527:         * it says in the terminal description file.
        !          2528:         */
        !          2529:        {
        !          2530:                struct jwinsize w;
        !          2531: 
        !          2532:                if (ioctl(1, JWINSIZE, &w) != -1) {
        !          2533:                        SCRNLIN = w.bytesy;
        !          2534:                        SCRWID = w.bytesx - 1;
        !          2535:                }
        !          2536:        }
        !          2537:        if (getenv ("LINES"))
        !          2538:                IGNORE (nscan (getenv ("LINES"), &SCRNLIN));
        !          2539:        if (getenv ("COLUMNS"))
        !          2540:        {
        !          2541:                IGNORE (nscan (getenv ("COLUMNS"), &SCRWID));
        !          2542:                SCRWID--;
        !          2543:        }
        !          2544: 
        !          2545: #endif
        !          2546:        REALWID=SCRWID;
        !          2547:        REALBOT=SCRNLIN;
        !          2548:        setsize();
        !          2549:        if (VCOST == 0) VCOST = 1;
        !          2550:        if (IN) BLANK= 0;
        !          2551:        else BLANK= ' ';
        !          2552:        if (CURAD) {
        !          2553:                acost = dcost(CURAD);
        !          2554:        } else {
        !          2555:                acost = dcost(RELUP)+dcost(RELFORW);
        !          2556:        }
        !          2557:        dccost = dcost(DELC);
        !          2558:        if (INSERTM) iccost = dcost(INSERTM)+dcost(OSERTC);
        !          2559:        else iccost = dcost (INSERTC);
        !          2560:        lUP = dcost(UP);
        !          2561:        lDOWN = dcost(DOWN);
        !          2562:        lBAK = dcost(BACK);
        !          2563:        lCR = dcost(CR);
        !          2564:        if (SCREG) LOPEN = SCREG; /* make sure we use SCREG */
        !          2565:        if ((NOP == NULL) || (*NOP == 0)) NOP = "\200"; /* null pads get lost */
        !          2566:        if (ULINE) BACKP = 1;           /* Set backspace mode if terminal underscores */
        !          2567:        vinit();                        /* Initialize screen */
        !          2568:        
        !          2569:        TERMIQ = 0;             /* Compute terminal's IQ */
        !          2570:        if (CURAD) TERMIQ += 1;
        !          2571:        if (CLINE) TERMIQ += 2;
        !          2572:        if (LOPEN || SCREG) TERMIQ += 4;
        !          2573:        if (INSERTC || INSERTM) TERMIQ += 8; 
        !          2574:        clear();
        !          2575: }
        !          2576: #else
        !          2577: #ifndef PC
        !          2578: 
        !          2579: /* terminal description file parser: */
        !          2580: 
        !          2581: /* terminal description file contains lines with 
        !          2582: 
        !          2583:        parameter=data
        !          2584:        
        !          2585:  * where data is either a number of a string */
        !          2586: 
        !          2587: 
        !          2588: ttyparse(mp)
        !          2589: char *mp;
        !          2590: 
        !          2591: /* Keywords: conversions:20 terminal-parameters terminal-initialization reading */
        !          2592: 
        !          2593: {
        !          2594:        register FILE *file;
        !          2595:        char xbuf[128];
        !          2596:        FILE ttyfile[1];
        !          2597: #define OPTSIZE 256
        !          2598:        char optbuf[OPTSIZE];
        !          2599:        register char *cp;
        !          2600:        register int c;
        !          2601: #ifdef PORTEXT
        !          2602:        int parmp;
        !          2603: #else
        !          2604:        int *parmp;
        !          2605: #endif 
        !          2606:        int parm;
        !          2607:        
        !          2608:        
        !          2609: /* find the terminal file and open it */
        !          2610:        
        !          2611:        if (mp) {
        !          2612:                seprintf(xbuf,"%s/terminals/%s",em_dir,mp);     /* terminal file */
        !          2613:                file = xopen(ttyfile,xbuf,"r");
        !          2614:                if (file == NULL) {
        !          2615:                        file = xopen(ttyfile,mp,"r"); /* Try full pathname */
        !          2616:                }
        !          2617:                if (file == NULL) {
        !          2618: badterm:               error (WARN,43,mp,em_dir);
        !          2619:                        return(0);
        !          2620:                }
        !          2621:        } else {
        !          2622: 
        !          2623: /* This code restores the terminal to a "sane" default */
        !          2624:                
        !          2625:                file = ttyfile;
        !          2626:                ttyfile[0]._frn = open("/dev/null",0);
        !          2627:                ttyfile[0]._cnt = lng(nulltty);
        !          2628:                ttyfile[0]._ptr = nulltty;
        !          2629:        }
        !          2630:        /* first find what option we  are setting */
        !          2631: 
        !          2632: nextparm: cp = optbuf;
        !          2633:        while ((c = getc(file)) != '=') {
        !          2634:                if (c == '\n') goto nextparm; /* comment line */
        !          2635:                if (c == EOF) {
        !          2636:                        mclose(file);
        !          2637:                        return(1); /* abort during option scan */
        !          2638:                }
        !          2639:                if (cp-optbuf >= OPTSIZE) goto badterm; /* OOPS! */
        !          2640:                *cp++=c;
        !          2641:        }
        !          2642:        *cp = 0;
        !          2643:        
        !          2644: /* look up parameter in parameter table */
        !          2645:        
        !          2646: #ifdef PORTEXT
        !          2647:        for (parmp = 0, cp = ttydata; *cp; parmp++,cp+=2) {
        !          2648: #else
        !          2649:        for (parmp = ((int * )&UP), cp = ttydata; *cp; parmp++,cp+=2) {
        !          2650: #endif
        !          2651:                if ((optbuf[0]==cp[0])&& (optbuf[1]==cp[1])) {
        !          2652:                        
        !          2653:                        c = getc(file);
        !          2654:                        if ((c >= '0') && (c <= '9')) {
        !          2655:                                parm = 0;
        !          2656:                                while ((c >= '0') && (c <= '9')) {
        !          2657:                                        parm = 10*parm + (c-'0');
        !          2658:                                        c = getc(file);
        !          2659:                                }
        !          2660: #ifdef PORTEXT
        !          2661:                                *(parmptr[parmp]) = parm;
        !          2662: #else
        !          2663:                                *parmp = parm;
        !          2664: #endif
        !          2665:                                if (c != EOF) goto nextparm;
        !          2666:                                mclose(file);
        !          2667:                                return(1);
        !          2668:                        }
        !          2669: #ifdef PORTEXT
        !          2670:                        *(parmptr[parmp]) = ((int) &ttystrings[ttyptr]);
        !          2671: #else                  
        !          2672:                        *parmp = ((int) &ttystrings[ttyptr]);
        !          2673: #endif                 
        !          2674:                        while ((c != EOF) && (c != EOL)) {
        !          2675:                                if (c == '\\') {
        !          2676:                                        c = getc(file);
        !          2677:                                        if (c == 'n') c = '\n';
        !          2678:                                }
        !          2679:                                
        !          2680:                                ttystrings[ttyptr++] = c;
        !          2681:                                c = getc(file);
        !          2682:                        }
        !          2683:                        ttystrings[ttyptr++] = 0;
        !          2684:                        if (c != EOF) goto nextparm;
        !          2685:                }
        !          2686:        }
        !          2687: /*     error(WARN,68,optbuf);          Don't complain about non-existent capabilities */
        !          2688:        
        !          2689:        goto nextparm;
        !          2690: }
        !          2691: #endif
        !          2692: sttype(mp)
        !          2693: register char *mp;
        !          2694: 
        !          2695: /* Keywords: terminal-parameters terminal-initialization terminal-modes:20 string-handling:20 statistics:10 */
        !          2696: 
        !          2697: 
        !          2698: 
        !          2699: {
        !          2700: #ifdef PORTEXT
        !          2701:        int parmp;
        !          2702: #else
        !          2703:        int *parmp;
        !          2704: #endif
        !          2705: /* First, initialize the tty data */
        !          2706:        
        !          2707:        ttyptr = 0;
        !          2708: #ifdef PORTEXT
        !          2709:        for (parmp = 0; parmptr[parmp]; parmp++) {
        !          2710:                *(parmptr[parmp])=0;
        !          2711:        }
        !          2712: #else
        !          2713:        for (parmp = ( (int *) &UP); parmp <= &DELMODE; parmp++) {
        !          2714:                *parmp=0;
        !          2715:        }
        !          2716: #endif
        !          2717: #ifdef PC
        !          2718: 
        !          2719:        SCRWID = 79;
        !          2720:        SCRNLIN = 24;
        !          2721:        ECHOL = 23;
        !          2722:        MODLN = 21;
        !          2723:        SCRLINES = 20;
        !          2724:        CLINE = "";
        !          2725:        clear();
        !          2726: #else  
        !          2727:        if (ttyparse(mp)) {
        !          2728: 
        !          2729: #ifdef JWINSIZE
        !          2730: 
        !          2731:                /*
        !          2732:                 * Courtesy of Mark Horton - CDB
        !          2733:                 *
        !          2734:                 * ioctls for Blit - you may need to #include <jioctl.h>
        !          2735:                 * This ioctl defines the window size and overrides what
        !          2736:                 * it says in the terminal description file.
        !          2737:                 */
        !          2738:                {
        !          2739:                        struct jwinsize w;
        !          2740: 
        !          2741:                        if (ioctl(1, JWINSIZE, &w) != -1) {
        !          2742:                                SCRNLIN = w.bytesy;
        !          2743:                                SCRWID = w.bytesx;
        !          2744:                        }
        !          2745:                }
        !          2746: /*
        !          2747:                if (getenv ("LINES"))
        !          2748:                        IGNORE (nscan (getenv ("LINES"), &SCRNLIN));
        !          2749:                if (getenv ("COLUMNS"))
        !          2750:                {
        !          2751:                        IGNORE (nscan (getenv ("COLUMNS"), &SCRWID));
        !          2752:                }
        !          2753: */
        !          2754: #endif
        !          2755:                SCRWID--;
        !          2756:                REALWID=SCRWID;
        !          2757:                REALBOT=SCRNLIN;
        !          2758:                setsize();
        !          2759:                if (IN) BLANK= 0;
        !          2760:                else BLANK= ' ';
        !          2761:                if (VCOST == 0) VCOST = 1;
        !          2762:                if (CURAD) {
        !          2763:                        acost = dcost(CURAD);
        !          2764:                } else {
        !          2765:                        acost = dcost(RELUP)+dcost(RELFORW);
        !          2766:                }
        !          2767:                dccost = dcost(DELC);
        !          2768:                if (INSERTM) iccost = dcost(INSERTM)+dcost(OSERTC);
        !          2769:                if (INSERTM) iccost = 1;
        !          2770:                else iccost = dcost (INSERTC);
        !          2771: 
        !          2772:                lUP = dcost(UP);
        !          2773:                lDOWN = dcost(DOWN);
        !          2774:                lBAK = dcost(BACK);
        !          2775:                lCR = dcost(CR);
        !          2776:                if (ULINE) BACKP = 1;           /* Set backspace mode if terminal underscores */
        !          2777:                if (OSERTC && (INSERTM == 0)) {
        !          2778:                        INSERTM=INSERTC;                /* old style insert modes */
        !          2779:                        INSERTC=0;
        !          2780:                }
        !          2781:                if (SCREG) LOPEN = SCREG; /* make sure we use SCREG */
        !          2782:                if ((NOP == NULL) || (*NOP == 0)) NOP = "\200"; /* null pads get lost */
        !          2783:                vinit();
        !          2784:                TERMIQ = 0;             /* Compute terminal's IQ */
        !          2785:                if (CURAD) TERMIQ += 1;
        !          2786:                if (CLINE) TERMIQ += 2;
        !          2787:                if (LOPEN || SCREG) TERMIQ += 4;
        !          2788:                if (INSERTC || INSERTM) TERMIQ += 8; 
        !          2789: 
        !          2790:                clear();
        !          2791:        }
        !          2792: #endif
        !          2793: }
        !          2794: #endif
        !          2795: #endif
        !          2796: #ifndef PC
        !          2797: /* dcost -- calculate display cost of a string */
        !          2798: 
        !          2799: dcost(sp)
        !          2800: register char *sp;
        !          2801: {
        !          2802: /* Keywords: terminal-parameters terminal-initialization */
        !          2803:        register int dc;
        !          2804:        char dcbuf[512];                /* buffer for string */
        !          2805:        
        !          2806:        if (sp == NULL) return(1000); /* infinite cost for missing capability */
        !          2807: #ifdef TERMINFO
        !          2808:        TIcount=0;
        !          2809:        tputs(tparm(sp,10,10),10,TIcost);
        !          2810:        return(TIcount);
        !          2811: #else
        !          2812: #ifdef TERMCAP 
        !          2813:        dc = 0;
        !          2814:        while (*sp) {
        !          2815:                if (*sp++ != '%') dc++;
        !          2816:        }
        !          2817:        return(dc);
        !          2818: #else
        !          2819:        seprintf(dcbuf,sp,10,10);       /* expand a 'typical' example */
        !          2820:        return(lng(dcbuf));             /* return its length */
        !          2821: #endif 
        !          2822: #endif
        !          2823: }
        !          2824: #endif
        !          2825: /* yes or no question */
        !          2826: /*VARARGS1*/
        !          2827: int
        !          2828: gyn(string,arg1)
        !          2829: 
        !          2830: char *string;
        !          2831: char *arg1;
        !          2832: {
        !          2833: /* Keywords: prompting user-interface yes-no-questions */
        !          2834:        
        !          2835:        register char c;
        !          2836:        
        !          2837:        while (1) {
        !          2838:                prompt2(ECHOL,string,&arg1);
        !          2839:                sgo(mline,mcol);
        !          2840:                if (infrn < 0) {
        !          2841:                        pushin(NULL);
        !          2842:                        c = getchar();
        !          2843:                        inpop();
        !          2844:                } else c = getchar();
        !          2845:                donttime = 0;           /* Re-enable time mode */
        !          2846:                switch(c) {
        !          2847:                        
        !          2848:                case 'y':
        !          2849:                case 'Y':
        !          2850:                case ' ':
        !          2851:                        return(1);
        !          2852:                case CTRLZ:     /* This is necessary to insure exit */
        !          2853:                case 'n':
        !          2854:                case 'N':
        !          2855:                case RUBOUT:
        !          2856:                        unprompt();
        !          2857:                        return(0);
        !          2858:                case CTRLG:
        !          2859:                        unprompt();
        !          2860:                        return(-1);
        !          2861:                default:
        !          2862:                        donttime = 1; /* Avoid time mode */
        !          2863:                        prompt3("y for yes, n for no, ^G to quit");
        !          2864:                }
        !          2865:        }
        !          2866: };
        !          2867: 
        !          2868: /* beep -- obvious */
        !          2869: 
        !          2870: beep()
        !          2871: 
        !          2872: {
        !          2873:        
        !          2874: /* Keywords: bell-ringing terminal-parameters:20 commands:20 error-messages:10 */
        !          2875:        
        !          2876: #ifdef PC
        !          2877: 
        !          2878:        if (!NOBEL) video(REG(WR_TTY,BELL),REG(PAGE_0,NORMATB),0,0);
        !          2879:        
        !          2880:        
        !          2881: #else
        !          2882:        if (!NOBEL) PUTS(BELL);                 /* print a bell */
        !          2883: #endif 
        !          2884: }
        !          2885: 
        !          2886: /* mtop -- move to top of display for message output */
        !          2887: 
        !          2888: mtop()
        !          2889: {
        !          2890: /* Keywords: the-screen-cursor informational-displays MORE-processing */
        !          2891:        mgo(0,0);                       /* for messages */
        !          2892: }
        !          2893: 
        !          2894: /* fclear -- declare the contents of the file invalid */
        !          2895: 
        !          2896: fclear()
        !          2897: 
        !          2898: /* Keywords: screen-handling the-screen-map clearing terminal-initialization:20 */
        !          2899: 
        !          2900: {
        !          2901:        register int i;
        !          2902:        scrmap[MODLN] = 0;              /* wipe out mode line */
        !          2903:        for (i = 0; i < NSCRLIN; i++) fmap[i] = 0;
        !          2904: }
        !          2905: 
        !          2906: /* dclear-- cause screen to be cleared at next refresh */
        !          2907: 
        !          2908: dclear()
        !          2909: {
        !          2910: /* Keywords: screen-handling clearing break-handling:20 */
        !          2911:        junked++;
        !          2912:        minln=0;
        !          2913: }
        !          2914: 
        !          2915: /* xclear -- declare the contents of the screen as junk */
        !          2916: 
        !          2917: 
        !          2918: xclear()
        !          2919: {
        !          2920: /* Keywords: screen-handling the-screen-map clearing terminal-initialization:20 */
        !          2921:        register int i;
        !          2922: 
        !          2923:        for(i = 0; i < SCRNLIN; i++) scrmap[i]=0;
        !          2924: }
        !          2925: 
        !          2926: /* two window mode -- enter two window mode, prompt user for buffer */
        !          2927: 
        !          2928: twind()
        !          2929: {
        !          2930: /* Keywords: windows commands screen-handling:20 */
        !          2931: 
        !          2932:        if (twowind) return;
        !          2933:        twowind = 1;
        !          2934:        wscrlines = SCRLINES;           /* remember real size */
        !          2935:        w1base = (wscrlines/2)-woff; /* Compute start of window 2 */
        !          2936:        cwind = 0;
        !          2937:        owind();                        /* enter second window */
        !          2938:        cpbuf(1);                       /* and go to buffer */
        !          2939: }
        !          2940: 
        !          2941: onewind()
        !          2942: {
        !          2943: /* Keywords: windows commands screen-handling:20 */
        !          2944:        
        !          2945:        if (twowind) {
        !          2946:                fclear();               /* file map bad */
        !          2947:                twowind = 0;
        !          2948:                cwind = 0;              /* in window 0 */
        !          2949:                wbase = 0;
        !          2950:                SCRLINES = wscrlines;
        !          2951:        }
        !          2952: }
        !          2953: 
        !          2954: /* Return buffer in other window or -1 */
        !          2955: 
        !          2956: windbuf()
        !          2957: 
        !          2958: /* Keywords: windows commands buffers killing: */
        !          2959: {
        !          2960:        if (twind) return(windb[1-cwind]);
        !          2961:        else return(-1);
        !          2962: }
        !          2963: owind()                                /* switch windows */
        !          2964:        /* returns -1 if not in two window mode, 0 if different buffer,
        !          2965:        and 1 if same buffer */
        !          2966: /* Keywords: windows commands screen-handling:20 */
        !          2967: {
        !          2968:        if (!twowind) return(-1);
        !          2969:        fclear();
        !          2970:        windb[cwind] = curbf;
        !          2971:        wminln[cwind] = minln;
        !          2972:        wmaxln[cwind] = maxln;
        !          2973:        
        !          2974:        switch(cwind) {
        !          2975:                
        !          2976:        case 0:
        !          2977:                cwind = 1;
        !          2978:                wbase = w1base;
        !          2979:                SCRLINES = wscrlines;
        !          2980:                break;
        !          2981:        case 1:
        !          2982:                cwind = 0;
        !          2983:                wbase = 0;
        !          2984:                SCRLINES=w1base-1;
        !          2985:                break;
        !          2986:        }
        !          2987:        
        !          2988:        minln = wminln[cwind];
        !          2989:        maxln = wmaxln[cwind];
        !          2990:        lastln = SCRLINES-1;            /* This is not accurate, but shouldn't matter much */
        !          2991:        chbuf(windb[cwind]);
        !          2992:        if (windb[0]==windb[1]) return(1);
        !          2993:        return(0) ;
        !          2994: }
        !          2995: 
        !          2996: wgrow(arg)
        !          2997: register int arg;
        !          2998: /* Keywords: windows screen-lines commands insertion:50 screen-handling:20 */
        !          2999: {
        !          3000:        fclear();               /* file map bad */
        !          3001:        if (twowind) {
        !          3002:                if (cwind) w1base -= arg;
        !          3003:                else w1base += arg;
        !          3004:                if (w1base < 2) w1base = 2;
        !          3005:                if (w1base > wscrlines-1) w1base = wscrlines-1;
        !          3006:                woff = (wscrlines/2)-w1base;
        !          3007:                if (cwind) {
        !          3008:                        wbase = w1base;
        !          3009:                } else {
        !          3010:                        SCRLINES = w1base-1;
        !          3011:                }
        !          3012:        } else {
        !          3013:                arg += SCRLINES;
        !          3014:                if ((arg > 0) && (arg < MODLN)) SCRLINES = arg;
        !          3015:        }
        !          3016: }
        !          3017: 
        !          3018: /* Mousing Specials */
        !          3019: 
        !          3020: /* Goto screen position at line x, collumn y.  arg is decoded as:
        !          3021:  *     x = arg mod 128.
        !          3022:  *     y = arg /128.
        !          3023:                        (128 is more lines than I can imagine on a screen.)
        !          3024:                        
        !          3025:  * Will switch windows, but fails if x is an illegal position. */
        !          3026: 
        !          3027: go_xy(arg)
        !          3028: int arg;
        !          3029: /* Keywords: screen-positioning commands macro-programming:40 */
        !          3030: {
        !          3031:        register int x,y,c;
        !          3032:        int linpos;
        !          3033: 
        !          3034:        x = arg&127;
        !          3035:        y = ((unsigned) arg) >>7;
        !          3036:        if ((x <wbase) || (x>= SCRLINES)) {
        !          3037:                if (twowind) {
        !          3038:                        if ((x >= 0) && (x < wscrlines)) {
        !          3039:                                owind();
        !          3040:                        } else return(0); /* Can't mouse out of the display */
        !          3041:                } else return(0);
        !          3042:        }
        !          3043:        linpos = scrmap[x]&SCRMSK;
        !          3044:        if (linpos== 0) {
        !          3045:                if (PICMODE && (maxln == nlines)) {
        !          3046:                        linpos = maxln+x-lastln;/* If nothing there, punt to end of file */
        !          3047:                        move(linpos,0);
        !          3048:                } else if (x > lastln) {
        !          3049:                        linpos = maxln;
        !          3050:                } else return(0);       /* PUNT */
        !          3051:        }
        !          3052:        
        !          3053:        if (findline(linpos)) mline = nln;
        !          3054:        else mline = x;
        !          3055: 
        !          3056:        column = 0;
        !          3057:        mcol = LNOMOD*LNOWID-hcol;
        !          3058:        if (y<mcol) y = mcol;
        !          3059:        clptr=mkline(linpos);
        !          3060:        while ((mline < x) || ((mline == x) && (mcol <= y))) {
        !          3061:                c = (clptr[column++]&0377);
        !          3062:                if (c == EOL) {
        !          3063:                        if (PICMODE) {
        !          3064:                                curln=linpos;
        !          3065:                                column--;
        !          3066:                                insertc(y-mcol+1,' ');
        !          3067:                        }
        !          3068:                        break;
        !          3069:                }
        !          3070:                if (c & META) mcol+= metal;
        !          3071:                switch(ctype[c& 0177]) {
        !          3072: 
        !          3073:                case PLAIN:
        !          3074:                case UL:
        !          3075:                        mcol++;
        !          3076:                        break;
        !          3077:                case BACKSP:
        !          3078:                        if (mcol) mcol--;
        !          3079:                        break;
        !          3080:                case CONTRL:
        !          3081:                        mcol += 2;
        !          3082:                        break;
        !          3083:                case TAB:
        !          3084:                        mcol+= TABSTOP-((mcol-(LNOMOD*LNOWID))%TABSTOP);
        !          3085:                        break;
        !          3086:                }
        !          3087:                if (mcol>SCRWID) {
        !          3088:                        mline++;
        !          3089:                        mcol = mcol-SCRWID;
        !          3090:                        if (LNOMOD) mcol+= LNOWID;
        !          3091:                }
        !          3092:        }
        !          3093:        move(linpos,column-1);
        !          3094:        return(1);
        !          3095: }
        !          3096: 
        !          3097: vinit()
        !          3098: /* Keywords: terminal-parameters terminal-initialization character-output */
        !          3099: {
        !          3100: #ifndef PC
        !          3101: #ifdef COMPRESS
        !          3102:        DOCOMP=CMPON;
        !          3103: #endif
        !          3104: 
        !          3105: #ifdef TERMINFO
        !          3106:        if (cur_term == NULL) return; /* Catch if called too soon */
        !          3107:        if (enter_ca_mode)  {
        !          3108:                putpad(enter_ca_mode);
        !          3109:        }
        !          3110:        if (keypad_xmit)  {
        !          3111:                putpad(keypad_xmit);
        !          3112:        }
        !          3113: #else
        !          3114:        if (SCINIT) PUTS(SCINIT);
        !          3115: #endif
        !          3116: #endif
        !          3117: }
        !          3118: 
        !          3119: vexit ()
        !          3120: {
        !          3121: /* Keywords: terminal-parameters exit-processing character-output */
        !          3122: #ifndef PC
        !          3123: #ifdef COMPRESS
        !          3124:        DOCOMP=0;
        !          3125: #endif
        !          3126: #ifdef TERMINFO
        !          3127:        if (exit_ca_mode)  {
        !          3128:                putpad(exit_ca_mode);
        !          3129:                }
        !          3130:        if (keypad_local)  {
        !          3131:                putpad(keypad_local);
        !          3132:        }
        !          3133: #else
        !          3134:        if (VEXIT) PUTS(VEXIT);
        !          3135: #endif
        !          3136: #endif
        !          3137: }

unix.superglobalmegacorp.com

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