1 /* NetHack 3.6 unixtty.c $NHDT-Date: 1450916700 2015/12/24 00:25:00 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.21 $ */
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;
125 #if defined(TTY_GRAPHICS) && ((!defined(SYSV) && !defined(HPUX)) \
126 || defined(UNIXPC) || defined(SVR4))
128 extern /* it is defined in libtermlib (libtermcap) */
130 short ospeed; /* terminal baudrate; set by gettty */
132 short ospeed = 0; /* gets around "not defined" error message */
135 #if defined(POSIX_TYPES) && defined(BSD)
139 intr_char, kill_char;
140 static boolean settty_needed = FALSE;
141 struct termstruct inittyb, curttyb;
190 if (STTY(&curttyb) < 0 || STTY2(&curttyb2) < 0)
191 perror("NetHack (setctty)");
195 * Get initial state of terminal, set ospeed (for termcap routines)
196 * and switch off tab expansion if necessary.
197 * Called by startup() in termcap.c and after returning from ! or ^Z
202 if (GTTY(&inittyb) < 0 || GTTY2(&inittyb2) < 0)
203 perror("NetHack (gettty)");
206 ospeed = OSPEED(inittyb);
207 erase_char = inittyb.erase_sym;
208 kill_char = inittyb.kill_sym;
209 intr_char = inittyb2.intr_sym;
212 /* do not expand tabs - they might be needed inside a cm sequence */
213 if (curttyb.tabflgs & EXTABS) {
214 curttyb.tabflgs &= ~EXTABS;
217 settty_needed = TRUE;
220 /* reset terminal to original state */
228 if (STTY(&inittyb) < 0 || STTY2(&inittyb2) < 0)
229 perror("NetHack (settty)");
230 iflags.echo = (inittyb.echoflgs & ECHO) ? ON : OFF;
231 iflags.cbreak = (CBRKON(inittyb.cbrkflgs & CBRKMASK)) ? ON : OFF;
232 curttyb.inputflags |= STRIPHI;
242 ef = 0; /* desired value of flags & ECHO */
243 cf = CBRKON(CBRKMASK); /* desired value of flags & CBREAK */
246 /* Should use (ECHO|CRMOD) here instead of ECHO */
247 if ((unsigned) (curttyb.echoflgs & ECHO) != ef) {
248 curttyb.echoflgs &= ~ECHO;
249 /* curttyb.echoflgs |= ef; */
252 if ((unsigned) (curttyb.cbrkflgs & CBRKMASK) != cf) {
253 curttyb.cbrkflgs &= ~CBRKMASK;
254 curttyb.cbrkflgs |= cf;
256 /* be satisfied with one character; no timeout */
257 curttyb.c_cc[VMIN] = 1; /* was VEOF */
258 curttyb.c_cc[VTIME] = 0; /* was VEOL */
259 #ifdef POSIX_JOB_CONTROL
260 /* turn off system suspend character
261 * due to differences in structure layout, this has to be
262 * here instead of in ioctl.c:getioctls() with the BSD
265 #ifdef VSUSP /* real POSIX */
266 curttyb.c_cc[VSUSP] = nonesuch;
267 #else /* other later SYSV */
268 curttyb.c_cc[VSWTCH] = nonesuch;
271 #ifdef VDSUSP /* SunOS Posix extensions */
272 curttyb.c_cc[VDSUSP] = nonesuch;
275 curttyb.c_cc[VREPRINT] = nonesuch;
278 curttyb.c_cc[VDISCARD] = nonesuch;
281 curttyb.c_cc[VWERASE] = nonesuch;
284 curttyb.c_cc[VLNEXT] = nonesuch;
289 if (!IS_7BIT(inittyb))
290 curttyb.inputflags &= ~STRIPHI;
291 /* If an interrupt character is used, it will be overridden and
294 if (intr_char != nonesuch && curttyb2.intr_sym != '\003') {
295 curttyb2.intr_sym = '\003';
304 void intron() /* enable kbd interupts if enabled when game started */
307 /* Ugly hack to keep from changing tty modes for non-tty games -dlc */
308 if (!strcmp(windowprocs.name, "tty") && intr_char != nonesuch
309 && curttyb2.intr_sym != '\003') {
310 curttyb2.intr_sym = '\003';
316 void introff() /* disable kbd interrupts if required*/
319 /* Ugly hack to keep from changing tty modes for non-tty games -dlc */
320 if (!strcmp(windowprocs.name, "tty") && curttyb2.intr_sym != nonesuch) {
321 curttyb2.intr_sym = nonesuch;
327 #ifdef _M_UNIX /* SCO UNIX (3.2.4), from Andreas Arens */
328 #include <sys/console.h>
330 #define BSIZE (E_TABSZ * 2)
331 #define LDIOC ('D' << 8) /* POSIX prevents definition */
333 #include <sys/emap.h>
335 int sco_flag_console = 0;
336 int sco_map_valid = -1;
337 unsigned char sco_chanmap_buf[BSIZE];
339 void NDECL(sco_mapon);
340 void NDECL(sco_mapoff);
341 void NDECL(check_sco_console);
342 void NDECL(init_sco_cons);
348 if (!strcmp(windowprocs.name, "tty") && sco_flag_console) {
349 if (sco_map_valid != -1) {
350 ioctl(0, LDSMAP, sco_chanmap_buf);
361 if (!strcmp(windowprocs.name, "tty") && sco_flag_console) {
362 sco_map_valid = ioctl(0, LDGMAP, sco_chanmap_buf);
363 if (sco_map_valid != -1) {
364 ioctl(0, LDNMAP, (char *) 0);
373 if (isatty(0) && ioctl(0, CONS_GET, 0) != -1) {
374 sco_flag_console = 1;
382 if (!strcmp(windowprocs.name, "tty") && sco_flag_console) {
385 load_symset("IBMGraphics", PRIMARY);
386 load_symset("RogueIBM", ROGUESET);
387 switch_symbols(TRUE);
390 iflags.use_color = TRUE;
397 #ifdef __linux__ /* via Jesse Thilo and Ben Gertzfield */
399 #include <sys/ioctl.h>
401 int linux_flag_console = 0;
403 void NDECL(linux_mapon);
404 void NDECL(linux_mapoff);
405 void NDECL(check_linux_console);
406 void NDECL(init_linux_cons);
412 if (!strcmp(windowprocs.name, "tty") && linux_flag_console) {
413 _pragma_ignore(-Wunused-result)
414 write(1, "\033(B", 3);
424 if (!strcmp(windowprocs.name, "tty") && linux_flag_console) {
425 _pragma_ignore(-Wunused-result)
426 write(1, "\033(U", 3);
433 check_linux_console()
437 if (isatty(0) && ioctl(0, VT_GETMODE, &vtm) >= 0) {
438 linux_flag_console = 1;
446 if (!strcmp(windowprocs.name, "tty") && linux_flag_console) {
451 iflags.use_color = TRUE;
456 #endif /* __linux__ */
458 #ifndef __begui__ /* the Be GUI will define its own error proc */
462 VA_DECL(const char *, s)
465 VA_INIT(s, const char *);
469 (void) putchar('\n');
473 #endif /* !__begui__ */