Annotation of coherent/d/usr/bin/elvis/redraw.c, revision 1.1

1.1     ! root        1: /* redraw.c */
        !             2: 
        !             3: /* Author:
        !             4:  *     Steve Kirkendall
        !             5:  *     16820 SW Tallac Way
        !             6:  *     Beaverton, OR 97006
        !             7:  *     [email protected], or ...uunet!tektronix!psueea!jove!kirkenda
        !             8:  */
        !             9: 
        !            10: 
        !            11: /* This file contains functions that draw text on the screen.  The major entry
        !            12:  * points are:
        !            13:  *     redrawrange()   - called from modify.c to give hints about what parts
        !            14:  *                       of the screen need to be redrawn.
        !            15:  *     redraw()        - redraws the screen (or part of it) and positions
        !            16:  *                       the cursor where it belongs.
        !            17:  *     idx2col()       - converts a markidx() value to a logical column number.
        !            18:  */
        !            19: 
        !            20: #include "config.h"
        !            21: #include "vi.h"
        !            22: 
        !            23: /* This variable contains the line number that smartdrawtext() knows best */
        !            24: static long smartlno;
        !            25: 
        !            26: /* This function remebers where changes were made, so that the screen can be
        !            27:  * redraw in a more efficient manner.
        !            28:  */
        !            29: static long    redrawafter;    /* line# of first line that must be redrawn */
        !            30: static long    preredraw;      /* line# of last line changed, before change */
        !            31: static long    postredraw;     /* line# of last line changed, after change */
        !            32: void redrawrange(after, pre, post)
        !            33:        long    after;  /* lower bound of redrawafter */
        !            34:        long    pre;    /* upper bound of preredraw */
        !            35:        long    post;   /* upper bound of postredraw */
        !            36: {
        !            37:        if (after == redrawafter)
        !            38:        {
        !            39:                /* multiple insertions/deletions at the same place -- combine
        !            40:                 * them
        !            41:                 */
        !            42:                preredraw -= (post - pre);
        !            43:                if (postredraw < post)
        !            44:                {
        !            45:                        preredraw += (post - postredraw);
        !            46:                        postredraw = post;
        !            47:                }
        !            48:                if (redrawafter > preredraw)
        !            49:                {
        !            50:                        redrawafter = preredraw;
        !            51:                }
        !            52:                if (redrawafter < 1L)
        !            53:                {
        !            54:                        redrawafter = 0L;
        !            55:                        preredraw = postredraw = INFINITY;
        !            56:                }
        !            57:        }
        !            58:        else if (postredraw > 0L)
        !            59:        {
        !            60:                /* multiple changes in different places -- redraw everything
        !            61:                 * after "after".
        !            62:                 */
        !            63:                postredraw = preredraw = INFINITY;
        !            64:                if (after < redrawafter)
        !            65:                        redrawafter = after;
        !            66:        }
        !            67:        else
        !            68:        {
        !            69:                /* first change */
        !            70:                redrawafter = after;
        !            71:                preredraw = pre;
        !            72:                postredraw = post;
        !            73:        }
        !            74: }
        !            75: 
        !            76: 
        !            77: #ifndef NO_CHARATTR
        !            78: /* see if a given line uses character attribute strings */
        !            79: static int hasattr(lno, text)
        !            80:        long            lno;    /* the line# of the cursor */
        !            81:        REG char        *text;  /* the text of the line, from fetchline */
        !            82: {
        !            83:        static long     plno;   /* previous line number */
        !            84:        static long     chgs;   /* previous value of changes counter */
        !            85:        static int      panswer;/* previous answer */
        !            86:        char            *scan;
        !            87: 
        !            88:        /* if charattr is off, then the answer is "no, it doesn't" */
        !            89:        if (!*o_charattr)
        !            90:        {
        !            91:                chgs = 0; /* <- forces us to check if charattr is later set */
        !            92:                return FALSE;
        !            93:        }
        !            94: 
        !            95:        /* if we already know the answer, return it... */
        !            96:        if (lno == plno && chgs == changes)
        !            97:        {
        !            98:                return panswer;
        !            99:        }
        !           100: 
        !           101:        /* get the line & look for "\fX" */
        !           102:        if (!text[0] || !text[1] || !text[2])
        !           103:        {
        !           104:                panswer = FALSE;
        !           105:        }
        !           106:        else
        !           107:        {
        !           108:                for (scan = text; scan[2] && !(scan[0] == '\\' && scan[1] == 'f'); scan++)
        !           109:                {
        !           110:                }
        !           111:                panswer = (scan[2] != '\0');
        !           112:        }
        !           113: 
        !           114:        /* save the results */
        !           115:        plno = lno;
        !           116:        chgs = changes;
        !           117: 
        !           118:        /* return the results */
        !           119:        return panswer;
        !           120: }
        !           121: #endif
        !           122: 
        !           123: 
        !           124: 
        !           125: /* This function converts a MARK to a column number.  It doesn't automatically
        !           126:  * adjust for leftcol; that must be done by the calling function
        !           127:  */
        !           128: int idx2col(curs, text, inputting)
        !           129:        MARK            curs;   /* the line# & index# of the cursor */
        !           130:        REG char        *text;  /* the text of the line, from fetchline */
        !           131:        int             inputting;      /* boolean: called from input() ? */
        !           132: {
        !           133:        static MARK     pcursor;/* previous cursor, for possible shortcut */
        !           134:        static MARK     pcol;   /* column number for pcol */
        !           135:        static long     chgs;   /* previous value of changes counter */
        !           136:        REG int         col;    /* used to count column numbers */
        !           137:        REG int         idx;    /* used to count down the index */
        !           138:        REG int         i;
        !           139: 
        !           140:        /* for now, assume we have to start counting at the left edge */
        !           141:        col = 0;
        !           142:        idx = markidx(curs);
        !           143: 
        !           144:        /* if the file hasn't changed & line number is the same & it has no
        !           145:         * embedded character attribute strings, can we do shortcuts?
        !           146:         */
        !           147:        if (chgs == changes
        !           148:         && !((curs ^ pcursor) & ~(BLKSIZE - 1))
        !           149: #ifndef NO_CHARATTR
        !           150:         && !hasattr(markline(curs), text)
        !           151: #endif
        !           152:        )
        !           153:        {
        !           154:                /* no movement? */
        !           155:                if (curs == pcursor)
        !           156:                {
        !           157:                        /* return the column of the char; for tabs, return its last column */
        !           158:                        if (text[idx] == '\t' && !inputting && !*o_list)
        !           159:                        {
        !           160:                                return pcol + *o_tabstop - (pcol % *o_tabstop) - 1;
        !           161:                        }
        !           162:                        else
        !           163:                        {
        !           164:                                return pcol;
        !           165:                        }
        !           166:                }
        !           167: 
        !           168:                /* movement to right? */
        !           169:                if (curs > pcursor)
        !           170:                {
        !           171:                        /* start counting from previous place */
        !           172:                        col = pcol;
        !           173:                        idx = markidx(curs) - markidx(pcursor);
        !           174:                        text += markidx(pcursor);
        !           175:                }
        !           176:        }
        !           177: 
        !           178:        /* count over to the char after the idx position */
        !           179:        while (idx > 0 && (i = *text)) /* yes, ASSIGNMENT! */
        !           180:        {
        !           181:                if (i == '\t' && !*o_list)
        !           182:                {
        !           183:                        col += *o_tabstop;
        !           184:                        col -= col % *o_tabstop;
        !           185:                }
        !           186:                else if (i >= '\0' && i < ' ' || i == '\177')
        !           187:                {
        !           188:                        col += 2;
        !           189:                }
        !           190: #ifndef NO_CHARATTR
        !           191:                else if (i == '\\' && text[1] == 'f' && text[2] && *o_charattr)
        !           192:                {
        !           193:                        text += 2; /* plus one more at bottom of loop */
        !           194:                        idx -= 2;
        !           195:                }                       
        !           196: #endif
        !           197:                else
        !           198:                {
        !           199:                        col++;
        !           200:                }
        !           201:                text++;
        !           202:                idx--;
        !           203:        }
        !           204: 
        !           205:        /* save stuff to speed next call */
        !           206:        pcursor = curs;
        !           207:        pcol = col;
        !           208:        chgs = changes;
        !           209: 
        !           210:        /* return the column of the char; for tabs, return its last column */
        !           211:        if (*text == '\t' && !inputting && !*o_list)
        !           212:        {
        !           213:                return col + *o_tabstop - (col % *o_tabstop) - 1;
        !           214:        }
        !           215:        else
        !           216:        {
        !           217:                return col;
        !           218:        }
        !           219: }
        !           220: 
        !           221: 
        !           222: /* This function is similar to idx2col except that it takes care of sideways
        !           223:  * scrolling - for the given line, at least.
        !           224:  */
        !           225: int mark2phys(m, text, inputting)
        !           226:        MARK    m;              /* a mark to convert */
        !           227:        char    *text;          /* the line that m refers to */
        !           228:        int     inputting;      /* boolean: caled from input() ? */
        !           229: {
        !           230:        int     i;
        !           231: 
        !           232:        i = idx2col(m, text, inputting);
        !           233:        while (i < leftcol)
        !           234:        {
        !           235:                leftcol -= *o_sidescroll;
        !           236:                mustredraw = TRUE;
        !           237:                redrawrange(1L, INFINITY, INFINITY);
        !           238:                qaddch('\r');
        !           239:                /* drawtext(text); */
        !           240:        }
        !           241:        while (i > rightcol)
        !           242:        {
        !           243:                leftcol += *o_sidescroll;
        !           244:                mustredraw = TRUE;
        !           245:                redrawrange(1L, INFINITY, INFINITY);
        !           246:                qaddch('\r');
        !           247:                /* drawtext(text); */
        !           248:        }
        !           249:        physcol = i - leftcol;
        !           250:        physrow = markline(m) - topline;
        !           251: 
        !           252:        return physcol;
        !           253: }
        !           254: 
        !           255: /* This function draws a single line of text on the screen.  The screen's
        !           256:  * cursor is assumed to be located at the leftmost column of the appropriate
        !           257:  * row.
        !           258:  */
        !           259: static void drawtext(text, clr)
        !           260:        REG char        *text;  /* the text to draw */
        !           261:        int             clr;    /* boolean: do a clrtoeol? */
        !           262: {
        !           263:        REG int         col;    /* column number */
        !           264:        REG int         i;
        !           265:        REG int         tabstop;        /* *o_tabstop */
        !           266:        REG int         limitcol;       /* leftcol or leftcol + COLS */
        !           267:        int             abnormal;       /* boolean: charattr != A_NORMAL? */
        !           268: 
        !           269: #ifndef NO_SENTENCE
        !           270:        /* if we're hiding format lines, and this is one of them, then hide it */
        !           271:        if (*o_hideformat && *text == '.')
        !           272:        {
        !           273:                clrtoeol();
        !           274: #if OSK
        !           275:                qaddch('\l');
        !           276: #else
        !           277:                qaddch('\n');
        !           278: #endif
        !           279:                return;
        !           280:        }
        !           281: #endif
        !           282: 
        !           283:        /* move some things into registers... */
        !           284:        limitcol = leftcol;
        !           285:        tabstop = *o_tabstop;
        !           286:        abnormal = FALSE;
        !           287: 
        !           288: #ifndef CRUNCH
        !           289:        if (clr)
        !           290:                clrtoeol();
        !           291: #endif
        !           292:        /* skip stuff that was scrolled off left edge */
        !           293:        for (col = 0;
        !           294:             (i = *text) && col < limitcol; /* yes, ASSIGNMENT! */
        !           295:             text++)
        !           296:        {
        !           297:                if (i == '\t' && !*o_list)
        !           298:                {
        !           299:                        col = col + tabstop - (col % tabstop);
        !           300:                }
        !           301:                else if (i >= 0 && i < ' ' || i == '\177')
        !           302:                {
        !           303:                        col += 2;
        !           304:                }
        !           305: #ifndef NO_CHARATTR
        !           306:                else if (i == '\\' && text[1] == 'f' && text[2] && *o_charattr)
        !           307:                {
        !           308:                        text += 2; /* plus one more as part of "for" loop */
        !           309: 
        !           310:                        /* since this attribute might carry over, we need it */
        !           311:                        switch (*text)
        !           312:                        {
        !           313:                          case 'R':
        !           314:                          case 'P':
        !           315:                                attrset(A_NORMAL);
        !           316:                                abnormal = FALSE;
        !           317:                                break;
        !           318: 
        !           319:                          case 'B':
        !           320:                                attrset(A_BOLD);
        !           321:                                abnormal = TRUE;
        !           322:                                break;
        !           323: 
        !           324:                          case 'U':
        !           325:                                attrset(A_UNDERLINE);
        !           326:                                abnormal = TRUE;
        !           327:                                break;
        !           328: 
        !           329:                          case 'I':
        !           330:                                attrset(A_ALTCHARSET);
        !           331:                                abnormal = TRUE;
        !           332:                                break;
        !           333:                        }
        !           334:                }
        !           335: #endif
        !           336:                else
        !           337:                {
        !           338:                        col++;
        !           339:                }
        !           340:        }
        !           341: 
        !           342:        /* adjust for control char that was partially visible */
        !           343:        while (col > limitcol)
        !           344:        {
        !           345:                qaddch(' ');
        !           346:                limitcol++;
        !           347:        }
        !           348: 
        !           349:        /* now for the visible characters */
        !           350:        for (limitcol = leftcol + COLS;
        !           351:             (i = *text) && col < limitcol;
        !           352:             text++)
        !           353:        {
        !           354:                if (i == '\t' && !*o_list)
        !           355:                {
        !           356:                        i = col + tabstop - (col % tabstop);
        !           357:                        if (i < limitcol)
        !           358:                        {
        !           359: #ifdef CRUNCH
        !           360:                                if (!clr && has_PT && !((i - leftcol) & 7))
        !           361: #else
        !           362:                                if (has_PT && !((i - leftcol) & 7))
        !           363: #endif
        !           364:                                {
        !           365:                                        do
        !           366:                                        {
        !           367:                                                qaddch('\t');
        !           368:                                                col += 8; /* not exact! */
        !           369:                                        } while (col < i);
        !           370:                                        col = i; /* NOW it is exact */
        !           371:                                }
        !           372:                                else
        !           373:                                {
        !           374:                                        do
        !           375:                                        {
        !           376:                                                qaddch(' ');
        !           377:                                                col++;
        !           378:                                        } while (col < i);
        !           379:                                }
        !           380:                        }
        !           381:                        else /* tab ending after screen? next line! */
        !           382:                        {
        !           383:                                col = limitcol;
        !           384:                                if (has_AM)
        !           385:                                {
        !           386:                                        addch('\n');    /* GB */
        !           387:                                }
        !           388:                        }
        !           389:                }
        !           390:                else if (i >= 0 && i < ' ' || i == '\177')
        !           391:                {
        !           392:                        col += 2;
        !           393:                        qaddch('^');
        !           394:                        if (col <= limitcol)
        !           395:                        {
        !           396:                                qaddch(i ^ '@');
        !           397:                        }
        !           398:                }
        !           399: #ifndef NO_CHARATTR
        !           400:                else if (i == '\\' && text[1] == 'f' && text[2] && *o_charattr)
        !           401:                {
        !           402:                        text += 2; /* plus one more as part of "for" loop */
        !           403:                        switch (*text)
        !           404:                        {
        !           405:                          case 'R':
        !           406:                          case 'P':
        !           407:                                attrset(A_NORMAL);
        !           408:                                abnormal = FALSE;
        !           409:                                break;
        !           410: 
        !           411:                          case 'B':
        !           412:                                attrset(A_BOLD);
        !           413:                                abnormal = TRUE;
        !           414:                                break;
        !           415: 
        !           416:                          case 'U':
        !           417:                                attrset(A_UNDERLINE);
        !           418:                                abnormal = TRUE;
        !           419:                                break;
        !           420: 
        !           421:                          case 'I':
        !           422:                                attrset(A_ALTCHARSET);
        !           423:                                abnormal = TRUE;
        !           424:                                break;
        !           425:                        }
        !           426:                }
        !           427: #endif
        !           428:                else
        !           429:                {
        !           430:                        col++;
        !           431:                        qaddch(i);
        !           432:                }
        !           433:        }
        !           434: 
        !           435:        /* get ready for the next line */
        !           436: #ifndef NO_CHARATTR
        !           437:        if (abnormal)
        !           438:        {
        !           439:                attrset(A_NORMAL);
        !           440:        }
        !           441: #endif
        !           442:        if (*o_list && col < limitcol)
        !           443:        {
        !           444:                qaddch('$');
        !           445:                col++;
        !           446:        }
        !           447: #ifdef CRUNCH
        !           448:        if (clr && col < limitcol)
        !           449:        {
        !           450:                clrtoeol();
        !           451:        }
        !           452: #endif
        !           453:        if (!has_AM || col < limitcol)
        !           454:        {
        !           455:                addch('\n');
        !           456:        }
        !           457: }
        !           458: 
        !           459: 
        !           460: #ifndef CRUNCH
        !           461: static void nudgecursor(same, scan, new, lno)
        !           462:        int     same;   /* number of chars to be skipped over */
        !           463:        char    *scan;  /* where the same chars end */
        !           464:        char    *new;   /* where the visible part of the line starts */
        !           465:        long    lno;    /* line number of this line */
        !           466: {
        !           467:        if (same > 0)
        !           468:        {
        !           469:                if (same < 5)
        !           470:                {
        !           471:                        /* move the cursor by overwriting */
        !           472:                        while (same > 0)
        !           473:                        {
        !           474:                                qaddch(scan[-same]);
        !           475:                                same--;
        !           476:                        }
        !           477:                }
        !           478:                else
        !           479:                {
        !           480:                        /* move the cursor by calling move() */
        !           481:                        move((int)(lno - topline), (int)(scan - new));
        !           482:                }
        !           483:        }
        !           484: }
        !           485: #endif /* not CRUNCH */
        !           486: 
        !           487: /* This function draws a single line of text on the screen, possibly with
        !           488:  * some cursor optimization.  The cursor is repositioned before drawing
        !           489:  * begins, so its position before doesn't really matter.
        !           490:  */
        !           491: static void smartdrawtext(text, lno)
        !           492:        REG char        *text;  /* the text to draw */
        !           493:        long            lno;    /* line number of the text */
        !           494: {
        !           495: #ifdef CRUNCH
        !           496:        move((int)(lno - topline), 0);
        !           497:        drawtext(text, TRUE);
        !           498: #else /* not CRUNCH */
        !           499:        static char     old[256];       /* how the line looked last time */
        !           500:        char            new[256];       /* how it looks now */
        !           501:        char            *build;         /* used to put chars into new[] */
        !           502:        char            *scan;          /* used for moving thru new[] or old[] */
        !           503:        char            *end;           /* last non-blank changed char */
        !           504:        char            *shift;         /* used to insert/delete chars */
        !           505:        int             same;           /* length of a run of unchanged chars */
        !           506:        int             limitcol;
        !           507:        int             col;
        !           508:        int             i;
        !           509: 
        !           510: # ifndef NO_CHARATTR
        !           511:        /* if this line has attributes, do it the dumb way instead */
        !           512:        if (hasattr(lno, text))
        !           513:        {
        !           514:                move((int)(lno - topline), 0);
        !           515:                drawtext(text, TRUE);
        !           516:                return;
        !           517:        }
        !           518: # endif
        !           519: # ifndef NO_SENTENCE
        !           520:        /* if this line is a format line, & we're hiding format lines, then
        !           521:         * let the dumb drawtext() function handle it
        !           522:         */
        !           523:        if (*o_hideformat && *text == '.')
        !           524:        {
        !           525:                move((int)(lno - topline), 0);
        !           526:                drawtext(text, TRUE);
        !           527:                return;
        !           528:        }
        !           529: # endif
        !           530: 
        !           531:        /* skip stuff that was scrolled off left edge */
        !           532:        limitcol = leftcol;
        !           533:        for (col = 0;
        !           534:             (i = *text) && col < limitcol; /* yes, ASSIGNMENT! */
        !           535:             text++)
        !           536:        {
        !           537:                if (i == '\t' && !*o_list)
        !           538:                {
        !           539:                        col = col + *o_tabstop - (col % *o_tabstop);
        !           540:                }
        !           541:                else if (i >= 0 && i < ' ' || i == '\177')
        !           542:                {
        !           543:                        col += 2;
        !           544:                }
        !           545:                else
        !           546:                {
        !           547:                        col++;
        !           548:                }
        !           549:        }
        !           550: 
        !           551:        /* adjust for control char that was partially visible */
        !           552:        build = new;
        !           553:        while (col > limitcol)
        !           554:        {
        !           555:                *build++ = ' ';
        !           556:                limitcol++;
        !           557:        }
        !           558: 
        !           559:        /* now for the visible characters */
        !           560:        for (limitcol = leftcol + COLS;
        !           561:             (i = *text) && col < limitcol;
        !           562:             text++)
        !           563:        {
        !           564:                if (i == '\t' && !*o_list)
        !           565:                {
        !           566:                        i = col + *o_tabstop - (col % *o_tabstop);
        !           567:                        while (col < i && col < limitcol)
        !           568:                        {
        !           569:                                *build++ = ' ';
        !           570:                                col++;
        !           571:                        }
        !           572:                }
        !           573:                else if (i >= 0 && i < ' ' || i == '\177')
        !           574:                {
        !           575:                        col += 2;
        !           576:                        *build++ = '^';
        !           577:                        if (col <= limitcol)
        !           578:                        {
        !           579:                                *build++ = (i ^ '@');
        !           580:                        }
        !           581:                }
        !           582:                else
        !           583:                {
        !           584:                        col++;
        !           585:                        *build++ = i;
        !           586:                }
        !           587:        }
        !           588:        if (col < limitcol && *o_list)
        !           589:        {
        !           590:                *build++ = '$';
        !           591:                col++;
        !           592:        }
        !           593:        end = build;
        !           594:        while (col < limitcol)
        !           595:        {
        !           596:                *build++ = ' ';
        !           597:                col++;
        !           598:        }
        !           599: 
        !           600:        /* locate the last non-blank character */
        !           601:        while (end > new && end[-1] == ' ')
        !           602:        {
        !           603:                end--;
        !           604:        }
        !           605: 
        !           606:        /* can we optimize the displaying of this line? */
        !           607:        if (lno != smartlno)
        !           608:        {
        !           609:                /* nope, can't optimize - different line */
        !           610:                move((int)(lno - topline), 0);
        !           611:                for (scan = new, build = old; scan < end; )
        !           612:                {
        !           613:                        qaddch(*scan);
        !           614:                        *build++ = *scan++;
        !           615:                }
        !           616:                if (end < new + COLS)
        !           617:                {
        !           618:                        clrtoeol();
        !           619:                        while (build < old + COLS)
        !           620:                        {
        !           621:                                *build++ = ' ';
        !           622:                        }
        !           623:                }
        !           624:                smartlno = lno;
        !           625:                return;
        !           626:        }
        !           627: 
        !           628:        /* skip any initial unchanged characters */
        !           629:        for (scan = new, build = old; scan < end && *scan == *build; scan++, build++)
        !           630:        {
        !           631:        }
        !           632:        move((int)(lno - topline), (int)(scan - new));
        !           633: 
        !           634:        /* The in-between characters must be changed */
        !           635:        same = 0;
        !           636:        while (scan < end)
        !           637:        {
        !           638:                /* is this character a match? */
        !           639:                if (scan[0] == build[0])
        !           640:                {
        !           641:                        same++;
        !           642:                }
        !           643:                else /* do we want to insert? */
        !           644:                if (scan < end - 1 && scan[1] == build[0] && (has_IC || has_IM))
        !           645:                {
        !           646:                        nudgecursor(same, scan, new, lno);
        !           647:                        same = 0;
        !           648: 
        !           649:                        insch(*scan);
        !           650:                        for (shift = old + COLS; --shift > build; )
        !           651:                        {
        !           652:                                shift[0] = shift[-1];
        !           653:                        }
        !           654:                        *build = *scan;
        !           655:                }
        !           656:                else /* do we want to delete? */
        !           657:                if (build < old + COLS - 1 && scan[0] == build[1] && has_DC)
        !           658:                {
        !           659:                        nudgecursor(same, scan, new, lno);
        !           660:                        same = 0;
        !           661: 
        !           662:                        delch();
        !           663:                        same++;
        !           664:                        for (shift = build; shift < old + COLS - 1; shift++)
        !           665:                        {
        !           666:                                shift[0] = shift[1];
        !           667:                        }
        !           668:                        *shift = ' ';
        !           669:                }
        !           670:                else /* we must overwrite */
        !           671:                {
        !           672:                        nudgecursor(same, scan, new, lno);
        !           673:                        same = 0;
        !           674: 
        !           675:                        addch(*scan);
        !           676:                        *build = *scan;
        !           677:                }
        !           678: 
        !           679:                build++;
        !           680:                scan++;
        !           681:        }
        !           682: 
        !           683:        /* maybe clear to EOL */
        !           684:        while (build < old + COLS && *build == ' ')
        !           685:        {
        !           686:                build++;
        !           687:        }
        !           688:        if (build < old + COLS)
        !           689:        {
        !           690:                nudgecursor(same, scan, new, lno);
        !           691:                same = 0;
        !           692: 
        !           693:                clrtoeol();
        !           694:                while (build < old + COLS)
        !           695:                {
        !           696:                        *build++ = ' ';
        !           697:                }
        !           698:        }
        !           699: #endif /* not CRUNCH */
        !           700: }
        !           701: 
        !           702: 
        !           703: /* This function is used in visual mode for drawing the screen (or just parts
        !           704:  * of the screen, if that's all thats needed).  It also takes care of
        !           705:  * scrolling.
        !           706:  */
        !           707: void redraw(curs, inputting)
        !           708:        MARK    curs;           /* where to leave the screen's cursor */
        !           709:        int     inputting;      /* boolean: being called from input() ? */
        !           710: {
        !           711:        char            *text;          /* a line of text to display */
        !           712:        static long     chgs;           /* previous changes level */
        !           713:        long            l;
        !           714:        int             i;
        !           715: 
        !           716:        /* if curs == MARK_UNSET, then we should reset internal vars */
        !           717:        if (curs == MARK_UNSET)
        !           718:        {
        !           719:                if (topline < 1 || topline > nlines)
        !           720:                {
        !           721:                        topline = 1L;
        !           722:                }
        !           723:                else
        !           724:                {
        !           725:                        move(LINES - 1, 0);
        !           726:                        clrtoeol();
        !           727:                }
        !           728:                leftcol = 0;
        !           729:                mustredraw = TRUE;
        !           730:                redrawafter = INFINITY;
        !           731:                preredraw = 0L;
        !           732:                postredraw = 0L;
        !           733:                chgs = 0;
        !           734:                smartlno = 0L;
        !           735:                return;
        !           736:        }
        !           737: 
        !           738:        /* figure out which column the cursor will be in */
        !           739:        l = markline(curs);
        !           740:        text = fetchline(l);
        !           741:        mark2phys(curs, text, inputting);
        !           742: 
        !           743:        /* adjust topline, if necessary, to get the cursor on the screen */
        !           744:        if (l >= topline && l <= botline)
        !           745:        {
        !           746:                /* it is on the screen already */
        !           747: 
        !           748:                /* if the file was changed but !mustredraw, then redraw line */
        !           749:                if (chgs != changes && !mustredraw)
        !           750:                {
        !           751:                        smartdrawtext(text, l);
        !           752:                }
        !           753:        }
        !           754:        else if (l < topline && l > topline - LINES && (has_SR || has_AL))
        !           755:        {
        !           756:                /* near top - scroll down */
        !           757:                if (!mustredraw)
        !           758:                {
        !           759:                        move(0,0);
        !           760:                        while (l < topline)
        !           761:                        {
        !           762:                                topline--;
        !           763:                                if (has_SR)
        !           764:                                {
        !           765:                                        do_SR();
        !           766:                                }
        !           767:                                else
        !           768:                                {
        !           769:                                        insertln();
        !           770:                                }
        !           771:                                text = fetchline(topline);
        !           772:                                drawtext(text, FALSE);
        !           773:                                do_UP();
        !           774:                        }
        !           775: 
        !           776:                        /* blank out the last line */
        !           777:                        move(LINES - 1, 0);
        !           778:                        clrtoeol();
        !           779:                }
        !           780:                else
        !           781:                {
        !           782:                        topline = l;
        !           783:                        redrawafter = INFINITY;
        !           784:                        preredraw = 0L;
        !           785:                        postredraw = 0L;
        !           786:                }
        !           787:        }
        !           788:        else if (l > topline && l < botline + LINES)
        !           789:        {
        !           790:                /* near bottom -- scroll up */
        !           791:                if (!mustredraw
        !           792: #if 1
        !           793:                 || redrawafter == preredraw && preredraw == botline && postredraw == l
        !           794: #endif
        !           795:                )
        !           796:                {
        !           797:                        move(LINES - 1,0);
        !           798:                        clrtoeol();
        !           799:                        while (l > botline)
        !           800:                        {
        !           801:                                topline++; /* <-- also adjusts botline */
        !           802:                                text = fetchline(botline);
        !           803:                                drawtext(text, FALSE);
        !           804:                        }
        !           805:                        mustredraw = FALSE;
        !           806:                }
        !           807:                else
        !           808:                {
        !           809:                        topline = l - (LINES - 2);
        !           810:                        redrawafter = INFINITY;
        !           811:                        preredraw = 0L;
        !           812:                        postredraw = 0L;
        !           813:                }
        !           814:        }
        !           815:        else
        !           816:        {
        !           817:                /* distant line - center it & force a redraw */
        !           818:                topline = l - (LINES / 2) - 1;
        !           819:                if (topline < 1)
        !           820:                {
        !           821:                        topline = 1;
        !           822:                }
        !           823:                mustredraw = TRUE;
        !           824:                redrawafter = INFINITY;
        !           825:                preredraw = 0L;
        !           826:                postredraw = 0L;
        !           827:        }
        !           828: 
        !           829:        /* Now... do we really have to redraw? */
        !           830:        if (mustredraw)
        !           831:        {
        !           832:                /* If redrawfter (and friends) aren't set, assume we should
        !           833:                 * redraw everything.
        !           834:                 */
        !           835:                if (redrawafter == INFINITY)
        !           836:                {
        !           837:                        redrawafter = 0L;
        !           838:                        preredraw = postredraw = INFINITY;
        !           839:                }
        !           840: 
        !           841:                /* adjust smartlno to correspond with inserted/deleted lines */
        !           842:                if (smartlno >= redrawafter)
        !           843:                {
        !           844:                        if (smartlno < preredraw)
        !           845:                        {
        !           846:                                smartlno = 0L;
        !           847:                        }
        !           848:                        else
        !           849:                        {
        !           850:                                smartlno += (postredraw - preredraw);
        !           851:                        }
        !           852:                }
        !           853: 
        !           854:                /* should we insert some lines into the screen? */
        !           855:                if (preredraw < postredraw && preredraw <= botline)
        !           856:                {
        !           857:                        /* lines were inserted into the file */
        !           858: 
        !           859:                        /* decide where insertion should start */
        !           860:                        if (preredraw < topline)
        !           861:                        {
        !           862:                                l = topline;
        !           863:                        }
        !           864:                        else
        !           865:                        {
        !           866:                                l = preredraw;
        !           867:                        }
        !           868: 
        !           869:                        /* insert the lines... maybe */
        !           870:                        if (l + postredraw - preredraw > botline || !has_AL)
        !           871:                        {
        !           872:                                /* Whoa!  a whole screen full - just redraw */
        !           873:                                preredraw = postredraw = INFINITY;
        !           874:                        }
        !           875:                        else
        !           876:                        {
        !           877:                                /* really insert 'em */
        !           878:                                move((int)(l - topline), 0);
        !           879:                                for (i = postredraw - preredraw; i > 0; i--)
        !           880:                                {
        !           881:                                        insertln();
        !           882:                                }
        !           883: 
        !           884:                                /* NOTE: the contents of those lines will be
        !           885:                                 * drawn as part of the regular redraw loop.
        !           886:                                 */
        !           887: 
        !           888:                                /* clear the last line */
        !           889:                                move(LINES - 1, 0);
        !           890:                                clrtoeol();
        !           891:                        }
        !           892:                }
        !           893: 
        !           894:                /* do we want to delete some lines from the screen? */
        !           895:                if (preredraw > postredraw && postredraw <= botline)
        !           896:                {
        !           897:                        if (preredraw > botline || !has_DL)
        !           898:                        {
        !           899:                                postredraw = preredraw = INFINITY;
        !           900:                        }
        !           901:                        else /* we'd best delete some lines from the screen */
        !           902:                        {
        !           903:                                /* clear the last line, so it doesn't look
        !           904:                                 * ugly as it gets pulled up into the screen
        !           905:                                 */
        !           906:                                move(LINES - 1, 0);
        !           907:                                clrtoeol();
        !           908: 
        !           909:                                /* delete the lines */
        !           910:                                move((int)(postredraw - topline), 0);
        !           911:                                for (l = postredraw;
        !           912:                                     l < preredraw && l <= botline;
        !           913:                                     l++)
        !           914:                                {
        !           915:                                        deleteln();
        !           916:                                }
        !           917: 
        !           918:                                /* draw the lines that are now newly visible
        !           919:                                 * at the bottom of the screen
        !           920:                                 */
        !           921:                                i = LINES - 1 + (postredraw - preredraw);
        !           922:                                move(i, 0);
        !           923:                                for (l = topline + i; l <= botline; l++)
        !           924:                                {
        !           925:                                        /* clear this line */
        !           926:                                        clrtoeol();
        !           927: 
        !           928:                                        /* draw the line, or ~ for non-lines */
        !           929:                                        if (l <= nlines)
        !           930:                                        {
        !           931:                                                text = fetchline(l);
        !           932:                                                drawtext(text, FALSE);
        !           933:                                        }
        !           934:                                        else
        !           935:                                        {
        !           936:                                                addstr("~\n");
        !           937:                                        }
        !           938:                                }
        !           939:                        }
        !           940:                }
        !           941: 
        !           942:                /* redraw the current line */
        !           943:                l = markline(curs);
        !           944:                pfetch(l);
        !           945:                smartdrawtext(ptext, l);
        !           946: 
        !           947:                /* decide where we should start redrawing from */
        !           948:                if (redrawafter < topline)
        !           949:                {
        !           950:                        l = topline;
        !           951:                }
        !           952:                else
        !           953:                {
        !           954:                        l = redrawafter;
        !           955:                }
        !           956:                move((int)(l - topline), 0);
        !           957: 
        !           958:                /* draw the other lines */
        !           959:                for (; l <= botline && l < postredraw; l++)
        !           960:                {
        !           961:                        /* we already drew the current line, so skip it now */
        !           962:                        if (l == smartlno)
        !           963:                        {
        !           964: #if OSK
        !           965:                                qaddch('\l');
        !           966: #else
        !           967:                                qaddch('\n');
        !           968: #endif
        !           969:                                continue;
        !           970:                        }
        !           971: 
        !           972:                        /* draw the line, or ~ for non-lines */
        !           973:                        if (l <= nlines)
        !           974:                        {
        !           975:                                text = fetchline(l);
        !           976:                                drawtext(text, TRUE);
        !           977:                        }
        !           978:                        else
        !           979:                        {
        !           980:                                qaddch('~');
        !           981:                                clrtoeol();
        !           982:                                addch('\n');
        !           983:                        }
        !           984:                }
        !           985: 
        !           986:                mustredraw = FALSE;
        !           987:        }
        !           988: 
        !           989:        /* force total (non-partial) redraw next time if not set */
        !           990:        redrawafter = INFINITY;
        !           991:        preredraw = 0L;
        !           992:        postredraw = 0L;
        !           993: 
        !           994:        /* move the cursor to where it belongs */
        !           995:        move((int)(markline(curs) - topline), physcol);
        !           996:        wqrefresh(stdscr);
        !           997: 
        !           998:        chgs = changes;
        !           999: }

unix.superglobalmegacorp.com

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