summaryrefslogtreecommitdiff
path: root/lib/libcurses/tty.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libcurses/tty.c')
-rw-r--r--lib/libcurses/tty.c281
1 files changed, 281 insertions, 0 deletions
diff --git a/lib/libcurses/tty.c b/lib/libcurses/tty.c
new file mode 100644
index 00000000000..d04586d853f
--- /dev/null
+++ b/lib/libcurses/tty.c
@@ -0,0 +1,281 @@
+/*-
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tty.c 8.5 (Berkeley) 8/13/94";
+#endif /* not lint */
+
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "curses.h"
+
+/*
+ * In general, curses should leave tty hardware settings alone (speed, parity,
+ * word size). This is most easily done in BSD by using TCSASOFT on all
+ * tcsetattr calls. On other systems, it would be better to get and restore
+ * those attributes at each change, or at least when stopped and restarted.
+ * See also the comments in getterm().
+ */
+#ifdef TCSASOFT
+int __tcaction = 1; /* Ignore hardware settings. */
+#else
+int __tcaction = 0;
+#endif
+
+struct termios __orig_termios, __baset;
+static struct termios cbreakt, rawt, *curt;
+static int useraw;
+
+#ifndef OXTABS
+#ifdef XTABS /* SMI uses XTABS. */
+#define OXTABS XTABS
+#else
+#define OXTABS 0
+#endif
+#endif
+
+/*
+ * gettmode --
+ * Do terminal type initialization.
+ */
+int
+gettmode()
+{
+ useraw = 0;
+
+ if (tcgetattr(STDIN_FILENO, &__orig_termios))
+ return (ERR);
+
+ __baset = __orig_termios;
+ __baset.c_oflag &= ~OXTABS;
+
+ GT = 0; /* historical. was used before we wired OXTABS off */
+ NONL = (__baset.c_oflag & ONLCR) == 0;
+
+ /*
+ * XXX
+ * System V and SMI systems overload VMIN and VTIME, such that
+ * VMIN is the same as the VEOF element, and VTIME is the same
+ * as the VEOL element. This means that, if VEOF was ^D, the
+ * default VMIN is 4. Majorly stupid.
+ */
+ cbreakt = __baset;
+ cbreakt.c_lflag &= ~ICANON;
+ cbreakt.c_cc[VMIN] = 1;
+ cbreakt.c_cc[VTIME] = 0;
+
+ rawt = cbreakt;
+ rawt.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INLCR|IGNCR|ICRNL|IXON);
+ rawt.c_oflag &= ~OPOST;
+ rawt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+
+ /*
+ * In general, curses should leave hardware-related settings alone.
+ * This includes parity and word size. Older versions set the tty
+ * to 8 bits, no parity in raw(), but this is considered to be an
+ * artifact of the old tty interface. If it's desired to change
+ * parity and word size, the TCSASOFT bit has to be removed from the
+ * calls that switch to/from "raw" mode.
+ */
+ if (!__tcaction) {
+ rawt.c_iflag &= ~ISTRIP;
+ rawt.c_cflag &= ~(CSIZE|PARENB);
+ rawt.c_cflag |= CS8;
+ }
+
+ curt = &__baset;
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
+}
+
+int
+raw()
+{
+ useraw = __pfast = __rawmode = 1;
+ curt = &rawt;
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
+}
+
+int
+noraw()
+{
+ useraw = __pfast = __rawmode = 0;
+ curt = &__baset;
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
+}
+
+int
+cbreak()
+{
+
+ __rawmode = 1;
+ curt = useraw ? &rawt : &cbreakt;
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
+}
+
+int
+nocbreak()
+{
+
+ __rawmode = 0;
+ curt = useraw ? &rawt : &__baset;
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
+}
+
+int
+echo()
+{
+ rawt.c_lflag |= ECHO;
+ cbreakt.c_lflag |= ECHO;
+ __baset.c_lflag |= ECHO;
+
+ __echoit = 1;
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
+}
+
+int
+noecho()
+{
+ rawt.c_lflag &= ~ECHO;
+ cbreakt.c_lflag &= ~ECHO;
+ __baset.c_lflag &= ~ECHO;
+
+ __echoit = 0;
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
+}
+
+int
+nl()
+{
+ rawt.c_iflag |= ICRNL;
+ rawt.c_oflag |= ONLCR;
+ cbreakt.c_iflag |= ICRNL;
+ cbreakt.c_oflag |= ONLCR;
+ __baset.c_iflag |= ICRNL;
+ __baset.c_oflag |= ONLCR;
+
+ __pfast = __rawmode;
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
+}
+
+int
+nonl()
+{
+ rawt.c_iflag &= ~ICRNL;
+ rawt.c_oflag &= ~ONLCR;
+ cbreakt.c_iflag &= ~ICRNL;
+ cbreakt.c_oflag &= ~ONLCR;
+ __baset.c_iflag &= ~ICRNL;
+ __baset.c_oflag &= ~ONLCR;
+
+ __pfast = 1;
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
+}
+
+void
+__startwin()
+{
+ static char *stdbuf;
+ static size_t len;
+
+ (void)fflush(stdout);
+
+ /*
+ * Some C libraries default to a 1K buffer when talking to a tty.
+ * With a larger screen, especially across a network, we'd like
+ * to get it to all flush in a single write. Make it twice as big
+ * as just the characters (so that we have room for cursor motions
+ * and standout information) but no more than 8K.
+ */
+ if (stdbuf == NULL) {
+ if ((len = LINES * COLS * 2) > 8192)
+ len = 8192;
+ if ((stdbuf = malloc(len)) == NULL)
+ len = 0;
+ }
+ (void)setvbuf(stdout, stdbuf, _IOFBF, len);
+
+ tputs(TI, 0, __cputchar);
+ tputs(VS, 0, __cputchar);
+}
+
+int
+endwin()
+{
+ __restore_stophandler();
+
+ if (curscr != NULL) {
+ if (curscr->flags & __WSTANDOUT) {
+ tputs(SE, 0, __cputchar);
+ curscr->flags &= ~__WSTANDOUT;
+ }
+ __mvcur(curscr->cury, curscr->cury, curscr->maxy - 1, 0, 0);
+ }
+
+ (void)tputs(VE, 0, __cputchar);
+ (void)tputs(TE, 0, __cputchar);
+ (void)fflush(stdout);
+ (void)setvbuf(stdout, NULL, _IOLBF, 0);
+
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT | TCSADRAIN : TCSADRAIN, &__orig_termios) ? ERR : OK);
+}
+
+/*
+ * The following routines, savetty and resetty are completely useless and
+ * are left in only as stubs. If people actually use them they will almost
+ * certainly screw up the state of the world.
+ */
+static struct termios savedtty;
+int
+savetty()
+{
+ return (tcgetattr(STDIN_FILENO, &savedtty) ? ERR : OK);
+}
+
+int
+resetty()
+{
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT | TCSADRAIN : TCSADRAIN, &savedtty) ? ERR : OK);
+}