xref: /original-bsd/lib/libcurses/tty.c (revision 6a4e3636)
1 /*-
2  * Copyright (c) 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)tty.c	5.16 (Berkeley) 05/30/93";
10 #endif /* not lint */
11 
12 #include <sys/ioctl.h>
13 
14 #include <curses.h>
15 #include <termios.h>
16 #include <unistd.h>
17 
18 /*
19  * In general, curses should leave tty hardware settings alone (speed, parity,
20  * word size).  This is most easily done in BSD by using TCSASOFT on all
21  * tcsetattr calls.  On other systems, it would be better to get and restore
22  * those attributes at each change, or at least when stopped and restarted.
23  * See also the comments in getterm().
24  */
25 #ifdef TCSASOFT
26 #define	TCACTION (TCSASOFT | TCSADRAIN)		/* ignore hardware settings */
27 #else
28 #define	TCACTION  TCSADRAIN
29 #endif
30 
31 struct termios __orig_termios;
32 static struct termios baset, cbreakt, rawt, *curt;
33 static int useraw;
34 
35 #ifndef	OXTABS
36 #ifdef	XTABS			/* SMI uses XTABS. */
37 #define	OXTABS	XTABS
38 #else
39 #define	OXTABS	0
40 #endif
41 #endif
42 
43 /*
44  * gettmode --
45  *	Do terminal type initialization.
46  */
47 int
48 gettmode()
49 {
50 	useraw = 0;
51 
52 	if (tcgetattr(STDIN_FILENO, &__orig_termios))
53 		return (ERR);
54 
55 	GT = (__orig_termios.c_oflag & OXTABS) == 0;
56 	NONL = (__orig_termios.c_oflag & ONLCR) == 0;
57 
58 	baset = __orig_termios;
59 	baset.c_oflag &= ~OXTABS;
60 
61 	/*
62 	 * XXX
63 	 * System V and SMI systems overload VMIN and VTIME, such that
64 	 * VMIN is the same as the VEOF element, and VTIME is the same
65 	 * as the VEOL element.  This means that, if VEOF was ^D, the
66 	 * default VMIN is 4.  Majorly stupid.
67 	 */
68 	cbreakt = baset;
69 	cbreakt.c_lflag &= ~ICANON;
70 	cbreakt.c_cc[VMIN] = 1;
71 	cbreakt.c_cc[VTIME] = 0;
72 
73 	rawt = cbreakt;
74 	rawt.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INLCR|IGNCR|ICRNL|IXON);
75 	rawt.c_oflag &= ~OPOST;
76 	rawt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
77 #if 0
78 	/*
79 	 * In general, curses should leave hardware-related settings alone.
80 	 * This includes parity and word size.  Older versions set the tty
81 	 * to 8 bits, no parity in raw(), but this is considered to be an
82 	 * artifact of the old tty interface.  If it's desired to change
83 	 * parity and word size, the TCSASOFT bit would have to be removed
84 	 * from the calls that switch to/from "raw" mode.
85 	 */
86 	rawt.c_iflag &= ~ISTRIP;
87 	rawt.c_cflag &= ~(CSIZE|PARENB);
88 	rawt.c_cflag |= CS8;
89 #endif
90 
91 	curt = &baset;
92 	return (tcsetattr(STDIN_FILENO, TCACTION, &baset) ? ERR : OK);
93 }
94 
95 int
96 raw()
97 {
98 	useraw = __pfast = __rawmode = 1;
99 	curt = &rawt;
100 	return (tcsetattr(STDIN_FILENO, TCACTION, &rawt));
101 }
102 
103 int
104 noraw()
105 {
106 	useraw = __pfast = __rawmode = 0;
107 	curt = &baset;
108 	return (tcsetattr(STDIN_FILENO, TCACTION, &baset));
109 }
110 
111 int
112 cbreak()
113 {
114 
115 	__rawmode = 1;
116 	curt = useraw ? &rawt : &cbreakt;
117 	return (tcsetattr(STDIN_FILENO, TCACTION, curt));
118 }
119 
120 int
121 nocbreak()
122 {
123 
124 	__rawmode = 0;
125 	curt = useraw ? &rawt : &baset;
126 	return (tcsetattr(STDIN_FILENO, TCACTION, curt));
127 }
128 
129 int
130 echo()
131 {
132 	rawt.c_lflag |= ECHO;
133 	cbreakt.c_lflag |= ECHO;
134 	baset.c_lflag |= ECHO;
135 
136 	__echoit = 1;
137 	return (tcsetattr(STDIN_FILENO, TCACTION, curt));
138 }
139 
140 int
141 noecho()
142 {
143 	rawt.c_lflag &= ~ECHO;
144 	cbreakt.c_lflag &= ~ECHO;
145 	baset.c_lflag &= ~ECHO;
146 
147 	__echoit = 0;
148 	return (tcsetattr(STDIN_FILENO, TCACTION, curt));
149 }
150 
151 int
152 nl()
153 {
154 	rawt.c_iflag |= ICRNL;
155 	rawt.c_oflag |= ONLCR;
156 	cbreakt.c_iflag |= ICRNL;
157 	cbreakt.c_oflag |= ONLCR;
158 	baset.c_iflag |= ICRNL;
159 	baset.c_oflag |= ONLCR;
160 
161 	__pfast = __rawmode;
162 	return (tcsetattr(STDIN_FILENO, TCACTION, curt));
163 }
164 
165 int
166 nonl()
167 {
168 	rawt.c_iflag &= ~ICRNL;
169 	rawt.c_oflag &= ~ONLCR;
170 	cbreakt.c_iflag &= ~ICRNL;
171 	cbreakt.c_oflag &= ~ONLCR;
172 	baset.c_iflag &= ~ICRNL;
173 	baset.c_oflag &= ~ONLCR;
174 
175 	__pfast = 1;
176 	return (tcsetattr(STDIN_FILENO, TCACTION, curt));
177 }
178 
179 void
180 __startwin()
181 {
182 	(void)fflush(stdout);
183 	(void)setvbuf(stdout, NULL, _IOFBF, 0);
184 
185 	tputs(TI, 0, __cputchar);
186 	tputs(VS, 0, __cputchar);
187 }
188 
189 int
190 endwin()
191 {
192 	if (curscr != NULL) {
193 		if (curscr->flags & __WSTANDOUT) {
194 			tputs(SE, 0, __cputchar);
195 			curscr->flags &= ~__WSTANDOUT;
196 		}
197 		__mvcur(curscr->cury, curscr->cury, curscr->maxy - 1, 0, 0);
198 	}
199 
200 	(void)tputs(VE, 0, __cputchar);
201 	(void)tputs(TE, 0, __cputchar);
202 	(void)fflush(stdout);
203 	(void)setvbuf(stdout, NULL, _IOLBF, 0);
204 
205 	return (tcsetattr(STDIN_FILENO, TCACTION, &__orig_termios));
206 }
207 
208 /*
209  * The following routines, savetty and resetty are completely useless and
210  * are left in only as stubs.  If people actually use them they will almost
211  * certainly screw up the state of the world.
212  */
213 static struct termios savedtty;
214 int
215 savetty()
216 {
217 	return (tcgetattr(STDIN_FILENO, &savedtty));
218 }
219 
220 int
221 resetty()
222 {
223 	return (tcsetattr(STDIN_FILENO, TCACTION, &savedtty));
224 }
225