/* ** changetty.c ** ** Localize in one place all the data and functions ** needed to change to and from cbreak mode for ** the se screen editor. ** ** Only functions available to rest of se are: ** ttyedit(), ttynormal(), and getspeed(). ** ** If USG is defined, we use the System V TTY driver. ** Otherwise (the default) we use the Berkeley terminal driver. ** ** If we are using System V, then the Release 2 version does not ** need ospeed. If not release 2, we assume Release 1 that someone ** have moved the BSD termlib to. ** ** This file is part of mse, under GPLv3. */ #include "config.h" #include "ascii.h" #include "constdefs.h" #include "changetty.h" #include "main.h" #ifdef HAVE_TERMIOS_H #include #else /* fallback to termio */ #ifdef HAVE_TERMIO_H #include #endif #endif extern short ospeed; /* from the termlib library */ static int set_ospeed = NO; static TTYINFO OldTtyInfo; /* initial state of terminal */ static TTYINFO NewTtyInfo; /* modified state for editing */ static int first = YES; /* first time anything called */ void init(void) { if (gttyinfo(1, &OldTtyInfo) == -1) /* get current state */ { error (NO, "couldn't get TTY info from system. get help!\n"); } NewTtyInfo = OldTtyInfo; /* copy it */ mttyinfo(&NewTtyInfo); /* change, but don't reset terminal */ /* really should check the return value here ... */ } void ttyedit(void) /* set the terminal to correct modes for editing */ { if (first == YES) { first = NO; init(); } sttyinfo(1, &NewTtyInfo); /* make the change */ /* really should check the return value here too ... */ } void ttynormal(void) /* set the terminal to correct modes for normal use */ { if (first) { first = NO; init(); } sttyinfo(1, &OldTtyInfo); /* make the change */ } /* getspeed --- find out the terminal speed in characters/second */ /* this routine only used if terminal types are hardwired */ /* into se, however, since it will be in an archive, the */ /* loader won't grab it if it isn't needed. */ int getspeed(int fd) { int i; TTYINFO ttybuf; static struct brstruct { int unixrate; int cps; int baudrate; } stab[] = { B0, 0, 0, B50, 5, 50, B75, 8, 75, B110, 10, 110, B134, 14, 134, B150, 15, 150, B200, 20, 200, B300, 30, 300, B600, 60, 600, B1200, 120, 1200, B1800, 180, 1800, B2400, 240, 2400, B4800, 480, 4800, B9600, 960, 9600 }; if (first) /* might as well set it here, too */ { first = NO; init(); } if (gttyinfo(fd, &ttybuf) == -1) { return 960; } for (i = 0; i < sizeof(stab) / sizeof(struct brstruct); i++) { if (stab[i].unixrate == (ttybuf.c_cflag & 017)) { return stab[i].cps; } } return 960; } /* gttyinfo --- make all necessary calls to obtain terminal status */ int gttyinfo(int fd, TTYINFO *buf) { #ifdef HAVE_TCGETATTR if (tcgetattr(fd, buf)) { return -1; } #else if (ioctl(fd, TCGETA, buf) < 0) { return -1; } #endif if (set_ospeed == NO) { set_ospeed = YES; ospeed = buf->c_cflag & 017; } return 0; } /* mttyinfo --- modify a TTYINFO structure for interactive operation */ int mttyinfo(TTYINFO *buf) { buf->c_cc[0] = DLE; /* interrupt */ buf->c_cc[1] = -1; /* ignore quit */ buf->c_cc[4] = 1; /* min # chars to read */ buf->c_cc[5] = 1; /* min time to wait */ buf->c_iflag &= ~(INLCR|IGNCR|ICRNL); /* allow CR to come thru */ buf->c_lflag |= ISIG|NOFLSH; /* keep these bits */ buf->c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL #ifdef XCASE |XCASE #endif ); return 0; } /* sttyinfo --- make all necessary calls to set terminal status */ int sttyinfo(int fd, TTYINFO *buf) { #ifdef HAVE_TCSETATTR if (tcsetattr(fd, TCSANOW, buf) < 0) #else if (ioctl(fd, TCSETAW, buf) < 0) #endif { return -1; } else { return 0; } }