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 389