home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MISC / GNU / LES177AS.ZIP / SCREEN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-12  |  16.9 KB  |  986 lines

  1. /*
  2.  * Routines which deal with the characteristics of the terminal.
  3.  * Uses termcap to be as terminal-independent as possible.
  4.  *
  5.  * {{ Someday this should be rewritten to use curses. }}
  6.  */
  7.  
  8. #include "less.h"
  9.  
  10. #ifdef TURBOC
  11. extern struct text_info _video;
  12. #else
  13.  
  14. #if XENIX
  15. #include <sys/types.h>
  16. #include <sys/ioctl.h>
  17. #endif
  18.  
  19. #if TERMIO
  20. #include <termio.h>
  21. #else
  22. #include <sgtty.h>
  23. #endif
  24.  
  25. #if !TERMIO && defined(TIOCGWINSZ)
  26. #include <sys/ioctl.h>
  27. #else
  28. /*
  29.  * For the Unix PC (ATT 7300 & 3B1):
  30.  * Since WIOCGETD is defined in sys/window.h, we can't use that to decide
  31.  * whether to include sys/window.h.  Use SIGPHONE from signal.h instead.
  32.  */
  33. #include <signal.h>
  34. #ifdef SIGPHONE
  35. #include <sys/window.h>
  36. #endif
  37. #endif
  38.  
  39. #if NEED_PTEM_H && defined(TIOCGWINSZ)
  40. /*
  41.  * All this just to get struct winsize.  Sigh.
  42.  */
  43. #include <sys/types.h>
  44. #include <sys/stream.h>
  45. #include <sys/ptem.h>
  46. #endif
  47.  
  48. /*
  49.  * Strings passed to tputs() to do various terminal functions.
  50.  */
  51. static char
  52.     *sc_pad,        /* Pad string */
  53.     *sc_home,        /* Cursor home */
  54.     *sc_addline,        /* Add line, scroll down following lines */
  55.     *sc_lower_left,        /* Cursor to last line, first column */
  56.     *sc_move,        /* General cursor positioning */
  57.     *sc_clear,        /* Clear screen */
  58.     *sc_eol_clear,        /* Clear to end of line */
  59.     *sc_s_in,        /* Enter standout (highlighted) mode */
  60.     *sc_s_out,        /* Exit standout mode */
  61.     *sc_u_in,        /* Enter underline mode */
  62.     *sc_u_out,        /* Exit underline mode */
  63.     *sc_b_in,        /* Enter bold mode */
  64.     *sc_b_out,        /* Exit bold mode */
  65.     *sc_bl_in,        /* Enter blink mode */
  66.     *sc_bl_out,        /* Exit blink mode */
  67.     *sc_visual_bell,    /* Visual bell (flash screen) sequence */
  68.     *sc_backspace,        /* Backspace cursor */
  69.     *sc_init,        /* Startup terminal initialization */
  70.     *sc_deinit;        /* Exit terminal de-initialization */
  71.  
  72. #endif /* TURBOC */
  73.  
  74. static int init_done = 0;
  75.  
  76. public int auto_wrap;        /* Terminal does \r\n when write past margin */
  77. public int ignaw;        /* Terminal ignores \n immediately after wrap */
  78. public int erase_char, kill_char; /* The user's erase and line-kill chars */
  79. public int sc_width, sc_height;    /* Height & width of screen */
  80. public int bo_s_width, bo_e_width;    /* Printing width of boldface seq */
  81. public int ul_s_width, ul_e_width;    /* Printing width of underline seq */
  82. public int so_s_width, so_e_width;    /* Printing width of standout seq */
  83. public int bl_s_width, bl_e_width;    /* Printing width of blink seq */
  84.  
  85. #ifndef TURBOC
  86.  
  87. static char *cheaper();
  88.  
  89. /*
  90.  * These two variables are sometimes defined in,
  91.  * and needed by, the termcap library.
  92.  * It may be necessary on some systems to declare them extern here.
  93.  */
  94. /*extern*/ short ospeed;    /* Terminal output baud rate */
  95. /*extern*/ char PC;        /* Pad character */
  96.  
  97. #endif /* TURBOC */
  98.  
  99. extern int quiet;        /* If VERY_QUIET, use visual bell for bell */
  100. extern int know_dumb;        /* Don't complain about a dumb terminal */
  101. extern int back_scroll, forw_scroll;
  102. extern int swindow;
  103.  
  104. #ifndef TURBOC
  105.  
  106. extern char *tgetstr();
  107. extern char *tgoto();
  108. extern char *getenv();
  109.  
  110.  
  111. /*
  112.  * Change terminal to "raw mode", or restore to "normal" mode.
  113.  * "Raw mode" means 
  114.  *    1. An outstanding read will complete on receipt of a single keystroke.
  115.  *    2. Input is not echoed.  
  116.  *    3. On output, \n is mapped to \r\n.
  117.  *    4. \t is NOT expanded into spaces.
  118.  *    5. Signal-causing characters such as ctrl-C (interrupt),
  119.  *       etc. are NOT disabled.
  120.  * It doesn't matter whether an input \n is mapped to \r, or vice versa.
  121.  */
  122.     public void
  123. raw_mode(on)
  124.     int on;
  125. {
  126.     static int curr_on = 0;
  127.  
  128.     if (on == curr_on)
  129.         return;
  130. #if TERMIO
  131.     {
  132.     struct termio s;
  133.     static struct termio save_term;
  134.  
  135.     if (on)
  136.     {
  137.         /*
  138.          * Get terminal modes.
  139.          */
  140.         ioctl(2, TCGETA, &s);
  141.  
  142.         /*
  143.          * Save modes and set certain variables dependent on modes.
  144.          */
  145.         save_term = s;
  146.         ospeed = s.c_cflag & CBAUD;
  147.         erase_char = s.c_cc[VERASE];
  148.         kill_char = s.c_cc[VKILL];
  149.  
  150.         /*
  151.          * Set the modes to the way we want them.
  152.          */
  153.         s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
  154.         s.c_oflag |=  (OPOST|ONLCR|TAB3);
  155.         s.c_oflag &= ~(OCRNL|ONOCR|ONLRET);
  156.         s.c_cc[VMIN] = 1;
  157.         s.c_cc[VTIME] = 0;
  158.     } else
  159.     {
  160.         /*
  161.          * Restore saved modes.
  162.          */
  163.         s = save_term;
  164.     }
  165.     ioctl(2, TCSETAW, &s);
  166.     }
  167. #else
  168.     {
  169.     struct sgttyb s;
  170.     static struct sgttyb save_term;
  171.  
  172.     if (on)
  173.     {
  174.         /*
  175.          * Get terminal modes.
  176.          */
  177.         ioctl(2, TIOCGETP, &s);
  178.  
  179.         /*
  180.          * Save modes and set certain variables dependent on modes.
  181.          */
  182.         save_term = s;
  183.         ospeed = s.sg_ospeed;
  184.         erase_char = s.sg_erase;
  185.         kill_char = s.sg_kill;
  186.  
  187.         /*
  188.          * Set the modes to the way we want them.
  189.          */
  190.         s.sg_flags |= CBREAK;
  191.         s.sg_flags &= ~(ECHO|XTABS);
  192.     } else
  193.     {
  194.         /*
  195.          * Restore saved modes.
  196.          */
  197.         s = save_term;
  198.     }
  199.     ioctl(2, TIOCSETN, &s);
  200.     }
  201. #endif
  202.     curr_on = on;
  203. }
  204.  
  205.     static void
  206. cannot(s)
  207.     char *s;
  208. {
  209.     PARG parg;
  210.  
  211.     if (know_dumb)
  212.         /* 
  213.          * User knows this is a dumb terminal, so don't tell him.
  214.          */
  215.         return;
  216.  
  217.     parg.p_string = s;
  218.     error("WARNING: terminal cannot %s", &parg);
  219. }
  220.  
  221. /*
  222.  * Get size of the output screen.
  223.  */
  224.     public void
  225. scrsize(p_height, p_width)
  226.     int *p_height;
  227.     int *p_width;
  228. {
  229.     register char *s;
  230. #ifdef TIOCGWINSZ
  231.     struct winsize w;
  232. #else
  233. #ifdef WIOCGETD
  234.     struct uwdata w;
  235. #endif
  236. #endif
  237.  
  238. #ifdef TIOCGWINSZ
  239.     if (ioctl(2, TIOCGWINSZ, &w) == 0 && w.ws_row > 0)
  240.         *p_height = w.ws_row;
  241.     else
  242. #else
  243. #ifdef WIOCGETD
  244.     if (ioctl(2, WIOCGETD, &w) == 0 && w.uw_height > 0)
  245.         *p_height = w.uw_height/w.uw_vs;
  246.     else
  247. #endif
  248. #endif
  249.     if ((s = getenv("LINES")) != NULL)
  250.         *p_height = atoi(s);
  251.     else
  252.          *p_height = tgetnum("li");
  253.  
  254.     if (*p_height <= 0)
  255.         *p_height = 24;
  256.  
  257. #ifdef TIOCGWINSZ
  258.      if (ioctl(2, TIOCGWINSZ, &w) == 0 && w.ws_col > 0)
  259.         *p_width = w.ws_col;
  260.     else
  261. #ifdef WIOCGETD
  262.     if (ioctl(2, WIOCGETD, &w) == 0 && w.uw_width > 0)
  263.         *p_width = w.uw_width/w.uw_hs;
  264.     else
  265. #endif
  266. #endif
  267.     if ((s = getenv("COLUMNS")) != NULL)
  268.         *p_width = atoi(s);
  269.     else
  270.          *p_width = tgetnum("co");
  271.  
  272.      if (*p_width <= 0)
  273.           *p_width = 80;
  274. }
  275.  
  276. /*
  277.  * Get terminal capabilities via termcap.
  278.  */
  279.     public void
  280. get_term()
  281. {
  282.     char *sp;
  283.     register char *t1, *t2;
  284.     register int hard;
  285.     char *term;
  286.     char termbuf[2048];
  287.  
  288.     static char sbuf[1024];
  289.  
  290.     /*
  291.      * Find out what kind of terminal this is.
  292.      */
  293.      if ((term = getenv("TERM")) == NULL)
  294.          term = "unknown";
  295.      if (tgetent(termbuf, term) <= 0)
  296.          strcpy(termbuf, "dumb:hc:");
  297.  
  298.      hard = tgetflag("hc");
  299.  
  300.     /*
  301.      * Get size of the screen.
  302.      */
  303.     scrsize(&sc_height, &sc_width);
  304.     pos_init();
  305.     if (swindow < 0)
  306.         swindow = sc_height - 2;
  307.  
  308.     auto_wrap = tgetflag("am");
  309.     ignaw = tgetflag("xn");
  310.  
  311.     /*
  312.      * Assumes termcap variable "sg" is the printing width of:
  313.      * the standout sequence, the end standout sequence,
  314.      * the underline sequence, the end underline sequence,
  315.      * the boldface sequence, and the end boldface sequence.
  316.      */
  317.     if ((so_s_width = tgetnum("sg")) < 0)
  318.         so_s_width = 0;
  319.     so_e_width = so_s_width;
  320.  
  321.     bo_s_width = bo_e_width = so_s_width;
  322.     ul_s_width = ul_e_width = so_s_width;
  323.     bl_s_width = bl_e_width = so_s_width;
  324.  
  325.     /*
  326.      * Get various string-valued capabilities.
  327.      */
  328.     sp = sbuf;
  329.  
  330.     sc_pad = tgetstr("pc", &sp);
  331.     if (sc_pad != NULL)
  332.         PC = *sc_pad;
  333.  
  334.     sc_init = tgetstr("ti", &sp);
  335.     if (sc_init == NULL)
  336.         sc_init = "";
  337.  
  338.     sc_deinit= tgetstr("te", &sp);
  339.     if (sc_deinit == NULL)
  340.         sc_deinit = "";
  341.  
  342.     sc_eol_clear = tgetstr("ce", &sp);
  343.     if (hard || sc_eol_clear == NULL || *sc_eol_clear == '\0')
  344.     {
  345.         cannot("clear to end of line");
  346.         sc_eol_clear = "";
  347.     }
  348.  
  349.     sc_clear = tgetstr("cl", &sp);
  350.     if (hard || sc_clear == NULL || *sc_clear == '\0')
  351.     {
  352.         cannot("clear screen");
  353.         sc_clear = "\n\n";
  354.     }
  355.  
  356.     sc_move = tgetstr("cm", &sp);
  357.     if (hard || sc_move == NULL || *sc_move == '\0')
  358.     {
  359.         /*
  360.          * This is not an error here, because we don't 
  361.          * always need sc_move.
  362.          * We need it only if we don't have home or lower-left.
  363.          */
  364.         sc_move = "";
  365.     }
  366.  
  367.     sc_s_in = tgetstr("so", &sp);
  368.     if (hard || sc_s_in == NULL)
  369.         sc_s_in = "";
  370.  
  371.     sc_s_out = tgetstr("se", &sp);
  372.     if (hard || sc_s_out == NULL)
  373.         sc_s_out = "";
  374.  
  375.     sc_u_in = tgetstr("us", &sp);
  376.     if (hard || sc_u_in == NULL)
  377.         sc_u_in = sc_s_in;
  378.  
  379.     sc_u_out = tgetstr("ue", &sp);
  380.     if (hard || sc_u_out == NULL)
  381.         sc_u_out = sc_s_out;
  382.  
  383.     sc_b_in = tgetstr("md", &sp);
  384.     if (hard || sc_b_in == NULL)
  385.     {
  386.         sc_b_in = sc_s_in;
  387.         sc_b_out = sc_s_out;
  388.     } else
  389.     {
  390.         sc_b_out = tgetstr("me", &sp);
  391.         if (hard || sc_b_out == NULL)
  392.             sc_b_out = "";
  393.     }
  394.  
  395.     sc_bl_in = tgetstr("mb", &sp);
  396.     if (hard || sc_bl_in == NULL)
  397.     {
  398.         sc_bl_in = sc_s_in;
  399.         sc_bl_out = sc_s_out;
  400.     } else
  401.     {
  402.         sc_bl_out = sc_b_out;
  403.     }
  404.  
  405.     sc_visual_bell = tgetstr("vb", &sp);
  406.     if (hard || sc_visual_bell == NULL)
  407.         sc_visual_bell = "";
  408.  
  409.     if (tgetflag("bs"))
  410.         sc_backspace = "\b";
  411.     else
  412.     {
  413.         sc_backspace = tgetstr("bc", &sp);
  414.         if (sc_backspace == NULL || *sc_backspace == '\0')
  415.             sc_backspace = "\b";
  416.     }
  417.  
  418.     /*
  419.      * Choose between using "ho" and "cm" ("home" and "cursor move")
  420.      * to move the cursor to the upper left corner of the screen.
  421.      */
  422.     t1 = tgetstr("ho", &sp);
  423.     if (hard || t1 == NULL)
  424.         t1 = "";
  425.     if (*sc_move == '\0')
  426.         t2 = "";
  427.     else
  428.     {
  429.         strcpy(sp, tgoto(sc_move, 0, 0));
  430.         t2 = sp;
  431.         sp += strlen(sp) + 1;
  432.     }
  433.     sc_home = cheaper(t1, t2, "home cursor", "|\b^");
  434.  
  435.     /*
  436.      * Choose between using "ll" and "cm"  ("lower left" and "cursor move")
  437.      * to move the cursor to the lower left corner of the screen.
  438.      */
  439.     t1 = tgetstr("ll", &sp);
  440.     if (hard || t1 == NULL)
  441.         t1 = "";
  442.     if (*sc_move == '\0')
  443.         t2 = "";
  444.     else
  445.     {
  446.         strcpy(sp, tgoto(sc_move, 0, sc_height-1));
  447.         t2 = sp;
  448.         sp += strlen(sp) + 1;
  449.     }
  450.     sc_lower_left = cheaper(t1, t2,
  451.         "move cursor to lower left of screen", "\r");
  452.  
  453.     /*
  454.      * Choose between using "al" or "sr" ("add line" or "scroll reverse")
  455.      * to add a line at the top of the screen.
  456.      */
  457.     t1 = tgetstr("al", &sp);
  458.     if (hard || t1 == NULL)
  459.         t1 = "";
  460.     t2 = tgetstr("sr", &sp);
  461.     if (hard || t2 == NULL)
  462.         t2 = "";
  463.     sc_addline = cheaper(t1, t2, "scroll backwards", "");
  464.     if (*sc_addline == '\0')
  465.     {
  466.         /*
  467.          * Force repaint on any backward movement.
  468.          */
  469.         back_scroll = 0;
  470.     }
  471. }
  472.  
  473. /*
  474.  * Return the cost of displaying a termcap string.
  475.  * We use the trick of calling tputs, but as a char printing function
  476.  * we give it inc_costcount, which just increments "costcount".
  477.  * This tells us how many chars would be printed by using this string.
  478.  * {{ Couldn't we just use strlen? }}
  479.  */
  480. static int costcount;
  481.  
  482. /*ARGSUSED*/
  483.     static void
  484. inc_costcount(c)
  485.     int c;
  486. {
  487.     costcount++;
  488. }
  489.  
  490.     static int
  491. cost(t)
  492.     char *t;
  493. {
  494.     costcount = 0;
  495.     tputs(t, sc_height, inc_costcount);
  496.     return (costcount);
  497. }
  498.  
  499. /*
  500.  * Return the "best" of the two given termcap strings.
  501.  * The best, if both exist, is the one with the lower 
  502.  * cost (see cost() function).
  503.  */
  504.     static char *
  505. cheaper(t1, t2, doit, def)
  506.     char *t1, *t2;
  507.     char *doit;
  508.     char *def;
  509. {
  510.     if (*t1 == '\0' && *t2 == '\0')
  511.     {
  512.         cannot(doit);
  513.         return (def);
  514.     }
  515.     if (*t1 == '\0')
  516.         return (t2);
  517.     if (*t2 == '\0')
  518.         return (t1);
  519.     if (cost(t1) < cost(t2))
  520.         return (t1);
  521.     return (t2);
  522. }
  523.  
  524.  
  525. /*
  526.  * Below are the functions which perform all the 
  527.  * terminal-specific screen manipulation.
  528.  */
  529.  
  530.  
  531. /*
  532.  * Initialize terminal
  533.  */
  534.     public void
  535. init()
  536. {
  537.     tputs(sc_init, sc_height, putchr);
  538.     init_done = 1;
  539. }
  540.  
  541. /*
  542.  * Deinitialize terminal
  543.  */
  544.     public void
  545. deinit()
  546. {
  547.     if (!init_done)
  548.         return;
  549.     tputs(sc_deinit, sc_height, putchr);
  550.     init_done = 0;
  551. }
  552.  
  553. /*
  554.  * Home cursor (move to upper left corner of screen).
  555.  */
  556.     public void
  557. home()
  558. {
  559.     tputs(sc_home, 1, putchr);
  560. }
  561.  
  562. /*
  563.  * Add a blank line (called with cursor at home).
  564.  * Should scroll the display down.
  565.  */
  566.     public void
  567. add_line()
  568. {
  569.     tputs(sc_addline, sc_height, putchr);
  570. }
  571.  
  572. /*
  573.  * Move cursor to lower left corner of screen.
  574.  */
  575.     public void
  576. lower_left()
  577. {
  578.     tputs(sc_lower_left, 1, putchr);
  579. }
  580.  
  581. /*
  582.  * Ring the terminal bell.
  583.  */
  584.     public void
  585. bell()
  586. {
  587.     if (quiet == VERY_QUIET)
  588.         vbell();
  589.     else
  590.         putchr('\7');
  591. }
  592.  
  593. /*
  594.  * Output the "visual bell", if there is one.
  595.  */
  596.     public void
  597. vbell()
  598. {
  599.     if (*sc_visual_bell == '\0')
  600.         return;
  601.     tputs(sc_visual_bell, sc_height, putchr);
  602. }
  603.  
  604. /*
  605.  * Clear the screen.
  606.  */
  607.     public void
  608. clear()
  609. {
  610.     tputs(sc_clear, sc_height, putchr);
  611. }
  612.  
  613. /*
  614.  * Clear from the cursor to the end of the cursor's line.
  615.  * {{ This must not move the cursor. }}
  616.  */
  617.     public void
  618. clear_eol()
  619. {
  620.     tputs(sc_eol_clear, 1, putchr);
  621. }
  622.  
  623. /*
  624.  * Begin "standout" (bold, underline, or whatever).
  625.  */
  626.     public void
  627. so_enter()
  628. {
  629.     tputs(sc_s_in, 1, putchr);
  630. }
  631.  
  632. /*
  633.  * End "standout".
  634.  */
  635.     public void
  636. so_exit()
  637. {
  638.     tputs(sc_s_out, 1, putchr);
  639. }
  640.  
  641. /*
  642.  * Begin "underline" (hopefully real underlining, 
  643.  * otherwise whatever the terminal provides).
  644.  */
  645.     public void
  646. ul_enter()
  647. {
  648.     tputs(sc_u_in, 1, putchr);
  649. }
  650.  
  651. /*
  652.  * End "underline".
  653.  */
  654.     public void
  655. ul_exit()
  656. {
  657.     tputs(sc_u_out, 1, putchr);
  658. }
  659.  
  660. /*
  661.  * Begin "bold"
  662.  */
  663.     public void
  664. bo_enter()
  665. {
  666.     tputs(sc_b_in, 1, putchr);
  667. }
  668.  
  669. /*
  670.  * End "bold".
  671.  */
  672.     public void
  673. bo_exit()
  674. {
  675.     tputs(sc_b_out, 1, putchr);
  676. }
  677.  
  678. /*
  679.  * Begin "blink"
  680.  */
  681.     public void
  682. bl_enter()
  683. {
  684.     tputs(sc_bl_in, 1, putchr);
  685. }
  686.  
  687. /*
  688.  * End "blink".
  689.  */
  690.     public void
  691. bl_exit()
  692. {
  693.     tputs(sc_bl_out, 1, putchr);
  694. }
  695.  
  696. /*
  697.  * Erase the character to the left of the cursor 
  698.  * and move the cursor left.
  699.  */
  700.     public void
  701. backspace()
  702. {
  703.     /* 
  704.      * Try to erase the previous character by overstriking with a space.
  705.      */
  706.     tputs(sc_backspace, 1, putchr);
  707.     putchr(' ');
  708.     tputs(sc_backspace, 1, putchr);
  709. }
  710.  
  711. /*
  712.  * Output a plain backspace, without erasing the previous char.
  713.  */
  714.     public void
  715. putbs()
  716. {
  717.     tputs(sc_backspace, 1, putchr);
  718. }
  719.  
  720. #else  /* TURBOC under MSDOS: */
  721.  
  722.     public void
  723. raw_mode(on)
  724.     int on;
  725. {
  726.     on = on;
  727. }
  728.  
  729. /*
  730.  * Set terminal capabilities for TURBOC video output
  731.  */
  732.     public void
  733. get_term()
  734. {
  735.     extern int output_mode;
  736.     /*
  737.      * Get size of the screen.
  738.      */
  739.     sc_height = _video.screenheight;
  740.     sc_width  = _video.screenwidth;
  741.     if (sc_width != 80)
  742.         directvideo = 0;
  743.     pos_init();
  744.     if (swindow < 0)
  745.         swindow = sc_height - 2;
  746.     auto_wrap = 1;
  747.     ignaw = 0;
  748.     erase_char = '\b';
  749.     kill_char = '\003';
  750.  
  751.     so_e_width = so_s_width = 0;
  752.     bo_s_width = bo_e_width = 0;
  753.     ul_s_width = ul_e_width = 0;
  754.     bl_s_width = bl_e_width = 0;
  755. }
  756.  
  757. /*
  758.  * Below are the functions which perform all the 
  759.  * terminal-specific screen manipulation.
  760.  */
  761.  
  762.  
  763. /*
  764.  * Initialize terminal
  765.  */
  766.     public void
  767. init()
  768. {
  769.     flush();
  770.     if (init_done)
  771.         return;
  772.     textbackground(BLACK);
  773.     textcolor(LIGHTGRAY);
  774.     init_done = 1;
  775. }
  776.  
  777. /*
  778.  * Deinitialize terminal
  779.  */
  780.     public void
  781. deinit()
  782. {
  783.     flush();
  784.     if (!init_done)
  785.         return;
  786.     init_done = 0;
  787. }
  788.  
  789. /*
  790.  * Home cursor (move to upper left corner of screen).
  791.  */
  792.     public void
  793. home()
  794. {
  795.     flush();
  796.     gotoxy(1,1);
  797. }
  798.  
  799. /*
  800.  * Add a blank line (called with cursor at home).
  801.  * Should scroll the display down.
  802.  */
  803.     public void
  804. add_line()
  805. {
  806.     flush();
  807.     insline();
  808. }
  809.  
  810. /*
  811.  * Move cursor to lower left corner of screen.
  812.  */
  813.     public void
  814. lower_left()
  815. {
  816.     flush();
  817.     gotoxy(1,sc_height);
  818. }
  819.  
  820. /*
  821.  * Ring the terminal bell.
  822.  */
  823.     public void
  824. bell()
  825. {
  826.     flush();
  827.     if (quiet == VERY_QUIET)
  828.         vbell();
  829.     else
  830.         putch('\7');
  831. }
  832.  
  833. /*
  834.  * Output the "visual bell", if there is one.
  835.  */
  836.     public void
  837. vbell()
  838. {
  839. }
  840.  
  841. /*
  842.  * Clear the screen.
  843.  */
  844.     public void
  845. clear()
  846. {
  847.     flush();
  848.     clrscr();
  849. }
  850.  
  851. /*
  852.  * Clear from the cursor to the end of the cursor's line.
  853.  * {{ This must not move the cursor. }}
  854.  */
  855.     public void
  856. clear_eol()
  857. {
  858.     flush();
  859.     clreol();
  860. }
  861.  
  862. /*
  863.  * Begin "standout" (bold, underline, or whatever).
  864.  */
  865.     public void
  866. so_enter()
  867. {
  868.     flush();
  869.     textcolor(RED);
  870. }
  871.  
  872. /*
  873.  * End "standout".
  874.  */
  875.     public void
  876. so_exit()
  877. {
  878.     flush();
  879.     textcolor(LIGHTGRAY);
  880. }
  881.  
  882. /*
  883.  * Begin "underline" (hopefully real underlining, 
  884.  * otherwise whatever the terminal provides).
  885.  */
  886.     public void
  887. ul_enter()
  888. {
  889.     flush();
  890.     textcolor(YELLOW);
  891. }
  892.  
  893. /*
  894.  * End "underline".
  895.  */
  896.     public void
  897. ul_exit()
  898. {
  899.     flush();
  900.     textcolor(LIGHTGRAY);
  901. }
  902.  
  903. /*
  904.  * Begin "bold"
  905.  */
  906.     public void
  907. bo_enter()
  908. {
  909.     flush();
  910.     textcolor(GREEN);
  911. }
  912.  
  913. /*
  914.  * End "bold".
  915.  */
  916.     public void
  917. bo_exit()
  918. {
  919.     flush();
  920.     textcolor(LIGHTGRAY);
  921. }
  922.  
  923. /*
  924.  * Begin "blink"
  925.  */
  926.     public void
  927. bl_enter()
  928. {
  929.     flush();
  930.     textcolor(_video.attribute|BLINK);
  931. }
  932.  
  933. /*
  934.  * End "blink".
  935.  */
  936.     public void
  937. bl_exit()
  938. {
  939.     flush();
  940.     textcolor(_video.attribute&127);
  941. }
  942.  
  943. /*
  944.  * Begin "bold2"
  945.  */
  946.     public void
  947. bo2_enter()
  948. {
  949.     flush();
  950.     textcolor(LIGHTBLUE);
  951. }
  952.  
  953. /*
  954.  * End "bold2".
  955.  */
  956.     public void
  957. bo2_exit()
  958. {
  959.     flush();
  960.     textcolor(LIGHTGRAY);
  961. }
  962.  
  963. /*
  964.  * Erase the character to the left of the cursor 
  965.  * and move the cursor left.
  966.  */
  967.     public void
  968. backspace()
  969. {
  970.     /* 
  971.      * Try to erase the previous character by overstriking with a space.
  972.      */
  973.     putstr("\b \b");
  974. }
  975.  
  976. /*
  977.  * Output a plain backspace, without erasing the previous char.
  978.  */
  979.     public void
  980. putbs()
  981. {
  982.     putchr('\b');
  983. }
  984.  
  985. #endif
  986.