1 /* $NetBSD: tty.c,v 1.5 1997/10/09 19:16:04 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Christos Zoulas of Cornell University. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 #if !defined(lint) && !defined(SCCSID) 41 #if 0 42 static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93"; 43 #else 44 __RCSID("$NetBSD: tty.c,v 1.5 1997/10/09 19:16:04 christos Exp $"); 45 #endif 46 #endif /* not lint && not SCCSID */ 47 48 /* 49 * tty.c: tty interface stuff 50 */ 51 #include "sys.h" 52 #include "tty.h" 53 #include "el.h" 54 55 typedef struct ttymodes_t { 56 char *m_name; 57 u_int m_value; 58 int m_type; 59 } ttymodes_t; 60 61 typedef struct ttymap_t { 62 int nch, och; /* Internal and termio rep of chars */ 63 el_action_t bind[3]; /* emacs, vi, and vi-cmd */ 64 } ttymap_t; 65 66 67 private ttyperm_t ttyperm = { 68 { 69 { "iflag:", ICRNL, (INLCR|IGNCR) }, 70 { "oflag:", (OPOST|ONLCR), ONLRET }, 71 { "cflag:", 0, 0 }, 72 { "lflag:", (ISIG|ICANON|ECHO|ECHOE|ECHOCTL|IEXTEN), 73 (NOFLSH|ECHONL|EXTPROC|FLUSHO) }, 74 { "chars:", 0, 0 }, 75 }, 76 { 77 { "iflag:", (INLCR|ICRNL), IGNCR }, 78 { "oflag:", (OPOST|ONLCR), ONLRET }, 79 { "cflag:", 0, 0 }, 80 { "lflag:", ISIG, 81 (NOFLSH|ICANON|ECHO|ECHOK|ECHONL|EXTPROC|IEXTEN|FLUSHO) }, 82 { "chars:", (C_SH(C_MIN)|C_SH(C_TIME)|C_SH(C_SWTCH)|C_SH(C_DSWTCH)| 83 C_SH(C_SUSP)|C_SH(C_DSUSP)|C_SH(C_EOL)|C_SH(C_DISCARD)| 84 C_SH(C_PGOFF)|C_SH(C_PAGE)|C_SH(C_STATUS)), 0 } 85 }, 86 { 87 { "iflag:", 0, IXON | IXOFF }, 88 { "oflag:", 0, 0 }, 89 { "cflag:", 0, 0 }, 90 { "lflag:", 0, ISIG | IEXTEN }, 91 { "chars:", 0, 0 }, 92 } 93 }; 94 95 private ttychar_t ttychar = { 96 { 97 CINTR, CQUIT, CERASE, CKILL, 98 CEOF, CEOL, CEOL2, CSWTCH, 99 CDSWTCH, CERASE2, CSTART, CSTOP, 100 CWERASE, CSUSP, CDSUSP, CREPRINT, 101 CDISCARD, CLNEXT, CSTATUS, CPAGE, 102 CPGOFF, CKILL2, CBRK, CMIN, 103 CTIME 104 }, 105 { 106 CINTR, CQUIT, CERASE, CKILL, 107 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 108 _POSIX_VDISABLE, CERASE2, CSTART, CSTOP, 109 _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE, 110 CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 111 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1, 112 0 113 }, 114 { 115 0, 0, 0, 0, 116 0, 0, 0, 0, 117 0, 0, 0, 0, 118 0, 0, 0, 0, 119 0, 0, 0, 0, 120 0, 0, 0, 0, 121 0 122 } 123 }; 124 125 private ttymap_t tty_map[] = { 126 #ifdef VERASE 127 { C_ERASE, VERASE, 128 { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } }, 129 #endif /* VERASE */ 130 #ifdef VERASE2 131 { C_ERASE2, VERASE2, 132 { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } }, 133 #endif /* VERASE2 */ 134 #ifdef VKILL 135 { C_KILL, VKILL, 136 { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } }, 137 #endif /* VKILL */ 138 #ifdef VKILL2 139 { C_KILL2, VKILL2, 140 { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } }, 141 #endif /* VKILL2 */ 142 #ifdef VEOF 143 { C_EOF, VEOF, 144 { EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED } }, 145 #endif /* VEOF */ 146 #ifdef VWERASE 147 { C_WERASE, VWERASE, 148 { ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD } }, 149 #endif /* VWERASE */ 150 #ifdef VREPRINT 151 { C_REPRINT, VREPRINT, 152 { ED_REDISPLAY, ED_INSERT, ED_REDISPLAY } }, 153 #endif /* VREPRINT */ 154 #ifdef VLNEXT 155 { C_LNEXT, VLNEXT, 156 { ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED } }, 157 #endif /* VLNEXT */ 158 { -1, -1, 159 { ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED } } 160 }; 161 162 private ttymodes_t ttymodes[] = { 163 # ifdef IGNBRK 164 { "ignbrk", IGNBRK, M_INP }, 165 # endif /* IGNBRK */ 166 # ifdef BRKINT 167 { "brkint", BRKINT, M_INP }, 168 # endif /* BRKINT */ 169 # ifdef IGNPAR 170 { "ignpar", IGNPAR, M_INP }, 171 # endif /* IGNPAR */ 172 # ifdef PARMRK 173 { "parmrk", PARMRK, M_INP }, 174 # endif /* PARMRK */ 175 # ifdef INPCK 176 { "inpck", INPCK, M_INP }, 177 # endif /* INPCK */ 178 # ifdef ISTRIP 179 { "istrip", ISTRIP, M_INP }, 180 # endif /* ISTRIP */ 181 # ifdef INLCR 182 { "inlcr", INLCR, M_INP }, 183 # endif /* INLCR */ 184 # ifdef IGNCR 185 { "igncr", IGNCR, M_INP }, 186 # endif /* IGNCR */ 187 # ifdef ICRNL 188 { "icrnl", ICRNL, M_INP }, 189 # endif /* ICRNL */ 190 # ifdef IUCLC 191 { "iuclc", IUCLC, M_INP }, 192 # endif /* IUCLC */ 193 # ifdef IXON 194 { "ixon", IXON, M_INP }, 195 # endif /* IXON */ 196 # ifdef IXANY 197 { "ixany", IXANY, M_INP }, 198 # endif /* IXANY */ 199 # ifdef IXOFF 200 { "ixoff", IXOFF, M_INP }, 201 # endif /* IXOFF */ 202 # ifdef IMAXBEL 203 { "imaxbel",IMAXBEL,M_INP }, 204 # endif /* IMAXBEL */ 205 206 # ifdef OPOST 207 { "opost", OPOST, M_OUT }, 208 # endif /* OPOST */ 209 # ifdef OLCUC 210 { "olcuc", OLCUC, M_OUT }, 211 # endif /* OLCUC */ 212 # ifdef ONLCR 213 { "onlcr", ONLCR, M_OUT }, 214 # endif /* ONLCR */ 215 # ifdef OCRNL 216 { "ocrnl", OCRNL, M_OUT }, 217 # endif /* OCRNL */ 218 # ifdef ONOCR 219 { "onocr", ONOCR, M_OUT }, 220 # endif /* ONOCR */ 221 # ifdef ONOEOT 222 { "onoeot", ONOEOT, M_OUT }, 223 # endif /* ONOEOT */ 224 # ifdef ONLRET 225 { "onlret", ONLRET, M_OUT }, 226 # endif /* ONLRET */ 227 # ifdef OFILL 228 { "ofill", OFILL, M_OUT }, 229 # endif /* OFILL */ 230 # ifdef OFDEL 231 { "ofdel", OFDEL, M_OUT }, 232 # endif /* OFDEL */ 233 # ifdef NLDLY 234 { "nldly", NLDLY, M_OUT }, 235 # endif /* NLDLY */ 236 # ifdef CRDLY 237 { "crdly", CRDLY, M_OUT }, 238 # endif /* CRDLY */ 239 # ifdef TABDLY 240 { "tabdly", TABDLY, M_OUT }, 241 # endif /* TABDLY */ 242 # ifdef XTABS 243 { "xtabs", XTABS, M_OUT }, 244 # endif /* XTABS */ 245 # ifdef BSDLY 246 { "bsdly", BSDLY, M_OUT }, 247 # endif /* BSDLY */ 248 # ifdef VTDLY 249 { "vtdly", VTDLY, M_OUT }, 250 # endif /* VTDLY */ 251 # ifdef FFDLY 252 { "ffdly", FFDLY, M_OUT }, 253 # endif /* FFDLY */ 254 # ifdef PAGEOUT 255 { "pageout",PAGEOUT,M_OUT }, 256 # endif /* PAGEOUT */ 257 # ifdef WRAP 258 { "wrap", WRAP, M_OUT }, 259 # endif /* WRAP */ 260 261 # ifdef CIGNORE 262 { "cignore",CIGNORE,M_CTL }, 263 # endif /* CBAUD */ 264 # ifdef CBAUD 265 { "cbaud", CBAUD, M_CTL }, 266 # endif /* CBAUD */ 267 # ifdef CSTOPB 268 { "cstopb", CSTOPB, M_CTL }, 269 # endif /* CSTOPB */ 270 # ifdef CREAD 271 { "cread", CREAD, M_CTL }, 272 # endif /* CREAD */ 273 # ifdef PARENB 274 { "parenb", PARENB, M_CTL }, 275 # endif /* PARENB */ 276 # ifdef PARODD 277 { "parodd", PARODD, M_CTL }, 278 # endif /* PARODD */ 279 # ifdef HUPCL 280 { "hupcl", HUPCL, M_CTL }, 281 # endif /* HUPCL */ 282 # ifdef CLOCAL 283 { "clocal", CLOCAL, M_CTL }, 284 # endif /* CLOCAL */ 285 # ifdef LOBLK 286 { "loblk", LOBLK, M_CTL }, 287 # endif /* LOBLK */ 288 # ifdef CIBAUD 289 { "cibaud", CIBAUD, M_CTL }, 290 # endif /* CIBAUD */ 291 # ifdef CRTSCTS 292 # ifdef CCTS_OFLOW 293 { "ccts_oflow",CCTS_OFLOW,M_CTL }, 294 # else 295 { "crtscts",CRTSCTS,M_CTL }, 296 # endif /* CCTS_OFLOW */ 297 # endif /* CRTSCTS */ 298 # ifdef CRTS_IFLOW 299 { "crts_iflow",CRTS_IFLOW,M_CTL }, 300 # endif /* CRTS_IFLOW */ 301 # ifdef MDMBUF 302 { "mdmbuf", MDMBUF, M_CTL }, 303 # endif /* MDMBUF */ 304 # ifdef RCV1EN 305 { "rcv1en", RCV1EN, M_CTL }, 306 # endif /* RCV1EN */ 307 # ifdef XMT1EN 308 { "xmt1en", XMT1EN, M_CTL }, 309 # endif /* XMT1EN */ 310 311 # ifdef ISIG 312 { "isig", ISIG, M_LIN }, 313 # endif /* ISIG */ 314 # ifdef ICANON 315 { "icanon", ICANON, M_LIN }, 316 # endif /* ICANON */ 317 # ifdef XCASE 318 { "xcase", XCASE, M_LIN }, 319 # endif /* XCASE */ 320 # ifdef ECHO 321 { "echo", ECHO, M_LIN }, 322 # endif /* ECHO */ 323 # ifdef ECHOE 324 { "echoe", ECHOE, M_LIN }, 325 # endif /* ECHOE */ 326 # ifdef ECHOK 327 { "echok", ECHOK, M_LIN }, 328 # endif /* ECHOK */ 329 # ifdef ECHONL 330 { "echonl", ECHONL, M_LIN }, 331 # endif /* ECHONL */ 332 # ifdef NOFLSH 333 { "noflsh", NOFLSH, M_LIN }, 334 # endif /* NOFLSH */ 335 # ifdef TOSTOP 336 { "tostop", TOSTOP, M_LIN }, 337 # endif /* TOSTOP */ 338 # ifdef ECHOCTL 339 { "echoctl",ECHOCTL,M_LIN }, 340 # endif /* ECHOCTL */ 341 # ifdef ECHOPRT 342 { "echoprt",ECHOPRT,M_LIN }, 343 # endif /* ECHOPRT */ 344 # ifdef ECHOKE 345 { "echoke", ECHOKE, M_LIN }, 346 # endif /* ECHOKE */ 347 # ifdef DEFECHO 348 { "defecho",DEFECHO,M_LIN }, 349 # endif /* DEFECHO */ 350 # ifdef FLUSHO 351 { "flusho", FLUSHO, M_LIN }, 352 # endif /* FLUSHO */ 353 # ifdef PENDIN 354 { "pendin", PENDIN, M_LIN }, 355 # endif /* PENDIN */ 356 # ifdef IEXTEN 357 { "iexten", IEXTEN, M_LIN }, 358 # endif /* IEXTEN */ 359 # ifdef NOKERNINFO 360 { "nokerninfo",NOKERNINFO,M_LIN }, 361 # endif /* NOKERNINFO */ 362 # ifdef ALTWERASE 363 { "altwerase",ALTWERASE,M_LIN }, 364 # endif /* ALTWERASE */ 365 # ifdef EXTPROC 366 { "extproc",EXTPROC, M_LIN }, 367 # endif /* EXTPROC */ 368 369 # if defined(VINTR) 370 { "intr", C_SH(C_INTR), M_CHAR }, 371 # endif /* VINTR */ 372 # if defined(VQUIT) 373 { "quit", C_SH(C_QUIT), M_CHAR }, 374 # endif /* VQUIT */ 375 # if defined(VERASE) 376 { "erase", C_SH(C_ERASE), M_CHAR }, 377 # endif /* VERASE */ 378 # if defined(VKILL) 379 { "kill", C_SH(C_KILL), M_CHAR }, 380 # endif /* VKILL */ 381 # if defined(VEOF) 382 { "eof", C_SH(C_EOF), M_CHAR }, 383 # endif /* VEOF */ 384 # if defined(VEOL) 385 { "eol", C_SH(C_EOL), M_CHAR }, 386 # endif /* VEOL */ 387 # if defined(VEOL2) 388 { "eol2", C_SH(C_EOL2), M_CHAR }, 389 # endif /* VEOL2 */ 390 # if defined(VSWTCH) 391 { "swtch", C_SH(C_SWTCH), M_CHAR }, 392 # endif /* VSWTCH */ 393 # if defined(VDSWTCH) 394 { "dswtch", C_SH(C_DSWTCH), M_CHAR }, 395 # endif /* VDSWTCH */ 396 # if defined(VERASE2) 397 { "erase2", C_SH(C_ERASE2), M_CHAR }, 398 # endif /* VERASE2 */ 399 # if defined(VSTART) 400 { "start", C_SH(C_START), M_CHAR }, 401 # endif /* VSTART */ 402 # if defined(VSTOP) 403 { "stop", C_SH(C_STOP), M_CHAR }, 404 # endif /* VSTOP */ 405 # if defined(VWERASE) 406 { "werase", C_SH(C_WERASE), M_CHAR }, 407 # endif /* VWERASE */ 408 # if defined(VSUSP) 409 { "susp", C_SH(C_SUSP), M_CHAR }, 410 # endif /* VSUSP */ 411 # if defined(VDSUSP) 412 { "dsusp", C_SH(C_DSUSP), M_CHAR }, 413 # endif /* VDSUSP */ 414 # if defined(VREPRINT) 415 { "reprint", C_SH(C_REPRINT),M_CHAR }, 416 # endif /* VREPRINT */ 417 # if defined(VDISCARD) 418 { "discard", C_SH(C_DISCARD),M_CHAR }, 419 # endif /* VDISCARD */ 420 # if defined(VLNEXT) 421 { "lnext", C_SH(C_LNEXT), M_CHAR }, 422 # endif /* VLNEXT */ 423 # if defined(VSTATUS) 424 { "status", C_SH(C_STATUS), M_CHAR }, 425 # endif /* VSTATUS */ 426 # if defined(VPAGE) 427 { "page", C_SH(C_PAGE), M_CHAR }, 428 # endif /* VPAGE */ 429 # if defined(VPGOFF) 430 { "pgoff", C_SH(C_PGOFF), M_CHAR }, 431 # endif /* VPGOFF */ 432 # if defined(VKILL2) 433 { "kill2", C_SH(C_KILL2), M_CHAR }, 434 # endif /* VKILL2 */ 435 # if defined(VBRK) 436 { "brk", C_SH(C_BRK), M_CHAR }, 437 # endif /* VBRK */ 438 # if defined(VMIN) 439 { "min", C_SH(C_MIN), M_CHAR }, 440 # endif /* VMIN */ 441 # if defined(VTIME) 442 { "time", C_SH(C_TIME), M_CHAR }, 443 # endif /* VTIME */ 444 { NULL, 0, -1 }, 445 }; 446 447 448 449 #define tty_getty(el, td) tcgetattr((el)->el_infd, (td)) 450 #define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td)) 451 452 #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1) 453 #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8) 454 #define tty__cooked_mode(td) ((td)->c_lflag & ICANON) 455 456 private void tty__getchar __P((struct termios *, unsigned char *)); 457 private void tty__setchar __P((struct termios *, unsigned char *)); 458 private speed_t tty__getspeed __P((struct termios *)); 459 private int tty_setup __P((EditLine *)); 460 461 #define t_qu t_ts 462 463 464 /* tty_setup(): 465 * Get the tty parameters and initialize the editing state 466 */ 467 private int 468 tty_setup(el) 469 EditLine *el; 470 { 471 int rst = 1; 472 if (tty_getty(el, &el->el_tty.t_ed) == -1) { 473 #ifdef DEBUG_TTY 474 (void) fprintf(el->el_errfile, 475 "tty_setup: tty_getty: %s\n", strerror(errno)); 476 #endif /* DEBUG_TTY */ 477 return(-1); 478 } 479 el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed; 480 481 el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex); 482 el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex); 483 el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex); 484 485 el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask; 486 el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask; 487 488 el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask; 489 el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask; 490 491 el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask; 492 el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask; 493 494 el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask; 495 el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask; 496 497 /* 498 * Reset the tty chars to reasonable defaults 499 * If they are disabled, then enable them. 500 */ 501 if (rst) { 502 if (tty__cooked_mode(&el->el_tty.t_ts)) { 503 tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); 504 /* 505 * Don't affect CMIN and CTIME for the editor mode 506 */ 507 for (rst = 0; rst < C_NCC - 2; rst++) 508 if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable && 509 el->el_tty.t_c[ED_IO][rst] != el->el_tty.t_vdisable) 510 el->el_tty.t_c[ED_IO][rst] = el->el_tty.t_c[TS_IO][rst]; 511 for (rst = 0; rst < C_NCC; rst++) 512 if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable) 513 el->el_tty.t_c[EX_IO][rst] = el->el_tty.t_c[TS_IO][rst]; 514 } 515 tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); 516 if (tty_setty(el, &el->el_tty.t_ex) == -1) { 517 #ifdef DEBUG_TTY 518 (void) fprintf(el->el_errfile, "tty_setup: tty_setty: %s\n", 519 strerror(errno)); 520 #endif /* DEBUG_TTY */ 521 return(-1); 522 } 523 } 524 else 525 tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); 526 527 el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask; 528 el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask; 529 530 el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask; 531 el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask; 532 533 el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask; 534 el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask; 535 536 el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask; 537 el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask; 538 539 tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); 540 return 0; 541 } 542 543 protected int 544 tty_init(el) 545 EditLine *el; 546 { 547 el->el_tty.t_mode = EX_IO; 548 el->el_tty.t_vdisable = _POSIX_VDISABLE; 549 (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t)); 550 (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t)); 551 return tty_setup(el); 552 } /* end tty_init */ 553 554 555 /* tty_end(): 556 * Restore the tty to its original settings 557 */ 558 protected void 559 /*ARGSUSED*/ 560 tty_end(el) 561 EditLine *el; 562 { 563 /* XXX: Maybe reset to an initial state? */ 564 } 565 566 567 /* tty__getspeed(): 568 * Get the tty speed 569 */ 570 private speed_t 571 tty__getspeed(td) 572 struct termios *td; 573 { 574 speed_t spd; 575 576 if ((spd = cfgetispeed(td)) == 0) 577 spd = cfgetospeed(td); 578 return spd; 579 } /* end tty__getspeed */ 580 581 582 /* tty__getchar(): 583 * Get the tty characters 584 */ 585 private void 586 tty__getchar(td, s) 587 struct termios *td; 588 unsigned char *s; 589 { 590 # ifdef VINTR 591 s[C_INTR] = td->c_cc[VINTR]; 592 # endif /* VINTR */ 593 # ifdef VQUIT 594 s[C_QUIT] = td->c_cc[VQUIT]; 595 # endif /* VQUIT */ 596 # ifdef VERASE 597 s[C_ERASE] = td->c_cc[VERASE]; 598 # endif /* VERASE */ 599 # ifdef VKILL 600 s[C_KILL] = td->c_cc[VKILL]; 601 # endif /* VKILL */ 602 # ifdef VEOF 603 s[C_EOF] = td->c_cc[VEOF]; 604 # endif /* VEOF */ 605 # ifdef VEOL 606 s[C_EOL] = td->c_cc[VEOL]; 607 # endif /* VEOL */ 608 # ifdef VEOL2 609 s[C_EOL2] = td->c_cc[VEOL2]; 610 # endif /* VEOL2 */ 611 # ifdef VSWTCH 612 s[C_SWTCH] = td->c_cc[VSWTCH]; 613 # endif /* VSWTCH */ 614 # ifdef VDSWTCH 615 s[C_DSWTCH] = td->c_cc[VDSWTCH]; 616 # endif /* VDSWTCH */ 617 # ifdef VERASE2 618 s[C_ERASE2] = td->c_cc[VERASE2]; 619 # endif /* VERASE2 */ 620 # ifdef VSTART 621 s[C_START] = td->c_cc[VSTART]; 622 # endif /* VSTART */ 623 # ifdef VSTOP 624 s[C_STOP] = td->c_cc[VSTOP]; 625 # endif /* VSTOP */ 626 # ifdef VWERASE 627 s[C_WERASE] = td->c_cc[VWERASE]; 628 # endif /* VWERASE */ 629 # ifdef VSUSP 630 s[C_SUSP] = td->c_cc[VSUSP]; 631 # endif /* VSUSP */ 632 # ifdef VDSUSP 633 s[C_DSUSP] = td->c_cc[VDSUSP]; 634 # endif /* VDSUSP */ 635 # ifdef VREPRINT 636 s[C_REPRINT]= td->c_cc[VREPRINT]; 637 # endif /* VREPRINT */ 638 # ifdef VDISCARD 639 s[C_DISCARD]= td->c_cc[VDISCARD]; 640 # endif /* VDISCARD */ 641 # ifdef VLNEXT 642 s[C_LNEXT] = td->c_cc[VLNEXT]; 643 # endif /* VLNEXT */ 644 # ifdef VSTATUS 645 s[C_STATUS] = td->c_cc[VSTATUS]; 646 # endif /* VSTATUS */ 647 # ifdef VPAGE 648 s[C_PAGE] = td->c_cc[VPAGE]; 649 # endif /* VPAGE */ 650 # ifdef VPGOFF 651 s[C_PGOFF] = td->c_cc[VPGOFF]; 652 # endif /* VPGOFF */ 653 # ifdef VKILL2 654 s[C_KILL2] = td->c_cc[VKILL2]; 655 # endif /* KILL2 */ 656 # ifdef VMIN 657 s[C_MIN] = td->c_cc[VMIN]; 658 # endif /* VMIN */ 659 # ifdef VTIME 660 s[C_TIME] = td->c_cc[VTIME]; 661 # endif /* VTIME */ 662 } /* tty__getchar */ 663 664 665 /* tty__setchar(): 666 * Set the tty characters 667 */ 668 private void 669 tty__setchar(td, s) 670 struct termios *td; 671 unsigned char *s; 672 { 673 # ifdef VINTR 674 td->c_cc[VINTR] = s[C_INTR]; 675 # endif /* VINTR */ 676 # ifdef VQUIT 677 td->c_cc[VQUIT] = s[C_QUIT]; 678 # endif /* VQUIT */ 679 # ifdef VERASE 680 td->c_cc[VERASE] = s[C_ERASE]; 681 # endif /* VERASE */ 682 # ifdef VKILL 683 td->c_cc[VKILL] = s[C_KILL]; 684 # endif /* VKILL */ 685 # ifdef VEOF 686 td->c_cc[VEOF] = s[C_EOF]; 687 # endif /* VEOF */ 688 # ifdef VEOL 689 td->c_cc[VEOL] = s[C_EOL]; 690 # endif /* VEOL */ 691 # ifdef VEOL2 692 td->c_cc[VEOL2] = s[C_EOL2]; 693 # endif /* VEOL2 */ 694 # ifdef VSWTCH 695 td->c_cc[VSWTCH] = s[C_SWTCH]; 696 # endif /* VSWTCH */ 697 # ifdef VDSWTCH 698 td->c_cc[VDSWTCH] = s[C_DSWTCH]; 699 # endif /* VDSWTCH */ 700 # ifdef VERASE2 701 td->c_cc[VERASE2] = s[C_ERASE2]; 702 # endif /* VERASE2 */ 703 # ifdef VSTART 704 td->c_cc[VSTART] = s[C_START]; 705 # endif /* VSTART */ 706 # ifdef VSTOP 707 td->c_cc[VSTOP] = s[C_STOP]; 708 # endif /* VSTOP */ 709 # ifdef VWERASE 710 td->c_cc[VWERASE] = s[C_WERASE]; 711 # endif /* VWERASE */ 712 # ifdef VSUSP 713 td->c_cc[VSUSP] = s[C_SUSP]; 714 # endif /* VSUSP */ 715 # ifdef VDSUSP 716 td->c_cc[VDSUSP] = s[C_DSUSP]; 717 # endif /* VDSUSP */ 718 # ifdef VREPRINT 719 td->c_cc[VREPRINT] = s[C_REPRINT]; 720 # endif /* VREPRINT */ 721 # ifdef VDISCARD 722 td->c_cc[VDISCARD] = s[C_DISCARD]; 723 # endif /* VDISCARD */ 724 # ifdef VLNEXT 725 td->c_cc[VLNEXT] = s[C_LNEXT]; 726 # endif /* VLNEXT */ 727 # ifdef VSTATUS 728 td->c_cc[VSTATUS] = s[C_STATUS]; 729 # endif /* VSTATUS */ 730 # ifdef VPAGE 731 td->c_cc[VPAGE] = s[C_PAGE]; 732 # endif /* VPAGE */ 733 # ifdef VPGOFF 734 td->c_cc[VPGOFF] = s[C_PGOFF]; 735 # endif /* VPGOFF */ 736 # ifdef VKILL2 737 td->c_cc[VKILL2] = s[C_KILL2]; 738 # endif /* VKILL2 */ 739 # ifdef VMIN 740 td->c_cc[VMIN] = s[C_MIN]; 741 # endif /* VMIN */ 742 # ifdef VTIME 743 td->c_cc[VTIME] = s[C_TIME]; 744 # endif /* VTIME */ 745 } /* tty__setchar */ 746 747 748 /* tty_bind_char(): 749 * Rebind the editline functions 750 */ 751 protected void 752 tty_bind_char(el, force) 753 EditLine *el; 754 int force; 755 { 756 unsigned char *t_n = el->el_tty.t_c[ED_IO]; 757 unsigned char *t_o = el->el_tty.t_ed.c_cc; 758 char new[2], old[2]; 759 ttymap_t *tp; 760 el_action_t *dmap, *dalt, *map, *alt; 761 new[1] = old[1] = '\0'; 762 763 764 map = el->el_map.key; 765 alt = el->el_map.alt; 766 if (el->el_map.type == MAP_VI) { 767 dmap = el->el_map.vii; 768 dalt = el->el_map.vic; 769 } 770 else { 771 dmap = el->el_map.emacs; 772 dalt = NULL; 773 } 774 775 for (tp = tty_map; tp->nch != -1; tp++) { 776 new[0] = t_n[tp->nch]; 777 old[0] = t_o[tp->och]; 778 if (new[0] == old[0] && !force) 779 continue; 780 /* Put the old default binding back, and set the new binding */ 781 key_clear(el, map, old); 782 map[old[0]] = dmap[old[0]]; 783 key_clear(el, map, new); 784 /* MAP_VI == 1, MAP_EMACS == 0... */ 785 map[new[0]] = tp->bind[el->el_map.type]; 786 if (dalt) { 787 key_clear(el, alt, old); 788 alt[old[0]] = dalt[old[0]]; 789 key_clear(el, alt, new); 790 alt[new[0]] = tp->bind[el->el_map.type+1]; 791 } 792 } 793 } 794 795 /* tty_rawmode(): 796 * Set terminal into 1 character at a time mode. 797 */ 798 protected int 799 tty_rawmode(el) 800 EditLine *el; 801 { 802 if (el->el_tty.t_mode == ED_IO) 803 return (0); 804 805 if (tty_getty(el, &el->el_tty.t_ts) == -1) { 806 #ifdef DEBUG_TTY 807 (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", strerror(errno)); 808 #endif /* DEBUG_TTY */ 809 return(-1); 810 } 811 812 /* 813 * We always keep up with the eight bit setting and the speed of the 814 * tty. But only we only believe changes that are made to cooked mode! 815 */ 816 el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts); 817 el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts); 818 819 if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed || 820 tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) { 821 (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed); 822 (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed); 823 (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed); 824 (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed); 825 } 826 827 if (tty__cooked_mode(&el->el_tty.t_ts)) { 828 if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) { 829 el->el_tty.t_ex.c_cflag = el->el_tty.t_ts.c_cflag; 830 el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask; 831 el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask; 832 833 el->el_tty.t_ed.c_cflag = el->el_tty.t_ts.c_cflag; 834 el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask; 835 el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask; 836 } 837 838 if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) && 839 (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) { 840 el->el_tty.t_ex.c_lflag = el->el_tty.t_ts.c_lflag; 841 el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask; 842 el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask; 843 844 el->el_tty.t_ed.c_lflag = el->el_tty.t_ts.c_lflag; 845 el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask; 846 el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask; 847 } 848 849 if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) && 850 (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) { 851 el->el_tty.t_ex.c_iflag = el->el_tty.t_ts.c_iflag; 852 el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask; 853 el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask; 854 855 el->el_tty.t_ed.c_iflag = el->el_tty.t_ts.c_iflag; 856 el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask; 857 el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask; 858 } 859 860 if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) && 861 (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) { 862 el->el_tty.t_ex.c_oflag = el->el_tty.t_ts.c_oflag; 863 el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask; 864 el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask; 865 866 el->el_tty.t_ed.c_oflag = el->el_tty.t_ts.c_oflag; 867 el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask; 868 el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask; 869 } 870 871 if (tty__gettabs(&el->el_tty.t_ex) == 0) 872 el->el_tty.t_tabs = 0; 873 else 874 el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0; 875 876 { 877 int i; 878 879 tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); 880 /* 881 * Check if the user made any changes. 882 * If he did, then propagate the changes to the 883 * edit and execute data structures. 884 */ 885 for (i = 0; i < C_NCC; i++) 886 if (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]) 887 break; 888 889 if (i != C_NCC) { 890 /* 891 * Propagate changes only to the unprotected chars 892 * that have been modified just now. 893 */ 894 for (i = 0; i < C_NCC; i++) { 895 if (!((el->el_tty.t_t[ED_IO][M_CHAR].t_setmask & C_SH(i))) 896 && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])) 897 el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i]; 898 if (el->el_tty.t_t[ED_IO][M_CHAR].t_clrmask & C_SH(i)) 899 el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable; 900 } 901 tty_bind_char(el, 0); 902 tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); 903 904 for (i = 0; i < C_NCC; i++) { 905 if (!((el->el_tty.t_t[EX_IO][M_CHAR].t_setmask & C_SH(i))) 906 && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])) 907 el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i]; 908 if (el->el_tty.t_t[EX_IO][M_CHAR].t_clrmask & C_SH(i)) 909 el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable; 910 } 911 tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); 912 } 913 } 914 } 915 916 if (tty_setty(el, &el->el_tty.t_ed) == -1) { 917 #ifdef DEBUG_TTY 918 (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n", 919 strerror(errno)); 920 #endif /* DEBUG_TTY */ 921 return -1; 922 } 923 el->el_tty.t_mode = ED_IO; 924 return (0); 925 } /* end tty_rawmode */ 926 927 928 /* tty_cookedmode(): 929 * Set the tty back to normal mode 930 */ 931 protected int 932 tty_cookedmode(el) 933 EditLine *el; 934 { /* set tty in normal setup */ 935 if (el->el_tty.t_mode == EX_IO) 936 return (0); 937 938 if (tty_setty(el, &el->el_tty.t_ex) == -1) { 939 #ifdef DEBUG_TTY 940 (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n", 941 strerror(errno)); 942 #endif /* DEBUG_TTY */ 943 return -1; 944 } 945 el->el_tty.t_mode = EX_IO; 946 return (0); 947 } /* end tty_cookedmode */ 948 949 950 /* tty_quotemode(): 951 * Turn on quote mode 952 */ 953 protected int 954 tty_quotemode(el) 955 EditLine *el; 956 { 957 if (el->el_tty.t_mode == QU_IO) 958 return 0; 959 960 el->el_tty.t_qu = el->el_tty.t_ed; 961 962 el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][M_INP].t_clrmask; 963 el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][M_INP].t_setmask; 964 965 el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][M_OUT].t_clrmask; 966 el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][M_OUT].t_setmask; 967 968 el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][M_CTL].t_clrmask; 969 el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][M_CTL].t_setmask; 970 971 el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][M_LIN].t_clrmask; 972 el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][M_LIN].t_setmask; 973 974 if (tty_setty(el, &el->el_tty.t_qu) == -1) { 975 #ifdef DEBUG_TTY 976 (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n", 977 strerror(errno)); 978 #endif /* DEBUG_TTY */ 979 return -1; 980 } 981 el->el_tty.t_mode = QU_IO; 982 return 0; 983 } /* end tty_quotemode */ 984 985 986 /* tty_noquotemode(): 987 * Turn off quote mode 988 */ 989 protected int 990 tty_noquotemode(el) 991 EditLine *el; 992 { 993 if (el->el_tty.t_mode != QU_IO) 994 return 0; 995 if (tty_setty(el, &el->el_tty.t_ed) == -1) { 996 #ifdef DEBUG_TTY 997 (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n", 998 strerror(errno)); 999 #endif /* DEBUG_TTY */ 1000 return -1; 1001 } 1002 el->el_tty.t_mode = ED_IO; 1003 return 0; 1004 } 1005 1006 /* tty_stty(): 1007 * Stty builtin 1008 */ 1009 protected int 1010 /*ARGSUSED*/ 1011 tty_stty(el, argc, argv) 1012 EditLine *el; 1013 int argc; 1014 char **argv; 1015 { 1016 ttymodes_t *m; 1017 char x, *d; 1018 int aflag = 0; 1019 char *s; 1020 char *name; 1021 int z = EX_IO; 1022 1023 if (argv == NULL) 1024 return -1; 1025 name = *argv++; 1026 1027 while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0') 1028 switch (argv[0][1]) { 1029 case 'a': 1030 aflag++; 1031 argv++; 1032 break; 1033 case 'd': 1034 argv++; 1035 z = ED_IO; 1036 break; 1037 case 'x': 1038 argv++; 1039 z = EX_IO; 1040 break; 1041 case 'q': 1042 argv++; 1043 z = QU_IO; 1044 break; 1045 default: 1046 (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n", 1047 name, argv[0][1]); 1048 return -1; 1049 } 1050 1051 if (!argv || !*argv) { 1052 int i = -1; 1053 int len = 0, st = 0, cu; 1054 for (m = ttymodes; m->m_name; m++) { 1055 if (m->m_type != i) { 1056 (void) fprintf(el->el_outfile, "%s%s", i != -1 ? "\n" : "", 1057 el->el_tty.t_t[z][m->m_type].t_name); 1058 i = m->m_type; 1059 st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name); 1060 } 1061 1062 x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) ? '+' : '\0'; 1063 x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) ? '-' : x; 1064 1065 if (x != '\0' || aflag) { 1066 1067 cu = strlen(m->m_name) + (x != '\0') + 1; 1068 1069 if (len + cu >= el->el_term.t_size.h) { 1070 (void) fprintf(el->el_outfile, "\n%*s", st, ""); 1071 len = st + cu; 1072 } 1073 else 1074 len += cu; 1075 1076 if (x != '\0') 1077 (void) fprintf(el->el_outfile, "%c%s ", x, m->m_name); 1078 else 1079 (void) fprintf(el->el_outfile, "%s ", m->m_name); 1080 } 1081 } 1082 (void) fprintf(el->el_outfile, "\n"); 1083 return 0; 1084 } 1085 1086 while (argv && (s = *argv++)) { 1087 switch (*s) { 1088 case '+': 1089 case '-': 1090 x = *s++; 1091 break; 1092 default: 1093 x = '\0'; 1094 break; 1095 } 1096 d = s; 1097 for (m = ttymodes; m->m_name; m++) 1098 if (strcmp(m->m_name, d) == 0) 1099 break; 1100 1101 if (!m->m_name) { 1102 (void) fprintf(el->el_errfile, "%s: Invalid argument `%s'.\n", 1103 name, d); 1104 return -1; 1105 } 1106 1107 switch (x) { 1108 case '+': 1109 el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value; 1110 el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value; 1111 break; 1112 case '-': 1113 el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value; 1114 el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value; 1115 break; 1116 default: 1117 el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value; 1118 el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value; 1119 break; 1120 } 1121 } 1122 return 0; 1123 } /* end tty_stty */ 1124 1125 1126 #ifdef notyet 1127 /* tty_printchar(): 1128 * DEbugging routine to print the tty characters 1129 */ 1130 private void 1131 tty_printchar(el, s) 1132 EditLine *el; 1133 unsigned char *s; 1134 { 1135 ttyperm_t *m; 1136 int i; 1137 1138 for (i = 0; i < C_NCC; i++) { 1139 for (m = el->el_tty.t_t; m->m_name; m++) 1140 if (m->m_type == M_CHAR && C_SH(i) == m->m_value) 1141 break; 1142 if (m->m_name) 1143 (void) fprintf(el->el_errfile, "%s ^%c ", m->m_name, s[i] + 'A'-1); 1144 if (i % 5 == 0) 1145 (void) fprintf(el->el_errfile, "\n"); 1146 } 1147 (void) fprintf(el->el_errfile, "\n"); 1148 } 1149 #endif /* notyet */ 1150