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
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
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
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
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
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*/