1/* Copyright (C) 1999 Free Software Foundation, Inc.
2
3   This file is part of GNU Bash, the Bourne Again SHell.
4
5   Bash is free software; you can redistribute it and/or modify it under
6   the terms of the GNU General Public License as published by the Free
7   Software Foundation; either version 2, or (at your option) any later
8   version.
9
10   Bash is distributed in the hope that it will be useful, but WITHOUT ANY
11   WARRANTY; without even the implied warranty of MERCHANTABILITY or
12   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13   for more details.
14
15   You should have received a copy of the GNU General Public License along
16   with Bash; see the file COPYING.  If not, write to the Free Software
17   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
18
19/*
20 * shtty.c -- abstract interface to the terminal, focusing on capabilities.
21 */
22
23#ifdef HAVE_CONFIG_H
24#  include <config.h>
25#endif
26
27#ifdef HAVE_UNISTD_H
28#  include <unistd.h>
29#endif
30
31#include <shtty.h>
32
33static TTYSTRUCT ttin, ttout;
34static int ttsaved = 0;
35
36int
37ttgetattr(fd, ttp)
38int	fd;
39TTYSTRUCT *ttp;
40{
41#ifdef TERMIOS_TTY_DRIVER
42  return tcgetattr(fd, ttp);
43#else
44#  ifdef TERMIO_TTY_DRIVER
45  return ioctl(fd, TCGETA, ttp);
46#  else
47  return ioctl(fd, TIOCGETP, ttp);
48#  endif
49#endif
50}
51
52int
53ttsetattr(fd, ttp)
54int	fd;
55TTYSTRUCT *ttp;
56{
57#ifdef TERMIOS_TTY_DRIVER
58  return tcsetattr(fd, TCSADRAIN, ttp);
59#else
60#  ifdef TERMIO_TTY_DRIVER
61  return ioctl(fd, TCSETAW, ttp);
62#  else
63  return ioctl(fd, TIOCSETN, ttp);
64#  endif
65#endif
66}
67
68void
69ttsave()
70{
71  if (ttsaved)
72   return;
73  ttgetattr (0, &ttin);
74  ttgetattr (1, &ttout);
75  ttsaved = 1;
76}
77
78void
79ttrestore()
80{
81  if (ttsaved == 0)
82    return;
83  ttsetattr (0, &ttin);
84  ttsetattr (1, &ttout);
85  ttsaved = 0;
86}
87
88/* Retrieve the attributes associated with tty fd FD. */
89TTYSTRUCT *
90ttattr (fd)
91     int fd;
92{
93  if (ttsaved == 0)
94    return ((TTYSTRUCT *)0);
95  if (fd == 0)
96    return &ttin;
97  else if (fd == 1)
98    return &ttout;
99  else
100    return ((TTYSTRUCT *)0);
101}
102
103/*
104 * Change attributes in ttp so that when it is installed using
105 * ttsetattr, the terminal will be in one-char-at-a-time mode.
106 */
107int
108tt_setonechar(ttp)
109     TTYSTRUCT *ttp;
110{
111#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
112
113  /* XXX - might not want this -- it disables erase and kill processing. */
114  ttp->c_lflag &= ~ICANON;
115
116  ttp->c_lflag |= ISIG;
117#  ifdef IEXTEN
118  ttp->c_lflag |= IEXTEN;
119#  endif
120
121  ttp->c_iflag |= ICRNL;	/* make sure we get CR->NL on input */
122  ttp->c_iflag &= ~INLCR;	/* but no NL->CR */
123
124#  ifdef OPOST
125  ttp->c_oflag |= OPOST;
126#  endif
127#  ifdef ONLCR
128  ttp->c_oflag |= ONLCR;
129#  endif
130#  ifdef OCRNL
131  ttp->c_oflag &= ~OCRNL;
132#  endif
133#  ifdef ONOCR
134  ttp->c_oflag &= ~ONOCR;
135#  endif
136#  ifdef ONLRET
137  ttp->c_oflag &= ~ONLRET;
138#  endif
139
140  ttp->c_cc[VMIN] = 1;
141  ttp->c_cc[VTIME] = 0;
142
143#else
144
145  ttp->sg_flags |= CBREAK;
146
147#endif
148
149  return 0;
150}
151
152/* Set the terminal into one-character-at-a-time mode */
153int
154ttonechar ()
155{
156  TTYSTRUCT tt;
157
158  if (ttsaved == 0)
159    return -1;
160  tt = ttin;
161  if (tt_setonechar(&tt) < 0)
162    return -1;
163  return (ttsetattr (0, &tt));
164}
165
166/*
167 * Change attributes in ttp so that when it is installed using
168 * ttsetattr, the terminal will be in no-echo mode.
169 */
170int
171tt_setnoecho(ttp)
172     TTYSTRUCT *ttp;
173{
174#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
175  ttp->c_lflag &= ~(ECHO|ECHOK|ECHONL);
176#else
177  ttp->sg_flags &= ~ECHO;
178#endif
179
180  return 0;
181}
182
183/* Set the terminal into no-echo mode */
184int
185ttnoecho ()
186{
187  TTYSTRUCT tt;
188
189  if (ttsaved == 0)
190    return -1;
191  tt = ttin;
192  if (tt_setnoecho (&tt) < 0)
193    return -1;
194  return (ttsetattr (0, &tt));
195}
196
197/*
198 * Change attributes in ttp so that when it is installed using
199 * ttsetattr, the terminal will be in eight-bit mode (pass8).
200 */
201int
202tt_seteightbit (ttp)
203     TTYSTRUCT *ttp;
204{
205#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
206  ttp->c_iflag &= ~ISTRIP;
207  ttp->c_cflag |= CS8;
208  ttp->c_cflag &= ~PARENB;
209#else
210  ttp->sg_flags |= ANYP;
211#endif
212
213  return 0;
214}
215
216/* Set the terminal into eight-bit mode */
217int
218tteightbit ()
219{
220  TTYSTRUCT tt;
221
222  if (ttsaved == 0)
223    return -1;
224  tt = ttin;
225  if (tt_seteightbit (&tt) < 0)
226    return -1;
227  return (ttsetattr (0, &tt));
228}
229
230/*
231 * Change attributes in ttp so that when it is installed using
232 * ttsetattr, the terminal will be in non-canonical input mode.
233 */
234int
235tt_setnocanon (ttp)
236     TTYSTRUCT *ttp;
237{
238#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
239  ttp->c_lflag &= ~ICANON;
240#endif
241
242  return 0;
243}
244
245/* Set the terminal into non-canonical mode */
246int
247ttnocanon ()
248{
249  TTYSTRUCT tt;
250
251  if (ttsaved == 0)
252    return -1;
253  tt = ttin;
254  if (tt_setnocanon (&tt) < 0)
255    return -1;
256  return (ttsetattr (0, &tt));
257}
258
259/*
260 * Change attributes in ttp so that when it is installed using
261 * ttsetattr, the terminal will be in cbreak, no-echo mode.
262 */
263int
264tt_setcbreak(ttp)
265     TTYSTRUCT *ttp;
266{
267  if (tt_setonechar (ttp) < 0)
268    return -1;
269  return (tt_setnoecho (ttp));
270}
271
272/* Set the terminal into cbreak (no-echo, one-character-at-a-time) mode */
273int
274ttcbreak ()
275{
276  TTYSTRUCT tt;
277
278  if (ttsaved == 0)
279    return -1;
280  tt = ttin;
281  if (tt_setcbreak (&tt) < 0)
282    return -1;
283  return (ttsetattr (0, &tt));
284}
285