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