tty.c revision 1.6 1 1.1 mycroft /*-
2 1.6 cgd * Copyright (c) 1992, 1993, 1994
3 1.2 cgd * The Regents of the University of California. All rights reserved.
4 1.1 mycroft *
5 1.1 mycroft * Redistribution and use in source and binary forms, with or without
6 1.1 mycroft * modification, are permitted provided that the following conditions
7 1.1 mycroft * are met:
8 1.1 mycroft * 1. Redistributions of source code must retain the above copyright
9 1.1 mycroft * notice, this list of conditions and the following disclaimer.
10 1.1 mycroft * 2. Redistributions in binary form must reproduce the above copyright
11 1.1 mycroft * notice, this list of conditions and the following disclaimer in the
12 1.1 mycroft * documentation and/or other materials provided with the distribution.
13 1.1 mycroft * 3. All advertising materials mentioning features or use of this software
14 1.1 mycroft * must display the following acknowledgement:
15 1.1 mycroft * This product includes software developed by the University of
16 1.1 mycroft * California, Berkeley and its contributors.
17 1.1 mycroft * 4. Neither the name of the University nor the names of its contributors
18 1.1 mycroft * may be used to endorse or promote products derived from this software
19 1.1 mycroft * without specific prior written permission.
20 1.1 mycroft *
21 1.1 mycroft * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 1.1 mycroft * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 1.1 mycroft * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 1.1 mycroft * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 1.1 mycroft * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 1.1 mycroft * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 1.1 mycroft * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 1.1 mycroft * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 1.1 mycroft * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 1.1 mycroft * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 1.1 mycroft * SUCH DAMAGE.
32 1.1 mycroft */
33 1.1 mycroft
34 1.1 mycroft #ifndef lint
35 1.6 cgd static char sccsid[] = "@(#)tty.c 8.5 (Berkeley) 8/13/94";
36 1.1 mycroft #endif /* not lint */
37 1.1 mycroft
38 1.6 cgd #include <stdlib.h>
39 1.1 mycroft #include <termios.h>
40 1.1 mycroft #include <unistd.h>
41 1.1 mycroft
42 1.6 cgd #include "curses.h"
43 1.6 cgd
44 1.2 cgd /*
45 1.2 cgd * In general, curses should leave tty hardware settings alone (speed, parity,
46 1.2 cgd * word size). This is most easily done in BSD by using TCSASOFT on all
47 1.2 cgd * tcsetattr calls. On other systems, it would be better to get and restore
48 1.2 cgd * those attributes at each change, or at least when stopped and restarted.
49 1.2 cgd * See also the comments in getterm().
50 1.2 cgd */
51 1.2 cgd #ifdef TCSASOFT
52 1.2 cgd int __tcaction = 1; /* Ignore hardware settings. */
53 1.2 cgd #else
54 1.2 cgd int __tcaction = 0;
55 1.2 cgd #endif
56 1.2 cgd
57 1.2 cgd struct termios __orig_termios, __baset;
58 1.2 cgd static struct termios cbreakt, rawt, *curt;
59 1.1 mycroft static int useraw;
60 1.1 mycroft
61 1.2 cgd #ifndef OXTABS
62 1.2 cgd #ifdef XTABS /* SMI uses XTABS. */
63 1.2 cgd #define OXTABS XTABS
64 1.2 cgd #else
65 1.2 cgd #define OXTABS 0
66 1.2 cgd #endif
67 1.2 cgd #endif
68 1.2 cgd
69 1.1 mycroft /*
70 1.1 mycroft * gettmode --
71 1.1 mycroft * Do terminal type initialization.
72 1.1 mycroft */
73 1.1 mycroft int
74 1.1 mycroft gettmode()
75 1.1 mycroft {
76 1.2 cgd useraw = 0;
77 1.2 cgd
78 1.2 cgd if (tcgetattr(STDIN_FILENO, &__orig_termios))
79 1.2 cgd return (ERR);
80 1.2 cgd
81 1.2 cgd __baset = __orig_termios;
82 1.2 cgd __baset.c_oflag &= ~OXTABS;
83 1.1 mycroft
84 1.2 cgd GT = 0; /* historical. was used before we wired OXTABS off */
85 1.2 cgd NONL = (__baset.c_oflag & ONLCR) == 0;
86 1.1 mycroft
87 1.2 cgd /*
88 1.2 cgd * XXX
89 1.2 cgd * System V and SMI systems overload VMIN and VTIME, such that
90 1.2 cgd * VMIN is the same as the VEOF element, and VTIME is the same
91 1.2 cgd * as the VEOL element. This means that, if VEOF was ^D, the
92 1.2 cgd * default VMIN is 4. Majorly stupid.
93 1.2 cgd */
94 1.2 cgd cbreakt = __baset;
95 1.2 cgd cbreakt.c_lflag &= ~ICANON;
96 1.2 cgd cbreakt.c_cc[VMIN] = 1;
97 1.2 cgd cbreakt.c_cc[VTIME] = 0;
98 1.2 cgd
99 1.2 cgd rawt = cbreakt;
100 1.2 cgd rawt.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INLCR|IGNCR|ICRNL|IXON);
101 1.2 cgd rawt.c_oflag &= ~OPOST;
102 1.2 cgd rawt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
103 1.2 cgd
104 1.2 cgd /*
105 1.2 cgd * In general, curses should leave hardware-related settings alone.
106 1.2 cgd * This includes parity and word size. Older versions set the tty
107 1.2 cgd * to 8 bits, no parity in raw(), but this is considered to be an
108 1.2 cgd * artifact of the old tty interface. If it's desired to change
109 1.2 cgd * parity and word size, the TCSASOFT bit has to be removed from the
110 1.2 cgd * calls that switch to/from "raw" mode.
111 1.2 cgd */
112 1.2 cgd if (!__tcaction) {
113 1.2 cgd rawt.c_iflag &= ~ISTRIP;
114 1.2 cgd rawt.c_cflag &= ~(CSIZE|PARENB);
115 1.2 cgd rawt.c_cflag |= CS8;
116 1.2 cgd }
117 1.1 mycroft
118 1.2 cgd curt = &__baset;
119 1.2 cgd return (tcsetattr(STDIN_FILENO, __tcaction ?
120 1.2 cgd TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
121 1.1 mycroft }
122 1.1 mycroft
123 1.1 mycroft int
124 1.1 mycroft raw()
125 1.1 mycroft {
126 1.1 mycroft useraw = __pfast = __rawmode = 1;
127 1.2 cgd curt = &rawt;
128 1.2 cgd return (tcsetattr(STDIN_FILENO, __tcaction ?
129 1.6 cgd TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
130 1.1 mycroft }
131 1.1 mycroft
132 1.1 mycroft int
133 1.1 mycroft noraw()
134 1.1 mycroft {
135 1.1 mycroft useraw = __pfast = __rawmode = 0;
136 1.2 cgd curt = &__baset;
137 1.2 cgd return (tcsetattr(STDIN_FILENO, __tcaction ?
138 1.6 cgd TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
139 1.1 mycroft }
140 1.1 mycroft
141 1.1 mycroft int
142 1.1 mycroft cbreak()
143 1.1 mycroft {
144 1.1 mycroft
145 1.1 mycroft __rawmode = 1;
146 1.2 cgd curt = useraw ? &rawt : &cbreakt;
147 1.2 cgd return (tcsetattr(STDIN_FILENO, __tcaction ?
148 1.6 cgd TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
149 1.1 mycroft }
150 1.1 mycroft
151 1.1 mycroft int
152 1.1 mycroft nocbreak()
153 1.1 mycroft {
154 1.1 mycroft
155 1.1 mycroft __rawmode = 0;
156 1.2 cgd curt = useraw ? &rawt : &__baset;
157 1.2 cgd return (tcsetattr(STDIN_FILENO, __tcaction ?
158 1.6 cgd TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
159 1.1 mycroft }
160 1.1 mycroft
161 1.1 mycroft int
162 1.1 mycroft echo()
163 1.1 mycroft {
164 1.1 mycroft rawt.c_lflag |= ECHO;
165 1.2 cgd cbreakt.c_lflag |= ECHO;
166 1.2 cgd __baset.c_lflag |= ECHO;
167 1.1 mycroft
168 1.1 mycroft __echoit = 1;
169 1.2 cgd return (tcsetattr(STDIN_FILENO, __tcaction ?
170 1.6 cgd TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
171 1.1 mycroft }
172 1.1 mycroft
173 1.1 mycroft int
174 1.1 mycroft noecho()
175 1.1 mycroft {
176 1.1 mycroft rawt.c_lflag &= ~ECHO;
177 1.2 cgd cbreakt.c_lflag &= ~ECHO;
178 1.2 cgd __baset.c_lflag &= ~ECHO;
179 1.1 mycroft
180 1.1 mycroft __echoit = 0;
181 1.2 cgd return (tcsetattr(STDIN_FILENO, __tcaction ?
182 1.6 cgd TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
183 1.1 mycroft }
184 1.1 mycroft
185 1.1 mycroft int
186 1.1 mycroft nl()
187 1.1 mycroft {
188 1.1 mycroft rawt.c_iflag |= ICRNL;
189 1.1 mycroft rawt.c_oflag |= ONLCR;
190 1.2 cgd cbreakt.c_iflag |= ICRNL;
191 1.2 cgd cbreakt.c_oflag |= ONLCR;
192 1.2 cgd __baset.c_iflag |= ICRNL;
193 1.2 cgd __baset.c_oflag |= ONLCR;
194 1.1 mycroft
195 1.1 mycroft __pfast = __rawmode;
196 1.2 cgd return (tcsetattr(STDIN_FILENO, __tcaction ?
197 1.6 cgd TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
198 1.1 mycroft }
199 1.1 mycroft
200 1.1 mycroft int
201 1.1 mycroft nonl()
202 1.1 mycroft {
203 1.1 mycroft rawt.c_iflag &= ~ICRNL;
204 1.1 mycroft rawt.c_oflag &= ~ONLCR;
205 1.2 cgd cbreakt.c_iflag &= ~ICRNL;
206 1.2 cgd cbreakt.c_oflag &= ~ONLCR;
207 1.2 cgd __baset.c_iflag &= ~ICRNL;
208 1.2 cgd __baset.c_oflag &= ~ONLCR;
209 1.1 mycroft
210 1.1 mycroft __pfast = 1;
211 1.2 cgd return (tcsetattr(STDIN_FILENO, __tcaction ?
212 1.6 cgd TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
213 1.2 cgd }
214 1.2 cgd
215 1.2 cgd void
216 1.2 cgd __startwin()
217 1.2 cgd {
218 1.6 cgd static char *stdbuf;
219 1.6 cgd static size_t len;
220 1.6 cgd
221 1.2 cgd (void)fflush(stdout);
222 1.6 cgd
223 1.6 cgd /*
224 1.6 cgd * Some C libraries default to a 1K buffer when talking to a tty.
225 1.6 cgd * With a larger screen, especially across a network, we'd like
226 1.6 cgd * to get it to all flush in a single write. Make it twice as big
227 1.6 cgd * as just the characters (so that we have room for cursor motions
228 1.6 cgd * and standout information) but no more than 8K.
229 1.6 cgd */
230 1.6 cgd if (stdbuf == NULL) {
231 1.6 cgd if ((len = LINES * COLS * 2) > 8192)
232 1.6 cgd len = 8192;
233 1.6 cgd if ((stdbuf = malloc(len)) == NULL)
234 1.6 cgd len = 0;
235 1.6 cgd }
236 1.6 cgd (void)setvbuf(stdout, stdbuf, _IOFBF, len);
237 1.2 cgd
238 1.2 cgd tputs(TI, 0, __cputchar);
239 1.2 cgd tputs(VS, 0, __cputchar);
240 1.1 mycroft }
241 1.1 mycroft
242 1.1 mycroft int
243 1.1 mycroft endwin()
244 1.1 mycroft {
245 1.2 cgd __restore_stophandler();
246 1.2 cgd
247 1.2 cgd if (curscr != NULL) {
248 1.2 cgd if (curscr->flags & __WSTANDOUT) {
249 1.1 mycroft tputs(SE, 0, __cputchar);
250 1.2 cgd curscr->flags &= ~__WSTANDOUT;
251 1.1 mycroft }
252 1.2 cgd __mvcur(curscr->cury, curscr->cury, curscr->maxy - 1, 0, 0);
253 1.1 mycroft }
254 1.1 mycroft
255 1.1 mycroft (void)tputs(VE, 0, __cputchar);
256 1.1 mycroft (void)tputs(TE, 0, __cputchar);
257 1.1 mycroft (void)fflush(stdout);
258 1.2 cgd (void)setvbuf(stdout, NULL, _IOLBF, 0);
259 1.1 mycroft
260 1.2 cgd return (tcsetattr(STDIN_FILENO, __tcaction ?
261 1.5 mycroft TCSASOFT | TCSADRAIN : TCSADRAIN, &__orig_termios) ? ERR : OK);
262 1.1 mycroft }
263 1.1 mycroft
264 1.1 mycroft /*
265 1.1 mycroft * The following routines, savetty and resetty are completely useless and
266 1.1 mycroft * are left in only as stubs. If people actually use them they will almost
267 1.1 mycroft * certainly screw up the state of the world.
268 1.1 mycroft */
269 1.1 mycroft static struct termios savedtty;
270 1.1 mycroft int
271 1.1 mycroft savetty()
272 1.1 mycroft {
273 1.6 cgd return (tcgetattr(STDIN_FILENO, &savedtty) ? ERR : OK);
274 1.1 mycroft }
275 1.1 mycroft
276 1.1 mycroft int
277 1.1 mycroft resetty()
278 1.1 mycroft {
279 1.2 cgd return (tcsetattr(STDIN_FILENO, __tcaction ?
280 1.6 cgd TCSASOFT | TCSADRAIN : TCSADRAIN, &savedtty) ? ERR : OK);
281 1.1 mycroft }
282