xref: /csrg-svn/usr.bin/more/screen.c (revision 67022)
135209Sbostic /*
235209Sbostic  * Copyright (c) 1988 Mark Nudleman
362131Sbostic  * Copyright (c) 1988, 1993
462131Sbostic  *	The Regents of the University of California.  All rights reserved.
535209Sbostic  *
642742Sbostic  * %sccs.include.redist.c%
735209Sbostic  */
835209Sbostic 
935209Sbostic #ifndef lint
10*67022Sbostic static char sccsid[] = "@(#)screen.c	8.2 (Berkeley) 04/20/94";
1135209Sbostic #endif /* not lint */
1235209Sbostic 
1335209Sbostic /*
1435209Sbostic  * Routines which deal with the characteristics of the terminal.
1535209Sbostic  * Uses termcap to be as terminal-independent as possible.
1635209Sbostic  *
1735209Sbostic  * {{ Someday this should be rewritten to use curses. }}
1835209Sbostic  */
1935209Sbostic 
2036253Sbostic #include <stdio.h>
2136253Sbostic #include <less.h>
2235209Sbostic 
23*67022Sbostic #define TERMIOS 1
24*67022Sbostic 
2535209Sbostic #if TERMIO
2635209Sbostic #include <termio.h>
2735209Sbostic #else
28*67022Sbostic #if TERMIOS
29*67022Sbostic #include <termios.h>
30*67022Sbostic #define TAB3 0
31*67022Sbostic #include <sys/ioctl.h>
32*67022Sbostic #else
3335209Sbostic #include <sgtty.h>
3435209Sbostic #endif
35*67022Sbostic #endif
3635209Sbostic 
3735209Sbostic #ifdef TIOCGWINSZ
3835209Sbostic #include <sys/ioctl.h>
3935209Sbostic #else
4035209Sbostic /*
4135209Sbostic  * For the Unix PC (ATT 7300 & 3B1):
4235209Sbostic  * Since WIOCGETD is defined in sys/window.h, we can't use that to decide
4335209Sbostic  * whether to include sys/window.h.  Use SIGPHONE from sys/signal.h instead.
4435209Sbostic  */
4535209Sbostic #include <sys/signal.h>
4635209Sbostic #ifdef SIGPHONE
4735209Sbostic #include <sys/window.h>
4835209Sbostic #endif
4935209Sbostic #endif
5035209Sbostic 
5135209Sbostic /*
5235209Sbostic  * Strings passed to tputs() to do various terminal functions.
5335209Sbostic  */
5435209Sbostic static char
5535209Sbostic 	*sc_pad,		/* Pad string */
5635209Sbostic 	*sc_home,		/* Cursor home */
5735209Sbostic 	*sc_addline,		/* Add line, scroll down following lines */
5835209Sbostic 	*sc_lower_left,		/* Cursor to last line, first column */
5935209Sbostic 	*sc_move,		/* General cursor positioning */
6035209Sbostic 	*sc_clear,		/* Clear screen */
6135209Sbostic 	*sc_eol_clear,		/* Clear to end of line */
6235209Sbostic 	*sc_s_in,		/* Enter standout (highlighted) mode */
6335209Sbostic 	*sc_s_out,		/* Exit standout mode */
6435209Sbostic 	*sc_u_in,		/* Enter underline mode */
6535209Sbostic 	*sc_u_out,		/* Exit underline mode */
6635209Sbostic 	*sc_b_in,		/* Enter bold mode */
6735209Sbostic 	*sc_b_out,		/* Exit bold mode */
6835209Sbostic 	*sc_backspace,		/* Backspace cursor */
6935209Sbostic 	*sc_init,		/* Startup terminal initialization */
7035209Sbostic 	*sc_deinit;		/* Exit terminal de-intialization */
7135209Sbostic 
7236253Sbostic int auto_wrap;			/* Terminal does \r\n when write past margin */
7336253Sbostic int ignaw;			/* Terminal ignores \n immediately after wrap */
7436253Sbostic 				/* The user's erase and line-kill chars */
7557940Sedward int retain_below;		/* Terminal retains text below the screen */
7636253Sbostic int erase_char, kill_char, werase_char;
7736253Sbostic int sc_width, sc_height = -1;	/* Height & width of screen */
7836253Sbostic int sc_window = -1;		/* window size for forward and backward */
7936253Sbostic int bo_width, be_width;		/* Printing width of boldface sequences */
8036253Sbostic int ul_width, ue_width;		/* Printing width of underline sequences */
8136253Sbostic int so_width, se_width;		/* Printing width of standout sequences */
8235209Sbostic 
8335209Sbostic /*
8435209Sbostic  * These two variables are sometimes defined in,
8535209Sbostic  * and needed by, the termcap library.
8635209Sbostic  * It may be necessary on some systems to declare them extern here.
8735209Sbostic  */
8835209Sbostic /*extern*/ short ospeed;	/* Terminal output baud rate */
8935209Sbostic /*extern*/ char PC;		/* Pad character */
9035209Sbostic 
9135209Sbostic extern int back_scroll;
9235209Sbostic char *tgetstr();
9335209Sbostic char *tgoto();
9435209Sbostic 
9535209Sbostic /*
9635209Sbostic  * Change terminal to "raw mode", or restore to "normal" mode.
9735209Sbostic  * "Raw mode" means
9835209Sbostic  *	1. An outstanding read will complete on receipt of a single keystroke.
9935209Sbostic  *	2. Input is not echoed.
10035209Sbostic  *	3. On output, \n is mapped to \r\n.
10135209Sbostic  *	4. \t is NOT expanded into spaces.
10235209Sbostic  *	5. Signal-causing characters such as ctrl-C (interrupt),
10335209Sbostic  *	   etc. are NOT disabled.
10435209Sbostic  * It doesn't matter whether an input \n is mapped to \r, or vice versa.
10535209Sbostic  */
raw_mode(on)10635209Sbostic raw_mode(on)
10735209Sbostic 	int on;
10835209Sbostic {
109*67022Sbostic #if TERMIO || TERMIOS
110*67022Sbostic 
11135209Sbostic #if TERMIO
11235209Sbostic 	struct termio s;
11335209Sbostic 	static struct termio save_term;
114*67022Sbostic #else
115*67022Sbostic 	struct termios s;
116*67022Sbostic 	static struct termios save_term;
117*67022Sbostic #endif
11835209Sbostic 
11935209Sbostic 	if (on)
12035209Sbostic 	{
12135209Sbostic 		/*
12235209Sbostic 		 * Get terminal modes.
12335209Sbostic 		 */
124*67022Sbostic #if TERMIO
12536253Sbostic 		(void)ioctl(2, TCGETA, &s);
126*67022Sbostic #else
127*67022Sbostic 		tcgetattr(2, &s);
128*67022Sbostic #endif
12935209Sbostic 
13035209Sbostic 		/*
13135209Sbostic 		 * Save modes and set certain variables dependent on modes.
13235209Sbostic 		 */
13335209Sbostic 		save_term = s;
134*67022Sbostic #if TERMIO
13535209Sbostic 		ospeed = s.c_cflag & CBAUD;
136*67022Sbostic #else
137*67022Sbostic 		ospeed = cfgetospeed(&s);
138*67022Sbostic #endif
13935209Sbostic 		erase_char = s.c_cc[VERASE];
14035209Sbostic 		kill_char = s.c_cc[VKILL];
14136253Sbostic 		werase_char = s.c_cc[VWERASE];
14235209Sbostic 
14335209Sbostic 		/*
14435209Sbostic 		 * Set the modes to the way we want them.
14535209Sbostic 		 */
14635209Sbostic 		s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
14735209Sbostic 		s.c_oflag |=  (OPOST|ONLCR|TAB3);
148*67022Sbostic #if TERMIO
14935209Sbostic 		s.c_oflag &= ~(OCRNL|ONOCR|ONLRET);
150*67022Sbostic #endif
15135209Sbostic 		s.c_cc[VMIN] = 1;
15235209Sbostic 		s.c_cc[VTIME] = 0;
15335209Sbostic 	} else
15435209Sbostic 	{
15535209Sbostic 		/*
15635209Sbostic 		 * Restore saved modes.
15735209Sbostic 		 */
15835209Sbostic 		s = save_term;
15935209Sbostic 	}
160*67022Sbostic #if TERMIO
16136253Sbostic 	(void)ioctl(2, TCSETAW, &s);
16235209Sbostic #else
163*67022Sbostic 	tcsetattr(2, TCSADRAIN, &s);
164*67022Sbostic #endif
165*67022Sbostic #else
16635209Sbostic 	struct sgttyb s;
16754543Sbostic 	struct ltchars l;
16835209Sbostic 	static struct sgttyb save_term;
16935209Sbostic 
17035209Sbostic 	if (on)
17135209Sbostic 	{
17235209Sbostic 		/*
17335209Sbostic 		 * Get terminal modes.
17435209Sbostic 		 */
17536253Sbostic 		(void)ioctl(2, TIOCGETP, &s);
17654543Sbostic 		(void)ioctl(2, TIOCGLTC, &l);
17735209Sbostic 
17835209Sbostic 		/*
17935209Sbostic 		 * Save modes and set certain variables dependent on modes.
18035209Sbostic 		 */
18135209Sbostic 		save_term = s;
18235209Sbostic 		ospeed = s.sg_ospeed;
18335209Sbostic 		erase_char = s.sg_erase;
18435209Sbostic 		kill_char = s.sg_kill;
18554543Sbostic 		werase_char = l.t_werasc;
18635209Sbostic 
18735209Sbostic 		/*
18835209Sbostic 		 * Set the modes to the way we want them.
18935209Sbostic 		 */
19035209Sbostic 		s.sg_flags |= CBREAK;
19135209Sbostic 		s.sg_flags &= ~(ECHO|XTABS);
19235209Sbostic 	} else
19335209Sbostic 	{
19435209Sbostic 		/*
19535209Sbostic 		 * Restore saved modes.
19635209Sbostic 		 */
19735209Sbostic 		s = save_term;
19835209Sbostic 	}
19936253Sbostic 	(void)ioctl(2, TIOCSETN, &s);
20035209Sbostic #endif
20135209Sbostic }
20235209Sbostic 
20335209Sbostic /*
20435209Sbostic  * Get terminal capabilities via termcap.
20535209Sbostic  */
get_term()20635209Sbostic get_term()
20735209Sbostic {
20835209Sbostic 	char termbuf[2048];
20935209Sbostic 	char *sp;
21035209Sbostic 	char *term;
21135209Sbostic 	int hard;
21235209Sbostic #ifdef TIOCGWINSZ
21335209Sbostic 	struct winsize w;
21435209Sbostic #else
21535209Sbostic #ifdef WIOCGETD
21635209Sbostic 	struct uwdata w;
21735209Sbostic #endif
21835209Sbostic #endif
21935209Sbostic 	static char sbuf[1024];
22035209Sbostic 
22135240Sbostic 	char *getenv(), *strcpy();
22235209Sbostic 
22335209Sbostic 	/*
22435209Sbostic 	 * Find out what kind of terminal this is.
22535209Sbostic 	 */
22635209Sbostic  	if ((term = getenv("TERM")) == NULL)
22735209Sbostic  		term = "unknown";
22835209Sbostic  	if (tgetent(termbuf, term) <= 0)
22935240Sbostic  		(void)strcpy(termbuf, "dumb:co#80:hc:");
23035209Sbostic 
23135209Sbostic 	/*
23235209Sbostic 	 * Get size of the screen.
23335209Sbostic 	 */
23435209Sbostic #ifdef TIOCGWINSZ
23536358Sbostic 	if (ioctl(2, TIOCGWINSZ, &w) == 0 && w.ws_row > 0)
23636358Sbostic 		sc_height = w.ws_row;
23735209Sbostic #else
23835209Sbostic #ifdef WIOCGETD
23936358Sbostic 	if (ioctl(2, WIOCGETD, &w) == 0 && w.uw_height > 0)
24036358Sbostic 		sc_height = w.uw_height/w.uw_vs;
24135209Sbostic #endif
24235209Sbostic #endif
24336358Sbostic 	else
24436358Sbostic 		sc_height = tgetnum("li");
24536253Sbostic 	hard = (sc_height < 0 || tgetflag("hc"));
24636253Sbostic 	if (hard) {
24735209Sbostic 		/* Oh no, this is a hardcopy terminal. */
24835209Sbostic 		sc_height = 24;
24935209Sbostic 	}
25035209Sbostic 
25135209Sbostic #ifdef TIOCGWINSZ
25235209Sbostic  	if (ioctl(2, TIOCGWINSZ, &w) == 0 && w.ws_col > 0)
25335209Sbostic 		sc_width = w.ws_col;
25435209Sbostic 	else
25535209Sbostic #ifdef WIOCGETD
25635209Sbostic 	if (ioctl(2, WIOCGETD, &w) == 0 && w.uw_width > 0)
25735209Sbostic 		sc_width = w.uw_width/w.uw_hs;
25835209Sbostic 	else
25935209Sbostic #endif
26035209Sbostic #endif
26135209Sbostic  		sc_width = tgetnum("co");
26235209Sbostic  	if (sc_width < 0)
26335209Sbostic   		sc_width = 80;
26435209Sbostic 
26535209Sbostic 	auto_wrap = tgetflag("am");
26635209Sbostic 	ignaw = tgetflag("xn");
26757940Sedward 	retain_below = tgetflag("db");
26835209Sbostic 
26935209Sbostic 	/*
27035209Sbostic 	 * Assumes termcap variable "sg" is the printing width of
27135209Sbostic 	 * the standout sequence, the end standout sequence,
27235209Sbostic 	 * the underline sequence, the end underline sequence,
27335209Sbostic 	 * the boldface sequence, and the end boldface sequence.
27435209Sbostic 	 */
27535209Sbostic 	if ((so_width = tgetnum("sg")) < 0)
27635209Sbostic 		so_width = 0;
27735209Sbostic 	be_width = bo_width = ue_width = ul_width = se_width = so_width;
27835209Sbostic 
27935209Sbostic 	/*
28035209Sbostic 	 * Get various string-valued capabilities.
28135209Sbostic 	 */
28235209Sbostic 	sp = sbuf;
28335209Sbostic 
28435209Sbostic 	sc_pad = tgetstr("pc", &sp);
28535209Sbostic 	if (sc_pad != NULL)
28635209Sbostic 		PC = *sc_pad;
28735209Sbostic 
28835209Sbostic 	sc_init = tgetstr("ti", &sp);
28935209Sbostic 	if (sc_init == NULL)
29035209Sbostic 		sc_init = "";
29135209Sbostic 
29235209Sbostic 	sc_deinit= tgetstr("te", &sp);
29335209Sbostic 	if (sc_deinit == NULL)
29435209Sbostic 		sc_deinit = "";
29535209Sbostic 
29635209Sbostic 	sc_eol_clear = tgetstr("ce", &sp);
29735209Sbostic 	if (hard || sc_eol_clear == NULL || *sc_eol_clear == '\0')
29835209Sbostic 	{
29935209Sbostic 		sc_eol_clear = "";
30035209Sbostic 	}
30135209Sbostic 
30235209Sbostic 	sc_clear = tgetstr("cl", &sp);
30335209Sbostic 	if (hard || sc_clear == NULL || *sc_clear == '\0')
30435209Sbostic 	{
30535209Sbostic 		sc_clear = "\n\n";
30635209Sbostic 	}
30735209Sbostic 
30835209Sbostic 	sc_move = tgetstr("cm", &sp);
30935209Sbostic 	if (hard || sc_move == NULL || *sc_move == '\0')
31035209Sbostic 	{
31135209Sbostic 		/*
31235209Sbostic 		 * This is not an error here, because we don't
31335209Sbostic 		 * always need sc_move.
31435209Sbostic 		 * We need it only if we don't have home or lower-left.
31535209Sbostic 		 */
31635209Sbostic 		sc_move = "";
31735209Sbostic 	}
31835209Sbostic 
31935209Sbostic 	sc_s_in = tgetstr("so", &sp);
32035209Sbostic 	if (hard || sc_s_in == NULL)
32135209Sbostic 		sc_s_in = "";
32235209Sbostic 
32335209Sbostic 	sc_s_out = tgetstr("se", &sp);
32435209Sbostic 	if (hard || sc_s_out == NULL)
32535209Sbostic 		sc_s_out = "";
32635209Sbostic 
32735209Sbostic 	sc_u_in = tgetstr("us", &sp);
32835209Sbostic 	if (hard || sc_u_in == NULL)
32935209Sbostic 		sc_u_in = sc_s_in;
33035209Sbostic 
33135209Sbostic 	sc_u_out = tgetstr("ue", &sp);
33235209Sbostic 	if (hard || sc_u_out == NULL)
33335209Sbostic 		sc_u_out = sc_s_out;
33435209Sbostic 
33535209Sbostic 	sc_b_in = tgetstr("md", &sp);
33635209Sbostic 	if (hard || sc_b_in == NULL)
33735209Sbostic 	{
33835209Sbostic 		sc_b_in = sc_s_in;
33935209Sbostic 		sc_b_out = sc_s_out;
34035209Sbostic 	} else
34135209Sbostic 	{
34235209Sbostic 		sc_b_out = tgetstr("me", &sp);
34335209Sbostic 		if (hard || sc_b_out == NULL)
34435209Sbostic 			sc_b_out = "";
34535209Sbostic 	}
34635209Sbostic 
34735209Sbostic 	sc_home = tgetstr("ho", &sp);
34835209Sbostic 	if (hard || sc_home == NULL || *sc_home == '\0')
34935209Sbostic 	{
35035209Sbostic 		if (*sc_move == '\0')
35135209Sbostic 		{
35235209Sbostic 			/*
35335209Sbostic 			 * This last resort for sc_home is supposed to
35435209Sbostic 			 * be an up-arrow suggesting moving to the
35535209Sbostic 			 * top of the "virtual screen". (The one in
35635209Sbostic 			 * your imagination as you try to use this on
35735209Sbostic 			 * a hard copy terminal.)
35835209Sbostic 			 */
35936265Sbostic 			sc_home = "|\b^";
36035209Sbostic 		} else
36135209Sbostic 		{
36235209Sbostic 			/*
36335209Sbostic 			 * No "home" string,
36435209Sbostic 			 * but we can use "move(0,0)".
36535209Sbostic 			 */
36635240Sbostic 			(void)strcpy(sp, tgoto(sc_move, 0, 0));
36735209Sbostic 			sc_home = sp;
36835209Sbostic 			sp += strlen(sp) + 1;
36935209Sbostic 		}
37035209Sbostic 	}
37135209Sbostic 
37235209Sbostic 	sc_lower_left = tgetstr("ll", &sp);
37335209Sbostic 	if (hard || sc_lower_left == NULL || *sc_lower_left == '\0')
37435209Sbostic 	{
37535209Sbostic 		if (*sc_move == '\0')
37635209Sbostic 		{
37735209Sbostic 			sc_lower_left = "\r";
37835209Sbostic 		} else
37935209Sbostic 		{
38035209Sbostic 			/*
38135209Sbostic 			 * No "lower-left" string,
38235209Sbostic 			 * but we can use "move(0,last-line)".
38335209Sbostic 			 */
38435240Sbostic 			(void)strcpy(sp, tgoto(sc_move, 0, sc_height-1));
38535209Sbostic 			sc_lower_left = sp;
38635209Sbostic 			sp += strlen(sp) + 1;
38735209Sbostic 		}
38835209Sbostic 	}
38935209Sbostic 
39035209Sbostic 	/*
39135209Sbostic 	 * To add a line at top of screen and scroll the display down,
39235209Sbostic 	 * we use "al" (add line) or "sr" (scroll reverse).
39335209Sbostic 	 */
39435209Sbostic 	if ((sc_addline = tgetstr("al", &sp)) == NULL ||
39535209Sbostic 		 *sc_addline == '\0')
39635209Sbostic 		sc_addline = tgetstr("sr", &sp);
39735209Sbostic 
39835209Sbostic 	if (hard || sc_addline == NULL || *sc_addline == '\0')
39935209Sbostic 	{
40035209Sbostic 		sc_addline = "";
40135209Sbostic 		/* Force repaint on any backward movement */
40235209Sbostic 		back_scroll = 0;
40335209Sbostic 	}
40435209Sbostic 
40535209Sbostic 	if (tgetflag("bs"))
40635209Sbostic 		sc_backspace = "\b";
40735209Sbostic 	else
40835209Sbostic 	{
40935209Sbostic 		sc_backspace = tgetstr("bc", &sp);
41035209Sbostic 		if (sc_backspace == NULL || *sc_backspace == '\0')
41135209Sbostic 			sc_backspace = "\b";
41235209Sbostic 	}
41335209Sbostic }
41435209Sbostic 
41535209Sbostic 
41635209Sbostic /*
41735209Sbostic  * Below are the functions which perform all the
41835209Sbostic  * terminal-specific screen manipulation.
41935209Sbostic  */
42035209Sbostic 
42136253Sbostic int putchr();
42235209Sbostic 
42335209Sbostic /*
42435209Sbostic  * Initialize terminal
42535209Sbostic  */
init()42635209Sbostic init()
42735209Sbostic {
42835209Sbostic 	tputs(sc_init, sc_height, putchr);
42935209Sbostic }
43035209Sbostic 
43135209Sbostic /*
43235209Sbostic  * Deinitialize terminal
43335209Sbostic  */
deinit()43435209Sbostic deinit()
43535209Sbostic {
43635209Sbostic 	tputs(sc_deinit, sc_height, putchr);
43735209Sbostic }
43835209Sbostic 
43935209Sbostic /*
44035209Sbostic  * Home cursor (move to upper left corner of screen).
44135209Sbostic  */
home()44235209Sbostic home()
44335209Sbostic {
44435209Sbostic 	tputs(sc_home, 1, putchr);
44535209Sbostic }
44635209Sbostic 
44735209Sbostic /*
44835209Sbostic  * Add a blank line (called with cursor at home).
44935209Sbostic  * Should scroll the display down.
45035209Sbostic  */
add_line()45135209Sbostic add_line()
45235209Sbostic {
45335209Sbostic 	tputs(sc_addline, sc_height, putchr);
45435209Sbostic }
45535209Sbostic 
45636358Sbostic int short_file;				/* if file less than a screen */
lower_left()45735209Sbostic lower_left()
45835209Sbostic {
45936358Sbostic 	if (short_file) {
46036358Sbostic 		putchr('\r');
46136358Sbostic 		flush();
46236358Sbostic 	}
46336358Sbostic 	else
46436358Sbostic 		tputs(sc_lower_left, 1, putchr);
46535209Sbostic }
46635209Sbostic 
46735209Sbostic /*
46835209Sbostic  * Ring the terminal bell.
46935209Sbostic  */
bell()47035209Sbostic bell()
47135209Sbostic {
47236253Sbostic 	putchr('\7');
47335209Sbostic }
47435209Sbostic 
47535209Sbostic /*
47635209Sbostic  * Clear the screen.
47735209Sbostic  */
clear()47835209Sbostic clear()
47935209Sbostic {
48035209Sbostic 	tputs(sc_clear, sc_height, putchr);
48135209Sbostic }
48235209Sbostic 
48335209Sbostic /*
48435209Sbostic  * Clear from the cursor to the end of the cursor's line.
48535209Sbostic  * {{ This must not move the cursor. }}
48635209Sbostic  */
clear_eol()48735209Sbostic clear_eol()
48835209Sbostic {
48935209Sbostic 	tputs(sc_eol_clear, 1, putchr);
49035209Sbostic }
49135209Sbostic 
49235209Sbostic /*
49335209Sbostic  * Begin "standout" (bold, underline, or whatever).
49435209Sbostic  */
so_enter()49535209Sbostic so_enter()
49635209Sbostic {
49735209Sbostic 	tputs(sc_s_in, 1, putchr);
49835209Sbostic }
49935209Sbostic 
50035209Sbostic /*
50135209Sbostic  * End "standout".
50235209Sbostic  */
so_exit()50335209Sbostic so_exit()
50435209Sbostic {
50535209Sbostic 	tputs(sc_s_out, 1, putchr);
50635209Sbostic }
50735209Sbostic 
50835209Sbostic /*
50935209Sbostic  * Begin "underline" (hopefully real underlining,
51035209Sbostic  * otherwise whatever the terminal provides).
51135209Sbostic  */
ul_enter()51235209Sbostic ul_enter()
51335209Sbostic {
51435209Sbostic 	tputs(sc_u_in, 1, putchr);
51535209Sbostic }
51635209Sbostic 
51735209Sbostic /*
51835209Sbostic  * End "underline".
51935209Sbostic  */
ul_exit()52035209Sbostic ul_exit()
52135209Sbostic {
52235209Sbostic 	tputs(sc_u_out, 1, putchr);
52335209Sbostic }
52435209Sbostic 
52535209Sbostic /*
52635209Sbostic  * Begin "bold"
52735209Sbostic  */
bo_enter()52835209Sbostic bo_enter()
52935209Sbostic {
53035209Sbostic 	tputs(sc_b_in, 1, putchr);
53135209Sbostic }
53235209Sbostic 
53335209Sbostic /*
53435209Sbostic  * End "bold".
53535209Sbostic  */
bo_exit()53635209Sbostic bo_exit()
53735209Sbostic {
53835209Sbostic 	tputs(sc_b_out, 1, putchr);
53935209Sbostic }
54035209Sbostic 
54135209Sbostic /*
54235209Sbostic  * Erase the character to the left of the cursor
54335209Sbostic  * and move the cursor left.
54435209Sbostic  */
backspace()54535209Sbostic backspace()
54635209Sbostic {
54735209Sbostic 	/*
54835209Sbostic 	 * Try to erase the previous character by overstriking with a space.
54935209Sbostic 	 */
55035209Sbostic 	tputs(sc_backspace, 1, putchr);
55135209Sbostic 	putchr(' ');
55235209Sbostic 	tputs(sc_backspace, 1, putchr);
55335209Sbostic }
55435209Sbostic 
55535209Sbostic /*
55635209Sbostic  * Output a plain backspace, without erasing the previous char.
55735209Sbostic  */
putbs()55835209Sbostic putbs()
55935209Sbostic {
56035209Sbostic 	tputs(sc_backspace, 1, putchr);
56135209Sbostic }
562