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