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