1 /*- 2 * Copyright (c) 1992, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)tty.c 8.6 (Berkeley) 01/10/95"; 10 #endif /* not lint */ 11 12 #include <stdlib.h> 13 #include <termios.h> 14 #include <unistd.h> 15 16 #include "curses.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 = 1; /* Ignore hardware settings. */ 27 #else 28 int __tcaction = 0; 29 #endif 30 31 struct termios __orig_termios, __baset; 32 static struct termios cbreakt, rawt, *curt; 33 static int useraw; 34 35 #ifndef OXTABS 36 #ifdef XTABS /* SMI uses XTABS. */ 37 #define OXTABS XTABS 38 #else 39 #define OXTABS 0 40 #endif 41 #endif 42 43 /* 44 * gettmode -- 45 * Do terminal type initialization. 46 */ 47 int 48 gettmode() 49 { 50 useraw = 0; 51 52 if (tcgetattr(STDIN_FILENO, &__orig_termios)) 53 return (ERR); 54 55 __baset = __orig_termios; 56 __baset.c_oflag &= ~OXTABS; 57 58 GT = 0; /* historical. was used before we wired OXTABS off */ 59 NONL = (__baset.c_oflag & ONLCR) == 0; 60 61 /* 62 * XXX 63 * System V and SMI systems overload VMIN and VTIME, such that 64 * VMIN is the same as the VEOF element, and VTIME is the same 65 * as the VEOL element. This means that, if VEOF was ^D, the 66 * default VMIN is 4. Majorly stupid. 67 */ 68 cbreakt = __baset; 69 cbreakt.c_lflag &= ~ICANON; 70 cbreakt.c_cc[VMIN] = 1; 71 cbreakt.c_cc[VTIME] = 0; 72 73 rawt = cbreakt; 74 rawt.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INLCR|IGNCR|ICRNL|IXON); 75 rawt.c_oflag &= ~OPOST; 76 rawt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 77 78 /* 79 * In general, curses should leave hardware-related settings alone. 80 * This includes parity and word size. Older versions set the tty 81 * to 8 bits, no parity in raw(), but this is considered to be an 82 * artifact of the old tty interface. If it's desired to change 83 * parity and word size, the TCSASOFT bit has to be removed from the 84 * calls that switch to/from "raw" mode. 85 */ 86 if (!__tcaction) { 87 rawt.c_iflag &= ~ISTRIP; 88 rawt.c_cflag &= ~(CSIZE|PARENB); 89 rawt.c_cflag |= CS8; 90 } 91 92 curt = &__baset; 93 return (tcsetattr(STDIN_FILENO, __tcaction ? 94 TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); 95 } 96 97 int 98 raw() 99 { 100 useraw = __pfast = __rawmode = 1; 101 curt = &rawt; 102 return (tcsetattr(STDIN_FILENO, __tcaction ? 103 TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); 104 } 105 106 int 107 noraw() 108 { 109 useraw = __pfast = __rawmode = 0; 110 curt = &__baset; 111 return (tcsetattr(STDIN_FILENO, __tcaction ? 112 TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); 113 } 114 115 int 116 cbreak() 117 { 118 119 __rawmode = 1; 120 curt = useraw ? &rawt : &cbreakt; 121 return (tcsetattr(STDIN_FILENO, __tcaction ? 122 TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); 123 } 124 125 int 126 nocbreak() 127 { 128 129 __rawmode = 0; 130 curt = useraw ? &rawt : &__baset; 131 return (tcsetattr(STDIN_FILENO, __tcaction ? 132 TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); 133 } 134 135 int 136 echo() 137 { 138 rawt.c_lflag |= ECHO; 139 cbreakt.c_lflag |= ECHO; 140 __baset.c_lflag |= ECHO; 141 142 __echoit = 1; 143 return (tcsetattr(STDIN_FILENO, __tcaction ? 144 TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); 145 } 146 147 int 148 noecho() 149 { 150 rawt.c_lflag &= ~ECHO; 151 cbreakt.c_lflag &= ~ECHO; 152 __baset.c_lflag &= ~ECHO; 153 154 __echoit = 0; 155 return (tcsetattr(STDIN_FILENO, __tcaction ? 156 TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); 157 } 158 159 int 160 nl() 161 { 162 rawt.c_iflag |= ICRNL; 163 rawt.c_oflag |= ONLCR; 164 cbreakt.c_iflag |= ICRNL; 165 cbreakt.c_oflag |= ONLCR; 166 __baset.c_iflag |= ICRNL; 167 __baset.c_oflag |= ONLCR; 168 169 __pfast = __rawmode; 170 return (tcsetattr(STDIN_FILENO, __tcaction ? 171 TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); 172 } 173 174 int 175 nonl() 176 { 177 rawt.c_iflag &= ~ICRNL; 178 rawt.c_oflag &= ~ONLCR; 179 cbreakt.c_iflag &= ~ICRNL; 180 cbreakt.c_oflag &= ~ONLCR; 181 __baset.c_iflag &= ~ICRNL; 182 __baset.c_oflag &= ~ONLCR; 183 184 __pfast = 1; 185 return (tcsetattr(STDIN_FILENO, __tcaction ? 186 TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); 187 } 188 189 void 190 __startwin() 191 { 192 static char *stdbuf; 193 static size_t len; 194 195 (void)fflush(stdout); 196 197 /* 198 * Some C libraries default to a 1K buffer when talking to a tty. 199 * With a larger screen, especially across a network, we'd like 200 * to get it to all flush in a single write. Make it twice as big 201 * as just the characters (so that we have room for cursor motions 202 * and standout information) but no more than 8K. 203 */ 204 if (stdbuf == NULL) { 205 if ((len = LINES * COLS * 2) > 8192) 206 len = 8192; 207 if ((stdbuf = malloc(len)) == NULL) 208 len = 0; 209 } 210 (void)setvbuf(stdout, stdbuf, _IOFBF, len); 211 212 tputs(TI, 0, __cputchar); 213 tputs(VS, 0, __cputchar); 214 } 215 216 int 217 endwin() 218 { 219 __restore_stophandler(); 220 221 if (curscr != NULL) { 222 if (curscr->flags & __WSTANDOUT) { 223 tputs(SE, 0, __cputchar); 224 curscr->flags &= ~__WSTANDOUT; 225 } 226 __mvcur(curscr->cury, curscr->curx, curscr->maxy - 1, 0, 0); 227 } 228 229 (void)tputs(VE, 0, __cputchar); 230 (void)tputs(TE, 0, __cputchar); 231 (void)fflush(stdout); 232 (void)setvbuf(stdout, NULL, _IOLBF, 0); 233 234 return (tcsetattr(STDIN_FILENO, __tcaction ? 235 TCSASOFT | TCSADRAIN : TCSADRAIN, &__orig_termios) ? ERR : OK); 236 } 237 238 /* 239 * The following routines, savetty and resetty are completely useless and 240 * are left in only as stubs. If people actually use them they will almost 241 * certainly screw up the state of the world. 242 */ 243 static struct termios savedtty; 244 int 245 savetty() 246 { 247 return (tcgetattr(STDIN_FILENO, &savedtty) ? ERR : OK); 248 } 249 250 int 251 resetty() 252 { 253 return (tcsetattr(STDIN_FILENO, __tcaction ? 254 TCSASOFT | TCSADRAIN : TCSADRAIN, &savedtty) ? ERR : OK); 255 } 256