150276Speter/****************************************************************************
2174998Srafan * Copyright (c) 1998-2002,2007 Free Software Foundation, Inc.              *
350276Speter *                                                                          *
450276Speter * Permission is hereby granted, free of charge, to any person obtaining a  *
550276Speter * copy of this software and associated documentation files (the            *
650276Speter * "Software"), to deal in the Software without restriction, including      *
750276Speter * without limitation the rights to use, copy, modify, merge, publish,      *
850276Speter * distribute, distribute with modifications, sublicense, and/or sell       *
950276Speter * copies of the Software, and to permit persons to whom the Software is    *
1050276Speter * furnished to do so, subject to the following conditions:                 *
1150276Speter *                                                                          *
1250276Speter * The above copyright notice and this permission notice shall be included  *
1350276Speter * in all copies or substantial portions of the Software.                   *
1450276Speter *                                                                          *
1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2250276Speter *                                                                          *
2350276Speter * Except as contained in this notice, the name(s) of the above copyright   *
2450276Speter * holders shall not be used in advertising or otherwise to promote the     *
2550276Speter * sale, use or other dealings in this Software without prior written       *
2650276Speter * authorization.                                                           *
2750276Speter ****************************************************************************/
2850276Speter
2950276Speter/****************************************************************************
3050276Speter *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
3150276Speter *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
32166128Srafan *     and: Thomas E. Dickey 1998 on                                        *
3350276Speter ****************************************************************************/
3450276Speter
3550276Speter/*
3650276Speter *	raw.c
3750276Speter *
3850276Speter *	Routines:
3950276Speter *		raw()
4050276Speter *		cbreak()
4150276Speter *		noraw()
4250276Speter *		nocbreak()
4350276Speter *		qiflush()
4450276Speter *		noqiflush()
4550276Speter *		intrflush()
4650276Speter *
4750276Speter */
4850276Speter
4950276Speter#include <curses.priv.h>
5062452Speter#include <term.h>		/* cur_term */
5150276Speter
52174998SrafanMODULE_ID("$Id: lib_raw.c,v 1.14 2007/09/29 21:50:22 tom Exp $")
5350276Speter
5466967Speter#if SVR4_TERMIO && !defined(_POSIX_SOURCE)
5550276Speter#define _POSIX_SOURCE
5650276Speter#endif
5750276Speter
5850276Speter#if HAVE_SYS_TERMIO_H
5962452Speter#include <sys/termio.h>		/* needed for ISC */
6050276Speter#endif
6150276Speter
6250276Speter#ifdef __EMX__
6350276Speter#include <io.h>
64166128Srafan#define _nc_setmode(mode) setmode(SP->_ifd, mode)
65166128Srafan#else
66166128Srafan#define _nc_setmode(mode)	/* nothing */
6750276Speter#endif
6850276Speter
6950276Speter#define COOKED_INPUT	(IXON|BRKINT|PARMRK)
7050276Speter
7150276Speter#ifdef TRACE
72174998Srafan#define BEFORE(N)	if (USE_TRACEF(TRACE_BITS)) _nc_locked_tracef("%s before bits: %s", N, _nc_tracebits())
73174998Srafan#define AFTER(N)	if (USE_TRACEF(TRACE_BITS)) _nc_locked_tracef("%s after bits: %s", N, _nc_tracebits())
7450276Speter#else
7550276Speter#define BEFORE(s)
7650276Speter#define AFTER(s)
7750276Speter#endif /* TRACE */
7850276Speter
7976730SpeterNCURSES_EXPORT(int)
8062452Speterraw(void)
8150276Speter{
82166128Srafan    int result = ERR;
83166128Srafan
8462452Speter    T((T_CALLED("raw()")));
85166128Srafan
8662452Speter    if (SP != 0 && cur_term != 0) {
87166128Srafan	TTY buf;
8850276Speter
89166128Srafan	BEFORE("raw");
90166128Srafan	_nc_setmode(O_BINARY);
9150276Speter
92166128Srafan	buf = cur_term->Nttyb;
9350276Speter#ifdef TERMIOS
94166128Srafan	buf.c_lflag &= ~(ICANON | ISIG | IEXTEN);
95166128Srafan	buf.c_iflag &= ~(COOKED_INPUT);
96166128Srafan	buf.c_cc[VMIN] = 1;
97166128Srafan	buf.c_cc[VTIME] = 0;
9850276Speter#else
99166128Srafan	buf.sg_flags |= RAW;
10050276Speter#endif
101166128Srafan	if ((result = _nc_set_tty_mode(&buf)) == OK) {
102166128Srafan	    SP->_raw = TRUE;
103166128Srafan	    SP->_cbreak = 1;
104166128Srafan	    cur_term->Nttyb = buf;
105166128Srafan	}
106166128Srafan	AFTER("raw");
10762452Speter    }
108166128Srafan    returnCode(result);
10950276Speter}
11050276Speter
11176730SpeterNCURSES_EXPORT(int)
11262452Spetercbreak(void)
11350276Speter{
114166128Srafan    int result = ERR;
115166128Srafan
11662452Speter    T((T_CALLED("cbreak()")));
11750276Speter
118166128Srafan    if (SP != 0 && cur_term != 0) {
119166128Srafan	TTY buf;
12050276Speter
121166128Srafan	BEFORE("cbreak");
122166128Srafan	_nc_setmode(O_BINARY);
12350276Speter
124166128Srafan	buf = cur_term->Nttyb;
12550276Speter#ifdef TERMIOS
126166128Srafan	buf.c_lflag &= ~ICANON;
127166128Srafan	buf.c_iflag &= ~ICRNL;
128166128Srafan	buf.c_lflag |= ISIG;
129166128Srafan	buf.c_cc[VMIN] = 1;
130166128Srafan	buf.c_cc[VTIME] = 0;
13150276Speter#else
132166128Srafan	buf.sg_flags |= CBREAK;
13350276Speter#endif
134166128Srafan	if ((result = _nc_set_tty_mode(&buf)) == OK) {
135166128Srafan	    SP->_cbreak = 1;
136166128Srafan	    cur_term->Nttyb = buf;
137166128Srafan	}
138166128Srafan	AFTER("cbreak");
139166128Srafan    }
140166128Srafan    returnCode(result);
14150276Speter}
14250276Speter
143166128Srafan/*
144166128Srafan * Note:
145166128Srafan * this implementation may be wrong.  See the comment under intrflush().
146166128Srafan */
14776730SpeterNCURSES_EXPORT(void)
14862452Speterqiflush(void)
14950276Speter{
150166128Srafan    int result = ERR;
151166128Srafan
15262452Speter    T((T_CALLED("qiflush()")));
15350276Speter
154166128Srafan    if (cur_term != 0) {
155166128Srafan	TTY buf;
15650276Speter
157166128Srafan	BEFORE("qiflush");
158166128Srafan	buf = cur_term->Nttyb;
15950276Speter#ifdef TERMIOS
160166128Srafan	buf.c_lflag &= ~(NOFLSH);
161166128Srafan	result = _nc_set_tty_mode(&buf);
162166128Srafan#else
163166128Srafan	/* FIXME */
16497052Speter#endif
165166128Srafan	if (result == OK)
166166128Srafan	    cur_term->Nttyb = buf;
167166128Srafan	AFTER("qiflush");
168166128Srafan    }
16962452Speter    returnVoid;
17050276Speter}
17150276Speter
17276730SpeterNCURSES_EXPORT(int)
17362452Speternoraw(void)
17450276Speter{
175166128Srafan    int result = ERR;
176166128Srafan
17762452Speter    T((T_CALLED("noraw()")));
17850276Speter
179166128Srafan    if (SP != 0 && cur_term != 0) {
180166128Srafan	TTY buf;
18150276Speter
182166128Srafan	BEFORE("noraw");
183166128Srafan	_nc_setmode(O_TEXT);
18450276Speter
185166128Srafan	buf = cur_term->Nttyb;
18650276Speter#ifdef TERMIOS
187166128Srafan	buf.c_lflag |= ISIG | ICANON |
188166128Srafan	    (cur_term->Ottyb.c_lflag & IEXTEN);
189166128Srafan	buf.c_iflag |= COOKED_INPUT;
19050276Speter#else
191166128Srafan	buf.sg_flags &= ~(RAW | CBREAK);
19250276Speter#endif
193166128Srafan	if ((result = _nc_set_tty_mode(&buf)) == OK) {
194166128Srafan	    SP->_raw = FALSE;
195166128Srafan	    SP->_cbreak = 0;
196166128Srafan	    cur_term->Nttyb = buf;
197166128Srafan	}
198166128Srafan	AFTER("noraw");
199166128Srafan    }
200166128Srafan    returnCode(result);
20150276Speter}
20250276Speter
20376730SpeterNCURSES_EXPORT(int)
20462452Speternocbreak(void)
20550276Speter{
206166128Srafan    int result = ERR;
207166128Srafan
20862452Speter    T((T_CALLED("nocbreak()")));
20950276Speter
210166128Srafan    if (SP != 0 && cur_term != 0) {
211166128Srafan	TTY buf;
21250276Speter
213166128Srafan	BEFORE("nocbreak");
214166128Srafan	_nc_setmode(O_TEXT);
21550276Speter
216166128Srafan	buf = cur_term->Nttyb;
21750276Speter#ifdef TERMIOS
218166128Srafan	buf.c_lflag |= ICANON;
219166128Srafan	buf.c_iflag |= ICRNL;
22050276Speter#else
221166128Srafan	buf.sg_flags &= ~CBREAK;
22250276Speter#endif
223166128Srafan	if ((result = _nc_set_tty_mode(&buf)) == OK) {
224166128Srafan	    SP->_cbreak = 0;
225166128Srafan	    cur_term->Nttyb = buf;
226166128Srafan	}
227166128Srafan	AFTER("nocbreak");
228166128Srafan    }
229166128Srafan    returnCode(result);
23050276Speter}
23150276Speter
232166128Srafan/*
233166128Srafan * Note:
234166128Srafan * this implementation may be wrong.  See the comment under intrflush().
235166128Srafan */
23676730SpeterNCURSES_EXPORT(void)
23762452Speternoqiflush(void)
23850276Speter{
239166128Srafan    int result = ERR;
240166128Srafan
24162452Speter    T((T_CALLED("noqiflush()")));
24250276Speter
243166128Srafan    if (cur_term != 0) {
244166128Srafan	TTY buf;
24550276Speter
246166128Srafan	BEFORE("noqiflush");
247166128Srafan	buf = cur_term->Nttyb;
24850276Speter#ifdef TERMIOS
249166128Srafan	buf.c_lflag |= NOFLSH;
250166128Srafan	result = _nc_set_tty_mode(&buf);
251166128Srafan#else
252166128Srafan	/* FIXME */
25397052Speter#endif
254166128Srafan	if (result == OK) {
255166128Srafan	    cur_term->Nttyb = buf;
256166128Srafan	}
257166128Srafan	AFTER("noqiflush");
258166128Srafan    }
25962452Speter    returnVoid;
26050276Speter}
26150276Speter
262166128Srafan/*
263166128Srafan * This call does the same thing as the qiflush()/noqiflush() pair.  We know
264166128Srafan * for certain that SVr3 intrflush() tweaks the NOFLSH bit; on the other hand,
265166128Srafan * the match (in the SVr4 man pages) between the language describing NOFLSH in
266166128Srafan * termio(7) and the language describing qiflush()/noqiflush() in
267166128Srafan * curs_inopts(3x) is too exact to be coincidence.
268166128Srafan */
26976730SpeterNCURSES_EXPORT(int)
27062452Speterintrflush(WINDOW *win GCC_UNUSED, bool flag)
27150276Speter{
272166128Srafan    int result = ERR;
273166128Srafan
27462452Speter    T((T_CALLED("intrflush(%d)"), flag));
27550276Speter
276166128Srafan    if (cur_term != 0) {
277166128Srafan	TTY buf;
27850276Speter
279166128Srafan	BEFORE("intrflush");
280166128Srafan	buf = cur_term->Nttyb;
28150276Speter#ifdef TERMIOS
282166128Srafan	if (flag)
283166128Srafan	    buf.c_lflag &= ~(NOFLSH);
284166128Srafan	else
285166128Srafan	    buf.c_lflag |= (NOFLSH);
286166128Srafan	result = _nc_set_tty_mode(&buf);
28750276Speter#else
288166128Srafan	/* FIXME */
28950276Speter#endif
290166128Srafan	if (result == OK) {
291166128Srafan	    cur_term->Nttyb = buf;
292166128Srafan	}
293166128Srafan	AFTER("intrflush");
294166128Srafan    }
295166128Srafan    returnCode(result);
29650276Speter}
297