]> granicus.if.org Git - nethack/commitdiff
*** empty log message ***
authorjwalz <jwalz>
Sat, 5 Jan 2002 21:05:58 +0000 (21:05 +0000)
committerjwalz <jwalz>
Sat, 5 Jan 2002 21:05:58 +0000 (21:05 +0000)
sys/share/unixtty.c [new file with mode: 0644]

diff --git a/sys/share/unixtty.c b/sys/share/unixtty.c
new file mode 100644 (file)
index 0000000..f0d93f9
--- /dev/null
@@ -0,0 +1,450 @@
+/*     SCCS Id: @(#)unixtty.c  3.3     90/22/02 */
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* NetHack may be freely redistributed.  See license for details. */
+
+/* tty.c - (Unix) version */
+
+/* With thanks to the people who sent code for SYSV - hpscdi!jon,
+ * arnold@ucsf-cgl, wcs@bo95b, cbcephus!pds and others.
+ */
+
+#define NEED_VARARGS
+#include "hack.h"
+
+/*
+ * The distinctions here are not BSD - rest but rather USG - rest, as
+ * BSD still has the old sgttyb structure, but SYSV has termio. Thus:
+ */
+#if (defined(BSD) || defined(ULTRIX)) && !defined(POSIX_TYPES)
+# define V7
+#else
+# define USG
+#endif
+
+#ifdef USG
+
+# ifdef POSIX_TYPES
+#  include <termios.h>
+#  include <unistd.h>
+#  define termstruct   termios
+# else
+#  include <termio.h>
+#  if defined(TCSETS) && !defined(AIX_31)
+#   define termstruct  termios
+#  else
+#   define termstruct  termio
+#  endif
+# endif /* POSIX_TYPES */
+# ifdef LINUX
+#  include <sys/ioctl.h>
+#  undef delay_output  /* curses redefines this */
+#  include <curses.h>
+# endif
+# define kill_sym      c_cc[VKILL]
+# define erase_sym     c_cc[VERASE]
+# define intr_sym      c_cc[VINTR]
+# ifdef TAB3   /* not a POSIX flag, but some have it anyway */
+#  define EXTABS       TAB3
+# else
+#  define EXTABS       0
+# endif
+# define tabflgs       c_oflag
+# define echoflgs      c_lflag
+# define cbrkflgs      c_lflag
+# define CBRKMASK      ICANON
+# define CBRKON                ! /* reverse condition */
+# ifdef POSIX_TYPES
+#  define OSPEED(x)    (speednum(cfgetospeed(&x)))
+# else
+#  ifndef CBAUD
+#   define CBAUD       _CBAUD /* for POSIX nitpickers (like RS/6000 cc) */
+#  endif
+#  define OSPEED(x)    ((x).c_cflag & CBAUD)
+# endif
+# define IS_7BIT(x)    ((x).c_cflag & CS7)
+# define inputflags    c_iflag
+# define STRIPHI       ISTRIP
+# ifdef POSIX_TYPES
+#  define GTTY(x)      (tcgetattr(0, x))
+#  define STTY(x)      (tcsetattr(0, TCSADRAIN, x))
+# else
+#  if defined(TCSETS) && !defined(AIX_31)
+#   define GTTY(x)     (ioctl(0, TCGETS, x))
+#   define STTY(x)     (ioctl(0, TCSETSW, x))
+#  else
+#   define GTTY(x)     (ioctl(0, TCGETA, x))
+#   define STTY(x)     (ioctl(0, TCSETAW, x))
+#  endif
+# endif /* POSIX_TYPES */
+#  define GTTY2(x)     1
+#  define STTY2(x)     1
+# ifdef POSIX_TYPES
+#  if defined(BSD) && !defined(__DGUX__)
+#   define nonesuch    _POSIX_VDISABLE
+#  else
+#   define nonesuch    (fpathconf(0, _PC_VDISABLE))
+#  endif
+# else
+#  define nonesuch     0
+# endif
+# define inittyb2      inittyb
+# define curttyb2      curttyb
+
+#else  /* V7 */
+
+# include <sgtty.h>
+# define termstruct    sgttyb
+# define kill_sym      sg_kill
+# define erase_sym     sg_erase
+# define intr_sym      t_intrc
+# define EXTABS                XTABS
+# define tabflgs       sg_flags
+# define echoflgs      sg_flags
+# define cbrkflgs      sg_flags
+# define CBRKMASK      CBREAK
+# define CBRKON                /* empty */
+# define inputflags    sg_flags        /* don't know how enabling meta bits */
+# define IS_7BIT(x)    (FALSE)
+# define STRIPHI       0               /* should actually be done on BSD */
+# define OSPEED(x)     (x).sg_ospeed
+# if defined(bsdi) || defined(__386BSD) || defined(SUNOS4)
+#  define GTTY(x)      (ioctl(0, TIOCGETP, (char *)x))
+#  define STTY(x)      (ioctl(0, TIOCSETP, (char *)x))
+# else
+#  define GTTY(x)      (gtty(0, x))
+#  define STTY(x)      (stty(0, x))
+# endif
+# define GTTY2(x)      (ioctl(0, TIOCGETC, (char *)x))
+# define STTY2(x)      (ioctl(0, TIOCSETC, (char *)x))
+# define nonesuch      -1
+struct tchars inittyb2, curttyb2;
+
+#endif /* V7 */
+
+#if defined(TTY_GRAPHICS) && ((!defined(SYSV) && !defined(HPUX)) || defined(UNIXPC) || defined(SVR4))
+# ifndef LINT
+extern                 /* it is defined in libtermlib (libtermcap) */
+# endif
+       short ospeed;   /* terminal baudrate; set by gettty */
+#else
+short  ospeed = 0;     /* gets around "not defined" error message */
+#endif
+
+#if defined(POSIX_TYPES) && defined(BSD)
+unsigned
+#endif
+       char erase_char, intr_char, kill_char;
+static boolean settty_needed = FALSE;
+struct termstruct inittyb, curttyb;
+
+#ifdef POSIX_TYPES
+static int
+speednum(speed)
+speed_t speed;
+{
+       switch (speed) {
+               case B0:        return 0;
+               case B50:       return 1;
+               case B75:       return 2;
+               case B110:      return 3;
+               case B134:      return 4;
+               case B150:      return 5;
+               case B200:      return 6;
+               case B300:      return 7;
+               case B600:      return 8;
+               case B1200:     return 9;
+               case B1800:     return 10;
+               case B2400:     return 11;
+               case B4800:     return 12;
+               case B9600:     return 13;
+               case B19200:    return 14;
+               case B38400:    return 15;
+       }
+
+       return 0;
+}
+#endif
+
+static void
+setctty()
+{
+       if(STTY(&curttyb) < 0 || STTY2(&curttyb2) < 0)
+               perror("NetHack (setctty)");
+}
+
+/*
+ * Get initial state of terminal, set ospeed (for termcap routines)
+ * and switch off tab expansion if necessary.
+ * Called by startup() in termcap.c and after returning from ! or ^Z
+ */
+void
+gettty()
+{
+       if(GTTY(&inittyb) < 0 || GTTY2(&inittyb2) < 0)
+               perror("NetHack (gettty)");
+       curttyb = inittyb;
+       curttyb2 = inittyb2;
+       ospeed = OSPEED(inittyb);
+       erase_char = inittyb.erase_sym;
+       kill_char = inittyb.kill_sym;
+       intr_char = inittyb2.intr_sym;
+       getioctls();
+
+       /* do not expand tabs - they might be needed inside a cm sequence */
+       if(curttyb.tabflgs & EXTABS) {
+               curttyb.tabflgs &= ~EXTABS;
+               setctty();
+       }
+       settty_needed = TRUE;
+}
+
+/* reset terminal to original state */
+void
+settty(s)
+const char *s;
+{
+       end_screen();
+       if(s) raw_print(s);
+       if(STTY(&inittyb) < 0 || STTY2(&inittyb2) < 0)
+               perror("NetHack (settty)");
+       iflags.echo = (inittyb.echoflgs & ECHO) ? ON : OFF;
+       iflags.cbreak = (CBRKON(inittyb.cbrkflgs & CBRKMASK)) ? ON : OFF;
+       curttyb.inputflags |= STRIPHI;
+       setioctls();
+}
+
+void
+setftty()
+{
+register int ef = 0;                   /* desired value of flags & ECHO */
+#ifdef LINT    /* cf = CBRKON(CBRKMASK); const expr to initialize is ok */
+register int cf = 0;
+#else
+register int cf = CBRKON(CBRKMASK);    /* desired value of flags & CBREAK */
+#endif
+register int change = 0;
+       iflags.cbreak = ON;
+       iflags.echo = OFF;
+       /* Should use (ECHO|CRMOD) here instead of ECHO */
+       if((curttyb.echoflgs & ECHO) != ef){
+               curttyb.echoflgs &= ~ECHO;
+/*             curttyb.echoflgs |= ef;                                 */
+               change++;
+       }
+       if((curttyb.cbrkflgs & CBRKMASK) != cf){
+               curttyb.cbrkflgs &= ~CBRKMASK;
+               curttyb.cbrkflgs |= cf;
+#ifdef USG
+               /* be satisfied with one character; no timeout */
+               curttyb.c_cc[VMIN] = 1;         /* was VEOF */
+               curttyb.c_cc[VTIME] = 0;        /* was VEOL */
+# ifdef POSIX_JOB_CONTROL
+               /* turn off system suspend character
+                * due to differences in structure layout, this has to be
+                * here instead of in ioctl.c:getioctls() with the BSD
+                * equivalent
+                */
+#  ifdef VSUSP /* real POSIX */
+               curttyb.c_cc[VSUSP] = nonesuch;
+#  else                /* other later SYSV */
+               curttyb.c_cc[VSWTCH] = nonesuch;
+#  endif
+# endif
+# ifdef VDSUSP /* SunOS Posix extensions */
+               curttyb.c_cc[VDSUSP] = nonesuch;
+# endif
+# ifdef VREPRINT
+               curttyb.c_cc[VREPRINT] = nonesuch;
+# endif
+# ifdef VDISCARD
+               curttyb.c_cc[VDISCARD] = nonesuch;
+# endif
+# ifdef VWERASE
+               curttyb.c_cc[VWERASE] = nonesuch;
+# endif
+# ifdef VLNEXT
+               curttyb.c_cc[VLNEXT] = nonesuch;
+# endif
+#endif
+               change++;
+       }
+       if(!IS_7BIT(inittyb)) curttyb.inputflags &=~ STRIPHI;
+       /* If an interrupt character is used, it will be overriden and
+        * set to ^C.
+        */
+       if(intr_char != nonesuch && curttyb2.intr_sym != '\003') {
+           curttyb2.intr_sym = '\003';
+           change++;
+       }
+
+       if(change) setctty();
+       start_screen();
+}
+
+void
+intron()               /* enable kbd interupts if enabled when game started */
+{
+#ifdef TTY_GRAPHICS
+       /* Ugly hack to keep from changing tty modes for non-tty games -dlc */
+       if (!strcmp(windowprocs.name, "tty") &&
+           intr_char != nonesuch && curttyb2.intr_sym != '\003') {
+           curttyb2.intr_sym = '\003';
+           setctty();
+       }
+#endif
+}
+
+void
+introff()              /* disable kbd interrupts if required*/
+{
+#ifdef TTY_GRAPHICS
+       /* Ugly hack to keep from changing tty modes for non-tty games -dlc */
+       if (!strcmp(windowprocs.name, "tty") &&
+          curttyb2.intr_sym != nonesuch) {
+           curttyb2.intr_sym = nonesuch;
+           setctty();
+       }
+#endif
+}
+
+#ifdef _M_UNIX         /* SCO UNIX (3.2.4), from Andreas Arens */
+# include <sys/console.h>
+
+# define BSIZE (E_TABSZ*2)
+# define LDIOC ('D'<<8)                /* POSIX prevents definition */
+
+# include <sys/emap.h>
+
+int sco_flag_console = 0;
+int sco_map_valid = -1;
+unsigned char sco_chanmap_buf[BSIZE];
+
+void NDECL(sco_mapon);
+void NDECL(sco_mapoff);
+void NDECL(check_sco_console);
+void NDECL(init_sco_cons);
+
+void
+sco_mapon()
+{
+# ifdef TTY_GRAPHICS
+       if (!strcmp(windowprocs.name, "tty") && sco_flag_console) {
+               if (sco_map_valid != -1) {
+                       ioctl(0,LDSMAP,sco_chanmap_buf);
+               }
+               sco_map_valid = -1;
+       }
+# endif
+}
+
+void
+sco_mapoff()
+{
+# ifdef TTY_GRAPHICS
+       if (!strcmp(windowprocs.name, "tty") && sco_flag_console) {
+               sco_map_valid = ioctl(0,LDGMAP,sco_chanmap_buf);
+               if (sco_map_valid != -1) {
+                       ioctl(0,LDNMAP,(char *)0);
+               }
+       }
+# endif
+}
+
+void
+check_sco_console()
+{
+       if (isatty(0) && ioctl(0,CONS_GET,0) != -1) {
+               sco_flag_console = 1;
+       }
+}
+
+void
+init_sco_cons()
+{
+# ifdef TTY_GRAPHICS
+       if (!strcmp(windowprocs.name, "tty") && sco_flag_console) {
+               atexit(sco_mapon);
+               sco_mapoff();
+               switch_graphics(IBM_GRAPHICS);
+#  ifdef TEXTCOLOR
+               if (has_colors())
+                       iflags.use_color = TRUE;
+#  endif
+       }
+# endif
+}
+#endif /* _M_UNIX */
+
+
+#ifdef __linux__               /* via Jesse Thilo and Ben Gertzfield */
+# include <sys/vt.h>
+
+int linux_flag_console = 0;
+
+void NDECL(linux_mapon);
+void NDECL(linux_mapoff);
+void NDECL(check_linux_console);
+void NDECL(init_linux_cons);
+
+void
+linux_mapon()
+{
+# ifdef TTY_GRAPHICS
+       if (!strcmp(windowprocs.name, "tty") && linux_flag_console) {
+               write(1, "\033(B", 3);
+       }
+# endif
+}
+
+void
+linux_mapoff()
+{
+# ifdef TTY_GRAPHICS
+       if (!strcmp(windowprocs.name, "tty") && linux_flag_console) {
+               write(1, "\033(U", 3);
+       }
+# endif
+}
+
+void
+check_linux_console()
+{
+       struct vt_mode vtm;
+
+       if (isatty(0) && ioctl(0,VT_GETMODE,&vtm) >= 0) {
+               linux_flag_console = 1;
+       }
+}
+
+void
+init_linux_cons()
+{
+# ifdef TTY_GRAPHICS
+       if (!strcmp(windowprocs.name, "tty") && linux_flag_console) {
+               atexit(linux_mapon);
+               linux_mapoff();
+#  ifdef TEXTCOLOR
+               if (has_colors())
+                       iflags.use_color = TRUE;
+#  endif
+       }
+# endif
+}
+#endif /* __linux__ */
+
+
+#ifndef __begui__      /* the Be GUI will define its own error proc */
+/* fatal error */
+/*VARARGS1*/
+void
+error VA_DECL(const char *,s)
+       VA_START(s);
+       VA_INIT(s, const char *);
+       if(settty_needed)
+               settty((char *)0);
+       Vprintf(s,VA_ARGS);
+       (void) putchar('\n');
+       VA_END();
+       exit(EXIT_FAILURE);
+}
+#endif /* !__begui__ */