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