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