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.16 (Berkeley) 05/30/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 #define TCACTION (TCSASOFT | TCSADRAIN) /* ignore hardware settings */ 27 #else 28 #define TCACTION TCSADRAIN 29 #endif 30 31 struct termios __orig_termios; 32 static struct termios baset, 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 GT = (__orig_termios.c_oflag & OXTABS) == 0; 56 NONL = (__orig_termios.c_oflag & ONLCR) == 0; 57 58 baset = __orig_termios; 59 baset.c_oflag &= ~OXTABS; 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 #if 0 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 would have to be removed 84 * from the calls that switch to/from "raw" mode. 85 */ 86 rawt.c_iflag &= ~ISTRIP; 87 rawt.c_cflag &= ~(CSIZE|PARENB); 88 rawt.c_cflag |= CS8; 89 #endif 90 91 curt = &baset; 92 return (tcsetattr(STDIN_FILENO, TCACTION, &baset) ? ERR : OK); 93 } 94 95 int 96 raw() 97 { 98 useraw = __pfast = __rawmode = 1; 99 curt = &rawt; 100 return (tcsetattr(STDIN_FILENO, TCACTION, &rawt)); 101 } 102 103 int 104 noraw() 105 { 106 useraw = __pfast = __rawmode = 0; 107 curt = &baset; 108 return (tcsetattr(STDIN_FILENO, TCACTION, &baset)); 109 } 110 111 int 112 cbreak() 113 { 114 115 __rawmode = 1; 116 curt = useraw ? &rawt : &cbreakt; 117 return (tcsetattr(STDIN_FILENO, TCACTION, curt)); 118 } 119 120 int 121 nocbreak() 122 { 123 124 __rawmode = 0; 125 curt = useraw ? &rawt : &baset; 126 return (tcsetattr(STDIN_FILENO, TCACTION, curt)); 127 } 128 129 int 130 echo() 131 { 132 rawt.c_lflag |= ECHO; 133 cbreakt.c_lflag |= ECHO; 134 baset.c_lflag |= ECHO; 135 136 __echoit = 1; 137 return (tcsetattr(STDIN_FILENO, TCACTION, curt)); 138 } 139 140 int 141 noecho() 142 { 143 rawt.c_lflag &= ~ECHO; 144 cbreakt.c_lflag &= ~ECHO; 145 baset.c_lflag &= ~ECHO; 146 147 __echoit = 0; 148 return (tcsetattr(STDIN_FILENO, TCACTION, curt)); 149 } 150 151 int 152 nl() 153 { 154 rawt.c_iflag |= ICRNL; 155 rawt.c_oflag |= ONLCR; 156 cbreakt.c_iflag |= ICRNL; 157 cbreakt.c_oflag |= ONLCR; 158 baset.c_iflag |= ICRNL; 159 baset.c_oflag |= ONLCR; 160 161 __pfast = __rawmode; 162 return (tcsetattr(STDIN_FILENO, TCACTION, curt)); 163 } 164 165 int 166 nonl() 167 { 168 rawt.c_iflag &= ~ICRNL; 169 rawt.c_oflag &= ~ONLCR; 170 cbreakt.c_iflag &= ~ICRNL; 171 cbreakt.c_oflag &= ~ONLCR; 172 baset.c_iflag &= ~ICRNL; 173 baset.c_oflag &= ~ONLCR; 174 175 __pfast = 1; 176 return (tcsetattr(STDIN_FILENO, TCACTION, curt)); 177 } 178 179 void 180 __startwin() 181 { 182 (void)fflush(stdout); 183 (void)setvbuf(stdout, NULL, _IOFBF, 0); 184 185 tputs(TI, 0, __cputchar); 186 tputs(VS, 0, __cputchar); 187 } 188 189 int 190 endwin() 191 { 192 if (curscr != NULL) { 193 if (curscr->flags & __WSTANDOUT) { 194 tputs(SE, 0, __cputchar); 195 curscr->flags &= ~__WSTANDOUT; 196 } 197 __mvcur(curscr->cury, curscr->cury, curscr->maxy - 1, 0, 0); 198 } 199 200 (void)tputs(VE, 0, __cputchar); 201 (void)tputs(TE, 0, __cputchar); 202 (void)fflush(stdout); 203 (void)setvbuf(stdout, NULL, _IOLBF, 0); 204 205 return (tcsetattr(STDIN_FILENO, TCACTION, &__orig_termios)); 206 } 207 208 /* 209 * The following routines, savetty and resetty are completely useless and 210 * are left in only as stubs. If people actually use them they will almost 211 * certainly screw up the state of the world. 212 */ 213 static struct termios savedtty; 214 int 215 savetty() 216 { 217 return (tcgetattr(STDIN_FILENO, &savedtty)); 218 } 219 220 int 221 resetty() 222 { 223 return (tcsetattr(STDIN_FILENO, TCACTION, &savedtty)); 224 } 225