# 2.11BSD#431 - /usr/src/new/PORT/B/src/bed/scrn.c

##### Functions

    actupdate         X
    atlinestart       X
    backtranslate     X
    cmdprompt         X
    endshow           X
    fixlevels         X
    growwin           X
    initshow          X
    make2room         X
    makeroom          X
    setindent         X
    virtupdate        X

##### Variables

    indent            X
    llength           X
    noscroll          X
    nosense           X
    tops              X
    winheight         X
    winstart          X

       1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
       2: static char rcsid[] = "$Header: scrn.c,v 2.5 85/08/22 16:07:10 timo Exp $";
       3:
       4: /*
       5:  * B editor -- Screen management package, higher level routines.
       6:  */
       7:
       8: #include "b.h"
       9: #include "erro.h"
      10: #include "bobj.h"
      11: #include "node.h"
      12: #include "supr.h"
      13: #include "gram.h"
      14: #include "cell.h"
      15:
      16:
      17: extern bool dflag;
      18:
      19: cell *gettop();
      20: extern int focy;
      21: extern int focx;
      22:
      23: Visible int winstart;
      24:
      25: Visible int winheight;
      26: Visible int indent;
      27: Visible int llength;
      28:
      29: Visible bool noscroll;
      30: Visible bool nosense;
      31:
      32: Hidden cell *tops;
      33:
      34:
      35: /*
      36:  * Actual screen update.
      37:  */
      38:
      39: Visible Procedure
      40: actupdate(copybuffer, recording, lasttime)
      41:     value copybuffer;
      42:     bool recording;
      43:     bool lasttime; /* Yes if called from final screen update */
      44: {
      45:     register cell *p;
      46:     cell *top = tops;
      47:     register int diff;
      48:     register int curlno;
      49:     register int delcnt = 0; /* Lines deleted during the process. */
      50:         /* Used as offset for lines that are on the screen. */
      51:     int totlines = 0;
      52:     int topline = 0;
      53:     int scrlines = 0;
      54:
      55:     if (winstart > 0)
      56:         growwin();
      57:     if (winstart <= 0) {
      58:         top = gettop(tops);
      59:         for (p = tops; p && p != top; p = p->c_link)
      60:             ++topline;
      61:         totlines = topline;
      62:     }
      63:     startactupdate(lasttime);
      64:     focy = Nowhere;
      65:     for (p = top, curlno = winstart; p && curlno < winheight;
      66:         curlno += Space(p), p = p->c_link) {
      67:         ++scrlines;
      68:         if (lasttime) {
      69:             p->c_newfocus = No;
      70:             p->c_newvhole = 0;
      71:         }
      72:         if (p->c_onscreen != Nowhere && Space(p) == Oldspace(p)) {
      73:             /* Old comrade */
      74:             diff = p->c_onscreen - (curlno+delcnt);
      75:             /* diff can't be negative due to 'makeroom' below! */
      76:             if (diff > 0) { /* Get him here */
      77:                 trmscrollup(curlno, winheight, diff);
      78:                 delcnt += diff;
      79:             }
      80:             if (p->c_oldfocus || p->c_newfocus
      81:                 || p->c_oldindent != p->c_newindent
      82:                 || p->c_onscreen + Space(p) >= winheight) {
      83:                 delcnt = make2room(p, curlno, delcnt);
      84:                 outline(p, curlno);
      85:             }
      86:         }
      87:         else { /* New guy, make him toe the line */
      88:             delcnt = makeroom(p, curlno, delcnt);
      89:             delcnt = make2room(p, curlno, delcnt);
      90:             outline(p, curlno);
      91:         }
      92:         p->c_onscreen = curlno;
      93:         p->c_oldindent = p->c_newindent;
      94:         p->c_oldvhole = p->c_newvhole;
      95:         p->c_oldfocus = p->c_newfocus;
      96:     }
      97:     totlines += scrlines;
      98:     for (; p; p = p->c_link) { /* Count rest and remove old memories */
      99:         ++totlines;
     100:         /* This code should never find any garbage?! */
     101: #ifndef NDEBUG
     102:         if (p->c_onscreen != Nowhere)
     103:             debug("[Garbage removed from screen list]");
     104: #endif NDEBUG
     105:         p->c_onscreen = Nowhere;
     106:     }
     107:     trmscrollup(curlno, winheight, -delcnt);
     108:     curlno += delcnt;
     109:     if (curlno < winheight) { /* Clear lines beyond end of unit */
     110:         trmputdata(curlno, winheight-1, 0, "");
     111:         scrlines += winheight-curlno;
     112:     }
     113:     if (!lasttime) {
     114:         stsline(totlines, topline, scrlines, copybuffer, recording);
     115:         if (focy != Nowhere)
     116:             trmsync(focy, focx);
     117:         else
     118:             trmsync(winheight, 0);
     119:     }
     120:     endactupdate();
     121: }
     122:
     123:
     124: /*
     125:  * Grow the window if not maximum size.
     126:  */
     127:
     128: Hidden Procedure
     129: growwin()
     130: {
     131:     register int winsize;
     132:     register int growth;
     133:     register cell *p;
     134:
     135:     winsize = 0;
     136:     for (p = tops; p; p = p->c_link)
     137:         winsize += Space(p);
     138:     if (winsize <= winheight - winstart)
     139:         return; /* No need to grow */
     140:     if (winsize > winheight)
     141:         winsize = winheight; /* Limit size to maximum available */
     142:
     143:     growth = winsize - (winheight - winstart);
     144:     trmscrollup(0, winheight - (winstart!=winheight), growth);
     145:     winstart -= growth;
     146:     for (p = tops; p; p = p->c_link) {
     147:         if (p->c_onscreen != Nowhere)
     148:             p->c_onscreen -= growth;
     149:     }
     150: }
     151:
     152:
     153: /*
     154:  * Make room for possible insertions.
     155:  * (If a line is inserted, it may be necessary to delete lines
     156:  * further on the screen.)
     157:  */
     158:
     159: Hidden Procedure
     160: makeroom(p, curlno, delcnt)
     161:     register cell *p;
     162:     register int curlno;
     163:     register int delcnt;
     164: {
     165:     register int here = 0;
     166:     register int need = Space(p);
     167:     register int amiss;
     168:     int avail;
     169:     int diff;
     170:
     171:     Assert(p);
     172:     do {
     173:         p = p->c_link;
     174:         if (!p)
     175:             return delcnt;
     176:     } while (p->c_onscreen == Nowhere);
     177:     here = p->c_onscreen - delcnt;
     178:     avail = here - curlno;
     179:     amiss = need - avail;
     180: #ifndef NDEBUG
     181:     if (dflag)
     182:         debug("[makeroom: curlno=%d, delcnt=%d, here=%d, avail=%d, amiss=%d]",
     183:             curlno, delcnt, here, avail, amiss);
     184: #endif NDEBUG
     185:     if (amiss <= 0)
     186:         return delcnt;
     187:     if (amiss > delcnt) {
     188:         for (; p; p = p->c_link) {
     189:             if (p->c_onscreen != Nowhere) {
     190:                 diff = amiss-delcnt;
     191:                 if (p->c_onscreen - delcnt - here < diff)
     192:                     diff = p->c_onscreen - delcnt - here;
     193:                 if (diff > 0) {
     194:                     trmscrollup(here, winheight, diff);
     195:                     delcnt += diff;
     196:                 }
     197:                 p->c_onscreen += -delcnt + amiss;
     198:                 here = p->c_onscreen - amiss;
     199:                 if (p->c_onscreen >= winheight)
     200:                     p->c_onscreen = Nowhere;
     201:             }
     202:             here += Space(p);
     203:         }
     204:         /* Now for all p encountered whose p->c_onscreen != Nowhere,
     205: 		/* p->c_onscreen - amiss is its actual position. */
     206:         if (amiss > delcnt) {
     207:             trmscrollup(winheight - amiss, winheight, amiss-delcnt);
     208:             delcnt = amiss;
     209:         }
     210:     }
     211:     /* Now amiss <= delcnt */
     212:     trmscrollup(curlno + avail, winheight, -amiss);
     213:     return delcnt - amiss;
     214: }
     215:
     216:
     217: /*
     218:  * Addition to makeroom - make sure the status line is not overwritten.
     219:  * Returns new delcnt, like makeroom does.
     220:  */
     221:
     222: Hidden int
     223: make2room(p, curlno, delcnt)
     224:     cell *p;
     225:     int curlno;
     226:     int delcnt;
     227: {
     228:     int nextline = curlno + Space(p);
     229:     int sline = winheight - delcnt;
     230:     int diff;
     231:
     232:     if (sline < curlno) {
     233: #ifndef NDEBUG
     234:         debug("[Status line overwritten]");
     235: #endif NDEBUG
     236:         return delcnt;
     237:     }
     238:     if (nextline > winheight)
     239:         nextline = winheight;
     240:     diff = nextline - sline;
     241:     if (diff > 0) {
     242:         trmscrollup(sline, winheight, -diff);
     243:         delcnt -= diff;
     244:     }
     245:     return delcnt;
     246:
     247: }
     248:
     249:
     250: /*
     251:  * Routine called for every change in the screen.
     252:  */
     253:
     254: Visible Procedure
     255: virtupdate(oldep, newep, highest)
     256:     environ *oldep;
     257:     environ *newep;
     258:     int highest;
     259: {
     260:     environ old;
     261:     environ new;
     262:     register int oldlno;
     263:     register int newlno;
     264:     register int oldlcnt;
     265:     register int newlcnt;
     266:     register int i;
     267:
     268:     if (!oldep) {
     269:         highest = 1;
     270:         trmputdata(winstart, winheight, indent, "");
     271:         discard(tops);
     272:         tops = Cnil;
     273:         Ecopy(*newep, old);
     274:     }
     275:     else {
     276:         Ecopy(*oldep, old);
     277:     }
     278:     Ecopy(*newep, new);
     279:
     280:     savefocus(&new);
     281:
     282:     oldlcnt = fixlevels(&old, &new, highest);
     283:     newlcnt = -width(tree(new.focus));
     284:     if (newlcnt < 0)
     285:         newlcnt = 0;
     286:     i = -width(tree(old.focus));
     287:     if (i < 0)
     288:         i = 0;
     289:     newlcnt -= i - oldlcnt;
     290:         /* Offset newlcnt as much as oldcnt is offset */
     291:
     292:     oldlno = Ycoord(old.focus);
     293:     newlno = Ycoord(new.focus);
     294:     if (!atlinestart(&old))
     295:         ++oldlcnt;
     296:     else
     297:         ++oldlno;
     298:     if (!atlinestart(&new))
     299:         ++newlcnt;
     300:     else
     301:         ++newlno;
     302:     Assert(oldlno == newlno);
     303:
     304:     tops = replist(tops, build(new.focus, newlcnt), oldlno, oldlcnt);
     305:
     306:     setfocus(tops); /* Incorporate the information saved by savefocus */
     307:
     308:     Erelease(old);
     309:     Erelease(new);
     310: }
     311:
     312:
     313: Hidden bool
     314: atlinestart(ep)
     315:     environ *ep;
     316: {
     317:     register string repr = noderepr(tree(ep->focus))[0];
     318:
     319:     return Fw_negative(repr);
     320: }
     321:
     322:
     323: /*
     324:  * Make the two levels the same, and make sure they both are line starters
     325:  * if at all possible.  Return the OLD number of lines to be replaced.
     326:  * (0 if the whole unit has no linefeeds.)
     327:  */
     328:
     329: Hidden int
     330: fixlevels(oldep, newep, highest)
     331:     register environ *oldep;
     332:     register environ *newep;
     333:     register int highest;
     334: {
     335:     register int oldpl = pathlength(oldep->focus);
     336:     register int newpl = pathlength(newep->focus);
     337:     register bool intraline = No;
     338:     register int w;
     339:
     340:     if (oldpl < highest)
     341:         highest = oldpl;
     342:     if (newpl < highest)
     343:         highest = newpl;
     344:     while (oldpl > highest) {
     345:         up(&oldep->focus) || Abort();
     346:         --oldpl;
     347:     }
     348:     while (newpl > highest) {
     349:         up(&newep->focus) || Abort();
     350:         --newpl;
     351:     }
     352:     if (Ycoord(newep->focus) != Ycoord(oldep->focus) ||
     353:         Level(newep->focus) != Level(newep->focus)) {
     354:         /* Inconsistency found.  */
     355:         Assert(highest > 1); /* Inconsistency at top level. Stop. */
     356:         return fixlevels(oldep, newep, 1); /* Try to recover. */
     357:     }
     358:     intraline = width(tree(oldep->focus)) >= 0
     359:         && width(tree(newep->focus)) >= 0;
     360:     while (!atlinestart(oldep) || !atlinestart(newep)) {
     361:         /* Find beginning of lines for both */
     362:         if (!up(&newep->focus)) {
     363:             Assert(!up(&newep->focus));
     364:             break;
     365:         }
     366:         --oldpl;
     367:         up(&oldep->focus) || Abort();
     368:         --newpl;
     369:     }
     370:     if (intraline)
     371:         return atlinestart(oldep);
     372:     w = width(tree(oldep->focus));
     373:     return w < 0 ? -w : 0;
     374: }
     375:
     376:
     377: /*
     378:  * Initialization code.
     379:  */
     380:
     381: Visible Procedure
     382: initshow()
     383: {
     384:     int flags = 0;
     385: #ifndef NDEBUG
     386:     if (dflag)
     387:         fprintf(stderr, "*** initshow();\n\r");
     388: #endif NDEBUG
     389:     if (!trmstart(&winheight, &llength, &flags)) {
     390:         endunix();
     391:         exit(2);
     392:     }
     393:     noscroll = (flags&2) == 0;
     394:     nosense = (flags&8) == 0;
     395:     winstart = --winheight;
     396: }
     397:
     398:
     399: /*
     400:  * Routine to move the cursor to the first line after the just edited
     401:  * document.  (Called after each editing action.)
     402:  */
     403:
     404: Visible Procedure
     405: endshow()
     406: {
     407:     register cell *p;
     408:     register int last = winheight;
     409:
     410:     for (p = tops; p; p = p->c_link) {
     411:         if (p->c_onscreen != Nowhere)
     412:             last = p->c_onscreen + Oldspace(p);
     413:     }
     414:     if (last > winheight)
     415:         last = winheight;
     416:     discard(tops);
     417:     tops = Cnil;
     418:     trmputdata(last, winheight, 0, "");
     419:     trmsync(last, 0);
     420:     trmend();
     421: }
     422:
     423:
     424: /*
     425:  * Translate a cursor position in tree coordinates.
     426:  *
     427:  * ***** DOESN'T WORK IF SCREEN INDENT DIFFERS FROM TREE INDENT! *****
     428:  * (I.e. for lines with >= 80 spaces indentation)
     429:  */
     430:
     431: Visible bool
     432: backtranslate(py, px)
     433:     int *py;
     434:     int *px;
     435: {
     436:     cell *p;
     437:     int y = *py;
     438:     int x = *px;
     439:     int i;
     440:
     441:     for (i = 0, p = tops; p; ++i, p = p->c_link) {
     442:         if (p->c_onscreen != Nowhere
     443:             && y >= p->c_onscreen && y < p->c_onscreen + Space(p)) {
     444:             *px += (y - p->c_onscreen) * llength - indent;
     445:             if (*px < 0)
     446:                 *px = 0;
     447:             *py = i;
     448:             if (p->c_oldvhole && (y > focy || y == focy && x > focx))
     449:                 --*px; /* Correction if beyond Vhole on same logical line */
     450:             return Yes;
     451:         }
     452:     }
     453:     error(GOTO_OUT);
     454:     return No;
     455: }
     456:
     457:
     458: /*
     459:  * Set the indent level and window start line.
     460:  */
     461:
     462: Visible Procedure
     463: setindent(x)
     464:     int x;
     465: {
     466:     winstart= winheight;
     467:     indent= x;
     468: }
     469:
     470:
     471: /*
     472:  * Show the command prompt.
     473:  */
     474:
     475: Visible Procedure cmdprompt(prompt)
     476:     string prompt;
     477: {
     478:     setindent(strlen(prompt));
     479:     trmputdata(winstart, winstart, 0, prompt);
     480: }

#### Defined functions

actupdate defined in line 39; used 2 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 303, 455

atlinestart defined in line 313; used 5 times

- in line 294-298(2), 360(2), 371

backtranslate defined in line 431; used 1 times

- in /usr/src/new/PORT/B/src/bed/goto.c line 42

cmdprompt defined in line 475; used 1 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 129

endshow defined in line 404; used 3 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 131, 151, 198

fixlevels defined in line 329; used 2 times

- in line 282, 356

growwin defined in line 128; used 1 times

- in line 56

initshow defined in line 381; used 3 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 127, 149, 196

make2room defined in line 222; used 2 times

- in line 83, 89

makeroom defined in line 159; used 1 times

- in line 88

setindent defined in line 462; used 2 times

- in line 478
- in /usr/src/new/PORT/B/src/bed/comm.c line 322

virtupdate defined in line 254; used 1 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 291

#### Defined variables

indent defined in line 26; used 9 times

- in line 270, 444, 467
- in /usr/src/new/PORT/B/src/bed/cell.h line 28
- in /usr/src/new/PORT/B/src/bed/outp.c line 193, 201
- in /usr/src/new/PORT/B/src/bed/scrn.c line 270, 444, 467

llength defined in line 27; used 11 times

- in line 389, 444
- in /usr/src/new/PORT/B/src/bed/cell.h line 28(2)
- in /usr/src/new/PORT/B/src/bed/erro.c line 50
- in /usr/src/new/PORT/B/src/bed/help.c line 92-93(2)
- in /usr/src/new/PORT/B/src/bed/outp.c line 194-195(2)
- in /usr/src/new/PORT/B/src/bed/scrn.c line 389, 444

noscroll defined in line 29; used 3 times

- in line 393
- in /usr/src/new/PORT/B/src/bed/cell.c line 297-301(2)

nosense defined in line 30; used 2 times

- in line 394
- in /usr/src/new/PORT/B/src/bed/term.c line 67

rcsid defined in line 2; never used
tops defined in line 32; used 14 times

- in line 46, 58-59(2), 136, 146, 271-272(2), 304-306(3), 410, 416-417(2), 441

winheight defined in line 25; used 86 times

- in line 65, 77-82(2), 107-111(4), 118, 138-144(6), 194-199(2), 207-212(3), 229, 238-242(3), 270, 389, 395, 408, 414-418(3), 466
- in /usr/src/new/PORT/B/src/bed/erro.c line 78(2), 104-107(4), 114
- in /usr/src/new/PORT/B/src/bed/goto.c line 39, 67, 79
- in /usr/src/new/PORT/B/src/bed/help.c line 98-100(4), 110-115(5), 121-122(3)
- in /usr/src/new/PORT/B/src/bed/outp.c line 173-174(2)
- in /usr/src/new/PORT/B/src/bed/scrn.c line 65, 77-82(2), 107-111(4), 118, 138-144(6), 194-199(2), 207-212(3), 229, 238-242(3), 270, 389, 395, 408, 414-418(3), 466

winstart defined in line 23; used 15 times

- in line 55-57(2), 65, 138-145(4), 270, 395, 466, 479(2)
- in /usr/src/new/PORT/B/src/bed/erro.c line 100
- in /usr/src/new/PORT/B/src/bed/goto.c line 67
- in /usr/src/new/PORT/B/src/bed/help.c line 122

Last modified: 1985-08-27 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1322 |