home *** CD-ROM | disk | FTP | other *** search
/ Serving the Web / ServingTheWeb1995.disc1of1.iso / linux / slacksrce / d / libc / libc-4.6 / libc-4 / libc-linux / curses-old / cr_put.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-17  |  9.6 KB  |  423 lines

  1. /*
  2.  * Copyright (c) 1981 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)cr_put.c    5.5 (Berkeley) 6/1/90";
  36. #endif /* not lint */
  37.  
  38. # include    "curses.ext"
  39.  
  40. # define    HARDTABS    8
  41.  
  42. void    fgoto (void);
  43. int    tabcol(int, int);
  44. int    plod (int);
  45. int    plodput (int);
  46.  
  47. /*
  48.  * Terminal driving and line formatting routines.
  49.  * Basic motion optimizations are done here as well
  50.  * as formatting of lines (printing of control characters,
  51.  * line numbering and the like).
  52.  */
  53.  
  54. /*
  55.  * Sync the position of the output cursor.
  56.  * Most work here is rounding for terminal boundaries getting the
  57.  * column position implied by wraparound or the lack thereof and
  58.  * rolling up the screen to get destline on the screen.
  59.  */
  60.  
  61. static int    outcol, outline, destcol, destline;
  62.  
  63. extern WINDOW        *_win;
  64.  
  65. mvcur(ly, lx, y, x)
  66. int    ly, lx, y, x; {
  67.  
  68. #ifdef DEBUG
  69.     fprintf(outf, "MVCUR: moving cursor from (%d,%d) to (%d,%d)\n", ly, lx, y, x);
  70. #endif
  71.     destcol = x;
  72.     destline = y;
  73.     outcol = lx;
  74.     outline = ly;
  75.     fgoto();
  76. }
  77.  
  78. void
  79. fgoto()
  80. {
  81.     register char    *cgp;
  82.     register int        l, c;
  83.  
  84.     if (destcol >= COLS) {
  85.         destline += destcol / COLS;
  86.         destcol %= COLS;
  87.     }
  88.     if (outcol >= COLS) {
  89.         l = (outcol + 1) / COLS;
  90.         outline += l;
  91.         outcol %= COLS;
  92.         if (AM == 0) {
  93.             while (l > 0) {
  94.                 if (_pfast)
  95.                     if (CR)
  96.                         _puts(CR);
  97.                     else
  98.                         _putchar('\r');
  99.                 if (NL)
  100.                     _puts(NL);
  101.                 else
  102.                     _putchar('\n');
  103.                 l--;
  104.             }
  105.             outcol = 0;
  106.         }
  107.         if (outline > LINES - 1) {
  108.             destline -= outline - (LINES - 1);
  109.             outline = LINES - 1;
  110.         }
  111.     }
  112.     if (destline >= LINES) {
  113.         l = destline;
  114.         destline = LINES - 1;
  115.         if (outline < LINES - 1) {
  116.             c = destcol;
  117.             if (_pfast == 0 && !CA)
  118.                 destcol = 0;
  119.             fgoto();
  120.             destcol = c;
  121.         }
  122.         while (l >= LINES) {
  123.             /*
  124.              * The following linefeed (or simulation thereof)
  125.              * is supposed to scroll up the screen, since we
  126.              * are on the bottom line.  We make the assumption
  127.              * that linefeed will scroll.  If ns is in the
  128.              * capability list this won't work.  We should
  129.              * probably have an sc capability but sf will
  130.              * generally take the place if it works.
  131.              *
  132.              * Superbee glitch:  in the middle of the screen we
  133.              * have to use esc B (down) because linefeed screws up
  134.              * in "Efficient Paging" (what a joke) mode (which is
  135.              * essential in some SB's because CRLF mode puts garbage
  136.              * in at end of memory), but you must use linefeed to
  137.              * scroll since down arrow won't go past memory end.
  138.              * I turned this off after recieving Paul Eggert's
  139.              * Superbee description which wins better.
  140.              */
  141.             if (NL /* && !XB */ && _pfast)
  142.                 _puts(NL);
  143.             else
  144.                 _putchar('\n');
  145.             l--;
  146.             if (_pfast == 0)
  147.                 outcol = 0;
  148.         }
  149.     }
  150.     if (destline < outline && !(CA || UP))
  151.         destline = outline;
  152.     if (CA) {
  153.         cgp = tgoto(CM, destcol, destline);
  154.         if (plod(strlen(cgp)) > 0)
  155.             plod(0);
  156.         else
  157.             tputs(cgp, 0, _putchar);
  158.     }
  159.     else
  160.         plod(0);
  161.     outline = destline;
  162.     outcol = destcol;
  163. }
  164.  
  165. /*
  166.  * Move (slowly) to destination.
  167.  * Hard thing here is using home cursor on really deficient terminals.
  168.  * Otherwise just use cursor motions, hacking use of tabs and overtabbing
  169.  * and backspace.
  170.  */
  171.  
  172. static int plodcnt, plodflg;
  173.  
  174. int
  175. plodput(int c)
  176. {
  177.     if (plodflg)
  178.         plodcnt--;
  179.     else
  180.         _putchar(c);
  181. }
  182.  
  183. int
  184. plod(int cnt)
  185. {
  186.     register int i, j, k;
  187.     register int soutcol, soutline;
  188.  
  189.     plodcnt = plodflg = cnt;
  190.     soutcol = outcol;
  191.     soutline = outline;
  192.     /*
  193.      * Consider homing and moving down/right from there, vs moving
  194.      * directly with local motions to the right spot.
  195.      */
  196.     if (HO) {
  197.         /*
  198.          * i is the cost to home and tab/space to the right to
  199.          * get to the proper column.  This assumes ND space costs
  200.          * 1 char.  So i+destcol is cost of motion with home.
  201.          */
  202.         if (GT)
  203.             i = (destcol / HARDTABS) + (destcol % HARDTABS);
  204.         else
  205.             i = destcol;
  206.         /*
  207.          * j is cost to move locally without homing
  208.          */
  209.         if (destcol >= outcol) {    /* if motion is to the right */
  210.             j = destcol / HARDTABS - outcol / HARDTABS;
  211.             if (GT && j)
  212.                 j += destcol % HARDTABS;
  213.             else
  214.                 j = destcol - outcol;
  215.         }
  216.         else
  217.             /* leftward motion only works if we can backspace. */
  218.             if (outcol - destcol <= i && (BS || BC))
  219.                 i = j = outcol - destcol; /* cheaper to backspace */
  220.             else
  221.                 j = i + 1; /* impossibly expensive */
  222.  
  223.         /* k is the absolute value of vertical distance */
  224.         k = outline - destline;
  225.         if (k < 0)
  226.             k = -k;
  227.         j += k;
  228.  
  229.         /*
  230.          * Decision.  We may not have a choice if no UP.
  231.          */
  232.         if (i + destline < j || (!UP && destline < outline)) {
  233.             /*
  234.              * Cheaper to home.  Do it now and pretend it's a
  235.              * regular local motion.
  236.              */
  237.             tputs(HO, 0, plodput);
  238.             outcol = outline = 0;
  239.         }
  240.         else if (LL) {
  241.             /*
  242.              * Quickly consider homing down and moving from there.
  243.              * Assume cost of LL is 2.
  244.              */
  245.             k = (LINES - 1) - destline;
  246.             if (i + k + 2 < j && (k<=0 || UP)) {
  247.                 tputs(LL, 0, plodput);
  248.                 outcol = 0;
  249.                 outline = LINES - 1;
  250.             }
  251.         }
  252.     }
  253.     else
  254.     /*
  255.      * No home and no up means it's impossible.
  256.      */
  257.         if (!UP && destline < outline)
  258.             return -1;
  259.     if (GT)
  260.         i = destcol % HARDTABS + destcol / HARDTABS;
  261.     else
  262.         i = destcol;
  263. /*
  264.     if (BT && outcol > destcol && (j = (((outcol+7) & ~7) - destcol - 1) >> 3)) {
  265.         j *= (k = strlen(BT));
  266.         if ((k += (destcol&7)) > 4)
  267.             j += 8 - (destcol&7);
  268.         else
  269.             j += k;
  270.     }
  271.     else
  272. */
  273.         j = outcol - destcol;
  274.     /*
  275.      * If we will later need a \n which will turn into a \r\n by
  276.      * the system or the terminal, then don't bother to try to \r.
  277.      */
  278.     if ((NONL || !_pfast) && outline < destline)
  279.         goto dontcr;
  280.     /*
  281.      * If the terminal will do a \r\n and there isn't room for it,
  282.      * then we can't afford a \r.
  283.      */
  284.     if (NC && outline >= destline)
  285.         goto dontcr;
  286.     /*
  287.      * If it will be cheaper, or if we can't back up, then send
  288.      * a return preliminarily.
  289.      */
  290.     if (j > i + 1 || outcol > destcol && !BS && !BC) {
  291.         /*
  292.          * BUG: this doesn't take the (possibly long) length
  293.          * of CR into account.
  294.          */
  295.         if (CR)
  296.             tputs(CR, 0, plodput);
  297.         else
  298.             plodput('\r');
  299.         if (NC) {
  300.             if (NL)
  301.                 tputs(NL, 0, plodput);
  302.             else
  303.                 plodput('\n');
  304.             outline++;
  305.         }
  306.         outcol = 0;
  307.     }
  308. dontcr:
  309.     while (outline < destline) {
  310.         outline++;
  311.         if (NL)
  312.             tputs(NL, 0, plodput);
  313.         else
  314.             plodput('\n');
  315.         if (plodcnt < 0)
  316.             goto out;
  317.         if (NONL || _pfast == 0)
  318.             outcol = 0;
  319.     }
  320.     if (BT)
  321.         k = strlen(BT);
  322.     while (outcol > destcol) {
  323.         if (plodcnt < 0)
  324.             goto out;
  325. /*
  326.         if (BT && outcol - destcol > k + 4) {
  327.             tputs(BT, 0, plodput);
  328.             outcol--;
  329.             outcol &= ~7;
  330.             continue;
  331.         }
  332. */
  333.         outcol--;
  334.         if (BC)
  335.             tputs(BC, 0, plodput);
  336.         else
  337.             plodput('\b');
  338.     }
  339.     while (outline > destline) {
  340.         outline--;
  341.         tputs(UP, 0, plodput);
  342.         if (plodcnt < 0)
  343.             goto out;
  344.     }
  345.     if (GT && destcol - outcol > 1) {
  346.         for (;;) {
  347.             i = tabcol(outcol, HARDTABS);
  348.             if (i > destcol)
  349.                 break;
  350.             if (TA)
  351.                 tputs(TA, 0, plodput);
  352.             else
  353.                 plodput('\t');
  354.             outcol = i;
  355.         }
  356.         if (destcol - outcol > 4 && i < COLS && (BC || BS)) {
  357.             if (TA)
  358.                 tputs(TA, 0, plodput);
  359.             else
  360.                 plodput('\t');
  361.             outcol = i;
  362.             while (outcol > destcol) {
  363.                 outcol--;
  364.                 if (BC)
  365.                     tputs(BC, 0, plodput);
  366.                 else
  367.                     plodput('\b');
  368.             }
  369.         }
  370.     }
  371.     while (outcol < destcol) {
  372.         /*
  373.          * move one char to the right.  We don't use ND space
  374.          * because it's better to just print the char we are
  375.          * moving over.
  376.          */
  377.         if (_win != NULL)
  378.             if (plodflg)    /* avoid a complex calculation */
  379.                 plodcnt--;
  380.             else {
  381.                 i = curscr->_y[outline][outcol];
  382.                 if ((i&_STANDOUT) == (curscr->_flags&_STANDOUT))
  383.                     _putchar(i & 0177);
  384.                 else
  385.                     goto nondes;
  386.             }
  387.         else
  388. nondes:
  389.              if (ND)
  390.             tputs(ND, 0, plodput);
  391.         else
  392.             plodput(' ');
  393.         outcol++;
  394.         if (plodcnt < 0)
  395.             goto out;
  396.     }
  397. out:
  398.     if (plodflg) {
  399.         outcol = soutcol;
  400.         outline = soutline;
  401.     }
  402.     return(plodcnt);
  403. }
  404.  
  405. /*
  406.  * Return the column number that results from being in column col and
  407.  * hitting a tab, where tabs are set every ts columns.  Work right for
  408.  * the case where col > COLS, even if ts does not divide COLS.
  409.  */
  410. tabcol(col, ts)
  411. int col, ts;
  412. {
  413.     int offset, result;
  414.  
  415.     if (col >= COLS) {
  416.         offset = COLS * (col / COLS);
  417.         col -= offset;
  418.     }
  419.     else
  420.         offset = 0;
  421.     return col + ts - (col % ts) + offset;
  422. }
  423.