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