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