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.26 2020/11/21 22:07:48 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 #elif defined(EXP_WIN32_DRIVER) 101 buf.dwFlagIn &= (unsigned long) ~CONMODE_NORAW; 102 #else 103 buf.sg_flags |= RAW; 104 #endif 105 result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf); 106 if (result == OK) { 107 #if USE_KLIBC_KBD 108 KBDINFO kbdinfo; 109 110 kbdinfo.cb = sizeof(kbdinfo); 111 KbdGetStatus(&kbdinfo, 0); 112 113 kbdinfo.cb = sizeof(kbdinfo); 114 kbdinfo.fsMask &= ~KEYBOARD_ASCII_MODE; 115 kbdinfo.fsMask |= KEYBOARD_BINARY_MODE; 116 KbdSetStatus(&kbdinfo, 0); 117 #endif 118 if (SP_PARM) { 119 SP_PARM->_raw = TRUE; 120 SP_PARM->_cbreak = 1; 121 } 122 termp->Nttyb = buf; 123 } 124 AFTER("raw"); 125 } 126 returnCode(result); 127 } 128 129 #if NCURSES_SP_FUNCS 130 NCURSES_EXPORT(int) 131 raw(void) 132 { 133 return NCURSES_SP_NAME(raw) (CURRENT_SCREEN); 134 } 135 #endif 136 137 NCURSES_EXPORT(int) 138 NCURSES_SP_NAME(cbreak) (NCURSES_SP_DCL0) 139 { 140 int result = ERR; 141 TERMINAL *termp; 142 143 T((T_CALLED("cbreak(%p)"), (void *) SP_PARM)); 144 if ((termp = TerminalOf(SP_PARM)) != 0) { 145 TTY buf; 146 147 BEFORE("cbreak"); 148 _nc_setmode(O_BINARY); 149 150 buf = termp->Nttyb; 151 #ifdef TERMIOS 152 buf.c_lflag &= (unsigned) ~ICANON; 153 buf.c_iflag &= (unsigned) ~ICRNL; 154 buf.c_lflag |= ISIG; 155 buf.c_cc[VMIN] = 1; 156 buf.c_cc[VTIME] = 0; 157 #elif defined(EXP_WIN32_DRIVER) 158 buf.dwFlagIn |= CONMODE_NORAW; 159 buf.dwFlagIn &= (unsigned long) ~CONMODE_NOCBREAK; 160 #else 161 buf.sg_flags |= CBREAK; 162 #endif 163 result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf); 164 if (result == OK) { 165 if (SP_PARM) { 166 SP_PARM->_cbreak = 1; 167 } 168 termp->Nttyb = buf; 169 } 170 AFTER("cbreak"); 171 } 172 returnCode(result); 173 } 174 175 #if NCURSES_SP_FUNCS 176 NCURSES_EXPORT(int) 177 cbreak(void) 178 { 179 return NCURSES_SP_NAME(cbreak) (CURRENT_SCREEN); 180 } 181 #endif 182 183 /* 184 * Note: 185 * this implementation may be wrong. See the comment under intrflush(). 186 */ 187 NCURSES_EXPORT(void) 188 NCURSES_SP_NAME(qiflush) (NCURSES_SP_DCL0) 189 { 190 TERMINAL *termp; 191 192 T((T_CALLED("qiflush(%p)"), (void *) SP_PARM)); 193 if ((termp = TerminalOf(SP_PARM)) != 0) { 194 TTY buf; 195 int result; 196 197 BEFORE("qiflush"); 198 buf = termp->Nttyb; 199 #ifdef TERMIOS 200 buf.c_lflag &= (unsigned) ~(NOFLSH); 201 result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf); 202 #else 203 result = ERR; 204 /* FIXME */ 205 #endif 206 if (result == OK) 207 termp->Nttyb = buf; 208 AFTER("qiflush"); 209 } 210 returnVoid; 211 } 212 213 #if NCURSES_SP_FUNCS 214 NCURSES_EXPORT(void) 215 qiflush(void) 216 { 217 NCURSES_SP_NAME(qiflush) (CURRENT_SCREEN); 218 } 219 #endif 220 221 NCURSES_EXPORT(int) 222 NCURSES_SP_NAME(noraw) (NCURSES_SP_DCL0) 223 { 224 int result = ERR; 225 TERMINAL *termp; 226 227 T((T_CALLED("noraw(%p)"), (void *) SP_PARM)); 228 if ((termp = TerminalOf(SP_PARM)) != 0) { 229 TTY buf; 230 231 BEFORE("noraw"); 232 _nc_setmode(O_TEXT); 233 234 buf = termp->Nttyb; 235 #ifdef TERMIOS 236 buf.c_lflag |= ISIG | ICANON | 237 (termp->Ottyb.c_lflag & IEXTEN); 238 buf.c_iflag |= COOKED_INPUT; 239 #elif defined(EXP_WIN32_DRIVER) 240 buf.dwFlagIn |= CONMODE_NORAW; 241 #else 242 buf.sg_flags &= ~(RAW | CBREAK); 243 #endif 244 result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf); 245 if (result == OK) { 246 #if USE_KLIBC_KBD 247 KBDINFO kbdinfo; 248 249 kbdinfo.cb = sizeof(kbdinfo); 250 KbdGetStatus(&kbdinfo, 0); 251 252 kbdinfo.cb = sizeof(kbdinfo); 253 kbdinfo.fsMask &= ~KEYBOARD_BINARY_MODE; 254 kbdinfo.fsMask |= KEYBOARD_ASCII_MODE; 255 KbdSetStatus(&kbdinfo, 0); 256 #endif 257 if (SP_PARM) { 258 SP_PARM->_raw = FALSE; 259 SP_PARM->_cbreak = 0; 260 } 261 termp->Nttyb = buf; 262 } 263 AFTER("noraw"); 264 } 265 returnCode(result); 266 } 267 268 #if NCURSES_SP_FUNCS 269 NCURSES_EXPORT(int) 270 noraw(void) 271 { 272 return NCURSES_SP_NAME(noraw) (CURRENT_SCREEN); 273 } 274 #endif 275 276 NCURSES_EXPORT(int) 277 NCURSES_SP_NAME(nocbreak) (NCURSES_SP_DCL0) 278 { 279 int result = ERR; 280 TERMINAL *termp; 281 282 T((T_CALLED("nocbreak(%p)"), (void *) SP_PARM)); 283 if ((termp = TerminalOf(SP_PARM)) != 0) { 284 TTY buf; 285 286 BEFORE("nocbreak"); 287 _nc_setmode(O_TEXT); 288 289 buf = termp->Nttyb; 290 #ifdef TERMIOS 291 buf.c_lflag |= ICANON; 292 buf.c_iflag |= ICRNL; 293 #elif defined(EXP_WIN32_DRIVER) 294 buf.dwFlagIn |= (CONMODE_NOCBREAK | CONMODE_NORAW); 295 #else 296 buf.sg_flags &= ~CBREAK; 297 #endif 298 result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf); 299 if (result == OK) { 300 if (SP_PARM) { 301 SP_PARM->_cbreak = 0; 302 } 303 termp->Nttyb = buf; 304 } 305 AFTER("nocbreak"); 306 } 307 returnCode(result); 308 } 309 310 #if NCURSES_SP_FUNCS 311 NCURSES_EXPORT(int) 312 nocbreak(void) 313 { 314 return NCURSES_SP_NAME(nocbreak) (CURRENT_SCREEN); 315 } 316 #endif 317 318 NCURSES_EXPORT(void) 319 NCURSES_SP_NAME(noqiflush) (NCURSES_SP_DCL0) 320 { 321 TERMINAL *termp; 322 323 T((T_CALLED("noqiflush(%p)"), (void *) SP_PARM)); 324 if ((termp = TerminalOf(SP_PARM)) != 0) { 325 TTY buf; 326 int result; 327 328 BEFORE("noqiflush"); 329 buf = termp->Nttyb; 330 #ifdef TERMIOS 331 buf.c_lflag |= NOFLSH; 332 result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf); 333 #else 334 /* FIXME */ 335 result = ERR; 336 #endif 337 if (result == OK) 338 termp->Nttyb = buf; 339 AFTER("noqiflush"); 340 } 341 returnVoid; 342 } 343 344 #if NCURSES_SP_FUNCS 345 NCURSES_EXPORT(void) 346 noqiflush(void) 347 { 348 NCURSES_SP_NAME(noqiflush) (CURRENT_SCREEN); 349 } 350 #endif 351 352 /* 353 * This call does the same thing as the qiflush()/noqiflush() pair. We know 354 * for certain that SVr3 intrflush() tweaks the NOFLSH bit; on the other hand, 355 * the match (in the SVr4 man pages) between the language describing NOFLSH in 356 * termio(7) and the language describing qiflush()/noqiflush() in 357 * curs_inopts(3x) is too exact to be coincidence. 358 */ 359 NCURSES_EXPORT(int) 360 NCURSES_SP_NAME(intrflush) (NCURSES_SP_DCLx WINDOW *win GCC_UNUSED, bool flag) 361 { 362 int result = ERR; 363 TERMINAL *termp; 364 365 T((T_CALLED("intrflush(%p,%d)"), (void *) SP_PARM, flag)); 366 if (SP_PARM == 0) 367 returnCode(ERR); 368 369 if ((termp = TerminalOf(SP_PARM)) != 0) { 370 TTY buf; 371 372 BEFORE("intrflush"); 373 buf = termp->Nttyb; 374 #ifdef TERMIOS 375 if (flag) 376 buf.c_lflag &= (unsigned) ~(NOFLSH); 377 else 378 buf.c_lflag |= (NOFLSH); 379 result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf); 380 #else 381 /* FIXME */ 382 #endif 383 if (result == OK) { 384 termp->Nttyb = buf; 385 } 386 AFTER("intrflush"); 387 } 388 returnCode(result); 389 } 390 391 #if NCURSES_SP_FUNCS 392 NCURSES_EXPORT(int) 393 intrflush(WINDOW *win GCC_UNUSED, bool flag) 394 { 395 return NCURSES_SP_NAME(intrflush) (CURRENT_SCREEN, win, flag); 396 } 397 #endif 398