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