155989Sbostic /*-
267082Sbostic * Copyright (c) 1992, 1993, 1994
362546Sbostic * The Regents of the University of California. All rights reserved.
455989Sbostic *
555989Sbostic * %sccs.include.redist.c%
655989Sbostic */
755989Sbostic
855989Sbostic #ifndef lint
9*68183Sbostic static char sccsid[] = "@(#)tty.c 8.6 (Berkeley) 01/10/95";
1055989Sbostic #endif /* not lint */
1155989Sbostic
1267666Sbostic #include <stdlib.h>
1355989Sbostic #include <termios.h>
1455989Sbostic #include <unistd.h>
1555989Sbostic
1667082Sbostic #include "curses.h"
1767082Sbostic
1860627Sbostic /*
1960627Sbostic * In general, curses should leave tty hardware settings alone (speed, parity,
2060627Sbostic * word size). This is most easily done in BSD by using TCSASOFT on all
2160627Sbostic * tcsetattr calls. On other systems, it would be better to get and restore
2260627Sbostic * those attributes at each change, or at least when stopped and restarted.
2360627Sbostic * See also the comments in getterm().
2460627Sbostic */
2560627Sbostic #ifdef TCSASOFT
2662545Sbostic int __tcaction = 1; /* Ignore hardware settings. */
2760627Sbostic #else
2862545Sbostic int __tcaction = 0;
2960627Sbostic #endif
3060627Sbostic
3161229Smarc struct termios __orig_termios, __baset;
3261229Smarc static struct termios cbreakt, rawt, *curt;
3355989Sbostic static int useraw;
3455989Sbostic
3560616Sbostic #ifndef OXTABS
3660616Sbostic #ifdef XTABS /* SMI uses XTABS. */
3760616Sbostic #define OXTABS XTABS
3860616Sbostic #else
3960616Sbostic #define OXTABS 0
4060616Sbostic #endif
4160616Sbostic #endif
4260616Sbostic
4355989Sbostic /*
4455989Sbostic * gettmode --
4555989Sbostic * Do terminal type initialization.
4655989Sbostic */
4755989Sbostic int
gettmode()4855989Sbostic gettmode()
4955989Sbostic {
5057286Sbostic useraw = 0;
5157286Sbostic
5257716Sbostic if (tcgetattr(STDIN_FILENO, &__orig_termios))
5357472Sbostic return (ERR);
5455989Sbostic
5561229Smarc __baset = __orig_termios;
5661229Smarc __baset.c_oflag &= ~OXTABS;
5755989Sbostic
5861229Smarc GT = 0; /* historical. was used before we wired OXTABS off */
5961229Smarc NONL = (__baset.c_oflag & ONLCR) == 0;
6060619Sbostic
6160619Sbostic /*
6260619Sbostic * XXX
6360619Sbostic * System V and SMI systems overload VMIN and VTIME, such that
6460619Sbostic * VMIN is the same as the VEOF element, and VTIME is the same
6560619Sbostic * as the VEOL element. This means that, if VEOF was ^D, the
6660619Sbostic * default VMIN is 4. Majorly stupid.
6760619Sbostic */
6861229Smarc cbreakt = __baset;
6960627Sbostic cbreakt.c_lflag &= ~ICANON;
7060627Sbostic cbreakt.c_cc[VMIN] = 1;
7160627Sbostic cbreakt.c_cc[VTIME] = 0;
7255989Sbostic
7360627Sbostic rawt = cbreakt;
7460627Sbostic rawt.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INLCR|IGNCR|ICRNL|IXON);
7560627Sbostic rawt.c_oflag &= ~OPOST;
7660627Sbostic rawt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
7762545Sbostic
7860627Sbostic /*
7960627Sbostic * In general, curses should leave hardware-related settings alone.
8060627Sbostic * This includes parity and word size. Older versions set the tty
8160627Sbostic * to 8 bits, no parity in raw(), but this is considered to be an
8260627Sbostic * artifact of the old tty interface. If it's desired to change
8362545Sbostic * parity and word size, the TCSASOFT bit has to be removed from the
8462545Sbostic * calls that switch to/from "raw" mode.
8560627Sbostic */
8662545Sbostic if (!__tcaction) {
8762545Sbostic rawt.c_iflag &= ~ISTRIP;
8862545Sbostic rawt.c_cflag &= ~(CSIZE|PARENB);
8962545Sbostic rawt.c_cflag |= CS8;
9062545Sbostic }
9160627Sbostic
9261229Smarc curt = &__baset;
9362545Sbostic return (tcsetattr(STDIN_FILENO, __tcaction ?
9462545Sbostic TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
9555989Sbostic }
9655989Sbostic
9755989Sbostic int
raw()9855989Sbostic raw()
9955989Sbostic {
10055989Sbostic useraw = __pfast = __rawmode = 1;
10160627Sbostic curt = &rawt;
10262545Sbostic return (tcsetattr(STDIN_FILENO, __tcaction ?
10367174Sbostic TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
10455989Sbostic }
10555989Sbostic
10655989Sbostic int
noraw()10755989Sbostic noraw()
10855989Sbostic {
10955989Sbostic useraw = __pfast = __rawmode = 0;
11061229Smarc curt = &__baset;
11162545Sbostic return (tcsetattr(STDIN_FILENO, __tcaction ?
11267174Sbostic TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
11355989Sbostic }
11455989Sbostic
11555989Sbostic int
cbreak()11655989Sbostic cbreak()
11755989Sbostic {
11855989Sbostic
11955989Sbostic __rawmode = 1;
12060627Sbostic curt = useraw ? &rawt : &cbreakt;
12162545Sbostic return (tcsetattr(STDIN_FILENO, __tcaction ?
12267174Sbostic TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
12355989Sbostic }
12455989Sbostic
12555989Sbostic int
nocbreak()12655989Sbostic nocbreak()
12755989Sbostic {
12855989Sbostic
12955989Sbostic __rawmode = 0;
13061229Smarc curt = useraw ? &rawt : &__baset;
13162545Sbostic return (tcsetattr(STDIN_FILENO, __tcaction ?
13267174Sbostic TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
13355989Sbostic }
13455989Sbostic
13555989Sbostic int
echo()13655989Sbostic echo()
13755989Sbostic {
13855989Sbostic rawt.c_lflag |= ECHO;
13960627Sbostic cbreakt.c_lflag |= ECHO;
14061229Smarc __baset.c_lflag |= ECHO;
14155989Sbostic
14255989Sbostic __echoit = 1;
14362545Sbostic return (tcsetattr(STDIN_FILENO, __tcaction ?
14467174Sbostic TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
14555989Sbostic }
14655989Sbostic
14755989Sbostic int
noecho()14855989Sbostic noecho()
14955989Sbostic {
15055989Sbostic rawt.c_lflag &= ~ECHO;
15160627Sbostic cbreakt.c_lflag &= ~ECHO;
15261229Smarc __baset.c_lflag &= ~ECHO;
15355989Sbostic
15455989Sbostic __echoit = 0;
15562545Sbostic return (tcsetattr(STDIN_FILENO, __tcaction ?
15667174Sbostic TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
15755989Sbostic }
15855989Sbostic
15955989Sbostic int
nl()16055989Sbostic nl()
16155989Sbostic {
16255989Sbostic rawt.c_iflag |= ICRNL;
16355989Sbostic rawt.c_oflag |= ONLCR;
16460627Sbostic cbreakt.c_iflag |= ICRNL;
16560627Sbostic cbreakt.c_oflag |= ONLCR;
16661229Smarc __baset.c_iflag |= ICRNL;
16761229Smarc __baset.c_oflag |= ONLCR;
16855989Sbostic
16955989Sbostic __pfast = __rawmode;
17062545Sbostic return (tcsetattr(STDIN_FILENO, __tcaction ?
17167174Sbostic TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
17255989Sbostic }
17355989Sbostic
17455989Sbostic int
nonl()17555989Sbostic nonl()
17655989Sbostic {
17755989Sbostic rawt.c_iflag &= ~ICRNL;
17855989Sbostic rawt.c_oflag &= ~ONLCR;
17960627Sbostic cbreakt.c_iflag &= ~ICRNL;
18060627Sbostic cbreakt.c_oflag &= ~ONLCR;
18161229Smarc __baset.c_iflag &= ~ICRNL;
18261229Smarc __baset.c_oflag &= ~ONLCR;
18355989Sbostic
18455989Sbostic __pfast = 1;
18562545Sbostic return (tcsetattr(STDIN_FILENO, __tcaction ?
18667174Sbostic TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
18755989Sbostic }
18855989Sbostic
18959862Sbostic void
__startwin()19059862Sbostic __startwin()
19159862Sbostic {
19267666Sbostic static char *stdbuf;
19367666Sbostic static size_t len;
19467666Sbostic
19559862Sbostic (void)fflush(stdout);
19659862Sbostic
19767666Sbostic /*
19867666Sbostic * Some C libraries default to a 1K buffer when talking to a tty.
19967666Sbostic * With a larger screen, especially across a network, we'd like
20067666Sbostic * to get it to all flush in a single write. Make it twice as big
20167666Sbostic * as just the characters (so that we have room for cursor motions
20267666Sbostic * and standout information) but no more than 8K.
20367666Sbostic */
20467666Sbostic if (stdbuf == NULL) {
20567666Sbostic if ((len = LINES * COLS * 2) > 8192)
20667666Sbostic len = 8192;
20767666Sbostic if ((stdbuf = malloc(len)) == NULL)
20867666Sbostic len = 0;
20967666Sbostic }
21067666Sbostic (void)setvbuf(stdout, stdbuf, _IOFBF, len);
21167666Sbostic
21259862Sbostic tputs(TI, 0, __cputchar);
21359862Sbostic tputs(VS, 0, __cputchar);
21459862Sbostic }
21559862Sbostic
21655989Sbostic int
endwin()21755989Sbostic endwin()
21855989Sbostic {
21965314Sbostic __restore_stophandler();
22065314Sbostic
22157716Sbostic if (curscr != NULL) {
22257716Sbostic if (curscr->flags & __WSTANDOUT) {
22357716Sbostic tputs(SE, 0, __cputchar);
22457716Sbostic curscr->flags &= ~__WSTANDOUT;
22557716Sbostic }
226*68183Sbostic __mvcur(curscr->cury, curscr->curx, curscr->maxy - 1, 0, 0);
22755989Sbostic }
22855989Sbostic
22955989Sbostic (void)tputs(VE, 0, __cputchar);
23055989Sbostic (void)tputs(TE, 0, __cputchar);
23155989Sbostic (void)fflush(stdout);
23259862Sbostic (void)setvbuf(stdout, NULL, _IOLBF, 0);
23355989Sbostic
23462545Sbostic return (tcsetattr(STDIN_FILENO, __tcaction ?
23567174Sbostic TCSASOFT | TCSADRAIN : TCSADRAIN, &__orig_termios) ? ERR : OK);
23655989Sbostic }
23755989Sbostic
23855989Sbostic /*
23955989Sbostic * The following routines, savetty and resetty are completely useless and
24055989Sbostic * are left in only as stubs. If people actually use them they will almost
24155989Sbostic * certainly screw up the state of the world.
24255989Sbostic */
24355989Sbostic static struct termios savedtty;
24455989Sbostic int
savetty()24555989Sbostic savetty()
24655989Sbostic {
24767174Sbostic return (tcgetattr(STDIN_FILENO, &savedtty) ? ERR : OK);
24855989Sbostic }
24955989Sbostic
25055989Sbostic int
resetty()25155989Sbostic resetty()
25255989Sbostic {
25362545Sbostic return (tcsetattr(STDIN_FILENO, __tcaction ?
25467174Sbostic TCSASOFT | TCSADRAIN : TCSADRAIN, &savedtty) ? ERR : OK);
25555989Sbostic }
256