Annotation of coherent/d/usr/bin/elvis/redraw.c, revision 1.1.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.