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*67666Sbostic static char sccsid[] = "@(#)tty.c 8.5 (Berkeley) 08/13/94"; 1055989Sbostic #endif /* not lint */ 1155989Sbostic 12*67666Sbostic #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 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 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 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 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 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 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 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 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 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 19059862Sbostic __startwin() 19159862Sbostic { 192*67666Sbostic static char *stdbuf; 193*67666Sbostic static size_t len; 194*67666Sbostic 19559862Sbostic (void)fflush(stdout); 19659862Sbostic 197*67666Sbostic /* 198*67666Sbostic * Some C libraries default to a 1K buffer when talking to a tty. 199*67666Sbostic * With a larger screen, especially across a network, we'd like 200*67666Sbostic * to get it to all flush in a single write. Make it twice as big 201*67666Sbostic * as just the characters (so that we have room for cursor motions 202*67666Sbostic * and standout information) but no more than 8K. 203*67666Sbostic */ 204*67666Sbostic if (stdbuf == NULL) { 205*67666Sbostic if ((len = LINES * COLS * 2) > 8192) 206*67666Sbostic len = 8192; 207*67666Sbostic if ((stdbuf = malloc(len)) == NULL) 208*67666Sbostic len = 0; 209*67666Sbostic } 210*67666Sbostic (void)setvbuf(stdout, stdbuf, _IOFBF, len); 211*67666Sbostic 21259862Sbostic tputs(TI, 0, __cputchar); 21359862Sbostic tputs(VS, 0, __cputchar); 21459862Sbostic } 21559862Sbostic 21655989Sbostic int 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 } 22660071Sbostic __mvcur(curscr->cury, curscr->cury, 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 24555989Sbostic savetty() 24655989Sbostic { 24767174Sbostic return (tcgetattr(STDIN_FILENO, &savedtty) ? ERR : OK); 24855989Sbostic } 24955989Sbostic 25055989Sbostic int 25155989Sbostic resetty() 25255989Sbostic { 25362545Sbostic return (tcsetattr(STDIN_FILENO, __tcaction ? 25467174Sbostic TCSASOFT | TCSADRAIN : TCSADRAIN, &savedtty) ? ERR : OK); 25555989Sbostic } 256