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