From 70a857f0ef155241e050d4979ff1198c113c1652 Mon Sep 17 00:00:00 2001 From: jwalz Date: Sat, 5 Jan 2002 21:05:58 +0000 Subject: [PATCH] *** empty log message *** --- sys/share/unixtty.c | 450 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 450 insertions(+) create mode 100644 sys/share/unixtty.c diff --git a/sys/share/unixtty.c b/sys/share/unixtty.c new file mode 100644 index 000000000..f0d93f96b --- /dev/null +++ b/sys/share/unixtty.c @@ -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 +# include +# define termstruct termios +# else +# include +# if defined(TCSETS) && !defined(AIX_31) +# define termstruct termios +# else +# define termstruct termio +# endif +# endif /* POSIX_TYPES */ +# ifdef LINUX +# include +# undef delay_output /* curses redefines this */ +# include +# 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 +# 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 + +# define BSIZE (E_TABSZ*2) +# define LDIOC ('D'<<8) /* POSIX prevents definition */ + +# include + +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 + +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__ */