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