Annotation of researchv10dc/ncurses/screen/mvcur.c, revision 1.1

1.1     ! root        1: #include "curses.ext"
        !             2: /*     @(#) mvcur.c: 1.1 10/15/83      (1.14   3/16/83)        */
        !             3: 
        !             4: 
        !             5: /*
        !             6:  * Cursor motion optimization routine.  This routine takes as parameters
        !             7:  * the screen positions that the cursor is currently at, and the position
        !             8:  * you want it to be at, and it will move the cursor there very
        !             9:  * efficiently.  It isn't really optimal, since several approximations
        !            10:  * are taken in the interests of efficiency and simplicity.  The code
        !            11:  * here considers directly addressing the cursor, and also considers
        !            12:  * local motions using left, right, up, down, tabs, backtabs, vertical
        !            13:  * and horizontal addressing, and parameterized motions.  It does not
        !            14:  * consider using home down, or taking advantage of automatic margins on
        !            15:  * any of the four directions.  (Two of these directions, left and right,
        !            16:  * are well defined by the am and bw capabilities, but up and down are
        !            17:  * not defined, nor are tab or backtab off the ends.)
        !            18:  *
        !            19:  * General strategies considered:
        !            20:  *     CA      Direct Cursor Addressing
        !            21:  *     LM      Local Motions from the old position
        !            22:  *     HDR     Home + Local Motions from upper left corner
        !            23:  *     CR      CR + Local Motions from left margin
        !            24:  *
        !            25:  * Local Motions can include
        !            26:  *     Up      cuu, cuu1, vpa
        !            27:  *     Down    cud, cud1, vpa
        !            28:  *     Left    cul, cul1, hpa, bs, cbt
        !            29:  *     Right   cuf, cuf1, hpa, tab, char moved over
        !            30:  */
        !            31: 
        !            32: #ifdef DEBUG
        !            33:   /* We don't want this debugging output now. */
        !            34: # undef DEBUG
        !            35: #endif
        !            36: 
        !            37: /* #define mvcurdebug */
        !            38: 
        !            39: #ifdef mvcurdebug
        !            40: # define DEBUG
        !            41: # define _outch oc
        !            42: FILE *outf;
        !            43: main()
        !            44: {
        !            45:        int oldrow, oldcol, newrow, newcol, n;
        !            46: 
        !            47:        newterm(getenv("TERM"), stdout, stdin);
        !            48:        echo();
        !            49:        nocrmode();
        !            50:        nl();
        !            51:        outf = stdout;
        !            52:        setbuf(stdout, NULL);
        !            53:        for (;;) {
        !            54:                printf("oldrow, oldcol, newrow, newcol: ");
        !            55:                n = scanf("%d %d %d %d", &oldrow, &oldcol, &newrow, &newcol);
        !            56:                if (n < 0) {
        !            57:                        endwin();
        !            58:                        exit(1);
        !            59:                }
        !            60:                mvcur(oldrow, oldcol, newrow, newcol);
        !            61:        }
        !            62: }
        !            63: 
        !            64: _outch(ch)
        !            65: {
        !            66:        printf("_outch '%s'\n", unctrl(ch));
        !            67: }
        !            68: #else
        !            69: int _outch();
        !            70: #endif
        !            71: 
        !            72: static int bare_lf_ok; /* bare_lf_ok is true if linefeed will work right */
        !            73: char *tparm();
        !            74: 
        !            75: mvcur(oldrow, oldcol, newrow, newcol)
        !            76: int oldrow, oldcol, newrow, newcol;
        !            77: {
        !            78:        /* temporary costs of various submotions */
        !            79:        int     home_right;     /* cost to move from col 0 right to newcol */
        !            80:        int     cur_right;      /* motion from current postition to right */
        !            81:        int     cur_left;       /* motion from current postition to left */
        !            82:        int     home_down;      /* motion from line 0 downward */
        !            83:        int     cur_down;       /* motion from current position downward */
        !            84:        int     cur_up;         /* motion from current position upward */
        !            85:        /* costs of various full motions we consider */
        !            86:        int     cost_ca;        /* cost of directly addressing the cursor */
        !            87:        int     cost_hdr;       /* going home, local motions down & right */
        !            88:        int     cost_cr;        /* return, local motions up/down & right */
        !            89:        int     cost_lm;        /* local motions up/down & left/right */
        !            90:        int     sgf;
        !            91: 
        !            92: #ifdef DEBUG
        !            93:        if(outf) fprintf(outf, "mvcur(oldrow=%d, oldcol=%d, newrow=%d, newcol=%d)\n",
        !            94:                oldrow, oldcol, newrow, newcol);
        !            95: #endif
        !            96:        /* Quick check for nothing to do - very common case. */
        !            97:        if (oldrow == newrow && oldcol == newcol)
        !            98:                return;
        !            99: #ifndef        NONSTANDARD
        !           100: # ifdef USG
        !           101:        bare_lf_ok = ((cur_term->Nttyb.c_oflag&ONLCR)==0);
        !           102: # else
        !           103:        sgf = cur_term->Nttyb.sg_flags;
        !           104:        bare_lf_ok = (sgf&RAW) ? 1 : (sgf&CRMOD)==0;
        !           105: # endif
        !           106: #else          NONSTANDARD
        !           107:        bare_lf_ok = 1;
        !           108: #endif         NONSTANDARD
        !           109:        /* Another common case: crlf */
        !           110:        if (newcol==0 && newrow==oldrow+1 && carriage_return && cursor_down) {
        !           111:                /*
        !           112:                 * Just because bare_lf_ok is on doesn't mean cursor_down is
        !           113:                 * crlf.  E.g. in the tty 40/2 it's escape B.  The test below
        !           114:                 * will be wrong on a newline style terminal (!bare_lf_ok)
        !           115:                 * with no carriage_return where cursor_down is not crlf.
        !           116:                 * I have never seen such a terminal.
        !           117:                 */
        !           118:                if (oldcol > 0 && carriage_return)
        !           119:                        tputs(carriage_return, 1, _outch);
        !           120:                tputs(cursor_down, 1, _outch);
        !           121:                return;
        !           122:        }
        !           123: 
        !           124:        /* Figure out costs of various component motions */
        !           125:        home_right = _loc_right(0     , newcol, 0, newcol);
        !           126:        cur_right  = _loc_right(oldcol, newcol, 0, newcol);
        !           127:        cur_left   = _loc_left (oldcol, newcol, 0);
        !           128:        home_down  = _loc_down (0     , newrow, 0, newcol);
        !           129:        cur_down   = _loc_down (oldrow, newrow, 0, newcol);
        !           130:        cur_up     = _loc_up   (oldrow, newrow, 0);
        !           131: #ifdef DEBUG
        !           132:        if(outf) fprintf(outf, "home_right %d, cur_right %d, cur_left %d, home_down %d, cur_down %d, cur_up %d\n",
        !           133:                home_right, cur_right, cur_left, home_down, cur_down, cur_up);
        !           134: #endif
        !           135: 
        !           136:        /* 4 possible strategies: get costs for each */
        !           137:        cost_ca    = _cost(Cursor_address);
        !           138:        cost_hdr   = _cost(Cursor_home) + home_down + home_right;
        !           139:        /* 3rd and 4th strategies: local motions and with carriage return. */
        !           140:        if (newrow < oldrow) {
        !           141:                if (newcol < oldcol)
        !           142:                        cost_lm    = cur_left + cur_up;
        !           143:                else
        !           144:                        cost_lm    = cur_right + cur_up;
        !           145:                cost_cr = _cost(Carriage_return) + cur_up + home_right;
        !           146:        } else {
        !           147:                if (newcol < oldcol)
        !           148:                        cost_lm    = cur_left + cur_down;
        !           149:                else
        !           150:                        cost_lm    = cur_right + cur_down;
        !           151:                if (cur_down >= INFINITY)
        !           152:                        cur_down = _loc_down(oldrow, newrow, 0, 0);
        !           153:                cost_cr = _cost(Carriage_return) + cur_down + home_right;
        !           154:        }
        !           155: 
        !           156: #ifdef DEBUG
        !           157:        if(outf) fprintf(outf, "cost_ca %d, cost_hdr %d, cost_cr %d, cost_lm %d\n",
        !           158:                cost_ca, cost_hdr, cost_cr, cost_lm);
        !           159: #endif
        !           160:        /*
        !           161:         * Now we pick which one is cheapest and actually do it.
        !           162:         * Note the ordering if they come out equal - this was
        !           163:         * conciously chosen based on how visually distracting
        !           164:         * it is to see the cursor bounce all over the screen,
        !           165:         * I did not take into account approximation errors.
        !           166:         */
        !           167:        if (cost_ca <= cost_hdr && cost_ca <= cost_cr && cost_ca <= cost_lm) {
        !           168:                /* direct cursor addressing is cheapest */
        !           169: #ifdef DEBUG
        !           170:                if(outf) fprintf(outf, "chose absolute cursor addressing\n");
        !           171: #endif
        !           172:                tputs(tparm(cursor_address, newrow, newcol), 1, _outch);
        !           173:        } else if (cost_lm <= cost_cr && cost_lm <= cost_hdr) {
        !           174:                /* local motions are cheapest */
        !           175: #ifdef DEBUG
        !           176:                if(outf) fprintf(outf, "chose local motions\n");
        !           177: #endif
        !           178:                if (newcol > oldcol) {
        !           179:                        if (newrow > oldrow)
        !           180:                                (void) _loc_down(oldrow, newrow, 1, newcol);
        !           181:                        else
        !           182:                                (void) _loc_up(oldrow, newrow, 1);
        !           183:                        (void) _loc_right(oldcol, newcol, 1, newrow);
        !           184:                } else {
        !           185:                        if (newrow > oldrow)
        !           186:                                (void) _loc_down(oldrow, newrow, 1, newcol);
        !           187:                        else
        !           188:                                (void) _loc_up(oldrow, newrow, 1);
        !           189:                        (void) _loc_left(oldcol, newcol, 1);
        !           190:                }
        !           191:        } else if (cost_cr <= cost_hdr) {
        !           192:                /* carriage return + local motions are cheapest */
        !           193: #ifdef DEBUG
        !           194:                if(outf) fprintf(outf, "chose carriage return + local motions\n");
        !           195: #endif
        !           196:                tputs(carriage_return, 1, _outch);
        !           197:                if (newrow > oldrow)
        !           198:                        (void) _loc_down(oldrow, newrow, 1, 0);
        !           199:                else
        !           200:                        (void) _loc_up(oldrow, newrow, 1);
        !           201:                (void) _loc_right(0, newcol, 1, newrow);
        !           202:        } else {
        !           203:                /* home + local motions are cheapest */
        !           204: #ifdef DEBUG
        !           205:                if(outf) fprintf(outf, "chose home + local motions\n");
        !           206: #endif
        !           207:                tputs(cursor_home, 1, _outch);
        !           208:                (void) _loc_down(0, newrow, 1, newcol);
        !           209:                (void) _loc_right(0, newcol, 1, newrow);
        !           210:        }
        !           211: #ifdef DEBUG
        !           212:        if(outf) fprintf(outf, "end of mvcur\n");
        !           213: #endif
        !           214: }
        !           215: 
        !           216: /*
        !           217:  * These four routines figure out what the cost of the most efficient
        !           218:  * kind of local motion from the given row or column to the other given
        !           219:  * row or column is.  They return the cost, in characters.  If the third
        !           220:  * argument is 1, they actually do the motion.  The row number is useful
        !           221:  * if we're going to actually do the motion - that way we can look in
        !           222:  * the screen image (if we have it) and just output the characters that
        !           223:  * are already on the screen - this usually saves 50% over cursor_right.
        !           224:  */
        !           225: static
        !           226: _loc_right(oldcol, newcol, domotion, row)
        !           227: {
        !           228:        int c0, c1, c2, c3;
        !           229:        int i, tabcol, ntabs, nright, nleft;
        !           230:        /* notinsmode: we know for sure we aren't in insert char mode */
        !           231:        int notinsmode = SP && SP->phys_irm!=1;
        !           232:        register struct line *rp;
        !           233: 
        !           234:        if (newcol < oldcol)    /* can't go left with right motions */
        !           235:                return INFINITY;
        !           236:        if (newcol == oldcol)
        !           237:                return 0;       /* already there - nothing to do */
        !           238: #ifdef DEBUG
        !           239:        fprintf(outf, "SP %x, phys_irm %d, notinsmode %d\n",
        !           240:        SP, SP->phys_irm, notinsmode);
        !           241: #endif
        !           242: 
        !           243:        /*
        !           244:         * Code here and further down attempts to output the character that
        !           245:         * is already on the screen to move right.
        !           246:         */
        !           247:        if (notinsmode)
        !           248:                _cost(Cursor_right) = 1;
        !           249:        else
        !           250:                _cost(Cursor_right) = _cost(Right_base);
        !           251:        /* figure out various costs */
        !           252: 
        !           253:        tabcol = (newcol+4)/8 * 8;   /* round to nearest 8 */
        !           254:        /* tab past right margin is undefined */
        !           255:        if (tabcol >= columns)
        !           256:                tabcol = (columns-1)/8 * 8;
        !           257:        ntabs = (tabcol-oldcol+7)/8;
        !           258:        if (ntabs <= 0)
        !           259:                tabcol = oldcol;
        !           260:        if (tabcol < newcol) {
        !           261:                /* some tabs plus some rights */
        !           262:                nright = newcol - tabcol;
        !           263:                c1 = ntabs*_cost(Tab) + nright*_cost(Cursor_right);
        !           264:        } else {
        !           265:                /* some tabs plus some lefts */
        !           266:                nleft = tabcol - newcol;
        !           267:                c1 = ntabs*_cost(Tab) + nleft*_cost(Cursor_left);
        !           268:        }
        !           269: 
        !           270:        c0 = (newcol - oldcol) * _cost(Cursor_right);
        !           271: 
        !           272:        if (parm_right_cursor)
        !           273:                c2 = _cost(Parm_right_cursor);
        !           274:        else
        !           275:                c2 = INFINITY;
        !           276: 
        !           277:        if (column_address)
        !           278:                c3 = _cost(Column_address);
        !           279:        else
        !           280:                c3 = INFINITY;
        !           281:        
        !           282: #ifdef DEBUG
        !           283:        if(outf) fprintf(outf, "_loc_right(%d, %d, %d), chars %d, ri %d, RI %d, ch %d\n",
        !           284:                oldcol, newcol, domotion, c0, c1, c2, c3);
        !           285: #endif
        !           286: 
        !           287:        /* Decide and maybe do them */
        !           288:        if (c3 <= c1 && c3 <= c2 && c3 <= c0) {
        !           289:                /* cheapest to use column absolute cursor addressing */
        !           290: #ifdef DEBUG
        !           291:                if(outf) fprintf(outf, "chose column absolute cursor addressing\n");
        !           292: #endif
        !           293:                if (domotion)
        !           294:                        tputs(tparm(column_address, newcol), 1, _outch);
        !           295:                return c3;
        !           296:        } else if (c2 <= c1 && c2 <= c0) {
        !           297:                /* cheapest to use column relative motion */
        !           298: #ifdef DEBUG
        !           299:                if(outf) fprintf(outf, "chose column relative motion\n");
        !           300: #endif
        !           301:                if (domotion)
        !           302:                        tputs(tparm(parm_right_cursor, newcol-oldcol), 1, _outch);
        !           303:                return c2;
        !           304:        } else {
        !           305:                /* cheapest to use several right commands */
        !           306: #ifdef DEBUG
        !           307:                if(outf) fprintf(outf, "chose rights: ntabs %d, tabcol %d, nleft %d, nright %d\n", ntabs, tabcol, nleft, nright);
        !           308: #endif
        !           309:                if (domotion)
        !           310:                        if (c1 < c0) {
        !           311:                                for (i=0; i<ntabs; i++)
        !           312:                                        tputs(tab, 1, _outch);
        !           313:                                if (tabcol < newcol) {
        !           314:                                        /* some tabs plus some rights */
        !           315:                                        for (i=0; i<nright; i++) {
        !           316: #ifdef DEBUG
        !           317:        if (outf && SP->cur_body[row+1]) fprintf(outf, "nd1, row %d col %d+%d=%d, char '%c'\n",
        !           318:        row, tabcol, i, tabcol+i, SP->cur_body[row+1]->body[tabcol+i]);
        !           319: #endif
        !           320:                                                rp = SP->cur_body[row+1];
        !           321:                                                if (cursor_right && (!notinsmode || rp && SP->phys_gr != (rp->body[tabcol+i] & A_ATTRIBUTES))) /* dont know */
        !           322:                                                        tputs(cursor_right,1,_outch);
        !           323:                                                else if (rp && rp->length > tabcol+i)
        !           324:                                                        /* Note we assume dumb terminals without cursor_right don't have
        !           325:                                                         * standout either, otherwise we should go into right standout
        !           326:                                                         * mode here and in the essentially similar code below.
        !           327:                                                         */
        !           328:                                                        _outch(rp->body[tabcol+i]&A_CHARTEXT);
        !           329:                                                else    /* off edge */
        !           330:                                                        _outch(' ');
        !           331:                                        }
        !           332:                                } else {
        !           333:                                        /* some tabs plus some lefts */
        !           334:                                        for (i=0; i<nleft; i++)
        !           335:                                                tputs(cursor_left,1,_outch);
        !           336:                                }
        !           337:                        } else {
        !           338:                                for (i=oldcol; i<newcol; i++) {
        !           339: #ifdef DEBUG
        !           340:        if (outf && SP->cur_body[row+1]) fprintf(outf, "nd2, row %d col %d, char '%c'\n",
        !           341:        row, i, SP->cur_body[row+1]->body[i]);
        !           342: #endif
        !           343:                                        rp = SP->cur_body[row+1];
        !           344:                                        if (cursor_right && (!notinsmode || rp && SP->phys_gr != (rp->body[i] & A_ATTRIBUTES))) /* dont know */
        !           345:                                                tputs(cursor_right,1,_outch);
        !           346:                                        else if (rp && rp->length > i)
        !           347:                                                _outch(rp->body[i]&A_CHARTEXT);
        !           348:                                        else    /* off edge */
        !           349:                                                _outch(' ');
        !           350:                                }
        !           351:                        }
        !           352:                return (c1 < c0) ? c1 : c0;
        !           353:        }
        !           354: }
        !           355: 
        !           356: static
        !           357: _loc_left(oldcol, newcol, domotion)
        !           358: {
        !           359:        int c1, c2, c3;
        !           360:        int i, tabcol, ntabs, nright, nleft;
        !           361: 
        !           362:        if (newcol > oldcol)    /* can't go right with left motions */
        !           363:                return INFINITY;
        !           364:        if (newcol == oldcol)
        !           365:                return 0;       /* already there - nothing to do */
        !           366: 
        !           367:        /* figure out various costs */
        !           368:        if (cursor_left) {
        !           369:                if (back_tab) {
        !           370:                        tabcol = (newcol+4)/8 * 8;   /* round to nearest 8 */
        !           371:                        /* tab past left margin is undefined */
        !           372:                        if (tabcol < 8)
        !           373:                                tabcol = 8;
        !           374:                        ntabs = (oldcol-tabcol+7)/8;
        !           375:                        if (ntabs <= 0)
        !           376:                                tabcol = oldcol;
        !           377:                        if (tabcol < newcol) {
        !           378:                                /* some backtabs plus some rights */
        !           379:                                nright = newcol - tabcol;
        !           380:                                c1 = ntabs*_cost(Back_tab) + nright*_cost(Cursor_right);
        !           381:                        } else {
        !           382:                                /* some tabs plus some lefts */
        !           383:                                nleft = tabcol - newcol;
        !           384:                                c1 = ntabs*_cost(Back_tab) + nleft*_cost(Cursor_left);
        !           385:                        }
        !           386:                } else {
        !           387:                        c1 = (oldcol - newcol) * _cost(Cursor_left);
        !           388:                }
        !           389:        } else
        !           390:                c1 = INFINITY;
        !           391:        if (parm_left_cursor)
        !           392:                c2 = _cost(Parm_left_cursor);
        !           393:        else
        !           394:                c2 = INFINITY;
        !           395:        if (column_address)
        !           396:                c3 = _cost(Column_address);
        !           397:        else
        !           398:                c3 = INFINITY;
        !           399:        
        !           400: #ifdef DEBUG
        !           401:        if(outf) fprintf(outf, "_loc_left(%d, %d, %d), le %d, LE %d, ch %d\n",
        !           402:                oldcol, newcol, domotion, c1, c2, c3);
        !           403: #endif
        !           404: 
        !           405:        /* Decide and maybe do them */
        !           406:        if (c3 <= c1 && c3 <= c2) {
        !           407:                /* cheapest to use column absolute cursor addressing */
        !           408: #ifdef DEBUG
        !           409:                if(outf) fprintf(outf, "chose column absolute cursor addressing\n");
        !           410: #endif
        !           411:                if (domotion)
        !           412:                        tputs(tparm(column_address, newcol), 1, _outch);
        !           413:                return c3;
        !           414:        } else if (c2 <= c1) {
        !           415:                /* cheapest to use column relative motion */
        !           416: #ifdef DEBUG
        !           417:                if(outf) fprintf(outf, "chose column relative motion\n");
        !           418: #endif
        !           419:                if (domotion)
        !           420:                        tputs(tparm(parm_left_cursor, oldcol-newcol), 1, _outch);
        !           421:                return c2;
        !           422:        } else {
        !           423:                /* cheapest to use several left commands */
        !           424: #ifdef DEBUG
        !           425:                if(outf) fprintf(outf, "chose several left commands\n");
        !           426: #endif
        !           427:                if (domotion)
        !           428:                        if (back_tab) {
        !           429:                                for (i=0; i<ntabs; i++)
        !           430:                                        tputs(back_tab, 1, _outch);
        !           431:                                if (tabcol < newcol) {
        !           432:                                        /* some tabs plus some rights */
        !           433:                                        for (i=0; i<nright; i++)
        !           434:                                                tputs(cursor_right,1, _outch);
        !           435:                                } else {
        !           436:                                        /* some tabs plus some lefts */
        !           437:                                        for (i=0; i<nleft; i++)
        !           438:                                                tputs(cursor_left,1,_outch);
        !           439:                                }
        !           440:                        } else {
        !           441:                                for (i=oldcol; i>newcol; i--)
        !           442:                                        tputs(cursor_left, 1, _outch);
        !           443:                        }
        !           444:                return c1;
        !           445:        }
        !           446: }
        !           447: 
        !           448: static
        !           449: _loc_up(oldrow, newrow, domotion)
        !           450: {
        !           451:        int c1, c2, c3, i;
        !           452: 
        !           453:        if (newrow > oldrow)    /* can't go down with up motions */
        !           454:                return INFINITY;
        !           455:        if (newrow == oldrow)
        !           456:                return 0;       /* already there - nothing to do */
        !           457: 
        !           458:        /* figure out various costs */
        !           459:        if (cursor_up)
        !           460:                c1 = (oldrow - newrow) * _cost(Cursor_up);
        !           461:        else
        !           462:                c1 = INFINITY;
        !           463:        if (parm_up_cursor)
        !           464:                c2 = _cost(Parm_up_cursor);
        !           465:        else
        !           466:                c2 = INFINITY;
        !           467:        if (row_address)
        !           468:                c3 = _cost(Row_address);
        !           469:        else
        !           470:                c3 = INFINITY;
        !           471:        
        !           472: #ifdef DEBUG
        !           473:        if(outf) fprintf(outf, "_loc_up(%d, %d, %d), up %d, UP %d, cv %d\n",
        !           474:                oldrow, newrow, domotion, c1, c2, c3);
        !           475: #endif
        !           476: 
        !           477:        /* Decide and maybe do them */
        !           478:        if (c3 <= c1 && c3 <= c2) {
        !           479:                /* cheapest to use row absolute cursor addressing */
        !           480: #ifdef DEBUG
        !           481:                if(outf) fprintf(outf, "chose row absolute cursor addressing\n");
        !           482: #endif
        !           483:                if (domotion)
        !           484:                        tputs(tparm(row_address, newrow), 1, _outch);
        !           485:                return c3;
        !           486:        } else if (c2 <= c1) {
        !           487:                /* cheapest to use row relative motion */
        !           488: #ifdef DEBUG
        !           489:                if(outf) fprintf(outf, "chose row relative motion\n");
        !           490: #endif
        !           491:                if (domotion)
        !           492:                        tputs(tparm(parm_up_cursor, oldrow-newrow), 1, _outch);
        !           493:                return c2;
        !           494:        } else {
        !           495:                /* cheapest to use several up commands */
        !           496: #ifdef DEBUG
        !           497:                if(outf) fprintf(outf, "chose several up commands\n");
        !           498: #endif
        !           499:                if (domotion)
        !           500:                        for (i=oldrow; i>newrow; i--)
        !           501:                                tputs(cursor_up, 1, _outch);
        !           502:                return c1;
        !           503:        }
        !           504: }
        !           505: 
        !           506: static
        !           507: _loc_down(oldrow, newrow, domotion, col)
        !           508: {
        !           509:        int c1, c2, c3, i;
        !           510: 
        !           511:        if (newrow < oldrow)    /* can't go up with down motions */
        !           512:                return INFINITY;
        !           513:        if (newrow == oldrow)
        !           514:                return 0;       /* already there - nothing to do */
        !           515: 
        !           516:        /* figure out various costs */
        !           517:        if (cursor_down && (col==0 || bare_lf_ok || *cursor_down!='\n'))
        !           518:                c1 = (newrow - oldrow) * _cost(Cursor_down);
        !           519:        else
        !           520:                c1 = INFINITY;
        !           521:        if (parm_down_cursor)
        !           522:                c2 = _cost(Parm_down_cursor);
        !           523:        else
        !           524:                c2 = INFINITY;
        !           525:        if (row_address)
        !           526:                c3 = _cost(Row_address);
        !           527:        else
        !           528:                c3 = INFINITY;
        !           529:        
        !           530: #ifdef DEBUG
        !           531:        if(outf) fprintf(outf, "_loc_down(%d, %d, %d, %d), do %d, DO %d, cv %d\n",
        !           532:                oldrow, newrow, domotion, col,c1, c2, c3);
        !           533: #endif
        !           534: 
        !           535:        /* Decide and maybe do them */
        !           536:        if (c3 <= c1 && c3 <= c2) {
        !           537:                /* cheapest to use row absolute cursor addressing */
        !           538: #ifdef DEBUG
        !           539:                if(outf) fprintf(outf, "chose row absolute cursor addressing\n");
        !           540: #endif
        !           541:                if (domotion)
        !           542:                        tputs(tparm(row_address, newrow), 1, _outch);
        !           543:                return c3;
        !           544:        } else if (c2 <= c1) {
        !           545:                /* cheapest to use row relative motion */
        !           546: #ifdef DEBUG
        !           547:                if(outf) fprintf(outf, "chose row relative motion\n");
        !           548: #endif
        !           549:                if (domotion)
        !           550:                        tputs(tparm(parm_down_cursor, newrow-oldrow), 1, _outch);
        !           551:                return c2;
        !           552:        } else {
        !           553:                /* cheapest to use several down commands */
        !           554: #ifdef DEBUG
        !           555:                if(outf) fprintf(outf, "chose several down commands\n");
        !           556: #endif
        !           557:                if (domotion)
        !           558:                        for (i=oldrow; i<newrow; i++)
        !           559:                                tputs(cursor_down, 1, _outch);
        !           560:                return c1;
        !           561:        }
        !           562: }

unix.superglobalmegacorp.com

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