home *** CD-ROM | disk | FTP | other *** search
- /*
- ** This software is Copyright (c) 1991 by Daniel Weaver.
- **
- ** Permission is hereby granted to copy, distribute or otherwise
- ** use any part of this package as long as you do not try to make
- ** money from it or pretend that you wrote it. This copyright
- ** notice must be maintained in any copy made.
- **
- ** Use of this software constitutes acceptance for use in an AS IS
- ** condition. There are NO warranties with regard to this software.
- ** In no event shall the author be liable for any damages whatsoever
- ** arising out of or in connection with the use or performance of this
- ** software. Any use of this software is at the user's own risk.
- **
- ** If you make modifications to this software that you feel
- ** increases it usefulness for the rest of the community, please
- ** email the changes, enhancements, bug fixes as well as any and
- ** all ideas to me. This software is going to be maintained and
- ** enhanced as deemed necessary by the community.
- */
- /*
- * Operating system dependant functions. Such as special tty handler
- * modes.
- */
-
- #include <sys/errno.h>
- #if defined(vax) || defined(_AIX)
- #include <fcntl.h>
- #else
- #include <sys/fcntl.h>
- #endif
- #include <curses.h>
- #include <signal.h>
- #include "ted.h"
-
- /* The appropriate speeds for various termio settings. */
- int speeds[] =
- {
- 0, /* B0, */
- 50, /* B50, */
- 75, /* B75, */
- 110, /* B110, */
- 134, /* B134, */
- 150, /* B150, */
- 200, /* B200, */
- 300, /* B300, */
- 600, /* B600, */
- 1200, /* B1200, */
- 1800, /* B1800, */
- 2400, /* B2400, */
- 4800, /* B4800, */
- 9600, /* B9600, */
- 19200, /* EXTA, */
- 38400, /* EXTB, */
- 0,
- };
-
- /* error report location for ioctl's */
- extern int errno;
-
- #ifdef ICANON /* ATT UNIX */
- #define SLEEP(x)
- #define TTY_IS_NOECHO !(new_modes.c_lflag & ECHO)
- #define TTY_IS_OUT_TRANS (new_modes.c_oflag & OPOST)
- #define TTY_IS_CHAR_MODE !(new_modes.c_lflag & ICANON)
-
- struct termio old_modes, new_modes;
-
- tty_raw(minch, mask)
- int minch, mask;
- { /* set tty to raw noecho */
- new_modes = old_modes;
- #ifdef SELECT
- new_modes.c_cc[VMIN]=1;
- #else
- new_modes.c_cc[VMIN]=minch;
- #endif
- new_modes.c_cc[VTIME]=2;
- new_modes.c_lflag &=
- ~(ISIG|ICANON|XCASE|ECHO|ECHOE|ECHOK|ECHONL);
- #ifdef LOBLK
- new_modes.c_lflag &= ~LOBLK;
- #endif
- new_modes.c_oflag &= ~(OPOST|OLCUC|TABDLY);
- if (mask == ALLOW_PARITY)
- {
- new_modes.c_cflag &= ~(CSIZE|PARENB|HUPCL);
- new_modes.c_cflag |= CS8;
- }
- new_modes.c_iflag &=
- ~(IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|
- IUCLC|IXON|IXANY|IXOFF);
- if (not_a_tty) return;
- ioctl(fileno(stdin), TCSETAW, &new_modes);
- }
-
-
- int
- tty_meta_prep()
- { /* print a warning before the meta key test */
- if (not_a_tty) return 0;
- if ((old_modes.c_cflag & CSIZE) == CS8) return 0;
- ptext("The meta key test must be run with the");
- ptext(" terminal set for 8 data bits. Two stop bits");
- ptext(" may also be needed for correct display. I will");
- ptext(" transmit 8 bit data but if the terminal is set for");
- ptext(" 7 bit data, garbage may appear on the screen.");
- return 1;
- }
-
-
- tty_set()
- { /* set tty to special modes */
- new_modes = old_modes;
- new_modes.c_cc[VMIN]=1;
- new_modes.c_cc[VTIME]=1;
- new_modes.c_lflag &= ~(ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHONL);
- new_modes.c_oflag &= ~(ONLCR|OCRNL|ONLRET|OFILL);
- if (char_mask == ALLOW_PARITY) new_modes.c_iflag &= ~ISTRIP;
- switch (select_xon_xoff) {
- case 0:
- new_modes.c_iflag &= ~(IXON|IXOFF);
- break;
- case 1:
- #if sequent
- /* the sequent System V emulation is broken */
- new_modes = old_modes;
- new_modes.c_cc[VEOL] = 6; /* control F (ACK) */
- #endif
- new_modes.c_iflag |= IXON | IXOFF;
- break;
- }
- switch (select_delay_type) {
- case 0:
- new_modes.c_oflag &=
- ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
- break;
- case 1:
- new_modes.c_oflag &=
- ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
- new_modes.c_oflag |= NL1 | CR2;
- break;
- }
- if (!(new_modes.c_oflag & ~OPOST)) new_modes.c_oflag &= ~OPOST;
- if (not_a_tty) return;
- ioctl(fileno(stdin), TCSETAW, &new_modes);
- }
-
-
- tty_reset()
- { /* reset the tty to the original modes */
- fflush(stdout);
- if (not_a_tty) return;
- ioctl(fileno(stdin), TCSETAW, &old_modes);
- }
-
-
- tty_init()
- { /* ATT terminal init */
- int flags;
-
- #ifdef F_GETFL
- flags = fcntl(fileno(stdin), F_GETFL, 0);
- nodelay_read = flags & O_NDELAY;
- #else
- nodelay_read = FALSE;
- #endif
- not_a_tty = FALSE;
- if (ioctl(fileno(stdin), TCGETA, &old_modes) == -1)
- {
- if (errno == ENOTTY)
- {
- tty_frame_size = 20;
- not_a_tty = TRUE;
- return;
- }
- printf("ioctl error: %d\n", errno);
- exit(1);
- }
- /* if TAB3 is set then setterm() wipes out tabs (ht) */
- new_modes = old_modes;
- new_modes.c_oflag &= ~TABDLY;
- if (ioctl(fileno(stdin), TCSETAW, &new_modes) == -1)
- {
- printf("ioctl error: %d\n", errno);
- exit(1);
- }
- #ifdef sequent
- /* the sequent ATT emulation is broken soooo. */
- old_modes.c_cflag &= ~(CSIZE | CSTOPB);
- old_modes.c_cflag |= CS7 | PARENB;
- #endif
- catchsig();
- tty_baud_rate = speeds[old_modes.c_cflag & CBAUD];
- switch (old_modes.c_cflag & CSIZE) {
- case CS5: tty_frame_size = 10; break;
- case CS6: tty_frame_size = 12; break;
- case CS7: tty_frame_size = 14; break;
- case CS8: tty_frame_size = 16; break;
- }
- tty_frame_size += 2 +
- ((old_modes.c_cflag & PARENB) ? 2 : 0) +
- ((old_modes.c_cflag & CSTOPB) ? 4 : 2);
- tty_abort = old_modes.c_cc[VINTR];
- }
-
-
- #else /* berkeley */
- #define SLEEP(x) sleep(x)
- #define TTY_IS_NOECHO !(new_modes.sg_flags & ECHO)
- #define TTY_IS_OUT_TRANS ((new_modes.sg_flags & (CBREAK|RAW|CRMOD)) == CRMOD)
- #define TTY_IS_CHAR_MODE ((new_modes.sg_flags & (CBREAK|RAW)) != 0)
-
- struct sgttyb old_modes, new_modes;
-
- tty_raw(minch, mask)
- int minch, mask;
- { /* set tty to raw noecho */
- fflush(stdout);
- new_modes = old_modes;
- new_modes.sg_flags |= RAW;
- new_modes.sg_flags &= ~(ALLDELAY | ECHO | CRMOD | CBREAK);
- if (not_a_tty) return;
- ioctl(fileno(stdin), TIOCSETP, &new_modes);
- }
-
- int
- tty_meta_prep()
- { /* print a warning before the meta key test */
- if (not_a_tty) return 0;
- ptext("The meta key test must be run with the");
- ptext(" terminal set for 8 data bits. Two stop bits");
- ptext(" may also be needed for correct display.");
- return 1;
- }
-
- extern short ospeed;
-
- tty_set()
- { /* set tty modes */
- fflush(stdout);
- new_modes = old_modes;
- new_modes.sg_flags &= ~(ECHO | CRMOD | CBREAK | RAW);
- if (select_delay_type == 0 & select_xon_xoff == 0)
- {
- new_modes.sg_flags |= RAW;
- }
- else new_modes.sg_flags |= CBREAK;
- switch (select_delay_type) {
- case 0:
- new_modes.sg_flags &= ~(ALLDELAY);
- break;
- case 1:
- new_modes.sg_flags &= ~(ALLDELAY);
- new_modes.sg_flags |= NL2 | CR1;
- break;
- }
- #ifdef TANDEM
- switch (select_xon_xoff) {
- case 0:
- new_modes.sg_flags &= ~TANDEM;
- break;
- case 1:
- new_modes.sg_flags |= TANDEM;
- break;
- }
- #endif
- if (select_pads == 1) ospeed = -1;
- if (not_a_tty) return;
- ioctl(fileno(stdin), TIOCSETP, &new_modes);
- }
-
-
- tty_reset()
- { /* reset the tty to the original modes */
- fflush(stdout);
- if (not_a_tty) return;
- ioctl(fileno(stdin), TIOCSETP, &old_modes);
- }
-
-
- tty_init()
- { /* Berkeley Unix tty init */
- struct tchars tc;
-
- not_a_tty = nodelay_read = FALSE;
- if (ioctl(fileno(stdin), TIOCGETC, &tc) == -1)
- {
- if (errno == ENOTTY)
- {
- not_a_tty = TRUE;
- return;
- }
- printf("ioctl error: %d\n", errno);
- exit(1);
- }
- tty_abort = tc.t_intrc;
- if (ioctl(fileno(stdin), TIOCGETP, &old_modes) == -1)
- {
- printf("ioctl error: %d\n", errno);
- exit(1);
- }
- catchsig();
- tty_baud_rate = speeds[old_modes.sg_ospeed];
- tty_frame_size = 22; /* 8 data bits, 2 stop bits, 1 start bit */
- tty_frame_size = 20; /* 8 data bits, 1 stop bit, 1 start bit */
- #ifdef vax
- tty_frame_size = 21; /* 8 data bits, 1.5 stop bits, 1 start bit */
- #endif
- if (ospeed < 0) ospeed = old_modes.sg_ospeed;
- }
- #endif
-
- int
- stty_query(q)
- int q;
- { /* return information about the terminal */
- switch (q) {
- case TTY_NOECHO:
- return TTY_IS_NOECHO;
- case TTY_OUT_TRANS:
- return TTY_IS_OUT_TRANS;
- case TTY_CHAR_MODE:
- return TTY_IS_CHAR_MODE;
- }
- }
-
- #ifdef SELECT
- int
- char_ready()
- {
- struct _timeval {
- long tv_sec;
- long tv_usec;
- };
- int ifds, ofds, efds, n;
- struct _timeval tv;
-
- ifds = 1 << fileno(stdin);
- ofds = efds = 0;
- tv.tv_sec = 0;
- tv.tv_usec = 200000;
- n = select(20, &ifds, &ofds, &efds, &tv);
- return (n != 0);
- }
- #else
- #ifdef FIONREAD
- int
- char_ready()
- {
- int i, j;
-
- /* the following loop has to be tuned for each computer */
- for (j = 0; j < 1000; j++) {
- ioctl(fileno(stdin), FIONREAD, &i);
- if (i) return i;
- }
- return i;
- }
- #else
- #define char_ready() 1
- #endif
- #endif
-
-
- nite_nite()
- { /* go to sleep */
- SLEEP(1);
- }
-
-
- read_key(buf, max)
- char *buf;
- int max;
- { /* read one function key from the input stream */
- int got, ask;
- char *s;
-
- *buf = '\0';
- s = buf;
- fflush(stdout);
- /* ATT unix may return 0 or 1, Berkeley Unix should be 1 */
- while (read(fileno(stdin), s, 1) == 0);
- ++s;
- --max;
- while (max > 0 && (ask = char_ready())) {
- if (ask > max) ask = max;
- if (got = read(fileno(stdin), s, ask)) s += got;
- else break;
- max -= got;
- }
- *s = '\0';
- /* strip high order bits (if any) */
- for (s = buf; *s; *s++ &= char_mask);
- }
-
-
- ignoresig( )
- {
- /* ignore signals */
- signal(SIGINT, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
- }
-
- /* onintr( )
- *
- * is the interrupt handling routine
- * onintr turns off interrupts while doing clean-up
- *
- * onintr always exits fatally
- */
-
-
- onintr()
- {
- ignoresig();
- tty_reset();
- exit(1);
- }
-
-
- /* catchsig( )
- *
- * set up to field interrupts (via function onintr( ))
- * so that if interrupted we can restore the correct terminal modes
- *
- * catchsig simply returns
- */
-
-
- catchsig( )
- {
- /* EXTERNAL VARIABLE USED */
- extern onintr( );
-
- if ((signal(SIGINT, SIG_IGN)) == SIG_DFL)
- signal(SIGINT, onintr);
-
- if ((signal(SIGHUP, SIG_IGN)) == SIG_DFL)
- signal(SIGHUP, onintr);
-
- if ((signal(SIGQUIT, SIG_IGN)) == SIG_DFL)
- signal(SIGQUIT, onintr);
-
- if ((signal(SIGTERM, SIG_IGN)) == SIG_DFL)
- signal(SIGTERM, onintr);
-
- }
-