1 /*	SCCS Id: @(#)getline.c	3.3	96/01/27	*/
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed.  See license for details. */
4 
5 #include "hack.h"
6 
7 #ifdef TTY_GRAPHICS
8 
9 #include "wintty.h"
10 #include "func_tab.h"
11 
12 #ifdef OVL1
13 char morc = 0;	/* tell the outside world what char you chose */
14 #endif /* OVL1 */
15 STATIC_DCL boolean FDECL(ext_cmd_getlin_hook, (char *));
16 
17 typedef boolean FDECL((*getlin_hook_proc), (char *));
18 
19 STATIC_DCL void FDECL(hooked_tty_getlin, (const char*,char*,getlin_hook_proc));
20 extern int NDECL(extcmd_via_menu);	/* cmd.c */
21 
22 extern char erase_char, kill_char;	/* from appropriate tty.c file */
23 
24 #ifdef OVL1
25 
26 /*
27  * Read a line closed with '\n' into the array char bufp[BUFSZ].
28  * (The '\n' is not stored. The string is closed with a '\0'.)
29  * Reading can be interrupted by an escape ('\033') - now the
30  * resulting string is "\033".
31  */
32 void
tty_getlin(query,bufp)33 tty_getlin(query, bufp)
34 const char *query;
35 register char *bufp;
36 {
37     hooked_tty_getlin(query, bufp, (getlin_hook_proc) 0);
38 }
39 
40 STATIC_OVL void
hooked_tty_getlin(query,bufp,hook)41 hooked_tty_getlin(query, bufp, hook)
42 const char *query;
43 register char *bufp;
44 getlin_hook_proc hook;
45 {
46 	register char *obufp = bufp;
47 	register int c;
48 	struct WinDesc *cw = wins[WIN_MESSAGE];
49 	boolean doprev = 0;
50 
51 	if(ttyDisplay->toplin == 1 && !(cw->flags & WIN_STOP)) more();
52 	cw->flags &= ~WIN_STOP;
53 	ttyDisplay->toplin = 3; /* special prompt state */
54 	ttyDisplay->inread++;
55 	pline("%s ", query);
56 	*obufp = 0;
57 	for(;;) {
58 		(void) fflush(stdout);
59 		Sprintf(toplines, "%s ", query);
60 		Strcat(toplines, obufp);
61 		if((c = Getchar()) == EOF) {
62 			*bufp = 0;
63 			break;
64 		}
65 		if(c == '\033') {
66 			*obufp = c;
67 			obufp[1] = 0;
68 			break;
69 		}
70 		if (ttyDisplay->intr) {
71 		    ttyDisplay->intr--;
72 		    *bufp = 0;
73 		}
74 		if(c == '\020') { /* ctrl-P */
75 		    if(!doprev)
76 			(void) tty_doprev_message(); /* need two initially */
77 		    (void) tty_doprev_message();
78 		    doprev = 1;
79 		    continue;
80 		} else if(doprev) {
81 		    tty_clear_nhwindow(WIN_MESSAGE);
82 		    cw->maxcol = cw->maxrow;
83 		    doprev = 0;
84 		    addtopl(query);
85 		    addtopl(" ");
86 		    *bufp = 0;
87 		    addtopl(obufp);
88 		}
89 		if(c == erase_char || c == '\b') {
90 			if(bufp != obufp) {
91 				bufp--;
92 				putsyms("\b \b");/* putsym converts \b */
93 			} else	tty_nhbell();
94 #if defined(apollo)
95 		} else if(c == '\n' || c == '\r') {
96 #else
97 		} else if(c == '\n') {
98 #endif
99 			*bufp = 0;
100 			break;
101 		} else if(' ' <= (unsigned char) c && c != '\177' &&
102 			    (bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO)) {
103 				/* avoid isprint() - some people don't have it
104 				   ' ' is not always a printing char */
105 			*bufp = c;
106 			bufp[1] = 0;
107 			putsyms(bufp);
108 			bufp++;
109 			if (hook && (*hook)(obufp)) {
110 			    putsyms(bufp);
111 			    bufp = eos(bufp);
112 			}
113 		} else if(c == kill_char || c == '\177') { /* Robert Viduya */
114 				/* this test last - @ might be the kill_char */
115 			while(bufp != obufp) {
116 				bufp--;
117 				putsyms("\b \b");
118 			}
119 		} else
120 			tty_nhbell();
121 	}
122 	ttyDisplay->toplin = 2;		/* nonempty, no --More-- required */
123 	ttyDisplay->inread--;
124 	clear_nhwindow(WIN_MESSAGE);	/* clean up after ourselves */
125 }
126 
127 void
xwaitforspace(s)128 xwaitforspace(s)
129 register const char *s;	/* chars allowed besides return */
130 {
131     register int c, x = ttyDisplay ? (int) ttyDisplay->dismiss_more : '\n';
132 
133     morc = 0;
134 
135     while((c = tty_nhgetch()) != '\n') {
136 	if(iflags.cbreak) {
137 	    if ((s && index(s,c)) || c == x) {
138 		morc = (char) c;
139 		break;
140 	    }
141 	    tty_nhbell();
142 	}
143     }
144 
145 }
146 
147 #endif /* OVL1 */
148 #ifdef OVL2
149 
150 /*
151  * Implement extended command completion by using this hook into
152  * tty_getlin.  Check the characters already typed, if they uniquely
153  * identify an extended command, expand the string to the whole
154  * command.
155  *
156  * Return TRUE if we've extended the string at base.  Otherwise return FALSE.
157  * Assumptions:
158  *
159  *	+ we don't change the characters that are already in base
160  *	+ base has enough room to hold our string
161  */
162 STATIC_OVL boolean
ext_cmd_getlin_hook(base)163 ext_cmd_getlin_hook(base)
164 	char *base;
165 {
166 	int oindex, com_index;
167 
168 	com_index = -1;
169 	for (oindex = 0; extcmdlist[oindex].ef_txt != (char *)0; oindex++) {
170 		if (!strncmpi(base, extcmdlist[oindex].ef_txt, strlen(base))) {
171 			if (com_index == -1)	/* no matches yet */
172 			    com_index = oindex;
173 			else			/* more than 1 match */
174 			    return FALSE;
175 		}
176 	}
177 	if (com_index >= 0) {
178 		Strcpy(base, extcmdlist[com_index].ef_txt);
179 		return TRUE;
180 	}
181 
182 	return FALSE;	/* didn't match anything */
183 }
184 
185 /*
186  * Read in an extended command, doing command line completion.  We
187  * stop when we have found enough characters to make a unique command.
188  */
189 int
tty_get_ext_cmd()190 tty_get_ext_cmd()
191 {
192 	int i;
193 	char buf[BUFSZ];
194 
195 	if (iflags.extmenu) return extcmd_via_menu();
196 	/* maybe a runtime option? */
197 	/* hooked_tty_getlin("#", buf, flags.cmd_comp ? ext_cmd_getlin_hook : (getlin_hook_proc) 0); */
198 #ifdef REDO
199 	hooked_tty_getlin("#", buf, in_doagain ? (getlin_hook_proc)0
200 		: ext_cmd_getlin_hook);
201 #else
202 	hooked_tty_getlin("#", buf, ext_cmd_getlin_hook);
203 #endif
204 	if (buf[0] == 0 || buf[0] == '\033') return -1;
205 
206 	for (i = 0; extcmdlist[i].ef_txt != (char *)0; i++)
207 		if (!strcmpi(buf, extcmdlist[i].ef_txt)) break;
208 
209 #ifdef REDO
210 	if (!in_doagain) {
211 	    int j;
212 	    for (j = 0; buf[j]; j++)
213 		savech(buf[j]);
214 	    savech('\n');
215 	}
216 #endif
217 
218 	if (extcmdlist[i].ef_txt == (char *)0) {
219 		pline("%s: unknown extended command.", buf);
220 		i = -1;
221 	}
222 
223 	return i;
224 }
225 
226 #endif /* OVL2 */
227 
228 #endif /* TTY_GRAPHICS */
229 
230 /*getline.c*/
231