Files @ 5e822fe9c265
Branch filter:

Location: libtransport.git/backends/frotz/dfrotz/dumb/dumb_input.c - annotation

Vitaly Takmazov
fixed dfrotz target
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
a22b6e149063
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
a22b6e149063
5e822fe9c265
5e822fe9c265
5e822fe9c265
5e822fe9c265
5e822fe9c265
a22b6e149063
a22b6e149063
a22b6e149063
a22b6e149063
a22b6e149063
a22b6e149063
a22b6e149063
a22b6e149063
a22b6e149063
a22b6e149063
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
a22b6e149063
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
a22b6e149063
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
a22b6e149063
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
a22b6e149063
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
a22b6e149063
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
a22b6e149063
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
a22b6e149063
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
a22b6e149063
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
a22b6e149063
a22b6e149063
a22b6e149063
a22b6e149063
a22b6e149063
a22b6e149063
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
51c03d82ea50
/* dumb-input.c
 * $Id: dumb-input.c,v 1.1.1.1 2002/03/26 22:38:34 feedle Exp $
 * Copyright 1997,1998 Alpine Petrofsky <alpine@petrofsky.berkeley.ca.us>.
 * Any use permitted provided this notice stays intact.
 */

#include "dumb_frotz.h"
f_setup_t f_setup;

static char runtime_usage[] =
  "DUMB-FROTZ runtime help:\n"
  "  General Commands:\n"
  "    \\help    Show this message.\n"
  "    \\set     Show the current values of runtime settings.\n"
  "    \\s       Show the current contents of the whole screen.\n"
  "    \\d       Discard the part of the input before the cursor.\n"
  "    \\wN      Advance clock N/10 seconds, possibly causing the current\n"
  "                and subsequent inputs to timeout.\n"
  "    \\w       Advance clock by the amount of real time since this input\n"
  "                started (times the current speed factor).\n"
  "    \\t       Advance clock just enough to timeout the current input\n"
  "  Reverse-Video Display Method Settings:\n"
  "    \\rn   none    \\rc   CAPS    \\rd   doublestrike    \\ru   underline\n"
  "    \\rbC  show rv blanks as char C (orthogonal to above modes)\n"
  "  Output Compression Settings:\n"
  "    \\cn      none: show whole screen before every input.\n"
  "    \\cm      max: show only lines that have new nonblank characters.\n"
  "    \\cs      spans: like max, but emit a blank line between each span of\n"
  "                screen lines shown.\n"
  "    \\chN     Hide top N lines (orthogonal to above modes).\n"
  "  Misc Settings:\n"
  "    \\sfX     Set speed factor to X.  (0 = never timeout automatically).\n"
  "    \\mp      Toggle use of MORE prompts\n"
  "    \\ln      Toggle display of line numbers.\n"
  "    \\lt      Toggle display of the line type identification chars.\n"
  "    \\vb      Toggle visual bell.\n"
  "    \\pb      Toggle display of picture outline boxes.\n"
  "    (Toggle commands can be followed by a 1 or 0 to set value ON or OFF.)\n"
  "  Character Escapes:\n"
  "    \\\\  backslash    \\#  backspace    \\[  escape    \\_  return\n"
  "    \\< \\> \\^ \\.  cursor motion        \\1 ..\\0  f1..f10\n"
  "    \\D ..\\X   Standard Frotz hotkeys.  Use \\H (help) to see the list.\n"
  "  Line Type Identification Characters:\n"
  "    Input lines:\n"
  "      untimed  timed\n"
  "      >        T      A regular line-oriented input\n"
  "      )        t      A single-character input\n"
  "      }        D      A line input with some input before the cursor.\n"
  "                         (Use \\d to discard it.)\n"
  "    Output lines:\n"
  "      ]     Output line that contains the cursor.\n"
  "      .     A blank line emitted as part of span compression.\n"
  "            (blank) Any other output line.\n"
;

static float speed = 1;
static bool do_more_prompts = FALSE;

enum input_type {
  INPUT_CHAR,
  INPUT_LINE,
  INPUT_LINE_CONTINUED,
};

/* get a character.  Exit with no fuss on EOF.  */
static int xgetchar(void)
{
  int c = getchar();
  if (c == EOF) {
    if (feof(stdin)) {
      fprintf(stderr, "\nEOT\n");
      exit(0);
    }
    os_fatal(strerror(errno));
  }
  return c;
}

/* Read one line, including the newline, into s.  Safely avoids buffer
 * overruns (but that's kind of pointless because there are several
 * other places where I'm not so careful).  */
static void getline_(char *s)
{
  int c;
  char *p;
	
  fflush(stdout);
  
  p = s;
  while (p < s + INPUT_BUFFER_SIZE - 1)
    if ((*p++ = xgetchar()) == '\n') {
      *p = '\0';
      return;
    }
  p[-1] = '\n';
  p[0] = '\0';
  while ((c = xgetchar()) != '\n')
    ;
  printf("Line too long, truncated to %s\n", s - INPUT_BUFFER_SIZE);
}

/* Translate in place all the escape characters in s.  */
static void translate_special_chars(char *s)
{
  char *src = s, *dest = s;
  while (*src)
    switch(*src++) {
    default: *dest++ = src[-1]; break;
    case '\n': *dest++ = ZC_RETURN; break;
    case '\\':
      switch (*src++) {
      case '\n': *dest++ = ZC_RETURN; break;
      case '\\': *dest++ = '\\'; break;
      case '?': *dest++ = ZC_BACKSPACE; break;
      case '[': *dest++ = ZC_ESCAPE; break;
      case '_': *dest++ = ZC_RETURN; break;
      case '^': *dest++ = ZC_ARROW_UP; break;
      case '.': *dest++ = ZC_ARROW_DOWN; break;
      case '<': *dest++ = ZC_ARROW_LEFT; break;
      case '>': *dest++ = ZC_ARROW_RIGHT; break;
      case 'R': *dest++ = ZC_HKEY_RECORD; break;
      case 'P': *dest++ = ZC_HKEY_PLAYBACK; break;
      case 'S': *dest++ = ZC_HKEY_SEED; break;
      case 'U': *dest++ = ZC_HKEY_UNDO; break;
      case 'N': *dest++ = ZC_HKEY_RESTART; break;
      case 'X': *dest++ = ZC_HKEY_QUIT; break;
      case 'D': *dest++ = ZC_HKEY_DEBUG; break;
      case 'H': *dest++ = ZC_HKEY_HELP; break;
      case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
	*dest++ = ZC_FKEY_MIN + src[-1] - '0' - 1; break;
      case '0': *dest++ = ZC_FKEY_MIN + 9; break;
      default:
	fprintf(stderr, "DUMB-FROTZ: unknown escape char: %c\n", src[-1]);
	fprintf(stderr, "Enter \\help to see the list\n");
      }
    }
  *dest = '\0';
}


/* The time in tenths of seconds that the user is ahead of z time.  */
static int time_ahead = 0;

/* Called from os_read_key and os_read_line if they have input from
 * a previous call to dumb_read_line.
 * Returns TRUE if we should timeout rather than use the read-ahead.
 * (because the user is further ahead than the timeout).  */
static bool check_timeout(int timeout)
{
  if ((timeout == 0) || (timeout > time_ahead))
    time_ahead = 0;
  else
    time_ahead -= timeout;
  return time_ahead != 0;
}

/* If val is '0' or '1', set *var accordingly, otherwise toggle it.  */
static void toggle(bool *var, char val)
{
  *var = val == '1' || (val != '0' && !*var);
}

/* Handle input-related user settings and call dumb_output_handle_setting.  */
bool dumb_handle_setting(const char *setting, bool show_cursor, bool startup)
{
  if (!strncmp(setting, "sf", 2)) {
    speed = atof(&setting[2]);
    printf("Speed Factor %g\n", speed);
  } else if (!strncmp(setting, "mp", 2)) {
    toggle(&do_more_prompts, setting[2]);
    printf("More prompts %s\n", do_more_prompts ? "ON" : "OFF");
  } else {
    if (!strcmp(setting, "set")) {
      printf("Speed Factor %g\n", speed);
      printf("More Prompts %s\n", do_more_prompts ? "ON" : "OFF");
    }
    return dumb_output_handle_setting(setting, show_cursor, startup);
  }
  return TRUE;
}

/* Read a line, processing commands (lines that start with a backslash
 * (that isn't the start of a special character)), and write the
 * first non-command to s.
 * Return true if timed-out.  */
static bool dumb_read_line(char *s, char *prompt, bool show_cursor,
			   int timeout, enum input_type type,
			   zchar *continued_line_chars)
{
  time_t start_time;

  if (timeout) {
    if (time_ahead >= timeout) {
      time_ahead -= timeout;
      return TRUE;
    }
    timeout -= time_ahead;
    start_time = time(0);
  }
  time_ahead = 0;

  dumb_show_screen(show_cursor);
  for (;;) {
    char *command;
    if (prompt)
      fputs(prompt, stdout);
    else
      dumb_show_prompt(show_cursor, (timeout ? "tTD" : ")>}")[type]);
    getline_(s);
    if ((s[0] != '\\') || ((s[1] != '\0') && !islower(s[1]))) {
      /* Is not a command line.  */
      translate_special_chars(s);
      if (timeout) {
	int elapsed = (time(0) - start_time) * 10 * speed;
	if (elapsed > timeout) {
	  time_ahead = elapsed - timeout;
	  return TRUE;
	}
      }
      return FALSE;
    }
    /* Commands.  */

    /* Remove the \ and the terminating newline.  */
    command = s + 1;
    command[strlen(command) - 1] = '\0';
    
    if (!strcmp(command, "t")) {
      if (timeout) {
	time_ahead = 0;
	s[0] = '\0';
	return TRUE;
      }
    } else if (*command == 'w') {
      if (timeout) {
	int elapsed = atoi(&command[1]);
	time_t now = time(0);
	if (elapsed == 0)
	  elapsed = (now - start_time) * 10 * speed;
	if (elapsed >= timeout) {
	  time_ahead = elapsed - timeout;
	  s[0] = '\0';
	  return TRUE;
	}
	timeout -= elapsed;
	start_time = now;
      }
    } else if (!strcmp(command, "d")) {
      if (type != INPUT_LINE_CONTINUED)
	fprintf(stderr, "DUMB-FROTZ: No input to discard\n");
      else {
	dumb_discard_old_input(strlen(continued_line_chars));
	continued_line_chars[0] = '\0';
	type = INPUT_LINE;
      }
    } else if (!strcmp(command, "help")) {
      if (!do_more_prompts)
	fputs(runtime_usage, stdout);
      else {
	char *current_page, *next_page;
	current_page = next_page = runtime_usage;
	for (;;) {
	  int i;
	  for (i = 0; (i < h_screen_rows - 2) && *next_page; i++)
	    next_page = strchr(next_page, '\n') + 1;
	  printf("%.*s", next_page - current_page, current_page);
	  current_page = next_page;
	  if (!*current_page)
	    break;
	  printf("HELP: Type <return> for more, or q <return> to stop: ");
	  getline_(s);
	  if (!strcmp(s, "q\n"))
	    break;
	}
      }
    } else if (!strcmp(command, "s")) {
	dumb_dump_screen();
    } else if (!dumb_handle_setting(command, show_cursor, FALSE)) {
      fprintf(stderr, "DUMB-FROTZ: unknown command: %s\n", s);
      fprintf(stderr, "Enter \\help to see the list of commands\n");
    }
  }
}

/* Read a line that is not part of z-machine input (more prompts and
 * filename requests).  */
static void dumb_read_misc_line(char *s, char *prompt)
{
  dumb_read_line(s, prompt, 0, 0, 0, 0);
  /* Remove terminating newline */
  s[strlen(s) - 1] = '\0';
}

/* For allowing the user to input in a single line keys to be returned
 * for several consecutive calls to read_char, with no screen update
 * in between.  Useful for traversing menus.  */
static char read_key_buffer[INPUT_BUFFER_SIZE];

/* Similar.  Useful for using function key abbreviations.  */
static char read_line_buffer[INPUT_BUFFER_SIZE];

zchar os_read_key (int timeout, bool show_cursor)
{
  char c;
  int timed_out;

  /* Discard any keys read for line input.  */
  read_line_buffer[0] = '\0';

  if (read_key_buffer[0] == '\0') {
    timed_out = dumb_read_line(read_key_buffer, NULL, show_cursor, timeout,
			       INPUT_CHAR, NULL);
    /* An empty input line is reported as a single CR.
     * If there's anything else in the line, we report only the line's
     * contents and not the terminating CR.  */
    if (strlen(read_key_buffer) > 1)
      read_key_buffer[strlen(read_key_buffer) - 1] = '\0';
  } else
    timed_out = check_timeout(timeout);
    
  if (timed_out)
    return ZC_TIME_OUT;

  c = read_key_buffer[0];
  memmove(read_key_buffer, read_key_buffer + 1, strlen(read_key_buffer));

  /* TODO: error messages for invalid special chars.  */

  return c;
}

zchar os_read_line (int max, zchar *buf, int timeout, int width, int continued)
{
  char *p;
  int terminator;
  static bool timed_out_last_time;
  int timed_out;

  /* Discard any keys read for single key input.  */
  read_key_buffer[0] = '\0';

  /* After timing out, discard any further input unless we're continuing.  */
  if (timed_out_last_time && !continued)
    read_line_buffer[0] = '\0';

  if (read_line_buffer[0] == '\0')
    timed_out = dumb_read_line(read_line_buffer, NULL, TRUE, timeout,
			       buf[0] ? INPUT_LINE_CONTINUED : INPUT_LINE,
			       buf);
  else
    timed_out = check_timeout(timeout);
  
  if (timed_out) {
    timed_out_last_time = TRUE;
    return ZC_TIME_OUT;
  }
    
  /* find the terminating character.  */
  for (p = read_line_buffer;; p++) {
    if (is_terminator(*p)) {
      terminator = *p;
      *p++ = '\0';
      break;
    }
  }

  /* TODO: Truncate to width and max.  */

  /* copy to screen */
  dumb_display_user_input(read_line_buffer);

  /* copy to the buffer and save the rest for next time.  */
  strcat(buf, read_line_buffer);
  p = read_line_buffer + strlen(read_line_buffer) + 1;
  memmove(read_line_buffer, p, strlen(p) + 1);
    
  /* If there was just a newline after the terminating character,
   * don't save it.  */
  if ((read_line_buffer[0] == '\r') && (read_line_buffer[1] == '\0'))
    read_line_buffer[0] = '\0';

  timed_out_last_time = FALSE;
  return terminator;
}

int os_read_file_name (char *file_name, const char *default_name, int flag)
{
  char buf[INPUT_BUFFER_SIZE], prompt[INPUT_BUFFER_SIZE];
  FILE *fp;

  sprintf(prompt, "Please enter a filename [%s]: ", default_name);
  dumb_read_misc_line(buf, prompt);
  if (strlen(buf) > MAX_FILE_NAME) {
    printf("Filename too long\n");
    return FALSE;
  }

  strcpy (file_name, buf[0] ? buf : default_name);

  /* Warn if overwriting a file.  */
//   if ((flag == FILE_SAVE || flag == FILE_SAVE_AUX || flag == FILE_RECORD)
//       && ((fp = fopen(file_name, "rb")) != NULL)) {
//     fclose (fp);
//     dumb_read_misc_line(buf, "Overwrite existing file? ");
//     return(tolower(buf[0]) == 'y');
//   }
  return TRUE;
}

void os_more_prompt (void)
{
  if (do_more_prompts) {
    char buf[INPUT_BUFFER_SIZE];
    dumb_read_misc_line(buf, "***MORE***");
  } else
    dumb_elide_more_prompt();
}

void dumb_init_input(void)
{
  if ((h_version >= V4) && (speed != 0))
    h_config |= CONFIG_TIMEDINPUT;

  if (h_version >= V5)
    h_flags &= ~(MOUSE_FLAG | MENU_FLAG);
}

zword os_read_mouse(void)
{
	/* NOT IMPLEMENTED */
}