xref: /freebsd/contrib/ncurses/ncurses/tinfo/lib_raw.c (revision 68ad2b0d7af2a3571c4abac9afa712f9b09b721c)
1 /****************************************************************************
2  * Copyright 2020-2024,2025 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.35 2025/12/23 09:22:35 tom Exp $")
54 
55 #if HAVE_SYS_TERMIO_H
56 #include <sys/termio.h>		/* needed for ISC */
57 #endif
58 
59 #ifdef __EMX__
60 #define _nc_setmode(mode) setmode(SP_PARM->_ifd, mode)
61 #else
62 #define _nc_setmode(mode)	/* nothing */
63 #endif
64 
65 #if USE_KLIBC_KBD
66 #define INCL_KBD
67 #include <os2.h>
68 #endif
69 
70 #define COOKED_INPUT	(IXON|BRKINT|PARMRK)
71 
72 #ifdef TRACE
73 #define BEFORE(N)	if (USE_TRACEF(TRACE_BITS)) _nc_locked_tracef("%s before bits: %s", N, _nc_tracebits())
74 #define AFTER(N)	if (USE_TRACEF(TRACE_BITS)) _nc_locked_tracef("%s after bits: %s", N, _nc_tracebits())
75 #else
76 #define BEFORE(s)
77 #define AFTER(s)
78 #endif /* TRACE */
79 
NCURSES_EXPORT(int)80 NCURSES_EXPORT(int)
81 NCURSES_SP_NAME(raw) (NCURSES_SP_DCL0)
82 {
83     int result = ERR;
84     TERMINAL *termp;
85 
86     T((T_CALLED("raw(%p)"), (void *) SP_PARM));
87     if ((termp = TerminalOf(SP_PARM)) != NULL) {
88 	TTY buf;
89 
90 	BEFORE("raw");
91 	_nc_setmode(O_BINARY);
92 
93 	buf = termp->Nttyb;
94 #ifdef TERMIOS
95 	buf.c_lflag &= (unsigned) ~(ICANON | ISIG | IEXTEN);
96 	buf.c_iflag &= (unsigned) ~(COOKED_INPUT);
97 	buf.c_cc[VMIN] = 1;
98 	buf.c_cc[VTIME] = 0;
99 #elif defined(USE_WIN32CON_DRIVER)
100 	buf.dwFlagIn &= (unsigned long) ~CONMODE_NORAW;
101 #else
102 	buf.sg_flags |= RAW;
103 #endif
104 	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
105 	if (result == OK) {
106 #if USE_KLIBC_KBD
107 	    KBDINFO kbdinfo;
108 
109 	    kbdinfo.cb = sizeof(kbdinfo);
110 	    KbdGetStatus(&kbdinfo, 0);
111 
112 	    kbdinfo.cb = sizeof(kbdinfo);
113 	    kbdinfo.fsMask &= ~KEYBOARD_ASCII_MODE;
114 	    kbdinfo.fsMask |= KEYBOARD_BINARY_MODE;
115 	    KbdSetStatus(&kbdinfo, 0);
116 #endif
117 	    if (SP_PARM) {
118 		IsRaw(SP_PARM) = TRUE;
119 		IsCbreak(SP_PARM) = 1;
120 	    }
121 	    termp->Nttyb = buf;
122 	}
123 	AFTER("raw");
124     }
125     returnCode(result);
126 }
127 
128 #if NCURSES_SP_FUNCS
129 NCURSES_EXPORT(int)
raw(void)130 raw(void)
131 {
132     return NCURSES_SP_NAME(raw) (CURRENT_SCREEN);
133 }
134 #endif
135 
136 NCURSES_EXPORT(int)
NCURSES_SP_NAME(cbreak)137 NCURSES_SP_NAME(cbreak) (NCURSES_SP_DCL0)
138 {
139     int result = ERR;
140     TERMINAL *termp;
141 
142     T((T_CALLED("cbreak(%p)"), (void *) SP_PARM));
143     if ((termp = TerminalOf(SP_PARM)) != NULL) {
144 	TTY buf;
145 
146 	BEFORE("cbreak");
147 	_nc_setmode(O_BINARY);
148 
149 	buf = termp->Nttyb;
150 #ifdef TERMIOS
151 	buf.c_lflag &= (unsigned) ~ICANON;
152 	buf.c_iflag &= (unsigned) ~ICRNL;
153 	buf.c_cc[VMIN] = 1;
154 	buf.c_cc[VTIME] = 0;
155 #elif defined(USE_WIN32CON_DRIVER)
156 	buf.dwFlagIn |= CONMODE_NORAW;
157 	buf.dwFlagIn &= (unsigned long) ~CONMODE_NOCBREAK;
158 #else
159 	buf.sg_flags |= CBREAK;
160 #endif
161 	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
162 	if (result == OK) {
163 	    if (SP_PARM) {
164 		IsCbreak(SP_PARM) = 1;
165 	    }
166 	    termp->Nttyb = buf;
167 	}
168 	AFTER("cbreak");
169     }
170     returnCode(result);
171 }
172 
173 #if NCURSES_SP_FUNCS
174 NCURSES_EXPORT(int)
cbreak(void)175 cbreak(void)
176 {
177     return NCURSES_SP_NAME(cbreak) (CURRENT_SCREEN);
178 }
179 #endif
180 
181 NCURSES_EXPORT(void)
NCURSES_SP_NAME(qiflush)182 NCURSES_SP_NAME(qiflush) (NCURSES_SP_DCL0)
183 {
184     TERMINAL *termp;
185 
186     T((T_CALLED("qiflush(%p)"), (void *) SP_PARM));
187     if ((termp = TerminalOf(SP_PARM)) != NULL) {
188 	TTY buf;
189 	int result;
190 
191 	BEFORE("qiflush");
192 	buf = termp->Nttyb;
193 #ifdef TERMIOS
194 	buf.c_lflag &= (unsigned) ~(NOFLSH);
195 	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
196 #else
197 	result = ERR;
198 	/* FIXME */
199 #endif
200 	if (result == OK)
201 	    termp->Nttyb = buf;
202 	AFTER("qiflush");
203     }
204     returnVoid;
205 }
206 
207 #if NCURSES_SP_FUNCS
208 NCURSES_EXPORT(void)
qiflush(void)209 qiflush(void)
210 {
211     NCURSES_SP_NAME(qiflush) (CURRENT_SCREEN);
212 }
213 #endif
214 
215 NCURSES_EXPORT(int)
NCURSES_SP_NAME(noraw)216 NCURSES_SP_NAME(noraw) (NCURSES_SP_DCL0)
217 {
218     int result = ERR;
219     TERMINAL *termp;
220 
221     T((T_CALLED("noraw(%p)"), (void *) SP_PARM));
222     if ((termp = TerminalOf(SP_PARM)) != NULL) {
223 	TTY buf;
224 
225 	BEFORE("noraw");
226 	_nc_setmode(O_TEXT);
227 
228 	buf = termp->Nttyb;
229 #ifdef TERMIOS
230 	buf.c_lflag |= ISIG | ICANON |
231 	    (termp->Ottyb.c_lflag & IEXTEN);
232 	buf.c_iflag |= COOKED_INPUT;
233 #elif defined(USE_WIN32CON_DRIVER)
234 	buf.dwFlagIn |= CONMODE_NORAW;
235 #else
236 	buf.sg_flags &= ~(RAW | CBREAK);
237 #endif
238 	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
239 	if (result == OK) {
240 #if USE_KLIBC_KBD
241 	    KBDINFO kbdinfo;
242 
243 	    kbdinfo.cb = sizeof(kbdinfo);
244 	    KbdGetStatus(&kbdinfo, 0);
245 
246 	    kbdinfo.cb = sizeof(kbdinfo);
247 	    kbdinfo.fsMask &= ~KEYBOARD_BINARY_MODE;
248 	    kbdinfo.fsMask |= KEYBOARD_ASCII_MODE;
249 	    KbdSetStatus(&kbdinfo, 0);
250 #endif
251 	    if (SP_PARM) {
252 		IsRaw(SP_PARM) = FALSE;
253 		IsCbreak(SP_PARM) = 0;
254 	    }
255 	    termp->Nttyb = buf;
256 	}
257 	AFTER("noraw");
258     }
259     returnCode(result);
260 }
261 
262 #if NCURSES_SP_FUNCS
263 NCURSES_EXPORT(int)
noraw(void)264 noraw(void)
265 {
266     return NCURSES_SP_NAME(noraw) (CURRENT_SCREEN);
267 }
268 #endif
269 
270 NCURSES_EXPORT(int)
NCURSES_SP_NAME(nocbreak)271 NCURSES_SP_NAME(nocbreak) (NCURSES_SP_DCL0)
272 {
273     int result = ERR;
274     TERMINAL *termp;
275 
276     T((T_CALLED("nocbreak(%p)"), (void *) SP_PARM));
277     if ((termp = TerminalOf(SP_PARM)) != NULL) {
278 	TTY buf;
279 
280 	BEFORE("nocbreak");
281 	_nc_setmode(O_TEXT);
282 
283 	buf = termp->Nttyb;
284 #ifdef TERMIOS
285 	buf.c_lflag |= ICANON;
286 	buf.c_iflag |= ICRNL;
287 #elif defined(USE_WIN32CON_DRIVER)
288 	buf.dwFlagIn |= (CONMODE_NOCBREAK | CONMODE_NORAW);
289 #else
290 	buf.sg_flags &= ~CBREAK;
291 #endif
292 	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
293 	if (result == OK) {
294 	    if (SP_PARM) {
295 		IsCbreak(SP_PARM) = 0;
296 	    }
297 	    termp->Nttyb = buf;
298 	}
299 	AFTER("nocbreak");
300     }
301     returnCode(result);
302 }
303 
304 #if NCURSES_SP_FUNCS
305 NCURSES_EXPORT(int)
nocbreak(void)306 nocbreak(void)
307 {
308     return NCURSES_SP_NAME(nocbreak) (CURRENT_SCREEN);
309 }
310 #endif
311 
312 NCURSES_EXPORT(void)
NCURSES_SP_NAME(noqiflush)313 NCURSES_SP_NAME(noqiflush) (NCURSES_SP_DCL0)
314 {
315     TERMINAL *termp;
316 
317     T((T_CALLED("noqiflush(%p)"), (void *) SP_PARM));
318     if ((termp = TerminalOf(SP_PARM)) != NULL) {
319 	TTY buf;
320 	int result;
321 
322 	BEFORE("noqiflush");
323 	buf = termp->Nttyb;
324 #ifdef TERMIOS
325 	buf.c_lflag |= NOFLSH;
326 	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
327 #else
328 	/* FIXME */
329 	result = ERR;
330 #endif
331 	if (result == OK)
332 	    termp->Nttyb = buf;
333 	AFTER("noqiflush");
334     }
335     returnVoid;
336 }
337 
338 #if NCURSES_SP_FUNCS
339 NCURSES_EXPORT(void)
noqiflush(void)340 noqiflush(void)
341 {
342     NCURSES_SP_NAME(noqiflush) (CURRENT_SCREEN);
343 }
344 #endif
345 
346 /*
347  * This call does the same thing as the qiflush()/noqiflush() pair.
348  */
349 NCURSES_EXPORT(int)
NCURSES_SP_NAME(intrflush)350 NCURSES_SP_NAME(intrflush) (NCURSES_SP_DCLx WINDOW *win GCC_UNUSED, bool flag)
351 {
352     int result = ERR;
353     TERMINAL *termp;
354 
355     T((T_CALLED("intrflush(%p,%d)"), (void *) SP_PARM, flag));
356     if (SP_PARM == NULL)
357 	returnCode(ERR);
358 
359     if ((termp = TerminalOf(SP_PARM)) != NULL) {
360 	TTY buf;
361 
362 	BEFORE("intrflush");
363 	buf = termp->Nttyb;
364 #ifdef TERMIOS
365 	if (flag)
366 	    buf.c_lflag &= (unsigned) ~(NOFLSH);
367 	else
368 	    buf.c_lflag |= (NOFLSH);
369 	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
370 #else
371 	/* FIXME */
372 #endif
373 	if (result == OK) {
374 	    termp->Nttyb = buf;
375 	}
376 	AFTER("intrflush");
377     }
378     returnCode(result);
379 }
380 
381 #if NCURSES_SP_FUNCS
382 NCURSES_EXPORT(int)
intrflush(WINDOW * win GCC_UNUSED,bool flag)383 intrflush(WINDOW *win GCC_UNUSED, bool flag)
384 {
385     return NCURSES_SP_NAME(intrflush) (CURRENT_SCREEN, win, flag);
386 }
387 #endif
388 
389 #if NCURSES_EXT_FUNCS
390 /* *INDENT-OFF* */
391 
392 /*
393  * SCREEN is always opaque, but nl/raw/cbreak/echo set properties in it.
394  * As an extension, provide a way to query the properties.
395  *
396  * There are other properties which could be queried, e.g., filter, keypad,
397  * use_env, use_meta, but these particular properties are saved/restored within
398  * the wgetnstr() and wgetn_wstr() functions, which requires that the higher
399  * level curses library knows about the internal state of the lower level
400  * terminfo library.
401  */
402 
403 #define is_TEST(show,what) \
404     NCURSES_EXPORT(int) \
405     NCURSES_SP_NAME(show) (NCURSES_SP_DCL0) \
406     { \
407 	return ((SP_PARM != NULL) ? (what(SP_PARM) ? 1 : 0) : -1); \
408     }
409 
410 is_TEST(is_nl, IsNl)
411 is_TEST(is_raw, IsRaw)
412 is_TEST(is_cbreak, IsCbreak)
413 is_TEST(is_echo, IsEcho)
414 
415 #if NCURSES_SP_FUNCS
416 #undef is_TEST
417 #define is_TEST(show) \
418     NCURSES_EXPORT(int) \
419     show(void) \
420     { \
421 	return NCURSES_SP_NAME(show) (CURRENT_SCREEN); \
422     }
423 is_TEST(is_nl)
424 is_TEST(is_raw)
425 is_TEST(is_cbreak)
426 is_TEST(is_echo)
427 #endif
428 
429 /* *INDENT-ON* */
430 #endif /* extensions */
431