"Fossies" - the Fresh Open Source Software Archive 
Member "tin-2.6.2/src/prompt.c" (9 Dec 2022, 19790 Bytes) of package /linux/misc/tin-2.6.2.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "prompt.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.6.1_vs_2.6.2.
1 /*
2 * Project : tin - a Usenet reader
3 * Module : prompt.c
4 * Author : I. Lea
5 * Created : 1991-04-01
6 * Updated : 2021-10-29
7 * Notes :
8 *
9 * Copyright (c) 1991-2023 Iain Lea <iain@bricbrac.de>
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * 3. Neither the name of the copyright holder nor the names of its
24 * contributors may be used to endorse or promote products derived from
25 * this software without specific prior written permission.
26 *
27 * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40
41 #ifndef TIN_H
42 # include "tin.h"
43 #endif /* !TIN_H */
44 #ifndef TCURSES_H
45 # include "tcurses.h"
46 #endif /* !TCURSES_H */
47
48
49 static char *prompt_slk_message; /* prompt message for prompt_slk_redraw */
50 static char *prompt_yn_message;
51 static char *prompt_yn_choice;
52
53 /*
54 * Local prototypes
55 */
56 static int prompt_list(int row, int col, int var, constext *help_text, constext *prompt_text, constext *list[], int size);
57
58
59 /*
60 * prompt_num
61 * get a number from the user
62 * Return -1 if missing or bad number typed
63 */
64 int
65 prompt_num(
66 int ch,
67 const char *prompt)
68 {
69 char *p;
70 char tmp[LEN];
71 int num;
72
73 clear_message();
74 snprintf(tmp, sizeof(tmp), "%c", ch);
75 if ((p = tin_getline(prompt, 1, tmp, 0, FALSE, HIST_OTHER)) != NULL) {
76 STRCPY(tmp, p);
77 num = atoi(tmp);
78 } else
79 num = -1;
80
81 clear_message();
82 return num;
83 }
84
85
86 /*
87 * prompt_string
88 * get a string from the user
89 * Return TRUE if a valid string was typed, FALSE otherwise
90 * TODO: no bounds checking on buf size, tin_getline() defaults to 1024
91 */
92 t_bool
93 prompt_string(
94 const char *prompt,
95 char *buf,
96 int which_hist)
97 {
98 return prompt_default_string(prompt, buf, 0, (char *) NULL, which_hist);
99 }
100
101
102 /*
103 * prompt_default_string
104 * get a string from the user, display default value
105 * Return TRUE if a valid string was typed, FALSE otherwise
106 */
107 t_bool
108 prompt_default_string(
109 const char *prompt,
110 char *buf,
111 int buf_len,
112 char *default_prompt,
113 int which_hist)
114 {
115 char *p;
116
117 clear_message();
118 if ((p = tin_getline(prompt, 0, default_prompt, buf_len, FALSE, which_hist)) == NULL) {
119 buf[0] = '\0';
120 clear_message();
121 return FALSE;
122 }
123 strcpy(buf, p);
124 clear_message();
125 return TRUE;
126 }
127
128
129 /*
130 * prompt_menu_string
131 * get a string from the user
132 * Return TRUE if a valid string was typed, FALSE otherwise
133 */
134 t_bool
135 prompt_menu_string(
136 int line,
137 const char *prompt,
138 char *var)
139 {
140 char *p;
141
142 /*
143 * clear buffer - this is needed, otherwise a lost
144 * connection right before a resync_active() call
145 * would lead to a 'n' answer to the reconnect prompt
146 */
147 /* fflush(stdin); */
148 MoveCursor(line, 0);
149 if ((p = tin_getline(prompt, 0, var, 0, FALSE, HIST_OTHER)) == NULL)
150 return FALSE;
151
152 strcpy(var, p);
153 return TRUE;
154 }
155
156
157 /*
158 * prompt_yn
159 * prompt user for 'y'es or 'n'o decision. "prompt" will be displayed in the
160 * last line giving the default answer "default_answer".
161 * The function returns 1 if the user decided "yes", -1 if the user wanted
162 * to escape, or 0 for any other decision.
163 */
164 int
165 prompt_yn(
166 const char *prompt,
167 t_bool default_answer)
168 {
169 char *keyprompt;
170 char keyno[MAXKEYLEN], keyyes[MAXKEYLEN];
171 int keyyes_len, keyno_len, maxlen, prompt_len;
172 t_function func;
173 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
174 wint_t yes, no, prompt_ch, ch;
175 #else
176 char yes, no, prompt_ch;
177 int ch;
178 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
179
180 /* fflush(stdin); */ /* Prevent finger trouble from making important decisions */
181
182 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
183 yes = (wint_t) func_to_key(PROMPT_YES, prompt_keys);
184 no = (wint_t) func_to_key(PROMPT_NO, prompt_keys);
185
186 printascii(keyyes, (default_answer ? towupper(yes) : yes));
187 printascii(keyno, (!default_answer ? towupper(no) : no));
188 #else
189 yes = func_to_key(PROMPT_YES, prompt_keys);
190 no = func_to_key(PROMPT_NO, prompt_keys);
191
192 printascii(keyyes, (default_answer ? my_toupper(yes) : yes));
193 printascii(keyno, (!default_answer ? my_toupper(no) : no));
194 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
195
196 keyyes_len = strwidth(keyyes);
197 keyno_len = strwidth(keyno);
198 maxlen = MAX(keyyes_len, keyno_len);
199 prompt_len = keyyes_len + keyno_len + maxlen + 6;
200 prompt_yn_message = my_strdup(prompt);
201 prompt_yn_choice = my_malloc(prompt_len + 1);
202
203 input_context = cPromptYN;
204
205 do {
206 prompt_ch = (default_answer ? yes : no);
207 keyprompt = (default_answer ? keyyes : keyno);
208
209 snprintf(prompt_yn_choice, (size_t) prompt_len, " (%s/%s) %-*s", keyyes, keyno, maxlen, keyprompt);
210 prompt_yn_redraw();
211
212 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
213 if (((ch = ReadWch()) == '\n') || (ch == '\r'))
214 #else
215 if (((ch = (char) ReadCh()) == '\n') || (ch == '\r'))
216 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
217 ch = prompt_ch;
218
219 switch (ch) {
220 case ESC: /* (ESC) common arrow keys */
221 #ifdef HAVE_KEY_PREFIX
222 case KEY_PREFIX:
223 #endif /* HAVE_KEY_PREFIX */
224 switch (get_arrow_key((int) ch)) {
225 case KEYMAP_UP:
226 case KEYMAP_DOWN:
227 default_answer = bool_not(default_answer);
228 ch = '\0'; /* set to a not bindable key to not leave the loop yet */
229 break;
230
231 case KEYMAP_LEFT:
232 ch = ESC;
233 break;
234
235 case KEYMAP_RIGHT:
236 ch = prompt_ch;
237 break;
238
239 default:
240 break;
241 }
242 break;
243
244 default:
245 break;
246 }
247 func = key_to_func((wchar_t) ch, prompt_keys);
248 } while (func == NOT_ASSIGNED);
249
250 input_context = cNone;
251 FreeAndNull(prompt_yn_message);
252 FreeAndNull(prompt_yn_choice);
253
254 if (!cmd_line) {
255 clear_message();
256 my_flush();
257 }
258 return (func == PROMPT_YES) ? 1 : (func == GLOBAL_ABORT) ? -1 : 0;
259 }
260
261
262 /*
263 * (Re)draws and resize the prompt message for prompt_yn()
264 */
265 void
266 prompt_yn_redraw(
267 void)
268 {
269 char *buf;
270 int choice_len = strwidth(prompt_yn_choice);
271 int message_len = strwidth(prompt_yn_message);
272
273 if (!cmd_line) {
274 MoveCursor(cLINES, 0);
275 CleartoEOLN();
276 }
277 if (message_len + choice_len > cCOLS - 1) {
278 buf = strunc(prompt_yn_message, cCOLS - choice_len - 1);
279 message_len = strwidth(buf);
280 my_printf("%s%s", buf, prompt_yn_choice);
281 free(buf);
282 } else
283 my_printf("%s%s", prompt_yn_message, prompt_yn_choice);
284
285 if (!cmd_line)
286 cursoron();
287 my_flush();
288 if (!cmd_line)
289 MoveCursor(cLINES, (message_len + choice_len) - 1);
290 }
291
292
293 /*
294 * help_text is displayed near the bottom of the screen.
295 * var is an index into a list containing size elements.
296 * The text from list is shown at row, col + len(prompt_text)
297 * Choice is incremented using the space bar, wrapping to 0
298 * ESC is used to abort any changes, RET saves changes.
299 * The new value is returned.
300 */
301 static int
302 prompt_list(
303 int row,
304 int col,
305 int var,
306 constext *help_text,
307 constext *prompt_text,
308 constext *list[],
309 int size)
310 {
311 int ch, var_orig;
312 int i, offset, width = 0;
313 int change;
314 int adjust = (strcasecmp(_(list[0]), _(txt_default)) == 0);
315 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
316 char *buf;
317 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
318
319 var += adjust;
320 var_orig = var;
321
322 /*
323 * Find the length of longest printable text
324 */
325 for (i = 0; i < size; i++)
326 width = MAX(width, strwidth(_(list[i])));
327
328 show_menu_help(help_text);
329 cursoron();
330
331 offset = strwidth(_(prompt_text));
332
333 /*
334 * Make sure to not exceed cCOLS
335 */
336 if (offset + width >= cCOLS)
337 width = cCOLS - offset - 1;
338
339 do {
340 MoveCursor(row, col + offset);
341 ch = (char) ReadCh();
342
343 /*
344 * change:
345 * 1 = move to the next list element
346 * 0 = do nothing
347 * -1 = move to the previous list element
348 *
349 * if an arrow key was pressed change ch to another value
350 * otherwise we will exit the while loop
351 */
352 switch (ch) {
353 case ' ':
354 change = 1;
355 break;
356
357 case ESC: /* (ESC) common arrow keys */
358 #ifdef HAVE_KEY_PREFIX
359 case KEY_PREFIX:
360 #endif /* HAVE_KEY_PREFIX */
361 switch (get_arrow_key(ch)) {
362 case KEYMAP_UP:
363 change = -1;
364 ch = ' ';
365 break;
366
367 case KEYMAP_DOWN:
368 change = 1;
369 ch = ' ';
370 break;
371
372 default:
373 change = 0;
374 break;
375 }
376 break;
377
378 default:
379 change = 0;
380 break;
381 }
382
383 if (change) {
384 /*
385 * increment or decrement list, loop around at the limits
386 */
387 var += change;
388 if (var < 0)
389 var = size - 1;
390 else
391 var %= (size ? size : 1);
392
393 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
394 if ((buf = spart(_(list[var]), width, TRUE)) != NULL) {
395 my_printf("%s", buf);
396 free(buf);
397 } else
398 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
399 my_printf("%-*s", width, _(list[var]));
400 my_flush();
401 }
402 } while (ch != '\r' && ch != '\n' && ch != ESC);
403
404 if (ch == ESC) {
405 var = var_orig;
406 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
407 if ((buf = spart(_(list[var]), width, TRUE)) != NULL) {
408 my_printf("%s", buf);
409 free(buf);
410 } else
411 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
412 my_printf("%-*s", width, _(list[var]));
413 my_flush();
414 }
415
416 cursoroff();
417 return (var - adjust);
418 }
419
420
421 /*
422 * Special case of prompt_option_list() Toggle between ON and OFF
423 * The function returns TRUE, if the value was changed, FALSE otherwise.
424 */
425 t_bool
426 prompt_option_on_off(
427 enum option_enum option)
428 {
429 char prompt[LEN];
430 t_bool *variable = OPT_ON_OFF_list[option_table[option].var_index];
431 t_bool old_value = *variable;
432
433 fmt_option_prompt(prompt, sizeof(prompt), TRUE, option);
434 *variable = prompt_list(option_row(option), 0, (int) *variable, option_table[option].txt->help, prompt, txt_onoff, 2) ? TRUE : FALSE;
435 return bool_not(bool_equal(*variable, old_value));
436 }
437
438
439 /*
440 * The function returns TRUE, if the value was changed, FALSE otherwise.
441 */
442 t_bool
443 prompt_option_list(
444 enum option_enum option)
445 {
446 char prompt[LEN];
447 int *variable = option_table[option].variable;
448 int old_value = *variable;
449 int opt_count = 0;
450
451 while (option_table[option].opt_list[opt_count] != NULL)
452 ++opt_count;
453 fmt_option_prompt(prompt, sizeof(prompt), TRUE, option);
454 *variable = prompt_list(option_row(option), 0, *variable, option_table[option].txt->help, prompt, option_table[option].opt_list, opt_count);
455 return *variable != old_value;
456 }
457
458
459 /*
460 * Displays option text and actual option value for string based options in
461 * one line, help text for that option near the bottom of the screen. Allows
462 * change of the old value by normal editing; history function of tin_getline()
463 * will be used properly so that editing won't leave the actual line.
464 *
465 * The function returns TRUE, if the value was changed, FALSE otherwise.
466 */
467 t_bool
468 prompt_option_string(
469 enum option_enum option) /* return value is always ignored */
470 {
471 char *variable = OPT_STRING_list[option_table[option].var_index];
472 char prompt[LEN];
473 char old_value[LEN];
474
475 STRCPY(old_value, variable);
476 show_menu_help(option_table[option].txt->help);
477 fmt_option_prompt(prompt, sizeof(prompt) - 1, TRUE, option);
478 if (prompt_menu_string(option_row(option), prompt, variable))
479 return strcmp(old_value, variable) ? TRUE : FALSE;
480 else
481 return FALSE;
482 }
483
484
485 /*
486 * Displays option text and current option value for number based options in
487 * one line, help text for that option near the bottom of the screen. Allows
488 * change of the old value by normal editing; history function of tin_getline()
489 * will be used properly so that editing won't leave the current line.
490 *
491 * The function returns TRUE if the value was changed, FALSE otherwise.
492 */
493 t_bool
494 prompt_option_num(
495 enum option_enum option) /* return value is always ignored */
496 {
497 char prompt[LEN];
498 char number[LEN];
499 char *p;
500 int num;
501
502 show_menu_help(option_table[option].txt->help);
503 MoveCursor(option_row(option), 0);
504 fmt_option_prompt(prompt, sizeof(prompt) - 1, TRUE, option);
505 snprintf(&number[0], sizeof(number), "%d", *(option_table[option].variable));
506
507 if ((p = tin_getline(prompt, 2, number, 0, FALSE, HIST_OTHER)) == NULL)
508 return FALSE;
509
510 STRCPY(number, p);
511 num = atoi(number);
512 *(option_table[option].variable) = num;
513 clear_message();
514 return TRUE;
515 }
516
517
518 /*
519 * Displays option text and actual option value for character based options
520 * in one line, help text for that option near the bottom of the screen.
521 * Allows change of the old value by normal editing.
522 *
523 * The function returns TRUE if the value was changed, FALSE otherwise.
524 */
525 t_bool
526 prompt_option_char(
527 enum option_enum option) /* return value is always ignored */
528 {
529 char prompt[LEN];
530 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
531 wchar_t input[2];
532 wchar_t *variable = OPT_CHAR_list[option_table[option].var_index];
533 int max_chars = (int) sizeof(wchar_t) + 1;
534 wchar_t *wp;
535 char *p;
536 char *curr_val;
537 #else
538 char input[2];
539 char *variable = OPT_CHAR_list[option_table[option].var_index];
540 char *p;
541 char *curr_val = &input[0];
542 int max_chars = 1;
543 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
544
545 input[0] = *variable;
546 input[1] = '\0';
547
548 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
549 if ((curr_val = wchar_t2char(input))) {
550 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
551
552 do {
553 show_menu_help(option_table[option].txt->help);
554 MoveCursor(option_row(option), 0);
555 fmt_option_prompt(prompt, sizeof(prompt) - 1, TRUE, option);
556
557 if ((p = tin_getline(prompt, 0, curr_val, max_chars, FALSE, HIST_OTHER)) == NULL) {
558 clear_message();
559 return FALSE;
560 }
561 if (!*p)
562 info_message(_(txt_info_enter_valid_character));
563 } while (!*p);
564
565 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
566 if ((wp = char2wchar_t(p))) {
567 *variable = wp[0];
568 free(wp);
569 }
570 free(curr_val);
571 }
572 #else
573 *variable = p[0];
574 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
575
576 clear_message();
577 return TRUE;
578 }
579
580
581 /*
582 * Get a string. Make it the new default.
583 * If none given, use the default.
584 * Return the string or NULL if we can't get anything useful
585 */
586 char *
587 prompt_string_default(
588 const char *prompt,
589 char *def,
590 const char *failtext,
591 int history)
592 {
593 char pattern[LEN];
594
595 clear_message();
596
597 if (!prompt_string(prompt, pattern, history)) {
598 clear_message();
599 return NULL;
600 }
601
602 if (pattern[0] != '\0') /* got a string - make it the default */
603 my_strncpy(def, pattern, LEN);
604 else {
605 if (def[0] == '\0') { /* no default - give up */
606 error_message(2, "%s", failtext);
607 return NULL;
608 }
609 }
610
611 return def; /* use the default */
612 }
613
614
615 /*
616 * Get a message ID for the 'L' command. Add <> if needed
617 * If the msgid exists and is reachable, return its index
618 * in arts[], else ART_UNAVAILABLE
619 */
620 int
621 prompt_msgid(
622 void)
623 {
624 char buf[LEN];
625
626 if (prompt_string(_(txt_enter_message_id), buf + 1, HIST_MESSAGE_ID) && buf[1]) {
627 char *ptr = str_trim(buf + 1);
628 struct t_msgid *msgid;
629
630 /*
631 * If the user failed to supply Message-ID in <>, add them
632 */
633 if (buf[1] != '<') {
634 buf[0] = '<';
635 strcat(buf, ">");
636 ptr = buf;
637 }
638
639 if ((msgid = find_msgid(ptr)) == NULL) {
640 info_message(_(txt_art_unavailable));
641 return ART_UNAVAILABLE;
642 }
643
644 /*
645 * Is it expired or otherwise not on the spool ?
646 */
647 if (msgid->article == ART_UNAVAILABLE) {
648 info_message(_(txt_art_unavailable));
649 return ART_UNAVAILABLE;
650 }
651
652 /*
653 * If the article is no longer part of a thread, then there is
654 * no way to display it
655 */
656 if (which_thread(msgid->article) == -1) {
657 info_message(_(txt_no_last_message));
658 return ART_UNAVAILABLE;
659 }
660
661 return msgid->article;
662 }
663
664 return ART_UNAVAILABLE;
665 }
666
667
668 /*
669 * Format a message such that it'll fit within the screen width
670 * Useful for fitting long Subjects and newsgroup names into prompts
671 * result will contain a pointer to the malloced memory containing the
672 * sized message
673 */
674 char *
675 sized_message(
676 char **result,
677 const char *format,
678 const char *subject)
679 {
680 char *buf;
681 int max_len;
682
683 max_len = cCOLS - strwidth(format) + 2 - 1; /* The formatting info (%s) wastes 2 chars, but our prompt needs 1 char */
684
685 buf = strunc(subject, max_len);
686
687 *result = fmt_string(format, buf);
688 free(buf);
689
690 return *result;
691 }
692
693
694 /*
695 * Implement the Single-Letter-Key mini menus at the bottom of the screen
696 * eg, Press a)ppend, o)verwrite, q)uit :
697 */
698 t_function
699 prompt_slk_response(
700 t_function default_func,
701 const struct keylist keys,
702 const char *fmt,
703 ...)
704 {
705 va_list ap;
706 char buf[LEN];
707 t_function func;
708 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
709 wchar_t ch;
710 #else
711 char ch;
712 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
713
714 va_start(ap, fmt);
715 vsnprintf(buf, sizeof(buf), fmt, ap);
716 va_end(ap);
717
718 prompt_slk_message = my_malloc(strlen(buf) + 2);
719 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
720 {
721 char *tmp;
722 wchar_t wtmp[2] = { '\0', '\0' };
723
724 wtmp[0] = func_to_key(default_func, keys);
725 tmp = wchar_t2char(wtmp);
726 snprintf(prompt_slk_message, strlen(buf) + 2, "%s%s", buf, tmp);
727 FreeIfNeeded(tmp);
728 }
729 #else
730 snprintf(prompt_slk_message, strlen(buf) + 2, "%s%c", buf, func_to_key(default_func, keys));
731 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
732
733 input_context = cPromptSLK;
734
735 do {
736 prompt_slk_redraw(); /* draw the prompt */
737
738 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
739 if ((ch = (wchar_t) ReadWch()) == '\r' || ch == '\n')
740 #else
741 if ((ch = ReadCh()) == '\r' || ch == '\n')
742 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
743 func = default_func;
744 else
745 func = key_to_func(ch, keys);
746
747 #if 1
748 /*
749 * ignore special-keys which are represented as a multibyte ESC-seq
750 * to avoid interpreting them as 'ESC' only
751 */
752 if (ch == ESC) {
753 switch (get_arrow_key(ch)) {
754 case KEYMAP_UP:
755 case KEYMAP_DOWN:
756 case KEYMAP_LEFT:
757 case KEYMAP_RIGHT:
758 case KEYMAP_PAGE_DOWN:
759 case KEYMAP_PAGE_UP:
760 case KEYMAP_HOME:
761 case KEYMAP_END:
762 ch = '\0';
763 func = NOT_ASSIGNED;
764 break;
765
766 default:
767 break;
768 }
769 }
770 #endif /* 1 */
771 } while (func == NOT_ASSIGNED);
772
773 input_context = cNone;
774 FreeAndNull(prompt_slk_message);
775
776 clear_message();
777 return func;
778 }
779
780
781 /* (Re)draws the prompt message for prompt_slk_response() */
782 void
783 prompt_slk_redraw(
784 void)
785 {
786 int column;
787
788 wait_message(0, "%s", prompt_slk_message);
789
790 /* get the cursor _just_ right */
791 column = strwidth(prompt_slk_message) - 1;
792 MoveCursor(cLINES, column);
793 }
794
795
796 /*
797 * Wait until a key is pressed. We specify the <RETURN> key otherwise
798 * pedants will point out that:
799 * i) There is no 'any' key on a keyboard
800 * ii) CTRL, SHIFT etc don't work
801 */
802 void
803 prompt_continue(
804 void)
805 {
806 int ch;
807 int save_signal_context = signal_context;
808
809 cmd_line = TRUE;
810 info_message(_(txt_return_key));
811 signal_context = cMain;
812 input_context = cPromptCONT;
813
814 switch ((ch = ReadCh())) {
815 case ESC:
816 #ifdef HAVE_KEY_PREFIX
817 case KEY_PREFIX:
818 #endif /* HAVE_KEY_PREFIX */
819 (void) get_arrow_key(ch);
820 /* FALLTHROUGH */
821
822 default:
823 break;
824 }
825
826 input_context = cNone;
827 signal_context = save_signal_context;
828
829 #ifdef USE_CURSES
830 my_fputc('\n', stdout);
831 #endif /* USE_CURSES */
832 cmd_line = FALSE;
833 #ifdef USE_CURSES
834 my_retouch();
835 #endif /* USE_CURSES */
836 }