00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "compat.h"
00047
00048
00049
00050
00051 #include "sys.h"
00052 #include "tty.h"
00053 #include "el.h"
00054 #include "errno.h"
00055 #include "stdio.h"
00056
00057
00058 struct TTYModes_t {
00059 const char* fName;
00060 u_int fValue;
00061 int fType;
00062 };
00063
00064 struct TTYMap_t {
00065 int fNCh;
00066 int fOCh;
00067 ElAction_t fBind[3];
00068 };
00069
00070
00071 el_private const TTYPerm_t ttyperm = {
00072 {
00073 { "iflag:", ICRNL, (INLCR | IGNCR) },
00074 { "oflag:", (OPOST | ONLCR), ONLRET },
00075 { "cflag:", 0, 0 },
00076 { "lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN),
00077 (NOFLSH | ECHONL | EXTPROC | FLUSHO) },
00078 { "chars:", 0, 0 },
00079 },
00080 {
00081 { "iflag:", (INLCR | ICRNL), IGNCR },
00082 { "oflag:", (OPOST | ONLCR), ONLRET },
00083 { "cflag:", 0, 0 },
00084 { "lflag:", ISIG,
00085 (NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO) },
00086 { "chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) |
00087 C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) |
00088 C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0 }
00089 },
00090 {
00091 { "iflag:", 0, IXON | IXOFF | INLCR | ICRNL },
00092 { "oflag:", 0, 0 },
00093 { "cflag:", 0, 0 },
00094 { "lflag:", 0, ISIG | IEXTEN },
00095 { "chars:", 0, 0 },
00096 }
00097 };
00098
00099 el_private const TTYChar_t ttychar = {
00100 {
00101 CINTR, CQUIT, CERASE, CKILL,
00102 CEOF, CEOL, CEOL2, CSWTCH,
00103 CDSWTCH, CERASE2, CSTART, CSTOP,
00104 CWERASE, CSUSP, CDSUSP, CREPRINT,
00105 CDISCARD, CLNEXT, CSTATUS, CPAGE,
00106 CPGOFF, CKILL2, CBRK, CMIN,
00107 CTIME
00108 },
00109 {
00110 CINTR, CQUIT, CERASE, CKILL,
00111 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
00112 _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
00113 _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
00114 CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
00115 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
00116 0
00117 },
00118 {
00119 0, 0, 0, 0,
00120 0, 0, 0, 0,
00121 0, 0, 0, 0,
00122 0, 0, 0, 0,
00123 0, 0, 0, 0,
00124 0, 0, 0, 0,
00125 0
00126 }
00127 };
00128
00129 el_private const TTYMap_t tty_map[] = {
00130 #ifdef VERASE
00131 { C_ERASE, VERASE,
00132 { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
00133 #endif
00134 #ifdef VERASE2
00135 { C_ERASE2, VERASE2,
00136 { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
00137 #endif
00138 #ifdef VKILL
00139 { C_KILL, VKILL,
00140 { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
00141 #endif
00142 #ifdef VKILL2
00143 { C_KILL2, VKILL2,
00144 { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
00145 #endif
00146 #ifdef VEOF
00147 { C_EOF, VEOF,
00148 { EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED } },
00149 #endif
00150 #ifdef VWERASE
00151 { C_WERASE, VWERASE,
00152 { ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD } },
00153 #endif
00154 #ifdef VREPRINT
00155 { C_REPRINT, VREPRINT,
00156 { ED_REDISPLAY, ED_INSERT, ED_REDISPLAY } },
00157 #endif
00158 #ifdef VLNEXT
00159 { C_LNEXT, VLNEXT,
00160 { ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED } },
00161 #endif
00162 { -1, -1,
00163 { ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED } }
00164 };
00165
00166 el_private const TTYModes_t ttymodes[] = {
00167 #ifdef IGNBRK
00168 { "ignbrk", IGNBRK, MD_INP },
00169 #endif
00170 #ifdef BRKINT
00171 { "brkint", BRKINT, MD_INP },
00172 #endif
00173 #ifdef IGNPAR
00174 { "ignpar", IGNPAR, MD_INP },
00175 #endif
00176 #ifdef PARMRK
00177 { "parmrk", PARMRK, MD_INP },
00178 #endif
00179 #ifdef INPCK
00180 { "inpck", INPCK, MD_INP },
00181 #endif
00182 #ifdef ISTRIP
00183 { "istrip", ISTRIP, MD_INP },
00184 #endif
00185 #ifdef INLCR
00186 { "inlcr", INLCR, MD_INP },
00187 #endif
00188 #ifdef IGNCR
00189 { "igncr", IGNCR, MD_INP },
00190 #endif
00191 #ifdef ICRNL
00192 { "icrnl", ICRNL, MD_INP },
00193 #endif
00194 #ifdef IUCLC
00195 { "iuclc", IUCLC, MD_INP },
00196 #endif
00197 #ifdef IXON
00198 { "ixon", IXON, MD_INP },
00199 #endif
00200 #ifdef IXANY
00201 { "ixany", IXANY, MD_INP },
00202 #endif
00203 #ifdef IXOFF
00204 { "ixoff", IXOFF, MD_INP },
00205 #endif
00206 #ifdef IMAXBEL
00207 { "imaxbel", IMAXBEL, MD_INP },
00208 #endif
00209
00210 #ifdef OPOST
00211 { "opost", OPOST, MD_OUT },
00212 #endif
00213 #ifdef OLCUC
00214 { "olcuc", OLCUC, MD_OUT },
00215 #endif
00216 #ifdef ONLCR
00217 { "onlcr", ONLCR, MD_OUT },
00218 #endif
00219 #ifdef OCRNL
00220 { "ocrnl", OCRNL, MD_OUT },
00221 #endif
00222 #ifdef ONOCR
00223 { "onocr", ONOCR, MD_OUT },
00224 #endif
00225 #ifdef ONOEOT
00226 { "onoeot", ONOEOT, MD_OUT },
00227 #endif
00228 #ifdef ONLRET
00229 { "onlret", ONLRET, MD_OUT },
00230 #endif
00231 #ifdef OFILL
00232 { "ofill", OFILL, MD_OUT },
00233 #endif
00234 #ifdef OFDEL
00235 { "ofdel", OFDEL, MD_OUT },
00236 #endif
00237 #ifdef NLDLY
00238 { "nldly", NLDLY, MD_OUT },
00239 #endif
00240 #ifdef CRDLY
00241 { "crdly", CRDLY, MD_OUT },
00242 #endif
00243 #ifdef TABDLY
00244 { "tabdly", TABDLY, MD_OUT },
00245 #endif
00246 #ifdef XTABS
00247 { "xtabs", XTABS, MD_OUT },
00248 #endif
00249 #ifdef BSDLY
00250 { "bsdly", BSDLY, MD_OUT },
00251 #endif
00252 #ifdef VTDLY
00253 { "vtdly", VTDLY, MD_OUT },
00254 #endif
00255 #ifdef FFDLY
00256 { "ffdly", FFDLY, MD_OUT },
00257 #endif
00258 #ifdef PAGEOUT
00259 { "pageout", PAGEOUT, MD_OUT },
00260 #endif
00261 #ifdef WRAP
00262 { "wrap", WRAP, MD_OUT },
00263 #endif
00264
00265 #ifdef CIGNORE
00266 { "cignore", CIGNORE, MD_CTL },
00267 #endif
00268 #ifdef CBAUD
00269 { "cbaud", CBAUD, MD_CTL },
00270 #endif
00271 #ifdef CSTOPB
00272 { "cstopb", CSTOPB, MD_CTL },
00273 #endif
00274 #ifdef CREAD
00275 { "cread", CREAD, MD_CTL },
00276 #endif
00277 #ifdef PARENB
00278 { "parenb", PARENB, MD_CTL },
00279 #endif
00280 #ifdef PARODD
00281 { "parodd", PARODD, MD_CTL },
00282 #endif
00283 #ifdef HUPCL
00284 { "hupcl", HUPCL, MD_CTL },
00285 #endif
00286 #ifdef CLOCAL
00287 { "clocal", CLOCAL, MD_CTL },
00288 #endif
00289 #ifdef LOBLK
00290 { "loblk", LOBLK, MD_CTL },
00291 #endif
00292 #ifdef CIBAUD
00293 { "cibaud", CIBAUD, MD_CTL },
00294 #endif
00295 #ifdef CRTSCTS
00296 # ifdef CCTS_OFLOW
00297 { "ccts_oflow", CCTS_OFLOW, MD_CTL },
00298 # else
00299 { "crtscts", CRTSCTS, MD_CTL },
00300 # endif
00301 #endif
00302 #ifdef CRTS_IFLOW
00303 { "crts_iflow", CRTS_IFLOW, MD_CTL },
00304 #endif
00305 #ifdef CDTRCTS
00306 { "cdtrcts", CDTRCTS, MD_CTL },
00307 #endif
00308 #ifdef MDMBUF
00309 { "mdmbuf", MDMBUF, MD_CTL },
00310 #endif
00311 #ifdef RCV1EN
00312 { "rcv1en", RCV1EN, MD_CTL },
00313 #endif
00314 #ifdef XMT1EN
00315 { "xmt1en", XMT1EN, MD_CTL },
00316 #endif
00317
00318 #ifdef ISIG
00319 { "isig", ISIG, MD_LIN },
00320 #endif
00321 #ifdef ICANON
00322 { "icanon", ICANON, MD_LIN },
00323 #endif
00324 #ifdef XCASE
00325 { "xcase", XCASE, MD_LIN },
00326 #endif
00327 #ifdef ECHO
00328 { "echo", ECHO, MD_LIN },
00329 #endif
00330 #ifdef ECHOE
00331 { "echoe", ECHOE, MD_LIN },
00332 #endif
00333 #ifdef ECHOK
00334 { "echok", ECHOK, MD_LIN },
00335 #endif
00336 #ifdef ECHONL
00337 { "echonl", ECHONL, MD_LIN },
00338 #endif
00339 #ifdef NOFLSH
00340 { "noflsh", NOFLSH, MD_LIN },
00341 #endif
00342 #ifdef TOSTOP
00343 { "tostop", TOSTOP, MD_LIN },
00344 #endif
00345 #ifdef ECHOCTL
00346 { "echoctl", ECHOCTL, MD_LIN },
00347 #endif
00348 #ifdef ECHOPRT
00349 { "echoprt", ECHOPRT, MD_LIN },
00350 #endif
00351 #ifdef ECHOKE
00352 { "echoke", ECHOKE, MD_LIN },
00353 #endif
00354 #ifdef DEFECHO
00355 { "defecho", DEFECHO, MD_LIN },
00356 #endif
00357 #ifdef FLUSHO
00358 { "flusho", FLUSHO, MD_LIN },
00359 #endif
00360 #ifdef PENDIN
00361 { "pendin", PENDIN, MD_LIN },
00362 #endif
00363 #ifdef IEXTEN
00364 { "iexten", IEXTEN, MD_LIN },
00365 #endif
00366 #ifdef NOKERNINFO
00367 { "nokerninfo", NOKERNINFO, MD_LIN },
00368 #endif
00369 #ifdef ALTWERASE
00370 { "altwerase", ALTWERASE, MD_LIN },
00371 #endif
00372 #ifdef EXTPROC
00373 { "extproc", EXTPROC, MD_LIN },
00374 #endif
00375
00376 #if defined(VINTR)
00377 { "intr", C_SH(C_INTR), MD_CHAR },
00378 #endif
00379 #if defined(VQUIT)
00380 { "quit", C_SH(C_QUIT), MD_CHAR },
00381 #endif
00382 #if defined(VERASE)
00383 { "erase", C_SH(C_ERASE), MD_CHAR },
00384 #endif
00385 #if defined(VKILL)
00386 { "kill", C_SH(C_KILL), MD_CHAR },
00387 #endif
00388 #if defined(VEOF)
00389 { "eof", C_SH(C_EOF), MD_CHAR },
00390 #endif
00391 #if defined(VEOL)
00392 { "eol", C_SH(C_EOL), MD_CHAR },
00393 #endif
00394 #if defined(VEOL2)
00395 { "eol2", C_SH(C_EOL2), MD_CHAR },
00396 #endif
00397 #if defined(VSWTCH)
00398 { "swtch", C_SH(C_SWTCH), MD_CHAR },
00399 #endif
00400 #if defined(VDSWTCH)
00401 { "dswtch", C_SH(C_DSWTCH), MD_CHAR },
00402 #endif
00403 #if defined(VERASE2)
00404 { "erase2", C_SH(C_ERASE2), MD_CHAR },
00405 #endif
00406 #if defined(VSTART)
00407 { "start", C_SH(C_START), MD_CHAR },
00408 #endif
00409 #if defined(VSTOP)
00410 { "stop", C_SH(C_STOP), MD_CHAR },
00411 #endif
00412 #if defined(VWERASE)
00413 { "werase", C_SH(C_WERASE), MD_CHAR },
00414 #endif
00415 #if defined(VSUSP)
00416 { "susp", C_SH(C_SUSP), MD_CHAR },
00417 #endif
00418 #if defined(VDSUSP)
00419 { "dsusp", C_SH(C_DSUSP), MD_CHAR },
00420 #endif
00421 #if defined(VREPRINT)
00422 { "reprint", C_SH(C_REPRINT), MD_CHAR },
00423 #endif
00424 #if defined(VDISCARD)
00425 { "discard", C_SH(C_DISCARD), MD_CHAR },
00426 #endif
00427 #if defined(VLNEXT)
00428 { "lnext", C_SH(C_LNEXT), MD_CHAR },
00429 #endif
00430 #if defined(VSTATUS)
00431 { "status", C_SH(C_STATUS), MD_CHAR },
00432 #endif
00433 #if defined(VPAGE)
00434 { "page", C_SH(C_PAGE), MD_CHAR },
00435 #endif
00436 #if defined(VPGOFF)
00437 { "pgoff", C_SH(C_PGOFF), MD_CHAR },
00438 #endif
00439 #if defined(VKILL2)
00440 { "kill2", C_SH(C_KILL2), MD_CHAR },
00441 #endif
00442 #if defined(VBRK)
00443 { "brk", C_SH(C_BRK), MD_CHAR },
00444 #endif
00445 #if defined(VMIN)
00446 { "min", C_SH(C_MIN), MD_CHAR },
00447 #endif
00448 #if defined(VTIME)
00449 { "time", C_SH(C_TIME), MD_CHAR },
00450 #endif
00451 { NULL, 0, -1 },
00452 };
00453
00454
00455 #define tty_getty(el, td) tcgetattr((el)->fInFD, (td))
00456 #define tty_setty(el, td) tcsetattr((el)->fInFD, TCSADRAIN, (td))
00457
00458 #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
00459 #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
00460 #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
00461
00462 el_private void tty__getchar(struct termios*, unsigned char*);
00463 el_private void tty__setchar(struct termios*, unsigned char*);
00464 el_private speed_t tty__getspeed(struct termios*);
00465 el_private int tty_setup(EditLine_t*);
00466
00467 #define t_qu t_ts
00468
00469
00470
00471
00472
00473 int
00474 tty_can_output(void)
00475 {
00476 return (getpgrp() == tcgetpgrp(STDOUT_FILENO));
00477 }
00478
00479 bool tty_need_to_run_setup = false;
00480
00481
00482
00483
00484 el_private int
00485 tty_setup(EditLine_t* el) {
00486 int rst = 1;
00487 if (!tty_can_output()) {
00488 tty_need_to_run_setup = true;
00489 return 0;
00490 }
00491 tty_need_to_run_setup = false;
00492
00493
00494
00495
00496
00497
00498
00499 if (tty_getty(el, &el->fTTY.t_ed) == -1) {
00500 #ifdef DEBUG_TTY
00501 (void) fprintf(el->fErrFile,
00502 "tty_setup: tty_getty: %s\n", strerror(errno));
00503 #endif
00504 return -1;
00505 }
00506 el->fTTY.t_ts = el->fTTY.t_ex = el->fTTY.t_ed;
00507
00508 el->fTTY.t_speed = tty__getspeed(&el->fTTY.t_ex);
00509 el->fTTY.t_tabs = tty__gettabs(&el->fTTY.t_ex);
00510 el->fTTY.t_eight = tty__geteightbit(&el->fTTY.t_ex);
00511
00512 el->fTTY.t_ex.c_iflag &= ~el->fTTY.t_t[EX_IO][MD_INP].t_clrmask;
00513 el->fTTY.t_ex.c_iflag |= el->fTTY.t_t[EX_IO][MD_INP].t_setmask;
00514
00515 el->fTTY.t_ex.c_oflag &= ~el->fTTY.t_t[EX_IO][MD_OUT].t_clrmask;
00516 el->fTTY.t_ex.c_oflag |= el->fTTY.t_t[EX_IO][MD_OUT].t_setmask;
00517
00518 el->fTTY.t_ex.c_cflag &= ~el->fTTY.t_t[EX_IO][MD_CTL].t_clrmask;
00519 el->fTTY.t_ex.c_cflag |= el->fTTY.t_t[EX_IO][MD_CTL].t_setmask;
00520
00521 el->fTTY.t_ex.c_lflag &= ~el->fTTY.t_t[EX_IO][MD_LIN].t_clrmask;
00522 el->fTTY.t_ex.c_lflag |= el->fTTY.t_t[EX_IO][MD_LIN].t_setmask;
00523
00524
00525
00526
00527
00528 if (rst) {
00529 if (tty__cooked_mode(&el->fTTY.t_ts)) {
00530 tty__getchar(&el->fTTY.t_ts, el->fTTY.t_c[TS_IO]);
00531
00532
00533
00534
00535 for (rst = 0; rst < C_NCC - 2; rst++) {
00536 if (el->fTTY.t_c[TS_IO][rst] !=
00537 el->fTTY.t_vdisable
00538 && el->fTTY.t_c[ED_IO][rst] !=
00539 el->fTTY.t_vdisable) {
00540 el->fTTY.t_c[ED_IO][rst] =
00541 el->fTTY.t_c[TS_IO][rst];
00542 }
00543 }
00544
00545 for (rst = 0; rst < C_NCC; rst++) {
00546 if (el->fTTY.t_c[TS_IO][rst] !=
00547 el->fTTY.t_vdisable) {
00548 el->fTTY.t_c[EX_IO][rst] =
00549 el->fTTY.t_c[TS_IO][rst];
00550 }
00551 }
00552 }
00553 tty__setchar(&el->fTTY.t_ex, el->fTTY.t_c[EX_IO]);
00554
00555 if (tty_setty(el, &el->fTTY.t_ex) == -1) {
00556 #ifdef DEBUG_TTY
00557 (void) fprintf(el->fErrFile,
00558 "tty_setup: tty_setty: %s\n",
00559 strerror(errno));
00560 #endif
00561 return -1;
00562 }
00563 } else {
00564
00565
00566 tty__setchar(&el->fTTY.t_ex, el->fTTY.t_c[EX_IO]);
00567 }
00568
00569 el->fTTY.t_ed.c_iflag &= ~el->fTTY.t_t[ED_IO][MD_INP].t_clrmask;
00570 el->fTTY.t_ed.c_iflag |= el->fTTY.t_t[ED_IO][MD_INP].t_setmask;
00571
00572 el->fTTY.t_ed.c_oflag &= ~el->fTTY.t_t[ED_IO][MD_OUT].t_clrmask;
00573 el->fTTY.t_ed.c_oflag |= el->fTTY.t_t[ED_IO][MD_OUT].t_setmask;
00574
00575 el->fTTY.t_ed.c_cflag &= ~el->fTTY.t_t[ED_IO][MD_CTL].t_clrmask;
00576 el->fTTY.t_ed.c_cflag |= el->fTTY.t_t[ED_IO][MD_CTL].t_setmask;
00577
00578 el->fTTY.t_ed.c_lflag &= ~el->fTTY.t_t[ED_IO][MD_LIN].t_clrmask;
00579 el->fTTY.t_ed.c_lflag |= el->fTTY.t_t[ED_IO][MD_LIN].t_setmask;
00580
00581 tty__setchar(&el->fTTY.t_ed, el->fTTY.t_c[ED_IO]);
00582 tty_bind_char(el, 1);
00583
00584 el_set(el, EL_EDITMODE, 1);
00585 return 0;
00586 }
00587
00588
00589 el_protected int
00590 tty_init(EditLine_t* el) {
00591 el->fTTY.t_mode = EX_IO;
00592 el->fTTY.t_vdisable = _POSIX_VDISABLE;
00593 (void) memcpy(el->fTTY.t_t, ttyperm, sizeof(TTYPerm_t));
00594 (void) memcpy(el->fTTY.t_c, ttychar, sizeof(TTYChar_t));
00595 return tty_setup(el);
00596 }
00597
00598
00599
00600
00601
00602 el_protected void
00603
00604 tty_end(EditLine_t* ) {
00605
00606 }
00607
00608
00609
00610
00611
00612 el_private speed_t
00613 tty__getspeed(struct termios* td) {
00614 speed_t spd;
00615
00616 if ((spd = cfgetispeed(td)) == 0) {
00617 spd = cfgetospeed(td);
00618 }
00619 return spd;
00620 }
00621
00622
00623
00624
00625
00626 el_private void
00627 tty__getchar(struct termios* td, unsigned char* s) {
00628 #ifdef VINTR
00629 s[C_INTR] = td->c_cc[VINTR];
00630 #endif
00631 #ifdef VQUIT
00632 s[C_QUIT] = td->c_cc[VQUIT];
00633 #endif
00634 #ifdef VERASE
00635 s[C_ERASE] = td->c_cc[VERASE];
00636 #endif
00637 #ifdef VKILL
00638 s[C_KILL] = td->c_cc[VKILL];
00639 #endif
00640 #ifdef VEOF
00641 s[C_EOF] = td->c_cc[VEOF];
00642 #endif
00643 #ifdef VEOL
00644 s[C_EOL] = td->c_cc[VEOL];
00645 #endif
00646 #ifdef VEOL2
00647 s[C_EOL2] = td->c_cc[VEOL2];
00648 #endif
00649 #ifdef VSWTCH
00650 s[C_SWTCH] = td->c_cc[VSWTCH];
00651 #endif
00652 #ifdef VDSWTCH
00653 s[C_DSWTCH] = td->c_cc[VDSWTCH];
00654 #endif
00655 #ifdef VERASE2
00656 s[C_ERASE2] = td->c_cc[VERASE2];
00657 #endif
00658 #ifdef VSTART
00659 s[C_START] = td->c_cc[VSTART];
00660 #endif
00661 #ifdef VSTOP
00662 s[C_STOP] = td->c_cc[VSTOP];
00663 #endif
00664 #ifdef VWERASE
00665 s[C_WERASE] = td->c_cc[VWERASE];
00666 #endif
00667 #ifdef VSUSP
00668 s[C_SUSP] = td->c_cc[VSUSP];
00669 #endif
00670 #ifdef VDSUSP
00671 s[C_DSUSP] = td->c_cc[VDSUSP];
00672 #endif
00673 #ifdef VREPRINT
00674 s[C_REPRINT] = td->c_cc[VREPRINT];
00675 #endif
00676 #ifdef VDISCARD
00677 s[C_DISCARD] = td->c_cc[VDISCARD];
00678 #endif
00679 #ifdef VLNEXT
00680 s[C_LNEXT] = td->c_cc[VLNEXT];
00681 #endif
00682 #ifdef VSTATUS
00683 s[C_STATUS] = td->c_cc[VSTATUS];
00684 #endif
00685 #ifdef VPAGE
00686 s[C_PAGE] = td->c_cc[VPAGE];
00687 #endif
00688 #ifdef VPGOFF
00689 s[C_PGOFF] = td->c_cc[VPGOFF];
00690 #endif
00691 #ifdef VKILL2
00692 s[C_KILL2] = td->c_cc[VKILL2];
00693 #endif
00694 #ifdef VMIN
00695 s[C_MIN] = td->c_cc[VMIN];
00696 #endif
00697 #ifdef VTIME
00698 s[C_TIME] = td->c_cc[VTIME];
00699 #endif
00700 }
00701
00702
00703
00704
00705
00706 el_private void
00707 tty__setchar(struct termios* td, unsigned char* s) {
00708 #ifdef VINTR
00709 td->c_cc[VINTR] = s[C_INTR];
00710 #endif
00711 #ifdef VQUIT
00712 td->c_cc[VQUIT] = s[C_QUIT];
00713 #endif
00714 #ifdef VERASE
00715 td->c_cc[VERASE] = s[C_ERASE];
00716 #endif
00717 #ifdef VKILL
00718 td->c_cc[VKILL] = s[C_KILL];
00719 #endif
00720 #ifdef VEOF
00721 td->c_cc[VEOF] = s[C_EOF];
00722 #endif
00723 #ifdef VEOL
00724 td->c_cc[VEOL] = s[C_EOL];
00725 #endif
00726 #ifdef VEOL2
00727 td->c_cc[VEOL2] = s[C_EOL2];
00728 #endif
00729 #ifdef VSWTCH
00730 td->c_cc[VSWTCH] = s[C_SWTCH];
00731 #endif
00732 #ifdef VDSWTCH
00733 td->c_cc[VDSWTCH] = s[C_DSWTCH];
00734 #endif
00735 #ifdef VERASE2
00736 td->c_cc[VERASE2] = s[C_ERASE2];
00737 #endif
00738 #ifdef VSTART
00739 td->c_cc[VSTART] = s[C_START];
00740 #endif
00741 #ifdef VSTOP
00742 td->c_cc[VSTOP] = s[C_STOP];
00743 #endif
00744 #ifdef VWERASE
00745 td->c_cc[VWERASE] = s[C_WERASE];
00746 #endif
00747 #ifdef VSUSP
00748 td->c_cc[VSUSP] = s[C_SUSP];
00749 #endif
00750 #ifdef VDSUSP
00751 td->c_cc[VDSUSP] = s[C_DSUSP];
00752 #endif
00753 #ifdef VREPRINT
00754 td->c_cc[VREPRINT] = s[C_REPRINT];
00755 #endif
00756 #ifdef VDISCARD
00757 td->c_cc[VDISCARD] = s[C_DISCARD];
00758 #endif
00759 #ifdef VLNEXT
00760 td->c_cc[VLNEXT] = s[C_LNEXT];
00761 #endif
00762 #ifdef VSTATUS
00763 td->c_cc[VSTATUS] = s[C_STATUS];
00764 #endif
00765 #ifdef VPAGE
00766 td->c_cc[VPAGE] = s[C_PAGE];
00767 #endif
00768 #ifdef VPGOFF
00769 td->c_cc[VPGOFF] = s[C_PGOFF];
00770 #endif
00771 #ifdef VKILL2
00772 td->c_cc[VKILL2] = s[C_KILL2];
00773 #endif
00774 #ifdef VMIN
00775 td->c_cc[VMIN] = s[C_MIN];
00776 #endif
00777 #ifdef VTIME
00778 td->c_cc[VTIME] = s[C_TIME];
00779 #endif
00780 }
00781
00782
00783
00784
00785
00786 el_protected void
00787 tty_bind_char(EditLine_t* el, int force) {
00788 unsigned char* t_n = el->fTTY.t_c[ED_IO];
00789 unsigned char* t_o = el->fTTY.t_ed.c_cc;
00790 unsigned char newp[2], old[2];
00791 const TTYMap_t* tp;
00792 ElAction_t* map, * alt;
00793 const ElAction_t* dmap, * dalt;
00794 newp[1] = old[1] = '\0';
00795
00796 map = el->fMap.fKey;
00797 alt = el->fMap.fAlt;
00798
00799 if (el->fMap.fType == MAP_VI) {
00800 dmap = el->fMap.fVii;
00801 dalt = el->fMap.fVic;
00802 } else {
00803 dmap = el->fMap.fEmacs;
00804 dalt = NULL;
00805 }
00806
00807 for (tp = tty_map; tp->fNCh != -1; tp++) {
00808 newp[0] = t_n[tp->fNCh];
00809 old[0] = t_o[tp->fOCh];
00810
00811 if (newp[0] == old[0] && !force) {
00812 continue;
00813 }
00814
00815 key_clear(el, map, (char*) old);
00816 map[old[0]] = dmap[old[0]];
00817 key_clear(el, map, (char*) newp);
00818
00819 map[newp[0]] = tp->fBind[el->fMap.fType];
00820
00821 if (dalt) {
00822 key_clear(el, alt, (char*) old);
00823 alt[old[0]] = dalt[old[0]];
00824 key_clear(el, alt, (char*) newp);
00825 alt[newp[0]] = tp->fBind[el->fMap.fType + 1];
00826 }
00827 }
00828 }
00829
00830
00831
00832
00833
00834 el_protected int
00835 tty_rawmode(EditLine_t* el) {
00836 if (tty_need_to_run_setup) {
00837 tty_setup(el);
00838 if (tty_need_to_run_setup)
00839 return 0;
00840 }
00841
00842 if (el->fTTY.t_mode == ED_IO || el->fTTY.t_mode == QU_IO) {
00843 return 0;
00844 }
00845
00846 if (el->fFlags & EDIT_DISABLED) {
00847 return 0;
00848 }
00849
00850 if (tty_getty(el, &el->fTTY.t_ts) == -1) {
00851 #ifdef DEBUG_TTY
00852 (void) fprintf(el->fErrFile, "tty_rawmode: tty_getty: %s\n",
00853 strerror(errno));
00854 #endif
00855 return -1;
00856 }
00857
00858
00859
00860
00861
00862 el->fTTY.t_eight = tty__geteightbit(&el->fTTY.t_ts);
00863 el->fTTY.t_speed = tty__getspeed(&el->fTTY.t_ts);
00864
00865 if (tty__getspeed(&el->fTTY.t_ex) != el->fTTY.t_speed ||
00866 tty__getspeed(&el->fTTY.t_ed) != el->fTTY.t_speed) {
00867 (void) cfsetispeed(&el->fTTY.t_ex, el->fTTY.t_speed);
00868 (void) cfsetospeed(&el->fTTY.t_ex, el->fTTY.t_speed);
00869 (void) cfsetispeed(&el->fTTY.t_ed, el->fTTY.t_speed);
00870 (void) cfsetospeed(&el->fTTY.t_ed, el->fTTY.t_speed);
00871 }
00872
00873 if (tty__cooked_mode(&el->fTTY.t_ts)) {
00874 if (el->fTTY.t_ts.c_cflag != el->fTTY.t_ex.c_cflag) {
00875 el->fTTY.t_ex.c_cflag =
00876 el->fTTY.t_ts.c_cflag;
00877 el->fTTY.t_ex.c_cflag &=
00878 ~el->fTTY.t_t[EX_IO][MD_CTL].t_clrmask;
00879 el->fTTY.t_ex.c_cflag |=
00880 el->fTTY.t_t[EX_IO][MD_CTL].t_setmask;
00881
00882 el->fTTY.t_ed.c_cflag =
00883 el->fTTY.t_ts.c_cflag;
00884 el->fTTY.t_ed.c_cflag &=
00885 ~el->fTTY.t_t[ED_IO][MD_CTL].t_clrmask;
00886 el->fTTY.t_ed.c_cflag |=
00887 el->fTTY.t_t[ED_IO][MD_CTL].t_setmask;
00888 }
00889
00890 if ((el->fTTY.t_ts.c_lflag != el->fTTY.t_ex.c_lflag) &&
00891 (el->fTTY.t_ts.c_lflag != el->fTTY.t_ed.c_lflag)) {
00892 el->fTTY.t_ex.c_lflag =
00893 el->fTTY.t_ts.c_lflag;
00894 el->fTTY.t_ex.c_lflag &=
00895 ~el->fTTY.t_t[EX_IO][MD_LIN].t_clrmask;
00896 el->fTTY.t_ex.c_lflag |=
00897 el->fTTY.t_t[EX_IO][MD_LIN].t_setmask;
00898
00899 el->fTTY.t_ed.c_lflag =
00900 el->fTTY.t_ts.c_lflag;
00901 el->fTTY.t_ed.c_lflag &=
00902 ~el->fTTY.t_t[ED_IO][MD_LIN].t_clrmask;
00903 el->fTTY.t_ed.c_lflag |=
00904 el->fTTY.t_t[ED_IO][MD_LIN].t_setmask;
00905 }
00906
00907 if ((el->fTTY.t_ts.c_iflag != el->fTTY.t_ex.c_iflag) &&
00908 (el->fTTY.t_ts.c_iflag != el->fTTY.t_ed.c_iflag)) {
00909 el->fTTY.t_ex.c_iflag =
00910 el->fTTY.t_ts.c_iflag;
00911 el->fTTY.t_ex.c_iflag &=
00912 ~el->fTTY.t_t[EX_IO][MD_INP].t_clrmask;
00913 el->fTTY.t_ex.c_iflag |=
00914 el->fTTY.t_t[EX_IO][MD_INP].t_setmask;
00915
00916 el->fTTY.t_ed.c_iflag =
00917 el->fTTY.t_ts.c_iflag;
00918 el->fTTY.t_ed.c_iflag &=
00919 ~el->fTTY.t_t[ED_IO][MD_INP].t_clrmask;
00920 el->fTTY.t_ed.c_iflag |=
00921 el->fTTY.t_t[ED_IO][MD_INP].t_setmask;
00922 }
00923
00924 if ((el->fTTY.t_ts.c_oflag != el->fTTY.t_ex.c_oflag) &&
00925 (el->fTTY.t_ts.c_oflag != el->fTTY.t_ed.c_oflag)) {
00926 el->fTTY.t_ex.c_oflag =
00927 el->fTTY.t_ts.c_oflag;
00928 el->fTTY.t_ex.c_oflag &=
00929 ~el->fTTY.t_t[EX_IO][MD_OUT].t_clrmask;
00930 el->fTTY.t_ex.c_oflag |=
00931 el->fTTY.t_t[EX_IO][MD_OUT].t_setmask;
00932
00933 el->fTTY.t_ed.c_oflag =
00934 el->fTTY.t_ts.c_oflag;
00935 el->fTTY.t_ed.c_oflag &=
00936 ~el->fTTY.t_t[ED_IO][MD_OUT].t_clrmask;
00937 el->fTTY.t_ed.c_oflag |=
00938 el->fTTY.t_t[ED_IO][MD_OUT].t_setmask;
00939 }
00940
00941 if (tty__gettabs(&el->fTTY.t_ex) == 0) {
00942 el->fTTY.t_tabs = 0;
00943 } else {
00944 el->fTTY.t_tabs = EL_CAN_TAB ? 1 : 0;
00945 }
00946
00947 {
00948 int i;
00949
00950 tty__getchar(&el->fTTY.t_ts, el->fTTY.t_c[TS_IO]);
00951
00952
00953
00954
00955
00956
00957 for (i = 0; i < C_NCC; i++) {
00958 if (el->fTTY.t_c[TS_IO][i] !=
00959 el->fTTY.t_c[EX_IO][i]) {
00960 break;
00961 }
00962 }
00963
00964 if (i != C_NCC) {
00965
00966
00967
00968
00969 for (i = 0; i < C_NCC; i++) {
00970 if (!((el->fTTY.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i)))
00971 && (el->fTTY.t_c[TS_IO][i] != el->fTTY.t_c[EX_IO][i])) {
00972 el->fTTY.t_c[ED_IO][i] = el->fTTY.t_c[TS_IO][i];
00973 }
00974
00975 if (el->fTTY.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i)) {
00976 el->fTTY.t_c[ED_IO][i] = el->fTTY.t_vdisable;
00977 }
00978 }
00979 tty_bind_char(el, 0);
00980 tty__setchar(&el->fTTY.t_ed, el->fTTY.t_c[ED_IO]);
00981
00982 for (i = 0; i < C_NCC; i++) {
00983 if (!((el->fTTY.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i)))
00984 && (el->fTTY.t_c[TS_IO][i] != el->fTTY.t_c[EX_IO][i])) {
00985 el->fTTY.t_c[EX_IO][i] = el->fTTY.t_c[TS_IO][i];
00986 }
00987
00988 if (el->fTTY.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i)) {
00989 el->fTTY.t_c[EX_IO][i] = el->fTTY.t_vdisable;
00990 }
00991 }
00992 tty__setchar(&el->fTTY.t_ex, el->fTTY.t_c[EX_IO]);
00993 }
00994 }
00995 }
00996
00997 if (tty_setty(el, &el->fTTY.t_ed) == -1) {
00998 #ifdef DEBUG_TTY
00999 (void) fprintf(el->fErrFile, "tty_rawmode: tty_setty: %s\n",
01000 strerror(errno));
01001 #endif
01002 return -1;
01003 }
01004 el->fTTY.t_mode = ED_IO;
01005 return 0;
01006 }
01007
01008
01009
01010
01011
01012 el_protected int
01013 tty_cookedmode(EditLine_t* el) {
01014 if (tty_need_to_run_setup) {
01015 tty_setup(el);
01016 if (tty_need_to_run_setup)
01017 return 0;
01018 }
01019
01020 if (el->fTTY.t_mode == EX_IO) {
01021 return 0;
01022 }
01023
01024 if (el->fFlags & EDIT_DISABLED) {
01025 return 0;
01026 }
01027
01028 if (tty_setty(el, &el->fTTY.t_ex) == -1) {
01029 #ifdef DEBUG_TTY
01030 (void) fprintf(el->fErrFile,
01031 "tty_cookedmode: tty_setty: %s\n",
01032 strerror(errno));
01033 #endif
01034 return -1;
01035 }
01036 el->fTTY.t_mode = EX_IO;
01037 return 0;
01038 }
01039
01040
01041
01042
01043
01044 el_protected int
01045 tty_quotemode(EditLine_t* el) {
01046 if (tty_need_to_run_setup) {
01047 tty_setup(el);
01048 if (tty_need_to_run_setup)
01049 return 0;
01050 }
01051
01052 if (el->fTTY.t_mode == QU_IO) {
01053 return 0;
01054 }
01055
01056 el->fTTY.t_qu = el->fTTY.t_ed;
01057
01058 el->fTTY.t_qu.c_iflag &= ~el->fTTY.t_t[QU_IO][MD_INP].t_clrmask;
01059 el->fTTY.t_qu.c_iflag |= el->fTTY.t_t[QU_IO][MD_INP].t_setmask;
01060
01061 el->fTTY.t_qu.c_oflag &= ~el->fTTY.t_t[QU_IO][MD_OUT].t_clrmask;
01062 el->fTTY.t_qu.c_oflag |= el->fTTY.t_t[QU_IO][MD_OUT].t_setmask;
01063
01064 el->fTTY.t_qu.c_cflag &= ~el->fTTY.t_t[QU_IO][MD_CTL].t_clrmask;
01065 el->fTTY.t_qu.c_cflag |= el->fTTY.t_t[QU_IO][MD_CTL].t_setmask;
01066
01067 el->fTTY.t_qu.c_lflag &= ~el->fTTY.t_t[QU_IO][MD_LIN].t_clrmask;
01068 el->fTTY.t_qu.c_lflag |= el->fTTY.t_t[QU_IO][MD_LIN].t_setmask;
01069
01070 if (tty_setty(el, &el->fTTY.t_qu) == -1) {
01071 #ifdef DEBUG_TTY
01072 (void) fprintf(el->fErrFile, "QuoteModeOn: tty_setty: %s\n",
01073 strerror(errno));
01074 #endif
01075 return -1;
01076 }
01077 el->fTTY.t_mode = QU_IO;
01078 return 0;
01079 }
01080
01081
01082
01083
01084
01085 el_protected int
01086 tty_noquotemode(EditLine_t* el) {
01087 if (tty_need_to_run_setup) {
01088 tty_setup(el);
01089 if (tty_need_to_run_setup)
01090 return 0;
01091 }
01092
01093 if (el->fTTY.t_mode != QU_IO) {
01094 return 0;
01095 }
01096
01097 if (tty_setty(el, &el->fTTY.t_ed) == -1) {
01098 #ifdef DEBUG_TTY
01099 (void) fprintf(el->fErrFile, "QuoteModeOff: tty_setty: %s\n",
01100 strerror(errno));
01101 #endif
01102 return -1;
01103 }
01104 el->fTTY.t_mode = ED_IO;
01105 return 0;
01106 }
01107
01108
01109
01110
01111
01112 el_protected int
01113
01114 tty_stty(EditLine_t* el, int , const char** cargv) {
01115 char** argv = (char**) cargv;
01116
01117
01118
01119
01120
01121
01122 const TTYModes_t* m;
01123 char x, * d;
01124 int aflag = 0;
01125 char* s;
01126 char* name;
01127 int z = EX_IO;
01128
01129 if (argv == NULL) {
01130 return -1;
01131 }
01132 name = *argv++;
01133
01134 while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
01135 switch (argv[0][1]) {
01136 case 'a':
01137 aflag++;
01138 argv++;
01139 break;
01140 case 'd':
01141 argv++;
01142 z = ED_IO;
01143 break;
01144 case 'x':
01145 argv++;
01146 z = EX_IO;
01147 break;
01148 case 'q':
01149 argv++;
01150 z = QU_IO;
01151 break;
01152 default:
01153 (void) fprintf(el->fErrFile,
01154 "%s: Unknown switch `%c'.\n",
01155 name, argv[0][1]);
01156 return -1;
01157 }
01158
01159 if (!argv || !*argv) {
01160 int i = -1;
01161 int len = 0, st = 0, cu;
01162
01163 for (m = ttymodes; m->fName; m++) {
01164 if (m->fType != i) {
01165 (void) fprintf(el->fOutFile, "%s%s",
01166 i != -1 ? "\n" : "",
01167 el->fTTY.t_t[z][m->fType].t_name);
01168 i = m->fType;
01169 st = len =
01170 strlen(el->fTTY.t_t[z][m->fType].t_name);
01171 }
01172 x = (el->fTTY.t_t[z][i].t_setmask & m->fValue)
01173 ? '+' : '\0';
01174 x = (el->fTTY.t_t[z][i].t_clrmask & m->fValue)
01175 ? '-' : x;
01176
01177 if (x != '\0' || aflag) {
01178 cu = strlen(m->fName) + (x != '\0') + 1;
01179
01180 if (len + cu >= el->fTerm.fSize.fH) {
01181 (void) fprintf(el->fOutFile, "\n%*s",
01182 st, "");
01183 len = st + cu;
01184 } else {
01185 len += cu;
01186 }
01187
01188 if (x != '\0') {
01189 (void) fprintf(el->fOutFile, "%c%s ",
01190 x, m->fName);
01191 } else {
01192 (void) fprintf(el->fOutFile, "%s ",
01193 m->fName);
01194 }
01195 }
01196 }
01197 (void) fprintf(el->fOutFile, "\n");
01198 return 0;
01199 }
01200
01201 while (argv && (s = *argv++)) {
01202 switch (*s) {
01203 case '+':
01204 case '-':
01205 x = *s++;
01206 break;
01207 default:
01208 x = '\0';
01209 break;
01210 }
01211 d = s;
01212
01213 for (m = ttymodes; m->fName; m++) {
01214 if (strcmp(m->fName, d) == 0) {
01215 break;
01216 }
01217 }
01218
01219 if (!m->fName) {
01220 (void) fprintf(el->fErrFile,
01221 "%s: Invalid argument `%s'.\n", name, d);
01222 return -1;
01223 }
01224
01225 switch (x) {
01226 case '+':
01227 el->fTTY.t_t[z][m->fType].t_setmask |= m->fValue;
01228 el->fTTY.t_t[z][m->fType].t_clrmask &= ~m->fValue;
01229 break;
01230 case '-':
01231 el->fTTY.t_t[z][m->fType].t_setmask &= ~m->fValue;
01232 el->fTTY.t_t[z][m->fType].t_clrmask |= m->fValue;
01233 break;
01234 default:
01235 el->fTTY.t_t[z][m->fType].t_setmask &= ~m->fValue;
01236 el->fTTY.t_t[z][m->fType].t_clrmask &= ~m->fValue;
01237 break;
01238 }
01239 }
01240 return 0;
01241 }
01242
01243
01244 #ifdef notyet
01245
01246
01247
01248
01249 el_private void
01250 tty_printchar(EditLine_t* el, unsigned char* s) {
01251 TTYPerm_t* m;
01252 int i;
01253
01254 for (i = 0; i < C_NCC; i++) {
01255 for (m = el->fTTY.t_t; m->fName; m++) {
01256 if (m->fType == MD_CHAR && C_SH(i) == m->fValue) {
01257 break;
01258 }
01259 }
01260
01261 if (m->fName) {
01262 (void) fprintf(el->fErrFile, "%s ^%c ",
01263 m->fName, s[i] + 'A' - 1);
01264 }
01265
01266 if (i % 5 == 0) {
01267 (void) fprintf(el->fErrFile, "\n");
01268 }
01269 }
01270 (void) fprintf(el->fErrFile, "\n");
01271 }
01272
01273
01274 #endif