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