1 /* NetHack 3.6 unixtty.c $NHDT-Date: 1548372343 2019/01/24 23:25:43 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.25 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Michael Allison, 2006. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* tty.c - (Unix) version */
8 /* With thanks to the people who sent code for SYSV - hpscdi!jon,
9 * arnold@ucsf-cgl, wcs@bo95b, cbcephus!pds and others.
16 * The distinctions here are not BSD - rest but rather USG - rest, as
17 * BSD still has the old sgttyb structure, but SYSV has termio. Thus:
19 #if (defined(BSD) || defined(ULTRIX)) && !defined(POSIX_TYPES)
30 #define termstruct termios
33 #if defined(TCSETS) && !defined(AIX_31)
34 #define termstruct termios
36 #define termstruct termio
38 #endif /* POSIX_TYPES */
40 #include <sys/ioctl.h>
41 #undef delay_output /* curses redefines this */
44 #define kill_sym c_cc[VKILL]
45 #define erase_sym c_cc[VERASE]
46 #define intr_sym c_cc[VINTR]
47 #ifdef TAB3 /* not a POSIX flag, but some have it anyway */
52 #define tabflgs c_oflag
53 #define echoflgs c_lflag
54 #define cbrkflgs c_lflag
55 #define CBRKMASK ICANON
56 #define CBRKON !/* reverse condition */
58 #define OSPEED(x) (speednum(cfgetospeed(&x)))
61 #define CBAUD _CBAUD /* for POSIX nitpickers (like RS/6000 cc) */
63 #define OSPEED(x) ((x).c_cflag & CBAUD)
65 #define IS_7BIT(x) ((x).c_cflag & CS7)
66 #define inputflags c_iflag
67 #define STRIPHI ISTRIP
69 #define GTTY(x) (tcgetattr(0, x))
70 #define STTY(x) (tcsetattr(0, TCSADRAIN, x))
72 #if defined(TCSETS) && !defined(AIX_31)
73 #define GTTY(x) (ioctl(0, TCGETS, x))
74 #define STTY(x) (ioctl(0, TCSETSW, x))
76 #define GTTY(x) (ioctl(0, TCGETA, x))
77 #define STTY(x) (ioctl(0, TCSETAW, x))
79 #endif /* POSIX_TYPES */
83 #if defined(BSD) && !defined(__DGUX__)
84 #define nonesuch _POSIX_VDISABLE
86 #define nonesuch (fpathconf(0, _PC_VDISABLE))
91 #define inittyb2 inittyb
92 #define curttyb2 curttyb
97 #define termstruct sgttyb
98 #define kill_sym sg_kill
99 #define erase_sym sg_erase
100 #define intr_sym t_intrc
102 #define tabflgs sg_flags
103 #define echoflgs sg_flags
104 #define cbrkflgs sg_flags
105 #define CBRKMASK CBREAK
106 #define CBRKON /* empty */
107 #define inputflags sg_flags /* don't know how enabling meta bits */
108 #define IS_7BIT(x) (FALSE)
109 #define STRIPHI 0 /* should actually be done on BSD */
110 #define OSPEED(x) (x).sg_ospeed
111 #if defined(bsdi) || defined(__386BSD) || defined(SUNOS4)
112 #define GTTY(x) (ioctl(0, TIOCGETP, (char *) x))
113 #define STTY(x) (ioctl(0, TIOCSETP, (char *) x))
115 #define GTTY(x) (gtty(0, x))
116 #define STTY(x) (stty(0, x))
118 #define GTTY2(x) (ioctl(0, TIOCGETC, (char *) x))
119 #define STTY2(x) (ioctl(0, TIOCSETC, (char *) x))
121 struct tchars inittyb2, curttyb2;
126 * Old curses.h relied on implicit declaration of has_colors().
127 * Modern compilers tend to warn about implicit declarations and
128 * modern curses.h declares has_colors() explicitly. However, the
129 * declaration it uses is not one we can simply clone (requires
130 * <stdbool.h>). This simpler declaration suffices but can't be
131 * used unconditionally because it conflicts with the 'bool' one.
133 #ifdef NEED_HAS_COLORS_DECL
137 #if defined(TTY_GRAPHICS) && ((!defined(SYSV) && !defined(HPUX)) \
138 || defined(UNIXPC) || defined(SVR4))
140 extern /* it is defined in libtermlib (libtermcap) */
142 short ospeed; /* terminal baudrate; set by gettty */
144 short ospeed = 0; /* gets around "not defined" error message */
147 #if defined(POSIX_TYPES) && defined(BSD)
151 intr_char, kill_char;
152 static boolean settty_needed = FALSE;
153 struct termstruct inittyb, curttyb;
202 if (STTY(&curttyb) < 0 || STTY2(&curttyb2) < 0)
203 perror("NetHack (setctty)");
207 * Get initial state of terminal, set ospeed (for termcap routines)
208 * and switch off tab expansion if necessary.
209 * Called by startup() in termcap.c and after returning from ! or ^Z
214 if (GTTY(&inittyb) < 0 || GTTY2(&inittyb2) < 0)
215 perror("NetHack (gettty)");
218 ospeed = OSPEED(inittyb);
219 erase_char = inittyb.erase_sym;
220 kill_char = inittyb.kill_sym;
221 intr_char = inittyb2.intr_sym;
224 /* do not expand tabs - they might be needed inside a cm sequence */
225 if (curttyb.tabflgs & EXTABS) {
226 curttyb.tabflgs &= ~EXTABS;
229 settty_needed = TRUE;
232 /* reset terminal to original state */
240 if (STTY(&inittyb) < 0 || STTY2(&inittyb2) < 0)
241 perror("NetHack (settty)");
242 iflags.echo = (inittyb.echoflgs & ECHO) ? ON : OFF;
243 iflags.cbreak = (CBRKON(inittyb.cbrkflgs & CBRKMASK)) ? ON : OFF;
244 curttyb.inputflags |= STRIPHI;
254 ef = 0; /* desired value of flags & ECHO */
255 cf = CBRKON(CBRKMASK); /* desired value of flags & CBREAK */
258 /* Should use (ECHO|CRMOD) here instead of ECHO */
259 if ((unsigned) (curttyb.echoflgs & ECHO) != ef) {
260 curttyb.echoflgs &= ~ECHO;
261 /* curttyb.echoflgs |= ef; */
264 if ((unsigned) (curttyb.cbrkflgs & CBRKMASK) != cf) {
265 curttyb.cbrkflgs &= ~CBRKMASK;
266 curttyb.cbrkflgs |= cf;
268 /* be satisfied with one character; no timeout */
269 curttyb.c_cc[VMIN] = 1; /* was VEOF */
270 curttyb.c_cc[VTIME] = 0; /* was VEOL */
271 #ifdef POSIX_JOB_CONTROL
272 /* turn off system suspend character
273 * due to differences in structure layout, this has to be
274 * here instead of in ioctl.c:getioctls() with the BSD
277 #ifdef VSUSP /* real POSIX */
278 curttyb.c_cc[VSUSP] = nonesuch;
279 #else /* other later SYSV */
280 curttyb.c_cc[VSWTCH] = nonesuch;
283 #ifdef VDSUSP /* SunOS Posix extensions */
284 curttyb.c_cc[VDSUSP] = nonesuch;
287 curttyb.c_cc[VREPRINT] = nonesuch;
290 curttyb.c_cc[VDISCARD] = nonesuch;
293 curttyb.c_cc[VWERASE] = nonesuch;
296 curttyb.c_cc[VLNEXT] = nonesuch;
301 if (!IS_7BIT(inittyb))
302 curttyb.inputflags &= ~STRIPHI;
303 /* If an interrupt character is used, it will be overridden and
306 if (intr_char != nonesuch && curttyb2.intr_sym != '\003') {
307 curttyb2.intr_sym = '\003';
316 void intron() /* enable kbd interupts if enabled when game started */
319 /* Ugly hack to keep from changing tty modes for non-tty games -dlc */
320 if (WINDOWPORT("tty") && intr_char != nonesuch
321 && curttyb2.intr_sym != '\003') {
322 curttyb2.intr_sym = '\003';
328 void introff() /* disable kbd interrupts if required*/
331 /* Ugly hack to keep from changing tty modes for non-tty games -dlc */
332 if (WINDOWPORT("tty") && curttyb2.intr_sym != nonesuch) {
333 curttyb2.intr_sym = nonesuch;
339 #ifdef _M_UNIX /* SCO UNIX (3.2.4), from Andreas Arens */
340 #include <sys/console.h>
342 #define BSIZE (E_TABSZ * 2)
343 #define LDIOC ('D' << 8) /* POSIX prevents definition */
345 #include <sys/emap.h>
347 int sco_flag_console = 0;
348 int sco_map_valid = -1;
349 unsigned char sco_chanmap_buf[BSIZE];
351 void NDECL(sco_mapon);
352 void NDECL(sco_mapoff);
353 void NDECL(check_sco_console);
354 void NDECL(init_sco_cons);
360 if (WINDOWPORT("tty") && sco_flag_console) {
361 if (sco_map_valid != -1) {
362 ioctl(0, LDSMAP, sco_chanmap_buf);
373 if (WINDOWPORT("tty") && sco_flag_console) {
374 sco_map_valid = ioctl(0, LDGMAP, sco_chanmap_buf);
375 if (sco_map_valid != -1) {
376 ioctl(0, LDNMAP, (char *) 0);
385 if (isatty(0) && ioctl(0, CONS_GET, 0) != -1) {
386 sco_flag_console = 1;
394 if (WINDOWPORT("tty") && sco_flag_console) {
397 load_symset("IBMGraphics", PRIMARY);
398 load_symset("RogueIBM", ROGUESET);
399 switch_symbols(TRUE);
402 iflags.use_color = TRUE;
409 #ifdef __linux__ /* via Jesse Thilo and Ben Gertzfield */
411 #include <sys/ioctl.h>
413 int linux_flag_console = 0;
415 void NDECL(linux_mapon);
416 void NDECL(linux_mapoff);
417 void NDECL(check_linux_console);
418 void NDECL(init_linux_cons);
424 if (WINDOWPORT("tty") && linux_flag_console) {
425 write(1, "\033(B", 3);
434 if (WINDOWPORT("tty") && linux_flag_console) {
435 write(1, "\033(U", 3);
441 check_linux_console()
445 if (isatty(0) && ioctl(0, VT_GETMODE, &vtm) >= 0) {
446 linux_flag_console = 1;
454 if (WINDOWPORT("tty") && linux_flag_console) {
459 iflags.use_color = TRUE;
464 #endif /* __linux__ */
466 #ifndef __begui__ /* the Be GUI will define its own error proc */
470 VA_DECL(const char *, s)
473 VA_INIT(s, const char *);
477 (void) putchar('\n');
481 #endif /* !__begui__ */