home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / b / bsdlib8f.zip / BSDSRC.ZIP / EMX / BSD / CURSES / CR_PUT.C < prev    next >
C/C++ Source or Header  |  1992-06-10  |  10KB  |  418 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. extern char    *tgoto();
  43. int        plodput();
  44.  
  45. /*
  46.  * Terminal driving and line formatting routines.
  47.  * Basic motion optimizations are done here as well
  48.  * as formatting of lines (printing of control characters,
  49.  * line numbering and the like).
  50.  */
  51.  
  52. /*
  53.  * Sync the position of the output cursor.
  54.  * Most work here is rounding for terminal boundaries getting the
  55.  * column position implied by wraparound or the lack thereof and
  56.  * rolling up the screen to get destline on the screen.
  57.  */
  58.  
  59. static int    outcol, outline, destcol, destline;
  60.  
  61. WINDOW        *_win;
  62.  
  63. mvcur(ly, lx, y, x)
  64. int    ly, lx, y, x; {
  65.  
  66. #ifdef DEBUG
  67.     fprintf(outf, "MVCUR: moving cursor from (%d,%d) to (%d,%d)\n", ly, lx, y, x);
  68. #endif
  69.     destcol = x;
  70.     destline = y;
  71.     outcol = lx;
  72.     outline = ly;
  73.     fgoto();
  74. }
  75.  
  76. fgoto()
  77. {
  78.     reg char    *cgp;
  79.     reg int        l, c;
  80.  
  81.     if (destcol >= COLS) {
  82.         destline += destcol / COLS;
  83.         destcol %= COLS;
  84.     }
  85.     if (outcol >= COLS) {
  86.         l = (outcol + 1) / COLS;
  87.         outline += l;
  88.         outcol %= COLS;
  89.         if (AM == 0) {
  90.             while (l > 0) {
  91.                 if (_pfast)
  92.                     if (CR)
  93.                         _puts(CR);
  94.                     else
  95.                         _putchar('\r');
  96.                 if (NL)
  97.                     _puts(NL);
  98.                 else
  99.                     _putchar('\n');
  100.                 l--;
  101.             }
  102.             outcol = 0;
  103.         }
  104.         if (outline > LINES - 1) {
  105.             destline -= outline - (LINES - 1);
  106.             outline = LINES - 1;
  107.         }
  108.     }
  109.     if (destline >= LINES) {
  110.         l = destline;
  111.         destline = LINES - 1;
  112.         if (outline < LINES - 1) {
  113.             c = destcol;
  114.             if (_pfast == 0 && !CA)
  115.                 destcol = 0;
  116.             fgoto();
  117.             destcol = c;
  118.         }
  119.         while (l >= LINES) {
  120.             /*
  121.              * The following linefeed (or simulation thereof)
  122.              * is supposed to scroll up the screen, since we
  123.              * are on the bottom line.  We make the assumption
  124.              * that linefeed will scroll.  If ns is in the
  125.              * capability list this won't work.  We should
  126.              * probably have an sc capability but sf will
  127.              * generally take the place if it works.
  128.              *
  129.              * Superbee glitch:  in the middle of the screen we
  130.              * have to use esc B (down) because linefeed screws up
  131.              * in "Efficient Paging" (what a joke) mode (which is
  132.              * essential in some SB's because CRLF mode puts garbage
  133.              * in at end of memory), but you must use linefeed to
  134.              * scroll since down arrow won't go past memory end.
  135.              * I turned this off after recieving Paul Eggert's
  136.              * Superbee description which wins better.
  137.              */
  138.             if (NL /* && !XB */ && _pfast)
  139.                 _puts(NL);
  140.             else
  141.                 _putchar('\n');
  142.             l--;
  143.             if (_pfast == 0)
  144.                 outcol = 0;
  145.         }
  146.     }
  147.     if (destline < outline && !(CA || UP))
  148.         destline = outline;
  149.     if (CA) {
  150.         cgp = tgoto(CM, destcol, destline);
  151.         if (plod(strlen(cgp)) > 0)
  152.             plod(0);
  153.         else
  154.             tputs(cgp, 0, _putchar);
  155.     }
  156.     else
  157.         plod(0);
  158.     outline = destline;
  159.     outcol = destcol;
  160. }
  161.  
  162. /*
  163.  * Move (slowly) to destination.
  164.  * Hard thing here is using home cursor on really deficient terminals.
  165.  * Otherwise just use cursor motions, hacking use of tabs and overtabbing
  166.  * and backspace.
  167.  */
  168.  
  169. static int plodcnt, plodflg;
  170.  
  171. plodput(c)
  172. {
  173.     if (plodflg)
  174.         plodcnt--;
  175.     else
  176.         _putchar(c);
  177. }
  178.  
  179. plod(cnt)
  180. {
  181.     register int i, j, k;
  182.     register int soutcol, soutline;
  183.  
  184.     plodcnt = plodflg = cnt;
  185.     soutcol = outcol;
  186.     soutline = outline;
  187.     /*
  188.      * Consider homing and moving down/right from there, vs moving
  189.      * directly with local motions to the right spot.
  190.      */
  191.     if (HO) {
  192.         /*
  193.          * i is the cost to home and tab/space to the right to
  194.          * get to the proper column.  This assumes ND space costs
  195.          * 1 char.  So i+destcol is cost of motion with home.
  196.          */
  197.         if (GT)
  198.             i = (destcol / HARDTABS) + (destcol % HARDTABS);
  199.         else
  200.             i = destcol;
  201.         /*
  202.          * j is cost to move locally without homing
  203.          */
  204.         if (destcol >= outcol) {    /* if motion is to the right */
  205.             j = destcol / HARDTABS - outcol / HARDTABS;
  206.             if (GT && j)
  207.                 j += destcol % HARDTABS;
  208.             else
  209.                 j = destcol - outcol;
  210.         }
  211.         else
  212.             /* leftward motion only works if we can backspace. */
  213.             if (outcol - destcol <= i && (BS || BC))
  214.                 i = j = outcol - destcol; /* cheaper to backspace */
  215.             else
  216.                 j = i + 1; /* impossibly expensive */
  217.  
  218.         /* k is the absolute value of vertical distance */
  219.         k = outline - destline;
  220.         if (k < 0)
  221.             k = -k;
  222.         j += k;
  223.  
  224.         /*
  225.          * Decision.  We may not have a choice if no UP.
  226.          */
  227.         if (i + destline < j || (!UP && destline < outline)) {
  228.             /*
  229.              * Cheaper to home.  Do it now and pretend it's a
  230.              * regular local motion.
  231.              */
  232.             tputs(HO, 0, plodput);
  233.             outcol = outline = 0;
  234.         }
  235.         else if (LL) {
  236.             /*
  237.              * Quickly consider homing down and moving from there.
  238.              * Assume cost of LL is 2.
  239.              */
  240.             k = (LINES - 1) - destline;
  241.             if (i + k + 2 < j && (k<=0 || UP)) {
  242.                 tputs(LL, 0, plodput);
  243.                 outcol = 0;
  244.                 outline = LINES - 1;
  245.             }
  246.         }
  247.     }
  248.     else
  249.     /*
  250.      * No home and no up means it's impossible.
  251.      */
  252.         if (!UP && destline < outline)
  253.             return -1;
  254.     if (GT)
  255.         i = destcol % HARDTABS + destcol / HARDTABS;
  256.     else
  257.         i = destcol;
  258. /*
  259.     if (BT && outcol > destcol && (j = (((outcol+7) & ~7) - destcol - 1) >> 3)) {
  260.         j *= (k = strlen(BT));
  261.         if ((k += (destcol&7)) > 4)
  262.             j += 8 - (destcol&7);
  263.         else
  264.             j += k;
  265.     }
  266.     else
  267. */
  268.         j = outcol - destcol;
  269.     /*
  270.      * If we will later need a \n which will turn into a \r\n by
  271.      * the system or the terminal, then don't bother to try to \r.
  272.      */
  273.     if ((NONL || !_pfast) && outline < destline)
  274.         goto dontcr;
  275.     /*
  276.      * If the terminal will do a \r\n and there isn't room for it,
  277.      * then we can't afford a \r.
  278.      */
  279.     if (NC && outline >= destline)
  280.         goto dontcr;
  281.     /*
  282.      * If it will be cheaper, or if we can't back up, then send
  283.      * a return preliminarily.
  284.      */
  285.     if (j > i + 1 || outcol > destcol && !BS && !BC) {
  286.         /*
  287.          * BUG: this doesn't take the (possibly long) length
  288.          * of CR into account.
  289.          */
  290.         if (CR)
  291.             tputs(CR, 0, plodput);
  292.         else
  293.             plodput('\r');
  294.         if (NC) {
  295.             if (NL)
  296.                 tputs(NL, 0, plodput);
  297.             else
  298.                 plodput('\n');
  299.             outline++;
  300.         }
  301.         outcol = 0;
  302.     }
  303. dontcr:
  304.     while (outline < destline) {
  305.         outline++;
  306.         if (NL)
  307.             tputs(NL, 0, plodput);
  308.         else
  309.             plodput('\n');
  310.         if (plodcnt < 0)
  311.             goto out;
  312.         if (NONL || _pfast == 0)
  313.             outcol = 0;
  314.     }
  315.     if (BT)
  316.         k = strlen(BT);
  317.     while (outcol > destcol) {
  318.         if (plodcnt < 0)
  319.             goto out;
  320. /*
  321.         if (BT && outcol - destcol > k + 4) {
  322.             tputs(BT, 0, plodput);
  323.             outcol--;
  324.             outcol &= ~7;
  325.             continue;
  326.         }
  327. */
  328.         outcol--;
  329.         if (BC)
  330.             tputs(BC, 0, plodput);
  331.         else
  332.             plodput('\b');
  333.     }
  334.     while (outline > destline) {
  335.         outline--;
  336.         tputs(UP, 0, plodput);
  337.         if (plodcnt < 0)
  338.             goto out;
  339.     }
  340.     if (GT && destcol - outcol > 1) {
  341.         for (;;) {
  342.             i = tabcol(outcol, HARDTABS);
  343.             if (i > destcol)
  344.                 break;
  345.             if (TA)
  346.                 tputs(TA, 0, plodput);
  347.             else
  348.                 plodput('\t');
  349.             outcol = i;
  350.         }
  351.         if (destcol - outcol > 4 && i < COLS && (BC || BS)) {
  352.             if (TA)
  353.                 tputs(TA, 0, plodput);
  354.             else
  355.                 plodput('\t');
  356.             outcol = i;
  357.             while (outcol > destcol) {
  358.                 outcol--;
  359.                 if (BC)
  360.                     tputs(BC, 0, plodput);
  361.                 else
  362.                     plodput('\b');
  363.             }
  364.         }
  365.     }
  366.     while (outcol < destcol) {
  367.         /*
  368.          * move one char to the right.  We don't use ND space
  369.          * because it's better to just print the char we are
  370.          * moving over.
  371.          */
  372.         if (_win != NULL)
  373.             if (plodflg)    /* avoid a complex calculation */
  374.                 plodcnt--;
  375.             else {
  376.                 i = curscr->_y[outline][outcol];
  377.                 if ((i&_STANDOUT) == (curscr->_flags&_STANDOUT))
  378.                     _putchar(i);
  379.                 else
  380.                     goto nondes;
  381.             }
  382.         else
  383. nondes:
  384.              if (ND)
  385.             tputs(ND, 0, plodput);
  386.         else
  387.             plodput(' ');
  388.         outcol++;
  389.         if (plodcnt < 0)
  390.             goto out;
  391.     }
  392. out:
  393.     if (plodflg) {
  394.         outcol = soutcol;
  395.         outline = soutline;
  396.     }
  397.     return(plodcnt);
  398. }
  399.  
  400. /*
  401.  * Return the column number that results from being in column col and
  402.  * hitting a tab, where tabs are set every ts columns.  Work right for
  403.  * the case where col > COLS, even if ts does not divide COLS.
  404.  */
  405. tabcol(col, ts)
  406. int col, ts;
  407. {
  408.     int offset, result;
  409.  
  410.     if (col >= COLS) {
  411.         offset = COLS * (col / COLS);
  412.         col -= offset;
  413.     }
  414.     else
  415.         offset = 0;
  416.     return col + ts - (col % ts) + offset;
  417. }
  418.