home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / sys / unix / unixtty.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  8.5 KB  |  382 lines  |  [TEXT/R*ch]

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