xref: /csrg-svn/lib/libcurses/tty.c (revision 68183)
155989Sbostic /*-
267082Sbostic  * Copyright (c) 1992, 1993, 1994
362546Sbostic  *	The Regents of the University of California.  All rights reserved.
455989Sbostic  *
555989Sbostic  * %sccs.include.redist.c%
655989Sbostic  */
755989Sbostic 
855989Sbostic #ifndef lint
9*68183Sbostic static char sccsid[] = "@(#)tty.c	8.6 (Berkeley) 01/10/95";
1055989Sbostic #endif /* not lint */
1155989Sbostic 
1267666Sbostic #include <stdlib.h>
1355989Sbostic #include <termios.h>
1455989Sbostic #include <unistd.h>
1555989Sbostic 
1667082Sbostic #include "curses.h"
1767082Sbostic 
1860627Sbostic /*
1960627Sbostic  * In general, curses should leave tty hardware settings alone (speed, parity,
2060627Sbostic  * word size).  This is most easily done in BSD by using TCSASOFT on all
2160627Sbostic  * tcsetattr calls.  On other systems, it would be better to get and restore
2260627Sbostic  * those attributes at each change, or at least when stopped and restarted.
2360627Sbostic  * See also the comments in getterm().
2460627Sbostic  */
2560627Sbostic #ifdef TCSASOFT
2662545Sbostic int __tcaction = 1;			/* Ignore hardware settings. */
2760627Sbostic #else
2862545Sbostic int __tcaction = 0;
2960627Sbostic #endif
3060627Sbostic 
3161229Smarc struct termios __orig_termios, __baset;
3261229Smarc static struct termios cbreakt, rawt, *curt;
3355989Sbostic static int useraw;
3455989Sbostic 
3560616Sbostic #ifndef	OXTABS
3660616Sbostic #ifdef	XTABS			/* SMI uses XTABS. */
3760616Sbostic #define	OXTABS	XTABS
3860616Sbostic #else
3960616Sbostic #define	OXTABS	0
4060616Sbostic #endif
4160616Sbostic #endif
4260616Sbostic 
4355989Sbostic /*
4455989Sbostic  * gettmode --
4555989Sbostic  *	Do terminal type initialization.
4655989Sbostic  */
4755989Sbostic int
gettmode()4855989Sbostic gettmode()
4955989Sbostic {
5057286Sbostic 	useraw = 0;
5157286Sbostic 
5257716Sbostic 	if (tcgetattr(STDIN_FILENO, &__orig_termios))
5357472Sbostic 		return (ERR);
5455989Sbostic 
5561229Smarc 	__baset = __orig_termios;
5661229Smarc 	__baset.c_oflag &= ~OXTABS;
5755989Sbostic 
5861229Smarc 	GT = 0;		/* historical. was used before we wired OXTABS off */
5961229Smarc 	NONL = (__baset.c_oflag & ONLCR) == 0;
6060619Sbostic 
6160619Sbostic 	/*
6260619Sbostic 	 * XXX
6360619Sbostic 	 * System V and SMI systems overload VMIN and VTIME, such that
6460619Sbostic 	 * VMIN is the same as the VEOF element, and VTIME is the same
6560619Sbostic 	 * as the VEOL element.  This means that, if VEOF was ^D, the
6660619Sbostic 	 * default VMIN is 4.  Majorly stupid.
6760619Sbostic 	 */
6861229Smarc 	cbreakt = __baset;
6960627Sbostic 	cbreakt.c_lflag &= ~ICANON;
7060627Sbostic 	cbreakt.c_cc[VMIN] = 1;
7160627Sbostic 	cbreakt.c_cc[VTIME] = 0;
7255989Sbostic 
7360627Sbostic 	rawt = cbreakt;
7460627Sbostic 	rawt.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INLCR|IGNCR|ICRNL|IXON);
7560627Sbostic 	rawt.c_oflag &= ~OPOST;
7660627Sbostic 	rawt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
7762545Sbostic 
7860627Sbostic 	/*
7960627Sbostic 	 * In general, curses should leave hardware-related settings alone.
8060627Sbostic 	 * This includes parity and word size.  Older versions set the tty
8160627Sbostic 	 * to 8 bits, no parity in raw(), but this is considered to be an
8260627Sbostic 	 * artifact of the old tty interface.  If it's desired to change
8362545Sbostic 	 * parity and word size, the TCSASOFT bit has to be removed from the
8462545Sbostic 	 * calls that switch to/from "raw" mode.
8560627Sbostic 	 */
8662545Sbostic 	if (!__tcaction) {
8762545Sbostic 		rawt.c_iflag &= ~ISTRIP;
8862545Sbostic 		rawt.c_cflag &= ~(CSIZE|PARENB);
8962545Sbostic 		rawt.c_cflag |= CS8;
9062545Sbostic 	}
9160627Sbostic 
9261229Smarc 	curt = &__baset;
9362545Sbostic 	return (tcsetattr(STDIN_FILENO, __tcaction ?
9462545Sbostic 	    TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
9555989Sbostic }
9655989Sbostic 
9755989Sbostic int
raw()9855989Sbostic raw()
9955989Sbostic {
10055989Sbostic 	useraw = __pfast = __rawmode = 1;
10160627Sbostic 	curt = &rawt;
10262545Sbostic 	return (tcsetattr(STDIN_FILENO, __tcaction ?
10367174Sbostic 	    TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
10455989Sbostic }
10555989Sbostic 
10655989Sbostic int
noraw()10755989Sbostic noraw()
10855989Sbostic {
10955989Sbostic 	useraw = __pfast = __rawmode = 0;
11061229Smarc 	curt = &__baset;
11162545Sbostic 	return (tcsetattr(STDIN_FILENO, __tcaction ?
11267174Sbostic 	    TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
11355989Sbostic }
11455989Sbostic 
11555989Sbostic int
cbreak()11655989Sbostic cbreak()
11755989Sbostic {
11855989Sbostic 
11955989Sbostic 	__rawmode = 1;
12060627Sbostic 	curt = useraw ? &rawt : &cbreakt;
12162545Sbostic 	return (tcsetattr(STDIN_FILENO, __tcaction ?
12267174Sbostic 	    TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
12355989Sbostic }
12455989Sbostic 
12555989Sbostic int
nocbreak()12655989Sbostic nocbreak()
12755989Sbostic {
12855989Sbostic 
12955989Sbostic 	__rawmode = 0;
13061229Smarc 	curt = useraw ? &rawt : &__baset;
13162545Sbostic 	return (tcsetattr(STDIN_FILENO, __tcaction ?
13267174Sbostic 	    TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
13355989Sbostic }
13455989Sbostic 
13555989Sbostic int
echo()13655989Sbostic echo()
13755989Sbostic {
13855989Sbostic 	rawt.c_lflag |= ECHO;
13960627Sbostic 	cbreakt.c_lflag |= ECHO;
14061229Smarc 	__baset.c_lflag |= ECHO;
14155989Sbostic 
14255989Sbostic 	__echoit = 1;
14362545Sbostic 	return (tcsetattr(STDIN_FILENO, __tcaction ?
14467174Sbostic 	    TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
14555989Sbostic }
14655989Sbostic 
14755989Sbostic int
noecho()14855989Sbostic noecho()
14955989Sbostic {
15055989Sbostic 	rawt.c_lflag &= ~ECHO;
15160627Sbostic 	cbreakt.c_lflag &= ~ECHO;
15261229Smarc 	__baset.c_lflag &= ~ECHO;
15355989Sbostic 
15455989Sbostic 	__echoit = 0;
15562545Sbostic 	return (tcsetattr(STDIN_FILENO, __tcaction ?
15667174Sbostic 	    TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
15755989Sbostic }
15855989Sbostic 
15955989Sbostic int
nl()16055989Sbostic nl()
16155989Sbostic {
16255989Sbostic 	rawt.c_iflag |= ICRNL;
16355989Sbostic 	rawt.c_oflag |= ONLCR;
16460627Sbostic 	cbreakt.c_iflag |= ICRNL;
16560627Sbostic 	cbreakt.c_oflag |= ONLCR;
16661229Smarc 	__baset.c_iflag |= ICRNL;
16761229Smarc 	__baset.c_oflag |= ONLCR;
16855989Sbostic 
16955989Sbostic 	__pfast = __rawmode;
17062545Sbostic 	return (tcsetattr(STDIN_FILENO, __tcaction ?
17167174Sbostic 	    TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
17255989Sbostic }
17355989Sbostic 
17455989Sbostic int
nonl()17555989Sbostic nonl()
17655989Sbostic {
17755989Sbostic 	rawt.c_iflag &= ~ICRNL;
17855989Sbostic 	rawt.c_oflag &= ~ONLCR;
17960627Sbostic 	cbreakt.c_iflag &= ~ICRNL;
18060627Sbostic 	cbreakt.c_oflag &= ~ONLCR;
18161229Smarc 	__baset.c_iflag &= ~ICRNL;
18261229Smarc 	__baset.c_oflag &= ~ONLCR;
18355989Sbostic 
18455989Sbostic 	__pfast = 1;
18562545Sbostic 	return (tcsetattr(STDIN_FILENO, __tcaction ?
18667174Sbostic 	    TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
18755989Sbostic }
18855989Sbostic 
18959862Sbostic void
__startwin()19059862Sbostic __startwin()
19159862Sbostic {
19267666Sbostic 	static char *stdbuf;
19367666Sbostic 	static size_t len;
19467666Sbostic 
19559862Sbostic 	(void)fflush(stdout);
19659862Sbostic 
19767666Sbostic 	/*
19867666Sbostic 	 * Some C libraries default to a 1K buffer when talking to a tty.
19967666Sbostic 	 * With a larger screen, especially across a network, we'd like
20067666Sbostic 	 * to get it to all flush in a single write.  Make it twice as big
20167666Sbostic 	 * as just the characters (so that we have room for cursor motions
20267666Sbostic 	 * and standout information) but no more than 8K.
20367666Sbostic 	 */
20467666Sbostic 	if (stdbuf == NULL) {
20567666Sbostic 		if ((len = LINES * COLS * 2) > 8192)
20667666Sbostic 			len = 8192;
20767666Sbostic 		if ((stdbuf = malloc(len)) == NULL)
20867666Sbostic 			len = 0;
20967666Sbostic 	}
21067666Sbostic 	(void)setvbuf(stdout, stdbuf, _IOFBF, len);
21167666Sbostic 
21259862Sbostic 	tputs(TI, 0, __cputchar);
21359862Sbostic 	tputs(VS, 0, __cputchar);
21459862Sbostic }
21559862Sbostic 
21655989Sbostic int
endwin()21755989Sbostic endwin()
21855989Sbostic {
21965314Sbostic 	__restore_stophandler();
22065314Sbostic 
22157716Sbostic 	if (curscr != NULL) {
22257716Sbostic 		if (curscr->flags & __WSTANDOUT) {
22357716Sbostic 			tputs(SE, 0, __cputchar);
22457716Sbostic 			curscr->flags &= ~__WSTANDOUT;
22557716Sbostic 		}
226*68183Sbostic 		__mvcur(curscr->cury, curscr->curx, curscr->maxy - 1, 0, 0);
22755989Sbostic 	}
22855989Sbostic 
22955989Sbostic 	(void)tputs(VE, 0, __cputchar);
23055989Sbostic 	(void)tputs(TE, 0, __cputchar);
23155989Sbostic 	(void)fflush(stdout);
23259862Sbostic 	(void)setvbuf(stdout, NULL, _IOLBF, 0);
23355989Sbostic 
23462545Sbostic 	return (tcsetattr(STDIN_FILENO, __tcaction ?
23567174Sbostic 	    TCSASOFT | TCSADRAIN : TCSADRAIN, &__orig_termios) ? ERR : OK);
23655989Sbostic }
23755989Sbostic 
23855989Sbostic /*
23955989Sbostic  * The following routines, savetty and resetty are completely useless and
24055989Sbostic  * are left in only as stubs.  If people actually use them they will almost
24155989Sbostic  * certainly screw up the state of the world.
24255989Sbostic  */
24355989Sbostic static struct termios savedtty;
24455989Sbostic int
savetty()24555989Sbostic savetty()
24655989Sbostic {
24767174Sbostic 	return (tcgetattr(STDIN_FILENO, &savedtty) ? ERR : OK);
24855989Sbostic }
24955989Sbostic 
25055989Sbostic int
resetty()25155989Sbostic resetty()
25255989Sbostic {
25362545Sbostic 	return (tcsetattr(STDIN_FILENO, __tcaction ?
25467174Sbostic 	    TCSASOFT | TCSADRAIN : TCSADRAIN, &savedtty) ? ERR : OK);
25555989Sbostic }
256