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
NCURSES_EXPORT(int)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)
raw(void)129 raw(void)
130 {
131 return NCURSES_SP_NAME(raw) (CURRENT_SCREEN);
132 }
133 #endif
134
135 NCURSES_EXPORT(int)
NCURSES_SP_NAME(cbreak)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)
cbreak(void)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)
NCURSES_SP_NAME(qiflush)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)
qiflush(void)210 qiflush(void)
211 {
212 NCURSES_SP_NAME(qiflush) (CURRENT_SCREEN);
213 }
214 #endif
215
216 NCURSES_EXPORT(int)
NCURSES_SP_NAME(noraw)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)
noraw(void)263 noraw(void)
264 {
265 return NCURSES_SP_NAME(noraw) (CURRENT_SCREEN);
266 }
267 #endif
268
269 NCURSES_EXPORT(int)
NCURSES_SP_NAME(nocbreak)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)
nocbreak(void)303 nocbreak(void)
304 {
305 return NCURSES_SP_NAME(nocbreak) (CURRENT_SCREEN);
306 }
307 #endif
308
309 NCURSES_EXPORT(void)
NCURSES_SP_NAME(noqiflush)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)
noqiflush(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)
NCURSES_SP_NAME(intrflush)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)
intrflush(WINDOW * win GCC_UNUSED,bool flag)384 intrflush(WINDOW *win GCC_UNUSED, bool flag)
385 {
386 return NCURSES_SP_NAME(intrflush) (CURRENT_SCREEN, win, flag);
387 }
388 #endif
389