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