1 /* $NetBSD: tty.c,v 1.10 1999/02/07 14:34:05 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.10 1999/02/07 14:34:05 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 | INLCR | ICRNL }, 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, MD_INP }, 165 # endif /* IGNBRK */ 166 # ifdef BRKINT 167 { "brkint", BRKINT, MD_INP }, 168 # endif /* BRKINT */ 169 # ifdef IGNPAR 170 { "ignpar", IGNPAR, MD_INP }, 171 # endif /* IGNPAR */ 172 # ifdef PARMRK 173 { "parmrk", PARMRK, MD_INP }, 174 # endif /* PARMRK */ 175 # ifdef INPCK 176 { "inpck", INPCK, MD_INP }, 177 # endif /* INPCK */ 178 # ifdef ISTRIP 179 { "istrip", ISTRIP, MD_INP }, 180 # endif /* ISTRIP */ 181 # ifdef INLCR 182 { "inlcr", INLCR, MD_INP }, 183 # endif /* INLCR */ 184 # ifdef IGNCR 185 { "igncr", IGNCR, MD_INP }, 186 # endif /* IGNCR */ 187 # ifdef ICRNL 188 { "icrnl", ICRNL, MD_INP }, 189 # endif /* ICRNL */ 190 # ifdef IUCLC 191 { "iuclc", IUCLC, MD_INP }, 192 # endif /* IUCLC */ 193 # ifdef IXON 194 { "ixon", IXON, MD_INP }, 195 # endif /* IXON */ 196 # ifdef IXANY 197 { "ixany", IXANY, MD_INP }, 198 # endif /* IXANY */ 199 # ifdef IXOFF 200 { "ixoff", IXOFF, MD_INP }, 201 # endif /* IXOFF */ 202 # ifdef IMAXBEL 203 { "imaxbel",IMAXBEL,MD_INP }, 204 # endif /* IMAXBEL */ 205 206 # ifdef OPOST 207 { "opost", OPOST, MD_OUT }, 208 # endif /* OPOST */ 209 # ifdef OLCUC 210 { "olcuc", OLCUC, MD_OUT }, 211 # endif /* OLCUC */ 212 # ifdef ONLCR 213 { "onlcr", ONLCR, MD_OUT }, 214 # endif /* ONLCR */ 215 # ifdef OCRNL 216 { "ocrnl", OCRNL, MD_OUT }, 217 # endif /* OCRNL */ 218 # ifdef ONOCR 219 { "onocr", ONOCR, MD_OUT }, 220 # endif /* ONOCR */ 221 # ifdef ONOEOT 222 { "onoeot", ONOEOT, MD_OUT }, 223 # endif /* ONOEOT */ 224 # ifdef ONLRET 225 { "onlret", ONLRET, MD_OUT }, 226 # endif /* ONLRET */ 227 # ifdef OFILL 228 { "ofill", OFILL, MD_OUT }, 229 # endif /* OFILL */ 230 # ifdef OFDEL 231 { "ofdel", OFDEL, MD_OUT }, 232 # endif /* OFDEL */ 233 # ifdef NLDLY 234 { "nldly", NLDLY, MD_OUT }, 235 # endif /* NLDLY */ 236 # ifdef CRDLY 237 { "crdly", CRDLY, MD_OUT }, 238 # endif /* CRDLY */ 239 # ifdef TABDLY 240 { "tabdly", TABDLY, MD_OUT }, 241 # endif /* TABDLY */ 242 # ifdef XTABS 243 { "xtabs", XTABS, MD_OUT }, 244 # endif /* XTABS */ 245 # ifdef BSDLY 246 { "bsdly", BSDLY, MD_OUT }, 247 # endif /* BSDLY */ 248 # ifdef VTDLY 249 { "vtdly", VTDLY, MD_OUT }, 250 # endif /* VTDLY */ 251 # ifdef FFDLY 252 { "ffdly", FFDLY, MD_OUT }, 253 # endif /* FFDLY */ 254 # ifdef PAGEOUT 255 { "pageout",PAGEOUT,MD_OUT }, 256 # endif /* PAGEOUT */ 257 # ifdef WRAP 258 { "wrap", WRAP, MD_OUT }, 259 # endif /* WRAP */ 260 261 # ifdef CIGNORE 262 { "cignore",CIGNORE,MD_CTL }, 263 # endif /* CBAUD */ 264 # ifdef CBAUD 265 { "cbaud", CBAUD, MD_CTL }, 266 # endif /* CBAUD */ 267 # ifdef CSTOPB 268 { "cstopb", CSTOPB, MD_CTL }, 269 # endif /* CSTOPB */ 270 # ifdef CREAD 271 { "cread", CREAD, MD_CTL }, 272 # endif /* CREAD */ 273 # ifdef PARENB 274 { "parenb", PARENB, MD_CTL }, 275 # endif /* PARENB */ 276 # ifdef PARODD 277 { "parodd", PARODD, MD_CTL }, 278 # endif /* PARODD */ 279 # ifdef HUPCL 280 { "hupcl", HUPCL, MD_CTL }, 281 # endif /* HUPCL */ 282 # ifdef CLOCAL 283 { "clocal", CLOCAL, MD_CTL }, 284 # endif /* CLOCAL */ 285 # ifdef LOBLK 286 { "loblk", LOBLK, MD_CTL }, 287 # endif /* LOBLK */ 288 # ifdef CIBAUD 289 { "cibaud", CIBAUD, MD_CTL }, 290 # endif /* CIBAUD */ 291 # ifdef CRTSCTS 292 # ifdef CCTS_OFLOW 293 { "ccts_oflow",CCTS_OFLOW,MD_CTL }, 294 # else 295 { "crtscts",CRTSCTS,MD_CTL }, 296 # endif /* CCTS_OFLOW */ 297 # endif /* CRTSCTS */ 298 # ifdef CRTS_IFLOW 299 { "crts_iflow",CRTS_IFLOW,MD_CTL }, 300 # endif /* CRTS_IFLOW */ 301 # ifdef CDTRCTS 302 { "cdtrcts",CDTRCTS,MD_CTL }, 303 # endif /* CDTRCTS */ 304 # ifdef MDMBUF 305 { "mdmbuf", MDMBUF, MD_CTL }, 306 # endif /* MDMBUF */ 307 # ifdef RCV1EN 308 { "rcv1en", RCV1EN, MD_CTL }, 309 # endif /* RCV1EN */ 310 # ifdef XMT1EN 311 { "xmt1en", XMT1EN, MD_CTL }, 312 # endif /* XMT1EN */ 313 314 # ifdef ISIG 315 { "isig", ISIG, MD_LIN }, 316 # endif /* ISIG */ 317 # ifdef ICANON 318 { "icanon", ICANON, MD_LIN }, 319 # endif /* ICANON */ 320 # ifdef XCASE 321 { "xcase", XCASE, MD_LIN }, 322 # endif /* XCASE */ 323 # ifdef ECHO 324 { "echo", ECHO, MD_LIN }, 325 # endif /* ECHO */ 326 # ifdef ECHOE 327 { "echoe", ECHOE, MD_LIN }, 328 # endif /* ECHOE */ 329 # ifdef ECHOK 330 { "echok", ECHOK, MD_LIN }, 331 # endif /* ECHOK */ 332 # ifdef ECHONL 333 { "echonl", ECHONL, MD_LIN }, 334 # endif /* ECHONL */ 335 # ifdef NOFLSH 336 { "noflsh", NOFLSH, MD_LIN }, 337 # endif /* NOFLSH */ 338 # ifdef TOSTOP 339 { "tostop", TOSTOP, MD_LIN }, 340 # endif /* TOSTOP */ 341 # ifdef ECHOCTL 342 { "echoctl",ECHOCTL,MD_LIN }, 343 # endif /* ECHOCTL */ 344 # ifdef ECHOPRT 345 { "echoprt",ECHOPRT,MD_LIN }, 346 # endif /* ECHOPRT */ 347 # ifdef ECHOKE 348 { "echoke", ECHOKE, MD_LIN }, 349 # endif /* ECHOKE */ 350 # ifdef DEFECHO 351 { "defecho",DEFECHO,MD_LIN }, 352 # endif /* DEFECHO */ 353 # ifdef FLUSHO 354 { "flusho", FLUSHO, MD_LIN }, 355 # endif /* FLUSHO */ 356 # ifdef PENDIN 357 { "pendin", PENDIN, MD_LIN }, 358 # endif /* PENDIN */ 359 # ifdef IEXTEN 360 { "iexten", IEXTEN, MD_LIN }, 361 # endif /* IEXTEN */ 362 # ifdef NOKERNINFO 363 { "nokerninfo",NOKERNINFO,MD_LIN }, 364 # endif /* NOKERNINFO */ 365 # ifdef ALTWERASE 366 { "altwerase",ALTWERASE,MD_LIN }, 367 # endif /* ALTWERASE */ 368 # ifdef EXTPROC 369 { "extproc",EXTPROC, MD_LIN }, 370 # endif /* EXTPROC */ 371 372 # if defined(VINTR) 373 { "intr", C_SH(C_INTR), MD_CHAR }, 374 # endif /* VINTR */ 375 # if defined(VQUIT) 376 { "quit", C_SH(C_QUIT), MD_CHAR }, 377 # endif /* VQUIT */ 378 # if defined(VERASE) 379 { "erase", C_SH(C_ERASE), MD_CHAR }, 380 # endif /* VERASE */ 381 # if defined(VKILL) 382 { "kill", C_SH(C_KILL), MD_CHAR }, 383 # endif /* VKILL */ 384 # if defined(VEOF) 385 { "eof", C_SH(C_EOF), MD_CHAR }, 386 # endif /* VEOF */ 387 # if defined(VEOL) 388 { "eol", C_SH(C_EOL), MD_CHAR }, 389 # endif /* VEOL */ 390 # if defined(VEOL2) 391 { "eol2", C_SH(C_EOL2), MD_CHAR }, 392 # endif /* VEOL2 */ 393 # if defined(VSWTCH) 394 { "swtch", C_SH(C_SWTCH), MD_CHAR }, 395 # endif /* VSWTCH */ 396 # if defined(VDSWTCH) 397 { "dswtch", C_SH(C_DSWTCH), MD_CHAR }, 398 # endif /* VDSWTCH */ 399 # if defined(VERASE2) 400 { "erase2", C_SH(C_ERASE2), MD_CHAR }, 401 # endif /* VERASE2 */ 402 # if defined(VSTART) 403 { "start", C_SH(C_START), MD_CHAR }, 404 # endif /* VSTART */ 405 # if defined(VSTOP) 406 { "stop", C_SH(C_STOP), MD_CHAR }, 407 # endif /* VSTOP */ 408 # if defined(VWERASE) 409 { "werase", C_SH(C_WERASE), MD_CHAR }, 410 # endif /* VWERASE */ 411 # if defined(VSUSP) 412 { "susp", C_SH(C_SUSP), MD_CHAR }, 413 # endif /* VSUSP */ 414 # if defined(VDSUSP) 415 { "dsusp", C_SH(C_DSUSP), MD_CHAR }, 416 # endif /* VDSUSP */ 417 # if defined(VREPRINT) 418 { "reprint", C_SH(C_REPRINT),MD_CHAR }, 419 # endif /* VREPRINT */ 420 # if defined(VDISCARD) 421 { "discard", C_SH(C_DISCARD),MD_CHAR }, 422 # endif /* VDISCARD */ 423 # if defined(VLNEXT) 424 { "lnext", C_SH(C_LNEXT), MD_CHAR }, 425 # endif /* VLNEXT */ 426 # if defined(VSTATUS) 427 { "status", C_SH(C_STATUS), MD_CHAR }, 428 # endif /* VSTATUS */ 429 # if defined(VPAGE) 430 { "page", C_SH(C_PAGE), MD_CHAR }, 431 # endif /* VPAGE */ 432 # if defined(VPGOFF) 433 { "pgoff", C_SH(C_PGOFF), MD_CHAR }, 434 # endif /* VPGOFF */ 435 # if defined(VKILL2) 436 { "kill2", C_SH(C_KILL2), MD_CHAR }, 437 # endif /* VKILL2 */ 438 # if defined(VBRK) 439 { "brk", C_SH(C_BRK), MD_CHAR }, 440 # endif /* VBRK */ 441 # if defined(VMIN) 442 { "min", C_SH(C_MIN), MD_CHAR }, 443 # endif /* VMIN */ 444 # if defined(VTIME) 445 { "time", C_SH(C_TIME), MD_CHAR }, 446 # endif /* VTIME */ 447 { NULL, 0, -1 }, 448 }; 449 450 451 452 #define tty_getty(el, td) tcgetattr((el)->el_infd, (td)) 453 #define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td)) 454 455 #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1) 456 #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8) 457 #define tty__cooked_mode(td) ((td)->c_lflag & ICANON) 458 459 private void tty__getchar __P((struct termios *, unsigned char *)); 460 private void tty__setchar __P((struct termios *, unsigned char *)); 461 private speed_t tty__getspeed __P((struct termios *)); 462 private int tty_setup __P((EditLine *)); 463 464 #define t_qu t_ts 465 466 467 /* tty_setup(): 468 * Get the tty parameters and initialize the editing state 469 */ 470 private int 471 tty_setup(el) 472 EditLine *el; 473 { 474 int rst = 1; 475 if (tty_getty(el, &el->el_tty.t_ed) == -1) { 476 #ifdef DEBUG_TTY 477 (void) fprintf(el->el_errfile, 478 "tty_setup: tty_getty: %s\n", strerror(errno)); 479 #endif /* DEBUG_TTY */ 480 return(-1); 481 } 482 el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed; 483 484 el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex); 485 el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex); 486 el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex); 487 488 el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask; 489 el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask; 490 491 el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask; 492 el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask; 493 494 el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask; 495 el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask; 496 497 el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask; 498 el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask; 499 500 /* 501 * Reset the tty chars to reasonable defaults 502 * If they are disabled, then enable them. 503 */ 504 if (rst) { 505 if (tty__cooked_mode(&el->el_tty.t_ts)) { 506 tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); 507 /* 508 * Don't affect CMIN and CTIME for the editor mode 509 */ 510 for (rst = 0; rst < C_NCC - 2; rst++) 511 if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable && 512 el->el_tty.t_c[ED_IO][rst] != el->el_tty.t_vdisable) 513 el->el_tty.t_c[ED_IO][rst] = el->el_tty.t_c[TS_IO][rst]; 514 for (rst = 0; rst < C_NCC; rst++) 515 if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable) 516 el->el_tty.t_c[EX_IO][rst] = el->el_tty.t_c[TS_IO][rst]; 517 } 518 tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); 519 if (tty_setty(el, &el->el_tty.t_ex) == -1) { 520 #ifdef DEBUG_TTY 521 (void) fprintf(el->el_errfile, "tty_setup: tty_setty: %s\n", 522 strerror(errno)); 523 #endif /* DEBUG_TTY */ 524 return(-1); 525 } 526 } 527 else 528 tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); 529 530 el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; 531 el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask; 532 533 el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask; 534 el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask; 535 536 el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask; 537 el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask; 538 539 el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask; 540 el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask; 541 542 tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); 543 tty_bind_char(el, 1); 544 return 0; 545 } 546 547 protected int 548 tty_init(el) 549 EditLine *el; 550 { 551 el->el_tty.t_mode = EX_IO; 552 el->el_tty.t_vdisable = _POSIX_VDISABLE; 553 (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t)); 554 (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t)); 555 return tty_setup(el); 556 } /* end tty_init */ 557 558 559 /* tty_end(): 560 * Restore the tty to its original settings 561 */ 562 protected void 563 /*ARGSUSED*/ 564 tty_end(el) 565 EditLine *el; 566 { 567 /* XXX: Maybe reset to an initial state? */ 568 } 569 570 571 /* tty__getspeed(): 572 * Get the tty speed 573 */ 574 private speed_t 575 tty__getspeed(td) 576 struct termios *td; 577 { 578 speed_t spd; 579 580 if ((spd = cfgetispeed(td)) == 0) 581 spd = cfgetospeed(td); 582 return spd; 583 } /* end tty__getspeed */ 584 585 586 /* tty__getchar(): 587 * Get the tty characters 588 */ 589 private void 590 tty__getchar(td, s) 591 struct termios *td; 592 unsigned char *s; 593 { 594 # ifdef VINTR 595 s[C_INTR] = td->c_cc[VINTR]; 596 # endif /* VINTR */ 597 # ifdef VQUIT 598 s[C_QUIT] = td->c_cc[VQUIT]; 599 # endif /* VQUIT */ 600 # ifdef VERASE 601 s[C_ERASE] = td->c_cc[VERASE]; 602 # endif /* VERASE */ 603 # ifdef VKILL 604 s[C_KILL] = td->c_cc[VKILL]; 605 # endif /* VKILL */ 606 # ifdef VEOF 607 s[C_EOF] = td->c_cc[VEOF]; 608 # endif /* VEOF */ 609 # ifdef VEOL 610 s[C_EOL] = td->c_cc[VEOL]; 611 # endif /* VEOL */ 612 # ifdef VEOL2 613 s[C_EOL2] = td->c_cc[VEOL2]; 614 # endif /* VEOL2 */ 615 # ifdef VSWTCH 616 s[C_SWTCH] = td->c_cc[VSWTCH]; 617 # endif /* VSWTCH */ 618 # ifdef VDSWTCH 619 s[C_DSWTCH] = td->c_cc[VDSWTCH]; 620 # endif /* VDSWTCH */ 621 # ifdef VERASE2 622 s[C_ERASE2] = td->c_cc[VERASE2]; 623 # endif /* VERASE2 */ 624 # ifdef VSTART 625 s[C_START] = td->c_cc[VSTART]; 626 # endif /* VSTART */ 627 # ifdef VSTOP 628 s[C_STOP] = td->c_cc[VSTOP]; 629 # endif /* VSTOP */ 630 # ifdef VWERASE 631 s[C_WERASE] = td->c_cc[VWERASE]; 632 # endif /* VWERASE */ 633 # ifdef VSUSP 634 s[C_SUSP] = td->c_cc[VSUSP]; 635 # endif /* VSUSP */ 636 # ifdef VDSUSP 637 s[C_DSUSP] = td->c_cc[VDSUSP]; 638 # endif /* VDSUSP */ 639 # ifdef VREPRINT 640 s[C_REPRINT]= td->c_cc[VREPRINT]; 641 # endif /* VREPRINT */ 642 # ifdef VDISCARD 643 s[C_DISCARD]= td->c_cc[VDISCARD]; 644 # endif /* VDISCARD */ 645 # ifdef VLNEXT 646 s[C_LNEXT] = td->c_cc[VLNEXT]; 647 # endif /* VLNEXT */ 648 # ifdef VSTATUS 649 s[C_STATUS] = td->c_cc[VSTATUS]; 650 # endif /* VSTATUS */ 651 # ifdef VPAGE 652 s[C_PAGE] = td->c_cc[VPAGE]; 653 # endif /* VPAGE */ 654 # ifdef VPGOFF 655 s[C_PGOFF] = td->c_cc[VPGOFF]; 656 # endif /* VPGOFF */ 657 # ifdef VKILL2 658 s[C_KILL2] = td->c_cc[VKILL2]; 659 # endif /* KILL2 */ 660 # ifdef VMIN 661 s[C_MIN] = td->c_cc[VMIN]; 662 # endif /* VMIN */ 663 # ifdef VTIME 664 s[C_TIME] = td->c_cc[VTIME]; 665 # endif /* VTIME */ 666 } /* tty__getchar */ 667 668 669 /* tty__setchar(): 670 * Set the tty characters 671 */ 672 private void 673 tty__setchar(td, s) 674 struct termios *td; 675 unsigned char *s; 676 { 677 # ifdef VINTR 678 td->c_cc[VINTR] = s[C_INTR]; 679 # endif /* VINTR */ 680 # ifdef VQUIT 681 td->c_cc[VQUIT] = s[C_QUIT]; 682 # endif /* VQUIT */ 683 # ifdef VERASE 684 td->c_cc[VERASE] = s[C_ERASE]; 685 # endif /* VERASE */ 686 # ifdef VKILL 687 td->c_cc[VKILL] = s[C_KILL]; 688 # endif /* VKILL */ 689 # ifdef VEOF 690 td->c_cc[VEOF] = s[C_EOF]; 691 # endif /* VEOF */ 692 # ifdef VEOL 693 td->c_cc[VEOL] = s[C_EOL]; 694 # endif /* VEOL */ 695 # ifdef VEOL2 696 td->c_cc[VEOL2] = s[C_EOL2]; 697 # endif /* VEOL2 */ 698 # ifdef VSWTCH 699 td->c_cc[VSWTCH] = s[C_SWTCH]; 700 # endif /* VSWTCH */ 701 # ifdef VDSWTCH 702 td->c_cc[VDSWTCH] = s[C_DSWTCH]; 703 # endif /* VDSWTCH */ 704 # ifdef VERASE2 705 td->c_cc[VERASE2] = s[C_ERASE2]; 706 # endif /* VERASE2 */ 707 # ifdef VSTART 708 td->c_cc[VSTART] = s[C_START]; 709 # endif /* VSTART */ 710 # ifdef VSTOP 711 td->c_cc[VSTOP] = s[C_STOP]; 712 # endif /* VSTOP */ 713 # ifdef VWERASE 714 td->c_cc[VWERASE] = s[C_WERASE]; 715 # endif /* VWERASE */ 716 # ifdef VSUSP 717 td->c_cc[VSUSP] = s[C_SUSP]; 718 # endif /* VSUSP */ 719 # ifdef VDSUSP 720 td->c_cc[VDSUSP] = s[C_DSUSP]; 721 # endif /* VDSUSP */ 722 # ifdef VREPRINT 723 td->c_cc[VREPRINT] = s[C_REPRINT]; 724 # endif /* VREPRINT */ 725 # ifdef VDISCARD 726 td->c_cc[VDISCARD] = s[C_DISCARD]; 727 # endif /* VDISCARD */ 728 # ifdef VLNEXT 729 td->c_cc[VLNEXT] = s[C_LNEXT]; 730 # endif /* VLNEXT */ 731 # ifdef VSTATUS 732 td->c_cc[VSTATUS] = s[C_STATUS]; 733 # endif /* VSTATUS */ 734 # ifdef VPAGE 735 td->c_cc[VPAGE] = s[C_PAGE]; 736 # endif /* VPAGE */ 737 # ifdef VPGOFF 738 td->c_cc[VPGOFF] = s[C_PGOFF]; 739 # endif /* VPGOFF */ 740 # ifdef VKILL2 741 td->c_cc[VKILL2] = s[C_KILL2]; 742 # endif /* VKILL2 */ 743 # ifdef VMIN 744 td->c_cc[VMIN] = s[C_MIN]; 745 # endif /* VMIN */ 746 # ifdef VTIME 747 td->c_cc[VTIME] = s[C_TIME]; 748 # endif /* VTIME */ 749 } /* tty__setchar */ 750 751 752 /* tty_bind_char(): 753 * Rebind the editline functions 754 */ 755 protected void 756 tty_bind_char(el, force) 757 EditLine *el; 758 int force; 759 { 760 unsigned char *t_n = el->el_tty.t_c[ED_IO]; 761 unsigned char *t_o = el->el_tty.t_ed.c_cc; 762 char new[2], old[2]; 763 ttymap_t *tp; 764 el_action_t *dmap, *dalt, *map, *alt; 765 new[1] = old[1] = '\0'; 766 767 768 map = el->el_map.key; 769 alt = el->el_map.alt; 770 if (el->el_map.type == MAP_VI) { 771 dmap = el->el_map.vii; 772 dalt = el->el_map.vic; 773 } 774 else { 775 dmap = el->el_map.emacs; 776 dalt = NULL; 777 } 778 779 for (tp = tty_map; tp->nch != -1; tp++) { 780 new[0] = t_n[tp->nch]; 781 old[0] = t_o[tp->och]; 782 if (new[0] == old[0] && !force) 783 continue; 784 /* Put the old default binding back, and set the new binding */ 785 key_clear(el, map, old); 786 map[(int)old[0]] = dmap[(int)old[0]]; 787 key_clear(el, map, new); 788 /* MAP_VI == 1, MAP_EMACS == 0... */ 789 map[(int)new[0]] = tp->bind[(int)el->el_map.type]; 790 if (dalt) { 791 key_clear(el, alt, old); 792 alt[(int)old[0]] = dalt[(int)old[0]]; 793 key_clear(el, alt, new); 794 alt[(int)new[0]] = tp->bind[(int)el->el_map.type+1]; 795 } 796 } 797 } 798 799 /* tty_rawmode(): 800 * Set terminal into 1 character at a time mode. 801 */ 802 protected int 803 tty_rawmode(el) 804 EditLine *el; 805 { 806 if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO) 807 return (0); 808 809 if (tty_getty(el, &el->el_tty.t_ts) == -1) { 810 #ifdef DEBUG_TTY 811 (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", strerror(errno)); 812 #endif /* DEBUG_TTY */ 813 return(-1); 814 } 815 816 /* 817 * We always keep up with the eight bit setting and the speed of the 818 * tty. But only we only believe changes that are made to cooked mode! 819 */ 820 el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts); 821 el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts); 822 823 if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed || 824 tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) { 825 (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed); 826 (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed); 827 (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed); 828 (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed); 829 } 830 831 if (tty__cooked_mode(&el->el_tty.t_ts)) { 832 if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) { 833 el->el_tty.t_ex.c_cflag = el->el_tty.t_ts.c_cflag; 834 el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask; 835 el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask; 836 837 el->el_tty.t_ed.c_cflag = el->el_tty.t_ts.c_cflag; 838 el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask; 839 el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask; 840 } 841 842 if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) && 843 (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) { 844 el->el_tty.t_ex.c_lflag = el->el_tty.t_ts.c_lflag; 845 el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask; 846 el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask; 847 848 el->el_tty.t_ed.c_lflag = el->el_tty.t_ts.c_lflag; 849 el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask; 850 el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask; 851 } 852 853 if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) && 854 (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) { 855 el->el_tty.t_ex.c_iflag = el->el_tty.t_ts.c_iflag; 856 el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask; 857 el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask; 858 859 el->el_tty.t_ed.c_iflag = el->el_tty.t_ts.c_iflag; 860 el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; 861 el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask; 862 } 863 864 if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) && 865 (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) { 866 el->el_tty.t_ex.c_oflag = el->el_tty.t_ts.c_oflag; 867 el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask; 868 el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask; 869 870 el->el_tty.t_ed.c_oflag = el->el_tty.t_ts.c_oflag; 871 el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask; 872 el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask; 873 } 874 875 if (tty__gettabs(&el->el_tty.t_ex) == 0) 876 el->el_tty.t_tabs = 0; 877 else 878 el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0; 879 880 { 881 int i; 882 883 tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); 884 /* 885 * Check if the user made any changes. 886 * If he did, then propagate the changes to the 887 * edit and execute data structures. 888 */ 889 for (i = 0; i < C_NCC; i++) 890 if (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]) 891 break; 892 893 if (i != C_NCC) { 894 /* 895 * Propagate changes only to the unprotected chars 896 * that have been modified just now. 897 */ 898 for (i = 0; i < C_NCC; i++) { 899 if (!((el->el_tty.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i))) 900 && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])) 901 el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i]; 902 if (el->el_tty.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i)) 903 el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable; 904 } 905 tty_bind_char(el, 0); 906 tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); 907 908 for (i = 0; i < C_NCC; i++) { 909 if (!((el->el_tty.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i))) 910 && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])) 911 el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i]; 912 if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i)) 913 el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable; 914 } 915 tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); 916 } 917 } 918 } 919 920 if (tty_setty(el, &el->el_tty.t_ed) == -1) { 921 #ifdef DEBUG_TTY 922 (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n", 923 strerror(errno)); 924 #endif /* DEBUG_TTY */ 925 return -1; 926 } 927 el->el_tty.t_mode = ED_IO; 928 return (0); 929 } /* end tty_rawmode */ 930 931 932 /* tty_cookedmode(): 933 * Set the tty back to normal mode 934 */ 935 protected int 936 tty_cookedmode(el) 937 EditLine *el; 938 { /* set tty in normal setup */ 939 if (el->el_tty.t_mode == EX_IO) 940 return (0); 941 942 if (tty_setty(el, &el->el_tty.t_ex) == -1) { 943 #ifdef DEBUG_TTY 944 (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n", 945 strerror(errno)); 946 #endif /* DEBUG_TTY */ 947 return -1; 948 } 949 el->el_tty.t_mode = EX_IO; 950 return (0); 951 } /* end tty_cookedmode */ 952 953 954 /* tty_quotemode(): 955 * Turn on quote mode 956 */ 957 protected int 958 tty_quotemode(el) 959 EditLine *el; 960 { 961 if (el->el_tty.t_mode == QU_IO) 962 return 0; 963 964 el->el_tty.t_qu = el->el_tty.t_ed; 965 966 el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask; 967 el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask; 968 969 el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask; 970 el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask; 971 972 el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask; 973 el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask; 974 975 el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask; 976 el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask; 977 978 if (tty_setty(el, &el->el_tty.t_qu) == -1) { 979 #ifdef DEBUG_TTY 980 (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n", 981 strerror(errno)); 982 #endif /* DEBUG_TTY */ 983 return -1; 984 } 985 el->el_tty.t_mode = QU_IO; 986 return 0; 987 } /* end tty_quotemode */ 988 989 990 /* tty_noquotemode(): 991 * Turn off quote mode 992 */ 993 protected int 994 tty_noquotemode(el) 995 EditLine *el; 996 { 997 if (el->el_tty.t_mode != QU_IO) 998 return 0; 999 if (tty_setty(el, &el->el_tty.t_ed) == -1) { 1000 #ifdef DEBUG_TTY 1001 (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n", 1002 strerror(errno)); 1003 #endif /* DEBUG_TTY */ 1004 return -1; 1005 } 1006 el->el_tty.t_mode = ED_IO; 1007 return 0; 1008 } 1009 1010 /* tty_stty(): 1011 * Stty builtin 1012 */ 1013 protected int 1014 /*ARGSUSED*/ 1015 tty_stty(el, argc, argv) 1016 EditLine *el; 1017 int argc; 1018 char **argv; 1019 { 1020 ttymodes_t *m; 1021 char x, *d; 1022 int aflag = 0; 1023 char *s; 1024 char *name; 1025 int z = EX_IO; 1026 1027 if (argv == NULL) 1028 return -1; 1029 name = *argv++; 1030 1031 while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0') 1032 switch (argv[0][1]) { 1033 case 'a': 1034 aflag++; 1035 argv++; 1036 break; 1037 case 'd': 1038 argv++; 1039 z = ED_IO; 1040 break; 1041 case 'x': 1042 argv++; 1043 z = EX_IO; 1044 break; 1045 case 'q': 1046 argv++; 1047 z = QU_IO; 1048 break; 1049 default: 1050 (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n", 1051 name, argv[0][1]); 1052 return -1; 1053 } 1054 1055 if (!argv || !*argv) { 1056 int i = -1; 1057 int len = 0, st = 0, cu; 1058 for (m = ttymodes; m->m_name; m++) { 1059 if (m->m_type != i) { 1060 (void) fprintf(el->el_outfile, "%s%s", i != -1 ? "\n" : "", 1061 el->el_tty.t_t[z][m->m_type].t_name); 1062 i = m->m_type; 1063 st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name); 1064 } 1065 1066 x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) ? '+' : '\0'; 1067 x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) ? '-' : x; 1068 1069 if (x != '\0' || aflag) { 1070 1071 cu = strlen(m->m_name) + (x != '\0') + 1; 1072 1073 if (len + cu >= el->el_term.t_size.h) { 1074 (void) fprintf(el->el_outfile, "\n%*s", st, ""); 1075 len = st + cu; 1076 } 1077 else 1078 len += cu; 1079 1080 if (x != '\0') 1081 (void) fprintf(el->el_outfile, "%c%s ", x, m->m_name); 1082 else 1083 (void) fprintf(el->el_outfile, "%s ", m->m_name); 1084 } 1085 } 1086 (void) fprintf(el->el_outfile, "\n"); 1087 return 0; 1088 } 1089 1090 while (argv && (s = *argv++)) { 1091 switch (*s) { 1092 case '+': 1093 case '-': 1094 x = *s++; 1095 break; 1096 default: 1097 x = '\0'; 1098 break; 1099 } 1100 d = s; 1101 for (m = ttymodes; m->m_name; m++) 1102 if (strcmp(m->m_name, d) == 0) 1103 break; 1104 1105 if (!m->m_name) { 1106 (void) fprintf(el->el_errfile, "%s: Invalid argument `%s'.\n", 1107 name, d); 1108 return -1; 1109 } 1110 1111 switch (x) { 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 case '-': 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 default: 1121 el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value; 1122 el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value; 1123 break; 1124 } 1125 } 1126 return 0; 1127 } /* end tty_stty */ 1128 1129 1130 #ifdef notyet 1131 /* tty_printchar(): 1132 * DEbugging routine to print the tty characters 1133 */ 1134 private void 1135 tty_printchar(el, s) 1136 EditLine *el; 1137 unsigned char *s; 1138 { 1139 ttyperm_t *m; 1140 int i; 1141 1142 for (i = 0; i < C_NCC; i++) { 1143 for (m = el->el_tty.t_t; m->m_name; m++) 1144 if (m->m_type == MD_CHAR && C_SH(i) == m->m_value) 1145 break; 1146 if (m->m_name) 1147 (void) fprintf(el->el_errfile, "%s ^%c ", m->m_name, s[i] + 'A'-1); 1148 if (i % 5 == 0) 1149 (void) fprintf(el->el_errfile, "\n"); 1150 } 1151 (void) fprintf(el->el_errfile, "\n"); 1152 } 1153 #endif /* notyet */ 1154