ncurses 5.7 - patch 20090801
[ncurses.git] / ncurses / tinfo / lib_raw.c
1 /****************************************************************************
2  * Copyright (c) 1998-2008,2009 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  *     and: Juergen Pfeifer                         2009                    *
34  ****************************************************************************/
35
36 /*
37  *      raw.c
38  *
39  *      Routines:
40  *              raw()
41  *              cbreak()
42  *              noraw()
43  *              nocbreak()
44  *              qiflush()
45  *              noqiflush()
46  *              intrflush()
47  *
48  */
49
50 #include <curses.priv.h>
51
52 MODULE_ID("$Id: lib_raw.c,v 1.17 2009/08/01 23:11:02 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_PARM->_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 NCURSES_SP_NAME(raw) (NCURSES_SP_DCL0)
81 {
82     int result = ERR;
83     TERMINAL *termp;
84
85     T((T_CALLED("raw(%p)"), SP_PARM));
86     if ((termp = TerminalOf(SP_PARM)) != 0) {
87         TTY buf;
88
89         BEFORE("raw");
90         _nc_setmode(O_BINARY);
91
92         buf = termp->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         result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
102         if (result == OK) {
103             SP_PARM->_raw = TRUE;
104             SP_PARM->_cbreak = 1;
105             termp->Nttyb = buf;
106         }
107         AFTER("raw");
108     }
109     returnCode(result);
110 }
111
112 #if NCURSES_SP_FUNCS
113 NCURSES_EXPORT(int)
114 raw(void)
115 {
116     return NCURSES_SP_NAME(raw) (CURRENT_SCREEN);
117 }
118 #endif
119
120 NCURSES_EXPORT(int)
121 NCURSES_SP_NAME(cbreak) (NCURSES_SP_DCL0)
122 {
123     int result = ERR;
124     TERMINAL *termp;
125
126     T((T_CALLED("cbreak(%p)"), SP_PARM));
127     if ((termp = TerminalOf(SP_PARM)) != 0) {
128         TTY buf;
129
130         BEFORE("cbreak");
131         _nc_setmode(O_BINARY);
132
133         buf = termp->Nttyb;
134 #ifdef TERMIOS
135         buf.c_lflag &= ~ICANON;
136         buf.c_iflag &= ~ICRNL;
137         buf.c_lflag |= ISIG;
138         buf.c_cc[VMIN] = 1;
139         buf.c_cc[VTIME] = 0;
140 #else
141         buf.sg_flags |= CBREAK;
142 #endif
143         result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
144         if (result == OK) {
145             SP_PARM->_cbreak = 1;
146             termp->Nttyb = buf;
147         }
148         AFTER("cbreak");
149     }
150     returnCode(result);
151 }
152
153 #if NCURSES_SP_FUNCS
154 NCURSES_EXPORT(int)
155 cbreak(void)
156 {
157     return NCURSES_SP_NAME(cbreak) (CURRENT_SCREEN);
158 }
159 #endif
160
161 /*
162  * Note:
163  * this implementation may be wrong.  See the comment under intrflush().
164  */
165 NCURSES_EXPORT(void)
166 NCURSES_SP_NAME(qiflush) (NCURSES_SP_DCL0)
167 {
168     int result = ERR;
169     TERMINAL *termp;
170
171     T((T_CALLED("qiflush(%p)"), SP_PARM));
172     if ((termp = TerminalOf(SP_PARM)) != 0) {
173         TTY buf;
174
175         BEFORE("qiflush");
176         buf = termp->Nttyb;
177 #ifdef TERMIOS
178         buf.c_lflag &= ~(NOFLSH);
179         result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
180 #else
181         /* FIXME */
182 #endif
183         if (result == OK)
184             termp->Nttyb = buf;
185         AFTER("qiflush");
186     }
187     returnVoid;
188 }
189
190 #if NCURSES_SP_FUNCS
191 NCURSES_EXPORT(void)
192 qiflush(void)
193 {
194     NCURSES_SP_NAME(qiflush) (CURRENT_SCREEN);
195 }
196 #endif
197
198 NCURSES_EXPORT(int)
199 NCURSES_SP_NAME(noraw) (NCURSES_SP_DCL0)
200 {
201     int result = ERR;
202     TERMINAL *termp;
203
204     T((T_CALLED("noraw(%p)"), SP_PARM));
205     if ((termp = TerminalOf(SP_PARM)) != 0) {
206         TTY buf;
207
208         BEFORE("noraw");
209         _nc_setmode(O_TEXT);
210
211         buf = termp->Nttyb;
212 #ifdef TERMIOS
213         buf.c_lflag |= ISIG | ICANON |
214             (termp->Ottyb.c_lflag & IEXTEN);
215         buf.c_iflag |= COOKED_INPUT;
216 #else
217         buf.sg_flags &= ~(RAW | CBREAK);
218 #endif
219         result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
220         if (result == OK) {
221             SP_PARM->_raw = FALSE;
222             SP_PARM->_cbreak = 0;
223             termp->Nttyb = buf;
224         }
225         AFTER("noraw");
226     }
227     returnCode(result);
228 }
229
230 #if NCURSES_SP_FUNCS
231 NCURSES_EXPORT(int)
232 noraw(void)
233 {
234     return NCURSES_SP_NAME(noraw) (CURRENT_SCREEN);
235 }
236 #endif
237
238 NCURSES_EXPORT(int)
239 NCURSES_SP_NAME(nocbreak) (NCURSES_SP_DCL0)
240 {
241     int result = ERR;
242     TERMINAL *termp;
243
244     T((T_CALLED("nocbreak(%p)"), SP_PARM));
245     if ((termp = TerminalOf(SP_PARM)) != 0) {
246         TTY buf;
247
248         BEFORE("nocbreak");
249         _nc_setmode(O_TEXT);
250
251         buf = termp->Nttyb;
252 #ifdef TERMIOS
253         buf.c_lflag |= ICANON;
254         buf.c_iflag |= ICRNL;
255 #else
256         buf.sg_flags &= ~CBREAK;
257 #endif
258         result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
259         if (result == OK) {
260             SP_PARM->_cbreak = 0;
261             termp->Nttyb = buf;
262         }
263         AFTER("nocbreak");
264     }
265     returnCode(result);
266 }
267
268 #if NCURSES_SP_FUNCS
269 NCURSES_EXPORT(int)
270 nocbreak(void)
271 {
272     return NCURSES_SP_NAME(nocbreak) (CURRENT_SCREEN);
273 }
274 #endif
275
276 NCURSES_EXPORT(void)
277 NCURSES_SP_NAME(noqiflush) (NCURSES_SP_DCL0)
278 {
279     int result = ERR;
280     TERMINAL *termp;
281
282     T((T_CALLED("noqiflush(%p)"), SP_PARM));
283     if ((termp = TerminalOf(SP_PARM)) != 0) {
284         TTY buf;
285
286         BEFORE("noqiflush");
287         buf = termp->Nttyb;
288 #ifdef TERMIOS
289         buf.c_lflag |= NOFLSH;
290         result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
291 #else
292         /* FIXME */
293 #endif
294         if (result == OK)
295             termp->Nttyb = buf;
296         AFTER("noqiflush");
297     }
298     returnVoid;
299 }
300
301 #if NCURSES_SP_FUNCS
302 NCURSES_EXPORT(void)
303 noqiflush(void)
304 {
305     NCURSES_SP_NAME(noqiflush) (CURRENT_SCREEN);
306 }
307 #endif
308
309 /*
310  * This call does the same thing as the qiflush()/noqiflush() pair.  We know
311  * for certain that SVr3 intrflush() tweaks the NOFLSH bit; on the other hand,
312  * the match (in the SVr4 man pages) between the language describing NOFLSH in
313  * termio(7) and the language describing qiflush()/noqiflush() in
314  * curs_inopts(3x) is too exact to be coincidence.
315  */
316 NCURSES_EXPORT(int)
317 NCURSES_SP_NAME(intrflush) (NCURSES_SP_DCLx WINDOW *win GCC_UNUSED, bool flag)
318 {
319     int result = ERR;
320     TERMINAL *termp;
321
322     T((T_CALLED("intrflush(%p,%d)"), SP_PARM, flag));
323     if (SP_PARM == 0)
324         returnCode(ERR);
325
326     if ((termp = TerminalOf(SP_PARM)) != 0) {
327         TTY buf;
328
329         BEFORE("intrflush");
330         buf = termp->Nttyb;
331 #ifdef TERMIOS
332         if (flag)
333             buf.c_lflag &= ~(NOFLSH);
334         else
335             buf.c_lflag |= (NOFLSH);
336         result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
337 #else
338         /* FIXME */
339 #endif
340         if (result == OK) {
341             termp->Nttyb = buf;
342         }
343         AFTER("intrflush");
344     }
345     returnCode(result);
346 }
347
348 #if NCURSES_SP_FUNCS
349 NCURSES_EXPORT(int)
350 intrflush(WINDOW *win GCC_UNUSED, bool flag)
351 {
352     return NCURSES_SP_NAME(intrflush) (CURRENT_SCREEN, win, flag);
353 }
354 #endif