home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / nethack-3.1 / sys / unix / unixtty.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-18  |  7.5 KB  |  325 lines

  1. /*    SCCS Id: @(#)unixtty.c    3.1    90/22/02
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /* tty.c - (Unix) version */
  6.  
  7. /* With thanks to the people who sent code for SYSV - hpscdi!jon,
  8.  * arnold@ucsf-cgl, wcs@bo95b, cbcephus!pds and others.
  9.  */
  10.  
  11. #define NEED_VARARGS
  12. #include "hack.h"
  13.  
  14. #ifdef TTY_GRAPHICS
  15. #include "wintty.h"
  16. #endif
  17.  
  18. /*
  19.  * The distinctions here are not BSD - rest but rather USG - rest, as
  20.  * BSD still has the old sgttyb structure, but SYSV has termio. Thus:
  21.  */
  22. #if (defined(BSD) || defined(ULTRIX)) && !defined(POSIX_TYPES)
  23. #define    V7
  24. #else
  25. #define USG
  26. #endif
  27.  
  28.  
  29. #ifdef USG
  30.  
  31. # ifdef POSIX_TYPES
  32. #include    <termios.h>
  33. #include    <unistd.h>
  34. #define termstruct    termios
  35. # else
  36. #include    <termio.h>
  37. #  if defined(TCSETS) && !defined(AIX_31)
  38. #define termstruct    termios
  39. #  else
  40. #define termstruct    termio
  41. #  endif
  42. # endif /* POSIX_TYPES */
  43. #define kill_sym    c_cc[VKILL]
  44. #define erase_sym    c_cc[VERASE]
  45. #define intr_sym    c_cc[VINTR]
  46. # ifdef TAB3    /* not a POSIX flag, but some have it anyway */
  47. #define EXTABS        TAB3
  48. # else
  49. #define EXTABS        0
  50. # endif
  51. #define tabflgs        c_oflag
  52. #define echoflgs    c_lflag
  53. #define cbrkflgs    c_lflag
  54. #define CBRKMASK    ICANON
  55. #define CBRKON        ! /* reverse condition */
  56. # ifdef POSIX_TYPES
  57. #define OSPEED(x)    (speednum(cfgetospeed(&x)))
  58. # else
  59. #  ifndef CBAUD
  60. # define CBAUD        _CBAUD /* for POSIX nitpickers (like RS/6000 cc) */
  61. #  endif
  62. #define OSPEED(x)    ((x).c_cflag & CBAUD)
  63. # endif
  64. #define IS_7BIT(x)    ((x).c_cflag & CS7)
  65. #define inputflags    c_iflag
  66. #define STRIPHI        ISTRIP
  67. # ifdef POSIX_TYPES
  68. #  define GTTY(x)    (tcgetattr(0, x))
  69. #  define STTY(x)    (tcsetattr(0, TCSADRAIN, x))
  70. # else
  71. #  if defined(TCSETS) && !defined(AIX_31)
  72. #   define GTTY(x)    (ioctl(0, TCGETS, x))
  73. #   define STTY(x)    (ioctl(0, TCSETSW, x))
  74. #  else
  75. #   define GTTY(x)    (ioctl(0, TCGETA, x))
  76. #   define STTY(x)    (ioctl(0, TCSETAW, x))
  77. #  endif
  78. # endif /* POSIX_TYPES */
  79. #define GTTY2(x)    1
  80. #define STTY2(x)    1
  81. # ifdef POSIX_TYPES
  82. #  ifdef BSD
  83. #   define nonesuch    _POSIX_VDISABLE
  84. #  else
  85. #   define nonesuch    (fpathconf(0, _PC_VDISABLE))
  86. #  endif
  87. # else
  88. #  define nonesuch    0
  89. # endif
  90. #define inittyb2    inittyb
  91. #define curttyb2    curttyb
  92.  
  93. #else    /* V7 */
  94.  
  95. #include    <sgtty.h>
  96. #define termstruct    sgttyb
  97. #define    kill_sym    sg_kill
  98. #define    erase_sym    sg_erase
  99. #define    intr_sym    t_intrc
  100. #define EXTABS        XTABS
  101. #define tabflgs        sg_flags
  102. #define echoflgs    sg_flags
  103. #define cbrkflgs    sg_flags
  104. #define CBRKMASK    CBREAK
  105. #define CBRKON        /* empty */
  106. #define inputflags    sg_flags    /* don't know how enabling meta bits */
  107. #define IS_7BIT(x)    (FALSE)
  108. #define STRIPHI        0        /* should actually be done on BSD */
  109. #define OSPEED(x)    (x).sg_ospeed
  110. #if defined(bsdi) || defined(__386BSD)
  111. # define GTTY(x)    (ioctl(0, TIOCGETP, (char *)x))
  112. # define STTY(x)    (ioctl(0, TIOCSETP, (char *)x))
  113. #else
  114. # define GTTY(x)    (gtty(0, x))
  115. # define STTY(x)    (stty(0, x))
  116. #endif
  117. #define GTTY2(x)    (ioctl(0, TIOCGETC, (char *)x))
  118. #define STTY2(x)    (ioctl(0, TIOCSETC, (char *)x))
  119. #define nonesuch    -1
  120. struct tchars inittyb2, curttyb2;
  121.  
  122. #endif
  123.  
  124. #if defined(TTY_GRAPHICS) && ((!defined(SYSV) && !defined(HPUX)) || defined(UNIXPC) || defined(SVR4))
  125. # ifndef LINT
  126. extern            /* it is defined in libtermlib (libtermcap) */
  127. # endif
  128.     short ospeed;    /* terminal baudrate; set by gettty */
  129. #else
  130. short    ospeed = 0;    /* gets around "not defined" error message */
  131. #endif
  132.  
  133. #if defined(POSIX_TYPES) && defined(BSD)
  134. unsigned
  135. #endif
  136.     char erase_char, intr_char, kill_char;
  137. static boolean settty_needed = FALSE;
  138. struct termstruct inittyb, curttyb;
  139.  
  140. #ifdef POSIX_TYPES
  141. static int
  142. speednum(speed)
  143. speed_t speed;
  144. {
  145.     switch (speed) {
  146.         case B0:    return 0;
  147.         case B50:    return 1;
  148.         case B75:    return 2;
  149.         case B110:    return 3;
  150.         case B134:    return 4;
  151.         case B150:    return 5;
  152.         case B200:    return 6;
  153.         case B300:    return 7;
  154.         case B600:    return 8;
  155.         case B1200:    return 9;
  156.         case B1800:    return 10;
  157.         case B2400:    return 11;
  158.         case B4800:    return 12;
  159.         case B9600:    return 13;
  160.         case B19200:    return 14;
  161.         case B38400:    return 15;
  162.     }
  163.  
  164.     return 0;
  165. }
  166. #endif
  167.  
  168. static void
  169. setctty()
  170. {
  171.     if(STTY(&curttyb) < 0 || STTY2(&curttyb2) < 0)
  172.         perror("NetHack (setctty)");
  173. }
  174.  
  175. /*
  176.  * Get initial state of terminal, set ospeed (for termcap routines)
  177.  * and switch off tab expansion if necessary.
  178.  * Called by startup() in termcap.c and after returning from ! or ^Z
  179.  */
  180. void
  181. gettty()
  182. {
  183.     if(GTTY(&inittyb) < 0 || GTTY2(&inittyb2) < 0)
  184.         perror("NetHack (gettty)");
  185.     curttyb = inittyb;
  186.     curttyb2 = inittyb2;
  187.     ospeed = OSPEED(inittyb);
  188.     erase_char = inittyb.erase_sym;
  189.     kill_char = inittyb.kill_sym;
  190.     intr_char = inittyb2.intr_sym;
  191.     getioctls();
  192.  
  193.     /* do not expand tabs - they might be needed inside a cm sequence */
  194.     if(curttyb.tabflgs & EXTABS) {
  195.         curttyb.tabflgs &= ~EXTABS;
  196.         setctty();
  197.     }
  198.     settty_needed = TRUE;
  199. }
  200.  
  201. /* reset terminal to original state */
  202. void
  203. settty(s)
  204. const char *s;
  205. {
  206.     end_screen();
  207.     if(s) raw_print(s);
  208.     if(STTY(&inittyb) < 0 || STTY2(&inittyb2) < 0)
  209.         perror("NetHack (settty)");
  210.     flags.echo = (inittyb.echoflgs & ECHO) ? ON : OFF;
  211.     flags.cbreak = (CBRKON(inittyb.cbrkflgs & CBRKMASK)) ? ON : OFF;
  212.     curttyb.inputflags |= STRIPHI;
  213.     setioctls();
  214. }
  215.  
  216. void
  217. setftty()
  218. {
  219. register int ef = 0;            /* desired value of flags & ECHO */
  220. #ifdef LINT    /* cf = CBRKON(CBRKMASK); const expr to initialize is ok */
  221. register int cf = 0;
  222. #else
  223. register int cf = CBRKON(CBRKMASK);    /* desired value of flags & CBREAK */
  224. #endif
  225. register int change = 0;
  226.     flags.cbreak = ON;
  227.     flags.echo = OFF;
  228.     /* Should use (ECHO|CRMOD) here instead of ECHO */
  229.     if((curttyb.echoflgs & ECHO) != ef){
  230.         curttyb.echoflgs &= ~ECHO;
  231. /*        curttyb.echoflgs |= ef;                    */
  232.         change++;
  233.     }
  234.     if((curttyb.cbrkflgs & CBRKMASK) != cf){
  235.         curttyb.cbrkflgs &= ~CBRKMASK;
  236.         curttyb.cbrkflgs |= cf;
  237. #ifdef USG
  238.         /* be satisfied with one character; no timeout */
  239.         curttyb.c_cc[VMIN] = 1;        /* was VEOF */
  240.         curttyb.c_cc[VTIME] = 0;    /* was VEOL */
  241. # ifdef POSIX_JOB_CONTROL
  242.         /* turn off system suspend character
  243.          * due to differences in structure layout, this has to be
  244.          * here instead of in ioctl.c:getioctls() with the BSD
  245.          * equivalent
  246.          */
  247. #  ifdef VSUSP    /* real POSIX */
  248.         curttyb.c_cc[VSUSP] = nonesuch;
  249. #  else        /* other later SYSV */
  250.         curttyb.c_cc[VSWTCH] = nonesuch;
  251. #  endif
  252. # endif
  253. # ifdef VDSUSP /* SunOS Posix extensions */
  254.         curttyb.c_cc[VDSUSP] = nonesuch;
  255. # endif
  256. # ifdef VREPRINT
  257.         curttyb.c_cc[VREPRINT] = nonesuch;
  258. # endif
  259. # ifdef VDISCARD
  260.         curttyb.c_cc[VDISCARD] = nonesuch;
  261. # endif
  262. # ifdef VWERASE
  263.         curttyb.c_cc[VWERASE] = nonesuch;
  264. # endif
  265. # ifdef VLNEXT
  266.         curttyb.c_cc[VLNEXT] = nonesuch;
  267. # endif
  268. #endif
  269.         change++;
  270.     }
  271.     if(!IS_7BIT(inittyb)) curttyb.inputflags &=~ STRIPHI;
  272.     /* If an interrupt character is used, it will be overriden and
  273.      * set to ^C.
  274.      */
  275.     if(intr_char != nonesuch && curttyb2.intr_sym != '\003') {
  276.         curttyb2.intr_sym = '\003';
  277.         change++;
  278.     }
  279.  
  280.     if(change) setctty();
  281.     start_screen();
  282. }
  283.  
  284. void
  285. intron()        /* enable kbd interupts if enabled when game started */
  286. {
  287. #ifdef TTY_GRAPHICS
  288.     /* Ugly hack to keep from changing tty modes for non-tty games -dlc */
  289.     if (windowprocs.win_init_nhwindows == tty_init_nhwindows &&
  290.         intr_char != nonesuch && curttyb2.intr_sym != '\003') {
  291.         curttyb2.intr_sym = '\003';
  292.         setctty();
  293.     }
  294. #endif
  295. }
  296.  
  297. void
  298. introff()        /* disable kbd interrupts if required*/
  299. {
  300. #ifdef TTY_GRAPHICS
  301.     /* Ugly hack to keep from changing tty modes for non-tty games -dlc */
  302.     if (windowprocs.win_init_nhwindows == tty_init_nhwindows &&
  303.        curttyb2.intr_sym != nonesuch) {
  304.         curttyb2.intr_sym = nonesuch;
  305.         setctty();
  306.     }
  307. #endif
  308. }
  309.  
  310.  
  311. /* fatal error */
  312. /*VARARGS1*/
  313.  
  314. void
  315. error VA_DECL(const char *,s)
  316.     VA_START(s);
  317.     VA_INIT(s, const char *);
  318.     if(settty_needed)
  319.         settty(NULL);
  320.     Vprintf(s,VA_ARGS);
  321.     (void) putchar('\n');
  322.     VA_END();
  323.     exit(1);
  324. }
  325.