1 /****************************************************************************
2  * Copyright (c) 1998-2002,2007 Free Software Foundation, Inc.              *
3  *                                                                          *
4  * Permission is hereby granted, free of charge, to any person obtaining a  *
5  * copy of this software and associated documentation files (the            *
6  * "Software"), to deal in the Software without restriction, including      *
7  * without limitation the rights to use, copy, modify, merge, publish,      *
8  * distribute, distribute with modifications, sublicense, and/or sell       *
9  * copies of the Software, and to permit persons to whom the Software is    *
10  * furnished to do so, subject to the following conditions:                 *
11  *                                                                          *
12  * The above copyright notice and this permission notice shall be included  *
13  * in all copies or substantial portions of the Software.                   *
14  *                                                                          *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22  *                                                                          *
23  * Except as contained in this notice, the name(s) of the above copyright   *
24  * holders shall not be used in advertising or otherwise to promote the     *
25  * sale, use or other dealings in this Software without prior written       *
26  * authorization.                                                           *
27  ****************************************************************************/
28 
29 /****************************************************************************
30  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
31  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
32  *     and: Thomas E. Dickey 1998 on                                        *
33  ****************************************************************************/
34 
35 /*
36  *	raw.c
37  *
38  *	Routines:
39  *		raw()
40  *		cbreak()
41  *		noraw()
42  *		nocbreak()
43  *		qiflush()
44  *		noqiflush()
45  *		intrflush()
46  *
47  */
48 
49 #include <curses.priv.h>
50 #include <term.h>		/* cur_term */
51 
52 MODULE_ID("$Id: lib_raw.c,v 1.14 2007/09/29 21:50:22 tom Exp $")
53 
54 #if SVR4_TERMIO && !defined(_POSIX_SOURCE)
55 #define _POSIX_SOURCE
56 #endif
57 
58 #if HAVE_SYS_TERMIO_H
59 #include <sys/termio.h>		/* needed for ISC */
60 #endif
61 
62 #ifdef __EMX__
63 #include <io.h>
64 #define _nc_setmode(mode) setmode(SP->_ifd, mode)
65 #else
66 #define _nc_setmode(mode)	/* nothing */
67 #endif
68 
69 #define COOKED_INPUT	(IXON|BRKINT|PARMRK)
70 
71 #ifdef TRACE
72 #define BEFORE(N)	if (USE_TRACEF(TRACE_BITS)) _nc_locked_tracef("%s before bits: %s", N, _nc_tracebits())
73 #define AFTER(N)	if (USE_TRACEF(TRACE_BITS)) _nc_locked_tracef("%s after bits: %s", N, _nc_tracebits())
74 #else
75 #define BEFORE(s)
76 #define AFTER(s)
77 #endif /* TRACE */
78 
79 NCURSES_EXPORT(int)
80 raw(void)
81 {
82     int result = ERR;
83 
84     T((T_CALLED("raw()")));
85 
86     if (SP != 0 && cur_term != 0) {
87 	TTY buf;
88 
89 	BEFORE("raw");
90 	_nc_setmode(O_BINARY);
91 
92 	buf = cur_term->Nttyb;
93 #ifdef TERMIOS
94 	buf.c_lflag &= ~(ICANON | ISIG | IEXTEN);
95 	buf.c_iflag &= ~(COOKED_INPUT);
96 	buf.c_cc[VMIN] = 1;
97 	buf.c_cc[VTIME] = 0;
98 #else
99 	buf.sg_flags |= RAW;
100 #endif
101 	if ((result = _nc_set_tty_mode(&buf)) == OK) {
102 	    SP->_raw = TRUE;
103 	    SP->_cbreak = 1;
104 	    cur_term->Nttyb = buf;
105 	}
106 	AFTER("raw");
107     }
108     returnCode(result);
109 }
110 
111 NCURSES_EXPORT(int)
112 cbreak(void)
113 {
114     int result = ERR;
115 
116     T((T_CALLED("cbreak()")));
117 
118     if (SP != 0 && cur_term != 0) {
119 	TTY buf;
120 
121 	BEFORE("cbreak");
122 	_nc_setmode(O_BINARY);
123 
124 	buf = cur_term->Nttyb;
125 #ifdef TERMIOS
126 	buf.c_lflag &= ~ICANON;
127 	buf.c_iflag &= ~ICRNL;
128 	buf.c_lflag |= ISIG;
129 	buf.c_cc[VMIN] = 1;
130 	buf.c_cc[VTIME] = 0;
131 #else
132 	buf.sg_flags |= CBREAK;
133 #endif
134 	if ((result = _nc_set_tty_mode(&buf)) == OK) {
135 	    SP->_cbreak = 1;
136 	    cur_term->Nttyb = buf;
137 	}
138 	AFTER("cbreak");
139     }
140     returnCode(result);
141 }
142 
143 /*
144  * Note:
145  * this implementation may be wrong.  See the comment under intrflush().
146  */
147 NCURSES_EXPORT(void)
148 qiflush(void)
149 {
150     int result = ERR;
151 
152     T((T_CALLED("qiflush()")));
153 
154     if (cur_term != 0) {
155 	TTY buf;
156 
157 	BEFORE("qiflush");
158 	buf = cur_term->Nttyb;
159 #ifdef TERMIOS
160 	buf.c_lflag &= ~(NOFLSH);
161 	result = _nc_set_tty_mode(&buf);
162 #else
163 	/* FIXME */
164 #endif
165 	if (result == OK)
166 	    cur_term->Nttyb = buf;
167 	AFTER("qiflush");
168     }
169     returnVoid;
170 }
171 
172 NCURSES_EXPORT(int)
173 noraw(void)
174 {
175     int result = ERR;
176 
177     T((T_CALLED("noraw()")));
178 
179     if (SP != 0 && cur_term != 0) {
180 	TTY buf;
181 
182 	BEFORE("noraw");
183 	_nc_setmode(O_TEXT);
184 
185 	buf = cur_term->Nttyb;
186 #ifdef TERMIOS
187 	buf.c_lflag |= ISIG | ICANON |
188 	    (cur_term->Ottyb.c_lflag & IEXTEN);
189 	buf.c_iflag |= COOKED_INPUT;
190 #else
191 	buf.sg_flags &= ~(RAW | CBREAK);
192 #endif
193 	if ((result = _nc_set_tty_mode(&buf)) == OK) {
194 	    SP->_raw = FALSE;
195 	    SP->_cbreak = 0;
196 	    cur_term->Nttyb = buf;
197 	}
198 	AFTER("noraw");
199     }
200     returnCode(result);
201 }
202 
203 NCURSES_EXPORT(int)
204 nocbreak(void)
205 {
206     int result = ERR;
207 
208     T((T_CALLED("nocbreak()")));
209 
210     if (SP != 0 && cur_term != 0) {
211 	TTY buf;
212 
213 	BEFORE("nocbreak");
214 	_nc_setmode(O_TEXT);
215 
216 	buf = cur_term->Nttyb;
217 #ifdef TERMIOS
218 	buf.c_lflag |= ICANON;
219 	buf.c_iflag |= ICRNL;
220 #else
221 	buf.sg_flags &= ~CBREAK;
222 #endif
223 	if ((result = _nc_set_tty_mode(&buf)) == OK) {
224 	    SP->_cbreak = 0;
225 	    cur_term->Nttyb = buf;
226 	}
227 	AFTER("nocbreak");
228     }
229     returnCode(result);
230 }
231 
232 /*
233  * Note:
234  * this implementation may be wrong.  See the comment under intrflush().
235  */
236 NCURSES_EXPORT(void)
237 noqiflush(void)
238 {
239     int result = ERR;
240 
241     T((T_CALLED("noqiflush()")));
242 
243     if (cur_term != 0) {
244 	TTY buf;
245 
246 	BEFORE("noqiflush");
247 	buf = cur_term->Nttyb;
248 #ifdef TERMIOS
249 	buf.c_lflag |= NOFLSH;
250 	result = _nc_set_tty_mode(&buf);
251 #else
252 	/* FIXME */
253 #endif
254 	if (result == OK) {
255 	    cur_term->Nttyb = buf;
256 	}
257 	AFTER("noqiflush");
258     }
259     returnVoid;
260 }
261 
262 /*
263  * This call does the same thing as the qiflush()/noqiflush() pair.  We know
264  * for certain that SVr3 intrflush() tweaks the NOFLSH bit; on the other hand,
265  * the match (in the SVr4 man pages) between the language describing NOFLSH in
266  * termio(7) and the language describing qiflush()/noqiflush() in
267  * curs_inopts(3x) is too exact to be coincidence.
268  */
269 NCURSES_EXPORT(int)
270 intrflush(WINDOW *win GCC_UNUSED, bool flag)
271 {
272     int result = ERR;
273 
274     T((T_CALLED("intrflush(%d)"), flag));
275 
276     if (cur_term != 0) {
277 	TTY buf;
278 
279 	BEFORE("intrflush");
280 	buf = cur_term->Nttyb;
281 #ifdef TERMIOS
282 	if (flag)
283 	    buf.c_lflag &= ~(NOFLSH);
284 	else
285 	    buf.c_lflag |= (NOFLSH);
286 	result = _nc_set_tty_mode(&buf);
287 #else
288 	/* FIXME */
289 #endif
290 	if (result == OK) {
291 	    cur_term->Nttyb = buf;
292 	}
293 	AFTER("intrflush");
294     }
295     returnCode(result);
296 }
297