1 /*- 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)tty.c 5.17 (Berkeley) 06/04/93"; 10 #endif /* not lint */ 11 12 #include <sys/ioctl.h> 13 14 #include <curses.h> 15 #include <termios.h> 16 #include <unistd.h> 17 18 /* 19 * In general, curses should leave tty hardware settings alone (speed, parity, 20 * word size). This is most easily done in BSD by using TCSASOFT on all 21 * tcsetattr calls. On other systems, it would be better to get and restore 22 * those attributes at each change, or at least when stopped and restarted. 23 * See also the comments in getterm(). 24 */ 25 #ifdef TCSASOFT 26 int __tcaction = TCSASOFT | TCSADRAIN; /* ignore hardware settings */ 27 #else 28 int __tcaction = TCSADRAIN; 29 #endif 30 31 /* was, pfast = rand() % HARDTABS; */ 32 33 struct termios __orig_termios, __baset; 34 static struct termios cbreakt, rawt, *curt; 35 static int useraw; 36 37 #ifndef OXTABS 38 #ifdef XTABS /* SMI uses XTABS. */ 39 #define OXTABS XTABS 40 #else 41 #define OXTABS 0 42 #endif 43 #endif 44 45 /* 46 * gettmode -- 47 * Do terminal type initialization. 48 */ 49 int 50 gettmode() 51 { 52 useraw = 0; 53 54 if (tcgetattr(STDIN_FILENO, &__orig_termios)) 55 return (ERR); 56 57 __baset = __orig_termios; 58 __baset.c_oflag &= ~OXTABS; 59 60 GT = 0; /* historical. was used before we wired OXTABS off */ 61 NONL = (__baset.c_oflag & ONLCR) == 0; 62 63 /* 64 * XXX 65 * System V and SMI systems overload VMIN and VTIME, such that 66 * VMIN is the same as the VEOF element, and VTIME is the same 67 * as the VEOL element. This means that, if VEOF was ^D, the 68 * default VMIN is 4. Majorly stupid. 69 */ 70 cbreakt = __baset; 71 cbreakt.c_lflag &= ~ICANON; 72 cbreakt.c_cc[VMIN] = 1; 73 cbreakt.c_cc[VTIME] = 0; 74 75 rawt = cbreakt; 76 rawt.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INLCR|IGNCR|ICRNL|IXON); 77 rawt.c_oflag &= ~OPOST; 78 rawt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 79 #if 0 80 /* 81 * In general, curses should leave hardware-related settings alone. 82 * This includes parity and word size. Older versions set the tty 83 * to 8 bits, no parity in raw(), but this is considered to be an 84 * artifact of the old tty interface. If it's desired to change 85 * parity and word size, the TCSASOFT bit would have to be removed 86 * from the calls that switch to/from "raw" mode. 87 */ 88 rawt.c_iflag &= ~ISTRIP; 89 rawt.c_cflag &= ~(CSIZE|PARENB); 90 rawt.c_cflag |= CS8; 91 #endif 92 93 curt = &__baset; 94 return (tcsetattr(STDIN_FILENO, __tcaction, &__baset) ? ERR : OK); 95 } 96 97 int 98 raw() 99 { 100 useraw = __pfast = __rawmode = 1; 101 curt = &rawt; 102 return (tcsetattr(STDIN_FILENO, __tcaction, &rawt)); 103 } 104 105 int 106 noraw() 107 { 108 useraw = __pfast = __rawmode = 0; 109 curt = &__baset; 110 return (tcsetattr(STDIN_FILENO, __tcaction, &__baset)); 111 } 112 113 int 114 cbreak() 115 { 116 117 __rawmode = 1; 118 curt = useraw ? &rawt : &cbreakt; 119 return (tcsetattr(STDIN_FILENO, __tcaction, curt)); 120 } 121 122 int 123 nocbreak() 124 { 125 126 __rawmode = 0; 127 curt = useraw ? &rawt : &__baset; 128 return (tcsetattr(STDIN_FILENO, __tcaction, curt)); 129 } 130 131 int 132 echo() 133 { 134 rawt.c_lflag |= ECHO; 135 cbreakt.c_lflag |= ECHO; 136 __baset.c_lflag |= ECHO; 137 138 __echoit = 1; 139 return (tcsetattr(STDIN_FILENO, __tcaction, curt)); 140 } 141 142 int 143 noecho() 144 { 145 rawt.c_lflag &= ~ECHO; 146 cbreakt.c_lflag &= ~ECHO; 147 __baset.c_lflag &= ~ECHO; 148 149 __echoit = 0; 150 return (tcsetattr(STDIN_FILENO, __tcaction, curt)); 151 } 152 153 int 154 nl() 155 { 156 rawt.c_iflag |= ICRNL; 157 rawt.c_oflag |= ONLCR; 158 cbreakt.c_iflag |= ICRNL; 159 cbreakt.c_oflag |= ONLCR; 160 __baset.c_iflag |= ICRNL; 161 __baset.c_oflag |= ONLCR; 162 163 __pfast = __rawmode; 164 return (tcsetattr(STDIN_FILENO, __tcaction, curt)); 165 } 166 167 int 168 nonl() 169 { 170 rawt.c_iflag &= ~ICRNL; 171 rawt.c_oflag &= ~ONLCR; 172 cbreakt.c_iflag &= ~ICRNL; 173 cbreakt.c_oflag &= ~ONLCR; 174 __baset.c_iflag &= ~ICRNL; 175 __baset.c_oflag &= ~ONLCR; 176 177 __pfast = 1; 178 return (tcsetattr(STDIN_FILENO, __tcaction, curt)); 179 } 180 181 void 182 __startwin() 183 { 184 (void)fflush(stdout); 185 (void)setvbuf(stdout, NULL, _IOFBF, 0); 186 187 tputs(TI, 0, __cputchar); 188 tputs(VS, 0, __cputchar); 189 } 190 191 int 192 endwin() 193 { 194 if (curscr != NULL) { 195 if (curscr->flags & __WSTANDOUT) { 196 tputs(SE, 0, __cputchar); 197 curscr->flags &= ~__WSTANDOUT; 198 } 199 __mvcur(curscr->cury, curscr->cury, curscr->maxy - 1, 0, 0); 200 } 201 202 (void)tputs(VE, 0, __cputchar); 203 (void)tputs(TE, 0, __cputchar); 204 (void)fflush(stdout); 205 (void)setvbuf(stdout, NULL, _IOLBF, 0); 206 207 return (tcsetattr(STDIN_FILENO, __tcaction, &__orig_termios)); 208 } 209 210 /* 211 * The following routines, savetty and resetty are completely useless and 212 * are left in only as stubs. If people actually use them they will almost 213 * certainly screw up the state of the world. 214 */ 215 static struct termios savedtty; 216 int 217 savetty() 218 { 219 return (tcgetattr(STDIN_FILENO, &savedtty)); 220 } 221 222 int 223 resetty() 224 { 225 return (tcsetattr(STDIN_FILENO, __tcaction, &savedtty)); 226 } 227