]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.tty.c
Don't use <sys/cdefs.h> __COPYRIGHT/__RCSID macros for host programs -
[bsdgames-darwin.git] / hack / hack.tty.c
1 /* $NetBSD: hack.tty.c,v 1.7 2000/07/10 10:19:25 itojun Exp $ */
2
3 /*-
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include <sys/cdefs.h>
37 #ifndef lint
38 #if 0
39 static char sccsid[] = "@(#)hack.tty.c 8.1 (Berkeley) 5/31/93";
40 #else
41 __RCSID("$NetBSD: hack.tty.c,v 1.7 2000/07/10 10:19:25 itojun Exp $");
42 #endif
43 #endif /* not lint */
44
45 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
46 /* hack.tty.c - version 1.0.3 */
47 /*
48 * With thanks to the people who sent code for SYSV - hpscdi!jon,
49 * arnold@ucsf-cgl, wcs@bo95b, cbcephus!pds and others.
50 */
51
52 #include <termios.h>
53 #include "hack.h"
54 #include "extern.h"
55
56 /*
57 * Some systems may have getchar() return EOF for various reasons, and
58 * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
59 */
60 #ifndef BSD
61 #define NR_OF_EOFS 20
62 #endif /* BSD */
63
64 static char erase_char, kill_char;
65 static boolean settty_needed = FALSE;
66 struct termios inittyb, curttyb;
67
68 /*
69 * Get initial state of terminal, set ospeed (for termcap routines)
70 * and switch off tab expansion if necessary.
71 * Called by startup() in termcap.c and after returning from ! or ^Z
72 */
73 void
74 gettty()
75 {
76 extern speed_t ospeed;
77 if (tcgetattr(0, &inittyb) < 0)
78 perror("Hack (gettty)");
79 curttyb = inittyb;
80 ospeed = cfgetospeed(&inittyb);
81 erase_char = inittyb.c_cc[VERASE];
82 kill_char = inittyb.c_cc[VKILL];
83 getioctls();
84
85 /* do not expand tabs - they might be needed inside a cm sequence */
86 if (curttyb.c_oflag & OXTABS) {
87 curttyb.c_oflag &= ~OXTABS;
88 setctty();
89 }
90 settty_needed = TRUE;
91 }
92
93 /* reset terminal to original state */
94 void
95 settty(s)
96 char *s;
97 {
98 clear_screen();
99 end_screen();
100 if (s)
101 printf("%s", s);
102 (void) fflush(stdout);
103 if (tcsetattr(0, TCSADRAIN, &inittyb) < 0)
104 perror("Hack (settty)");
105 flags.echo = (inittyb.c_lflag & ECHO) ? ON : OFF;
106 flags.cbreak = (inittyb.c_lflag & ICANON) ? OFF : ON;
107 setioctls();
108 }
109
110 void
111 setctty()
112 {
113 if (tcsetattr(0, TCSADRAIN, &curttyb) < 0)
114 perror("Hack (setctty)");
115 }
116
117
118 void
119 setftty()
120 {
121 int change = 0;
122 flags.cbreak = ON;
123 flags.echo = OFF;
124 /* Should use (ECHO|CRMOD) here instead of ECHO */
125 if (curttyb.c_lflag & ECHO) {
126 curttyb.c_lflag &= ~ECHO;
127 change++;
128 }
129 if (curttyb.c_lflag & ICANON) {
130 curttyb.c_lflag &= ~ICANON;
131 /* be satisfied with one character; no timeout */
132 curttyb.c_cc[VMIN] = 1;
133 curttyb.c_cc[VTIME] = 0;
134 change++;
135 }
136 if (change) {
137 setctty();
138 }
139 start_screen();
140 }
141
142
143 /* fatal error */
144 /* VARARGS1 */
145 void
146 #ifdef __STDC__
147 error(const char *fmt, ...)
148 #else
149 error(va_alist)
150 va_dcl
151 #endif
152 {
153 va_list ap;
154 #ifndef __STDC__
155 const char *fmt;
156
157 va_start(ap);
158 fmt = va_arg(ap, const char *);
159 #else
160 va_start(ap, fmt);
161 #endif
162 if (settty_needed)
163 settty((char *) 0);
164 vprintf(fmt, ap);
165 va_end(ap);
166 putchar('\n');
167 exit(1);
168 }
169
170 /*
171 * Read a line closed with '\n' into the array char bufp[BUFSZ].
172 * (The '\n' is not stored. The string is closed with a '\0'.)
173 * Reading can be interrupted by an escape ('\033') - now the
174 * resulting string is "\033".
175 */
176 void
177 getlin(bufp)
178 char *bufp;
179 {
180 char *obufp = bufp;
181 int c;
182
183 flags.toplin = 2; /* nonempty, no --More-- required */
184 for (;;) {
185 (void) fflush(stdout);
186 if ((c = getchar()) == EOF) {
187 *bufp = 0;
188 return;
189 }
190 if (c == '\033') {
191 *obufp = c;
192 obufp[1] = 0;
193 return;
194 }
195 if (c == erase_char || c == '\b') {
196 if (bufp != obufp) {
197 bufp--;
198 putstr("\b \b"); /* putsym converts \b */
199 } else
200 bell();
201 } else if (c == '\n') {
202 *bufp = 0;
203 return;
204 } else if (' ' <= c && c < '\177') {
205 /*
206 * avoid isprint() - some people don't have it ' ' is
207 * not always a printing char
208 */
209 *bufp = c;
210 bufp[1] = 0;
211 putstr(bufp);
212 if (bufp - obufp < BUFSZ - 1 && bufp - obufp < COLNO)
213 bufp++;
214 } else if (c == kill_char || c == '\177') { /* Robert Viduya */
215 /* this test last - @ might be the kill_char */
216 while (bufp != obufp) {
217 bufp--;
218 putstr("\b \b");
219 }
220 } else
221 bell();
222 }
223 }
224
225 void
226 getret()
227 {
228 cgetret("");
229 }
230
231 void
232 cgetret(s)
233 char *s;
234 {
235 putsym('\n');
236 if (flags.standout)
237 standoutbeg();
238 putstr("Hit ");
239 putstr(flags.cbreak ? "space" : "return");
240 putstr(" to continue: ");
241 if (flags.standout)
242 standoutend();
243 xwaitforspace(s);
244 }
245
246 char morc; /* tell the outside world what char he used */
247
248 void
249 xwaitforspace(s)
250 char *s; /* chars allowed besides space or return */
251 {
252 int c;
253
254 morc = 0;
255
256 while ((c = readchar()) != '\n') {
257 if (flags.cbreak) {
258 if (c == ' ')
259 break;
260 if (s && strchr(s, c)) {
261 morc = c;
262 break;
263 }
264 bell();
265 }
266 }
267 }
268
269 char *
270 parse()
271 {
272 static char inputline[COLNO];
273 int foo;
274
275 flags.move = 1;
276 if (!Invisible)
277 curs_on_u();
278 else
279 home();
280 while ((foo = readchar()) >= '0' && foo <= '9')
281 multi = 10 * multi + foo - '0';
282 if (multi) {
283 multi--;
284 save_cm = inputline;
285 }
286 inputline[0] = foo;
287 inputline[1] = 0;
288 if (foo == 'f' || foo == 'F') {
289 inputline[1] = getchar();
290 #ifdef QUEST
291 if (inputline[1] == foo)
292 inputline[2] = getchar();
293 else
294 #endif /* QUEST */
295 inputline[2] = 0;
296 }
297 if (foo == 'm' || foo == 'M') {
298 inputline[1] = getchar();
299 inputline[2] = 0;
300 }
301 clrlin();
302 return (inputline);
303 }
304
305 char
306 readchar()
307 {
308 int sym;
309
310 (void) fflush(stdout);
311 if ((sym = getchar()) == EOF)
312 #ifdef NR_OF_EOFS
313 { /*
314 * Some SYSV systems seem to return EOFs for various reasons
315 * (?like when one hits break or for interrupted systemcalls?),
316 * and we must see several before we quit.
317 */
318 int cnt = NR_OF_EOFS;
319 while (cnt--) {
320 clearerr(stdin); /* omit if clearerr is
321 * undefined */
322 if ((sym = getchar()) != EOF)
323 goto noteof;
324 }
325 end_of_input();
326 noteof: ;
327 }
328 #else
329 end_of_input();
330 #endif /* NR_OF_EOFS */
331 if (flags.toplin == 1)
332 flags.toplin = 2;
333 return ((char) sym);
334 }
335
336 void
337 end_of_input()
338 {
339 settty("End of input?\n");
340 clearlocks();
341 exit(0);
342 }