summaryrefslogtreecommitdiff
path: root/dviware/dvgtk/unixio.c
diff options
context:
space:
mode:
Diffstat (limited to 'dviware/dvgtk/unixio.c')
-rw-r--r--dviware/dvgtk/unixio.c357
1 files changed, 357 insertions, 0 deletions
diff --git a/dviware/dvgtk/unixio.c b/dviware/dvgtk/unixio.c
new file mode 100644
index 0000000000..3c54a8a8f9
--- /dev/null
+++ b/dviware/dvgtk/unixio.c
@@ -0,0 +1,357 @@
+/* unixio.c - Unix terminal and signal handling
+ $Id: unixio.c,v 0.2 1997/03/28 03:17:33 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#include "dvgt.h"
+#include "unixio.h"
+#include "screenio.h" /* for MesgString, MesgLine */
+
+/* Set DV_FD (ioctl file descriptor) to 0 or 1 ? */
+#define DV_FD STDIN_FILENO
+
+sig_flags_t sig_flags;
+cmode_flags_t cmode_flags;
+
+/* Alex Dickinson
+ Procedures for setting and resetting UNIX tty characteristics.
+ Interesting functions are:
+ save_init_tty;
+ restore_init_tty;
+ save_temp_tty;
+ restore_temp_tty;
+ echoon;
+ echooff;
+ singlecharon;
+ singlecharoff;
+ buffercount;
+ suspend;
+ A side effect of calling save_temp_tty is to set up signal handling
+ to reset the terminal characteristics appropriately for the various
+ interrupt signals.
+ */
+
+/*****************************************************************
+* terminal handling
+*/
+
+#if defined(HAVE_TERMIO_H)
+#include <fcntl.h>
+#include <termio.h>
+#define TERMIO
+#ifdef NCC
+#define MAXCC NCC
+#else
+#define MAXCC 256
+#endif
+#define DV_GTTY TCGETA
+#define DV_STTY TCSETAW
+typedef struct termio dv_tty;
+unsigned char saved_cc[NCC];
+#else
+#include <sgtty.h>
+#define DV_GTTY TIOCGETP
+#define DV_STTY TIOCSETN
+typedef struct sgttyb dv_tty;
+#endif /* TERMIOS || TERMIO */
+
+#include <signal.h>
+#include <errno.h>
+
+static dv_tty init_tty_state; /* store initial terminal characteristics */
+static dv_tty temp_tty_state; /* current terminal characteristics */
+
+/* locally defined and used functions and data */
+
+static void setsignals ();
+static void reportio PARAMS ((int iostat));
+static int iostatus; /* return status of ioctl system function */
+
+static void
+reportio (int iostat)
+{
+ if (iostat < 0)
+ { /* an ioctl error */
+ char *str = "";
+ String cstr;
+ switch (errno)
+ {
+ /* generic errors */
+#ifdef EBADF
+ case EBADF:
+ str = "Not a valid, open, file descriptor!";
+ break;
+#endif
+#ifdef EINTR
+ case EINTR:
+ str = "Signal caught.";
+ break;
+#endif
+#ifdef ENOTTY
+ case ENOTTY:
+ str = "No device driver, or doesn't accept control functions!";
+ break;
+#endif
+ /* specialised errors */
+#ifdef EFAULT
+ case EFAULT:
+ str = "Illegal data transfer address!";
+ break;
+#endif
+#ifdef EINVAL
+ case EINVAL:
+ str = "Driver ignorant of this request or arg!";
+ break;
+#endif
+#ifdef EIO
+ case EIO:
+ str = "Physical I/O error!";
+ break;
+#endif
+#ifdef ENOLINK
+ case ENOLINK:
+ str = "Remote machine link no longer active!";
+ break;
+#endif
+#ifdef ENXIO
+ case ENXIO:
+ str = "Subdevice cannot perform requested service!";
+ break;
+#endif
+ /* gt - should be ample space in cstr. */
+ default:
+ sprintf (cstr, "Unknown error %d !", errno);
+ str = cstr;
+ break;
+ }
+ MesgString ("ioctl: ");
+ MesgString (str);
+ MesgLine ();
+ }
+} /* reportio */
+
+void
+save_init_tty ()
+{
+ /* Save the original tty characteristics and set up the signalling. */
+ save_temp_tty ();
+ init_tty_state = temp_tty_state;
+} /* save_init_tty */
+
+void
+restore_init_tty ()
+{
+ /* Restore the original tty characteristics. */
+ temp_tty_state = init_tty_state;
+ restore_temp_tty ();
+} /* restore_init_tty */
+
+void
+save_temp_tty ()
+{
+ /* Save the current tty characteristics and set up the signalling. */
+ iostatus = ioctl (DV_FD, DV_GTTY, &temp_tty_state);
+ reportio (iostatus);
+ setsignals ();
+} /* save_temp_tty */
+
+void
+restore_temp_tty ()
+{
+ /* Restore the recent tty characteristics. */
+ iostatus = ioctl (DV_FD, DV_STTY, &temp_tty_state);
+ reportio (iostatus);
+} /* restore_temp_tty */
+
+void
+singlecharon ()
+{
+ /* Set driver to read characters as they are typed without waiting for a
+ terminator. Echo remains unchanged. */
+ dv_tty s;
+
+ if (cmode_flags.cbreak != 1)
+ {
+ reportio (ioctl (DV_FD, DV_GTTY, &s));
+#ifndef TERMIO
+ s.sg_flags |= CBREAK;
+#else /* TERMIO */
+ saved_cc[VEOL] = s.c_cc[VEOL];
+ saved_cc[VEOF] = s.c_cc[VEOF];
+ s.c_lflag &= ~ICANON; /* Disable erase/kill processing */
+ s.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
+ s.c_cc[VTIME] = 0; /* no matter how long that takes. */
+#endif /* TERMIO */
+ reportio (ioctl (DV_FD, DV_STTY, &s));
+#ifdef FLUSH_STDIN
+ fflush (stdin);
+#endif /* FLUSH_STDIN */
+
+ cmode_flags.cbreak = 1;
+ }
+} /* singlecharon */
+
+void
+singlecharoff ()
+{
+ /* Turn off single character read mode. */
+ dv_tty s;
+
+ if (cmode_flags.cbreak != 0)
+ {
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifndef TERMIO
+ s.sg_flags &= ~CBREAK;
+#else /* TERMIO */
+ s.c_lflag |= ICANON; /* Enable erase/kill processing */
+ s.c_cc[VEOL] = saved_cc[VEOL];
+ s.c_cc[VEOF] = saved_cc[VEOF];
+#endif /* TERMIO */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+
+ cmode_flags.cbreak = 0;
+ }
+} /* singlecharoff */
+
+void
+echoon ()
+{
+ /* Turn character echoing on. */
+ dv_tty s;
+
+ reportio (ioctl (DV_FD, DV_GTTY, &s));
+#ifndef TERMIO
+ s.sg_flags |= ECHO;
+#else /* TERMIO */
+ s.c_lflag |= ECHO;
+#endif /* TERMIO */
+ reportio (ioctl (DV_FD, DV_STTY, &s));
+ cmode_flags.echo = 1;
+} /* echoon */
+
+void
+echooff ()
+{
+ /* Turn character echoing off. */
+ dv_tty s;
+
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifndef TERMIO
+ s.sg_flags &= ~ECHO;
+#else /* TERMIO */
+ s.c_lflag &= ~ECHO;
+#endif /* TERMIO */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+ cmode_flags.echo = 0;
+} /* echooff */
+
+void
+rawouton ()
+{
+ dv_tty s;
+
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifdef TERMIO
+ s.c_oflag &= ~OPOST; /* Disables tab interpretation etc. */
+#endif /* TERMIO */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+
+ cmode_flags.raw = 1;
+} /* rawouton */
+
+void
+rawoutoff ()
+{
+ dv_tty s;
+
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifdef TERMIO /* TERMIO */
+ s.c_oflag |= OPOST;
+#endif /* TERMIO */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+
+ cmode_flags.raw = 0;
+} /* rawoutoff */
+
+int
+buffercount ()
+{
+ /* Return true if there are any characters currently in the input buffer. */
+#ifndef TERMIO
+ long count;
+ iostatus = ioctl (DV_FD, FIONREAD, &count);
+ reportio (iostatus);
+ return (count > 0);
+#else /* TERMIO */
+ int c, flags, ret;
+
+ /* Save the current fcntl flags and make reads return without waiting */
+ flags = fcntl (0, F_GETFL, 0);
+ fcntl (0, F_SETFL, flags | O_NDELAY); /* This might be SysV specific */
+ if ((c = getchar ()) != EOF)
+ {
+ ungetc (c, stdin);
+ ret = 1;
+ }
+ else
+ {
+ ret = 0;
+ }
+ fcntl (0, F_SETFL, flags); /* This might be SysV specific */
+ return ret;
+#endif /* TERMIO */
+} /* buffercount */
+
+RETSIGTYPE
+handleint (int sig)
+{
+ /* Catch signals from tty.
+ If sig is an interrupt, set the intr flag,
+ Otherwise it was a suspend, so set the tstop flag. */
+ fflush (stdin);
+ if (sig == SIGINT)
+ {
+ sig_flags.intr = 1;
+ }
+ else
+ {
+ sig_flags.tstop = 1;
+ }
+#ifdef TERMIO /* TERMIO */
+ setsignals (); /* Because SysV forgets its handlers */
+#endif /* TERMIO */
+} /* handleint */
+
+static void
+setsignals ()
+{
+ /* Signal initialization. */
+ signal (SIGINT, handleint);
+#ifndef TERMIO
+ signal (SIGTSTP, handleint);
+#endif /* TERMIO */
+} /* setsignals */
+
+void
+suspend ()
+{
+ /* Suspend the process */
+#ifndef TERMIO
+ signal (SIGTSTP, SIG_DFL);
+ kill (0, SIGTSTP);
+ /* resumed again, goody! */
+ setsignals ();
+#else
+ /* don't know what to do */
+#endif /* TERMIO */
+} /* suspend */
+
+#undef IN_UNIXIO_C