2 * ========================================================================
3 * Copyright 2013-2022 Eduardo Chappa
4 * Copyright 2006-2007 University of Washington
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
23 #include "../pith/state.h"
24 #include "../pith/conf.h"
25 #include "../pith/newmail.h"
26 #include "../pith/util.h"
32 int pre_screen_config_want_to(char *, int, int);
33 ESCKEY_S
*construct_combined_esclist(ESCKEY_S
*, ESCKEY_S
*);
34 void radio_help(int, int, HelpType
);
35 void draw_radio_prompt(int, unsigned, unsigned, char *);
39 #define WANT_TO_BUF 2500
43 * want_to's array passed to radio_buttions...
45 static ESCKEY_S yorn
[] = {
46 {'y', 'y', "Y", N_("Yes")},
47 {'n', 'n', "N", N_("No")},
52 pre_screen_config_want_to(char *question
, int dflt
, int on_ctrl_C
)
55 char rep
[WANT_TO_BUF
], *p
;
59 if(strlen(question
) + 3 < WANT_TO_BUF
){
60 snprintf(rep
, sizeof(rep
), "%s ?", question
);
61 rep
[sizeof(rep
)-1] = '\0';
64 switch (mswin_yesno_utf8 (*rep
? rep
: question
)) {
66 case 0: return (on_ctrl_C
);
72 if(fprintf(stdout
, "%s? [%c]:", question
, dflt
) < 0
73 || fgets(rep
, WANT_TO_BUF
, stdin
) == NULL
)
74 alpine_panic(_("error on fprintf() or fgets()"));
75 if((p
= strpbrk(rep
, "\r\n")) != NULL
)
97 /*----------------------------------------------------------------------
98 Ask a yes/no question in the status line
100 Args: question -- string to prompt user with
101 dflt -- The default answer to the question (should probably
103 on_ctrl_C -- Answer returned on ^C
104 help -- Two line help text
105 flags -- Flags to modify behavior
106 WT_DING - ding the bell when asking.
107 WT_FLUSH_IN - Discard pending input.
108 WT_SEQ_SENSITIVE - Caller is sensitive to sequence
109 number changes caused by
110 unsolicited expunges while we're
113 Result: Messes up the status line,
114 returns y, n, dflt, on_ctrl_C, or SEQ_EXCEPTION
117 want_to(char *question
, int dflt
, int on_ctrl_C
, HelpType help
, int flags
)
119 char *free_this
= NULL
, *free_this2
= NULL
, *prompt
;
123 if((flags
& WT_DING
) && F_OFF(F_QUELL_BEEPS
, ps_global
)){
129 return(pre_screen_config_want_to(question
, dflt
, on_ctrl_C
));
131 if (mswin_usedialog ()) {
133 switch (mswin_yesno_utf8 (question
)) {
135 case 0: return (on_ctrl_C
);
136 case 1: return ('y');
137 case 2: return ('n');
143 One problem with adding the (y/n) here is that shrinking the
144 screen while in radio_buttons() will cause it to get chopped
145 off. It would be better to truncate the question passed in
146 here and leave the full "(y/n) [x] : " on.
149 len
= strlen(question
) + 4;
150 free_this
= (char *) fs_get(len
);
151 width
= utf8_width(question
);
153 if(width
+ 2 < ps_global
->ttyo
->screen_cols
){
154 snprintf(free_this
, len
, "%s? ", question
);
155 free_this
[len
-1] = '\0';
158 else if(width
+ 1 < ps_global
->ttyo
->screen_cols
){
159 snprintf(free_this
, len
, "%s?", question
);
160 free_this
[len
-1] = '\0';
163 else if(width
< ps_global
->ttyo
->screen_cols
){
164 snprintf(free_this
, len
, "%s", question
);
165 free_this
[len
-1] = '\0';
169 free_this2
= (char *) fs_get(len
);
170 snprintf(free_this2
, len
, "%s? ", question
);
171 prompt
= short_str(free_this2
, free_this
, len
, ps_global
->ttyo
->screen_cols
-1, MidDots
);
174 if(on_ctrl_C
== 'n') /* don't ever let cancel == 'n' */
177 rv
= radio_buttons(prompt
,
178 (ps_global
->ttyo
->screen_rows
> 4) ? - FOOTER_ROWS(ps_global
) : -1,
179 yorn
, dflt
, on_ctrl_C
, help
, flags
);
182 fs_give((void **) &free_this
);
185 fs_give((void **) &free_this2
);
192 one_try_want_to(char *question
, int dflt
, int on_ctrl_C
, HelpType help
, int flags
)
198 l
= strlen(question
) + 5;
199 q2
= fs_get((l
+1) * sizeof(char));
200 strncpy(q2
, question
, l
);
202 (void) utf8_truncate(q2
, ps_global
->ttyo
->screen_cols
- 6);
203 strncat(q2
, "? ", l
+1 - strlen(q2
) - 1);
205 rv
= radio_buttons(q2
,
206 (ps_global
->ttyo
->screen_rows
> 4) ? - FOOTER_ROWS(ps_global
) : -1,
207 yorn
, dflt
, on_ctrl_C
, help
, flags
| RB_ONE_TRY
);
208 fs_give((void **) &q2
);
214 /*----------------------------------------------------------------------
215 Prompt user for a choice among alternatives
217 Args -- utf8prompt: The prompt for the question/selection
218 line: The line to prompt on, if negative then relative to bottom
219 esc_list: ESC_KEY_S list of keys
220 dflt: The selection when the <CR> is pressed (should probably
221 be one of the chars in esc_list)
222 on_ctrl_C: The selection when ^C is pressed
223 help_text: Text to be displayed on bottom two lines
224 flags: Logically OR'd flags modifying our behavior to:
225 RB_FLUSH_IN - Discard any pending input chars.
226 RB_ONE_TRY - Only give one chance to answer. Returns
227 on_ctrl_C value if not answered acceptably
229 RB_NO_NEWMAIL - Quell the usual newmail check.
230 RB_SEQ_SENSITIVE - The caller is sensitive to sequence number
231 changes so return on_ctrl_C if an
232 unsolicited expunge happens while we're
234 RB_RET_HELP - Instead of the regular internal handling
235 way of handling help_text, this just causes
236 radio_buttons to return 3 when help is
237 asked for, so that the caller handles it
240 Note: If there are enough keys in the esc_list to need a second
241 screen, and there is no help, then the 13th key will be
242 put in the help position.
244 Result -- Returns the letter pressed. Will be one of the characters in the
245 esc_list argument, or dflt, or on_ctrl_C, or SEQ_EXCEPTION.
247 This will pause for any new status message to be seen and then prompt the user.
248 The prompt will be truncated to fit on the screen. Redraw and resize are
249 handled along with ^Z suspension. Typing ^G will toggle the help text on and
250 off. Character types that are not buttons will result in a beep (unless one_try
254 radio_buttons(char *utf8prompt
, int line
, ESCKEY_S
*esc_list
, int dflt
,
255 int on_ctrl_C
, HelpType help_text
, int flags
)
258 register int ch
, real_line
;
261 int max_label
, i
, start
, fkey_table
[12];
263 struct key rb_keys
[12];
264 struct key_menu rb_keymenu
;
266 struct variable
*vars
= ps_global
->vars
;
267 COLOR_PAIR
*lastc
= NULL
, *promptc
= NULL
;
272 if (mswin_usedialog()){
273 MDlgButton button_list
[25];
274 LPTSTR free_names
[25];
275 LPTSTR free_labels
[25];
279 memset(&free_names
, 0, sizeof(LPTSTR
) * 25);
280 memset(&free_labels
, 0, sizeof(LPTSTR
) * 25);
281 memset(&button_list
, 0, sizeof (MDlgButton
) * 25);
284 if(flags
& RB_RET_HELP
){
285 if(help_text
!= NO_HELP
)
286 alpine_panic("RET_HELP and help in radio_buttons!");
288 button_list
[b
].ch
= '?';
289 button_list
[b
].rval
= 3;
290 button_list
[b
].name
= TEXT("?");
291 free_labels
[b
] = utf8_to_lptstr(N_("Help"));
292 button_list
[b
].label
= free_labels
[b
];
296 for(i
= 0; esc_list
&& esc_list
[i
].ch
!= -1 && i
< 23; ++i
){
297 if(esc_list
[i
].ch
!= -2){
298 button_list
[b
].ch
= esc_list
[i
].ch
;
299 button_list
[b
].rval
= esc_list
[i
].rval
;
300 free_names
[b
] = utf8_to_lptstr(esc_list
[i
].name
);
301 button_list
[b
].name
= free_names
[b
];
302 free_labels
[b
] = utf8_to_lptstr(esc_list
[i
].label
);
303 button_list
[b
].label
= free_labels
[b
];
308 button_list
[b
].ch
= -1;
310 /* assumption here is that HelpType is char ** */
313 ret
= mswin_select(utf8prompt
, button_list
, dflt
, on_ctrl_C
, help
, flags
);
314 for(i
= 0; i
< 25; i
++){
316 fs_give((void **) &free_names
[i
]);
318 fs_give((void **) &free_labels
[i
]);
324 #endif /* _WINDOWS */
327 flush_ordered_messages(); /* show user previous status msgs */
328 mark_status_dirty(); /* clear message next display call */
329 real_line
= line
> 0 ? line
: ps_global
->ttyo
->screen_rows
+ line
;
330 MoveCursor(real_line
, RAD_BUT_COL
);
333 /*---- Find widest label ----*/
335 for(i
= 0; esc_list
&& esc_list
[i
].ch
!= -1 && i
< 11; i
++){
336 if(esc_list
[i
].ch
== -2) /* -2 means to skip this key and leave blank */
339 max_label
= MAX(max_label
, utf8_width(esc_list
[i
].name
));
342 if(ps_global
->ttyo
->screen_cols
- max_label
- 1 > 0)
343 maxcol
= ps_global
->ttyo
->screen_cols
- max_label
- 1;
348 * We need to be able to truncate q, so copy it in case it is
351 q
= cpystr(utf8prompt
);
353 /*---- Init structs for keymenu ----*/
354 for(i
= 0; i
< 12; i
++)
355 memset((void *)&rb_keys
[i
], 0, sizeof(struct key
));
357 memset((void *)&rb_keymenu
, 0, sizeof(struct key_menu
));
358 rb_keymenu
.how_many
= 1;
359 rb_keymenu
.keys
= rb_keys
;
361 /*---- Setup key menu ----*/
364 memset(fkey_table
, NO_OP_COMMAND
, 12 * sizeof(int));
365 if(flags
& RB_RET_HELP
&& help_text
!= NO_HELP
)
366 alpine_panic("RET_HELP and help in radio_buttons!");
368 /* if shown, always at position 0 */
369 if(help_text
!= NO_HELP
|| flags
& RB_RET_HELP
){
370 rb_keymenu
.keys
[0].name
= "?";
371 rb_keymenu
.keys
[0].label
= N_("Help");
373 fkey_table
[0] = ctrl('G');
378 rb_keymenu
.keys
[1].name
= "^C";
379 rb_keymenu
.keys
[1].label
= N_("Cancel");
381 fkey_table
[1] = ctrl('C');
385 start
= start
? 2 : 0;
386 /*---- Show the usual possible keys ----*/
387 for(i
=start
; esc_list
&& esc_list
[i
-start
].ch
!= -1; i
++){
389 * If we have an esc_list item we'd like to put in the non-existent
390 * 13th slot, and there is no help, we put it in the help slot
391 * instead. We're hacking now...!
393 * We may also have invisible esc_list items that don't show up
394 * on the screen. We use this when we have two different keys
395 * which are synonyms, like ^P and KEY_UP. If all the slots are
396 * already full we can still fit invisible keys off the screen to
397 * the right. A key is invisible if it's label is "".
400 if(esc_list
[i
-start
].label
401 && esc_list
[i
-start
].label
[0] != '\0'){ /* visible */
402 if(i
== 12){ /* special case where we put it in help slot */
403 if(help_text
!= NO_HELP
)
404 alpine_panic("Programming botch in radio_buttons(): too many keys");
406 if(esc_list
[i
-start
].ch
!= -2)
407 setbitn(0, bitmap
); /* the help slot */
409 fkey_table
[0] = esc_list
[i
-start
].ch
;
410 rb_keymenu
.keys
[0].name
= esc_list
[i
-start
].name
;
411 if(esc_list
[i
-start
].ch
!= -2
412 && esc_list
[i
-start
].rval
== dflt
413 && esc_list
[i
-start
].label
){
416 l
= strlen(esc_list
[i
-start
].label
) + 2;
417 ds
= (char *)fs_get((l
+1) * sizeof(char));
418 snprintf(ds
, l
+1, "[%s]", esc_list
[i
-start
].label
);
420 rb_keymenu
.keys
[0].label
= ds
;
423 rb_keymenu
.keys
[0].label
= esc_list
[i
-start
].label
;
426 alpine_panic("Botch in radio_buttons(): too many keys");
430 if(esc_list
[i
-start
].ch
!= -2)
433 fkey_table
[i
] = esc_list
[i
-start
].ch
;
434 rb_keymenu
.keys
[i
].name
= esc_list
[i
-start
].name
;
435 if(esc_list
[i
-start
].ch
!= -2
436 && esc_list
[i
-start
].rval
== dflt
437 && esc_list
[i
-start
].label
){
440 l
= strlen(esc_list
[i
-start
].label
) + 2;
441 ds
= (char *)fs_get((l
+1) * sizeof(char));
442 snprintf(ds
, l
+1, "[%s]", esc_list
[i
-start
].label
);
444 rb_keymenu
.keys
[i
].label
= ds
;
447 rb_keymenu
.keys
[i
].label
= esc_list
[i
-start
].label
;
452 rb_keymenu
.keys
[i
].name
= NULL
;
454 ps_global
->mangled_footer
= 1;
457 cursor_shown
= mswin_showcaret(1);
460 if(pico_usingcolor() && VAR_PROMPT_FORE_COLOR
&&
461 VAR_PROMPT_BACK_COLOR
&&
462 pico_is_good_color(VAR_PROMPT_FORE_COLOR
) &&
463 pico_is_good_color(VAR_PROMPT_BACK_COLOR
)){
464 lastc
= pico_get_cur_color();
466 promptc
= new_color_pair(VAR_PROMPT_FORE_COLOR
,
467 VAR_PROMPT_BACK_COLOR
);
468 (void)pico_set_colorp(promptc
, PSC_NONE
);
474 draw_radio_prompt(real_line
, RAD_BUT_COL
, maxcol
, q
);
479 /*---- Paint the keymenu ----*/
481 (void)pico_set_colorp(lastc
, PSC_NONE
);
485 draw_keymenu(&rb_keymenu
, bitmap
, ps_global
->ttyo
->screen_cols
,
486 1 - FOOTER_ROWS(ps_global
), 0, FirstMenu
);
488 (void)pico_set_colorp(promptc
, PSC_NONE
);
492 MoveCursor(real_line
, MIN(RAD_BUT_COL
+utf8_width(q
), maxcol
+1));
494 if(flags
& RB_FLUSH_IN
)
498 /* Timeout 5 min to keep imap mail stream alive */
499 ucs
= read_char(600);
501 "Want_to read: %s (0x%x)\n", pretty_command(ucs
), ucs
));
502 if((ucs
< 0x80) && isupper((unsigned char) ucs
))
503 ucs
= tolower((unsigned char) ucs
);
505 if(F_ON(F_USE_FK
,ps_global
)
506 && (((ucs
< 0x80) && isalpha((unsigned char) ucs
) && !strchr("YyNn",(int) ucs
))
507 || ((ucs
>= PF1
&& ucs
<= PF12
)
508 && (ucs
= fkey_table
[ucs
- PF1
]) == NO_OP_COMMAND
))){
510 * The funky test above does two things. It maps
511 * esc_list character commands to function keys, *and* prevents
512 * character commands from input while in function key mode.
513 * NOTE: this breaks if we ever need more than the first
514 * twelve function keys...
516 if(flags
& RB_ONE_TRY
){
517 ch
= ucs
= on_ctrl_C
;
528 for(i
= 0; esc_list
&& esc_list
[i
].ch
!= -1; i
++)
529 if(ucs
== esc_list
[i
].ch
){
532 MoveCursor(real_line
,len
=MIN(RAD_BUT_COL
+utf8_width(q
),maxcol
+1));
533 for(n
= 0, len
= ps_global
->ttyo
->screen_cols
- len
;
534 esc_list
[i
].label
&& esc_list
[i
].label
[n
] && len
> 0;
536 Writechar(esc_list
[i
].label
[n
], 0);
538 ch
= esc_list
[i
].rval
;
542 if(flags
& RB_ONE_TRY
){
553 for(i
= 0; esc_list
&& esc_list
[i
].ch
!= -1; i
++)
554 if(ch
== esc_list
[i
].rval
){
557 MoveCursor(real_line
,len
=MIN(RAD_BUT_COL
+utf8_width(q
),maxcol
+1));
558 for(n
= 0, len
= ps_global
->ttyo
->screen_cols
- len
;
559 esc_list
[i
].label
&& esc_list
[i
].label
[n
] && len
> 0;
561 Writechar(esc_list
[i
].label
[n
], 0);
568 if(on_ctrl_C
|| (flags
& RB_ONE_TRY
)){
579 if(FOOTER_ROWS(ps_global
) == 1 && km_popped
== 0){
581 FOOTER_ROWS(ps_global
) = 3;
583 real_line
= ps_global
->ttyo
->screen_rows
+ line
;
585 (void)pico_set_colorp(lastc
, PSC_NONE
);
589 clearfooter(ps_global
);
591 (void)pico_set_colorp(promptc
, PSC_NONE
);
595 draw_radio_prompt(real_line
, RAD_BUT_COL
, maxcol
, q
);
599 if(flags
& RB_RET_HELP
){
603 else if(help_text
!= NO_HELP
&& FOOTER_ROWS(ps_global
) > 1){
604 mark_keymenu_dirty();
606 (void)pico_set_colorp(lastc
, PSC_NONE
);
610 MoveCursor(real_line
+ 1, RAD_BUT_COL
);
612 MoveCursor(real_line
+ 2, RAD_BUT_COL
);
614 radio_help(real_line
, RAD_BUT_COL
, help_text
);
616 MoveCursor(real_line
, MIN(RAD_BUT_COL
+utf8_width(q
), maxcol
+1));
618 (void)pico_set_colorp(promptc
, PSC_NONE
);
629 goto newcmd
; /* misunderstood escape? */
631 case NO_OP_IDLE
: /* UNODIR, keep the stream alive */
632 if(flags
& RB_NO_NEWMAIL
)
635 i
= new_mail(0, VeryBadTime
, NM_DEFER_SORT
);
636 if(sp_expunge_count(ps_global
->mail_stream
)
637 && flags
& RB_SEQ_SENSITIVE
){
647 break; /* no changes, get on with life */
648 /* Else fall into redraw to adjust displayed numbers and such */
653 real_line
= line
> 0 ? line
: ps_global
->ttyo
->screen_rows
+ line
;
655 (void)pico_set_colorp(lastc
, PSC_NONE
);
661 if(ps_global
->redrawer
!= NULL
)
662 (*ps_global
->redrawer
)();
663 if(FOOTER_ROWS(ps_global
) == 3 || km_popped
)
666 if(ps_global
->ttyo
->screen_cols
- max_label
- 1 > 0)
667 maxcol
= ps_global
->ttyo
->screen_cols
- max_label
- 1;
672 (void)pico_set_colorp(promptc
, PSC_NONE
);
676 draw_radio_prompt(real_line
, RAD_BUT_COL
, maxcol
, q
);
689 fs_give((void **) &q
);
691 fs_give((void **) &ds
);
694 (void) pico_set_colorp(lastc
, PSC_NONE
);
695 free_color_pair(&lastc
);
697 free_color_pair(&promptc
);
705 FOOTER_ROWS(ps_global
) = 1;
706 clearfooter(ps_global
);
707 ps_global
->mangled_body
= 1;
714 #define OTHER_RETURN_VAL 1300
715 #define KEYS_PER_LIST 8
718 * This should really be part of radio_buttons itself, I suppose. It was
719 * easier to do it this way. This is for when there are more than 12
720 * possible commands. We could have all the radio_buttons calls call this
721 * instead of radio_buttons, or rename this to radio_buttons.
723 * Radio_buttons is limited to 10 visible commands unless there is no Help,
724 * in which case it is 11 visible commands.
725 * Double_radio_buttons is limited to 16 visible commands because it uses
726 * slots 3 and 4 for readability and the OTHER CMD.
729 double_radio_buttons(char *prompt
, int line
, ESCKEY_S
*esc_list
, int dflt
, int on_ctrl_C
, HelpType help_text
, int flags
)
731 ESCKEY_S
*list
= NULL
, *list1
= NULL
, *list2
= NULL
;
733 int v
= OTHER_RETURN_VAL
, listnum
= 0;
736 if(mswin_usedialog())
737 return(radio_buttons(prompt
, line
, esc_list
, dflt
, on_ctrl_C
,
741 /* check to see if it will all fit in one */
742 while(esc_list
&& esc_list
[i
].ch
!= -1)
746 if(help_text
!= NO_HELP
)
750 return(radio_buttons(prompt
, line
, esc_list
, dflt
, on_ctrl_C
,
754 * Won't fit, split it into two lists.
756 * We can fit at most 8 items in the visible list. The rest of
757 * the commands have to be invisible. Each of list1 and list2 should
758 * have no more than 8 visible (name != "" || label != "") items.
760 list1
= (ESCKEY_S
*)fs_get((KEYS_PER_LIST
+1) * sizeof(*list1
));
761 memset(list1
, 0, (KEYS_PER_LIST
+1) * sizeof(*list1
));
762 list2
= (ESCKEY_S
*)fs_get((KEYS_PER_LIST
+1) * sizeof(*list2
));
763 memset(list2
, 0, (KEYS_PER_LIST
+1) * sizeof(*list2
));
765 for(j
=0,i
=0; esc_list
[i
].ch
!= -1 && j
< KEYS_PER_LIST
; j
++,i
++)
766 list1
[j
] = esc_list
[i
];
770 for(j
=0; esc_list
[i
].ch
!= -1 && j
< KEYS_PER_LIST
; j
++,i
++)
771 list2
[j
] = esc_list
[i
];
775 list
= construct_combined_esclist(list1
, list2
);
777 while(v
== OTHER_RETURN_VAL
){
778 v
= radio_buttons(prompt
,line
,list
,dflt
,on_ctrl_C
,help_text
,flags
);
779 if(v
== OTHER_RETURN_VAL
){
780 fs_give((void **) &list
);
781 listnum
= 1 - listnum
;
782 list
= construct_combined_esclist(listnum
? list2
: list1
,
783 listnum
? list1
: list2
);
788 fs_give((void **) &list
);
790 fs_give((void **) &list1
);
792 fs_give((void **) &list2
);
799 construct_combined_esclist(ESCKEY_S
*list1
, ESCKEY_S
*list2
)
804 count
= 2; /* for blank key and for OTHER key */
805 for(i
=0; list1
&& list1
[i
].ch
!= -1; i
++)
807 for(i
=0; list2
&& list2
[i
].ch
!= -1; i
++)
810 list
= (ESCKEY_S
*) fs_get((count
+ 1) * sizeof(*list
));
811 memset(list
, 0, (count
+ 1) * sizeof(*list
));
813 list
[j
].ch
= -2; /* leave blank */
816 list
[j
++].label
= NULL
;
819 list
[j
].rval
= OTHER_RETURN_VAL
;
821 list
[j
].label
= N_("OTHER CMDS");
824 * Make sure that O for OTHER CMD or the return val for OTHER CMD
825 * isn't used for something else.
827 for(i
=0; list1
&& list1
[i
].ch
!= -1; i
++){
828 if(list1
[i
].rval
== list
[j
].rval
)
829 alpine_panic("1bad rval in d_r");
830 if(F_OFF(F_USE_FK
,ps_global
) && list1
[i
].ch
== list
[j
].ch
)
831 alpine_panic("1bad ch in ccl");
834 for(i
=0; list2
&& list2
[i
].ch
!= -1; i
++){
835 if(list2
[i
].rval
== list
[j
].rval
)
836 alpine_panic("2bad rval in d_r");
837 if(F_OFF(F_USE_FK
,ps_global
) && list2
[i
].ch
== list
[j
].ch
)
838 alpine_panic("2bad ch in ccl");
843 /* the visible set */
844 for(i
=0; list1
&& list1
[i
].ch
!= -1; i
++){
845 if(i
>= KEYS_PER_LIST
&& list1
[i
].label
[0] != '\0')
846 alpine_panic("too many visible keys in ccl");
848 list
[j
++] = list1
[i
];
851 /* the rest are invisible */
852 for(i
=0; list2
&& list2
[i
].ch
!= -1; i
++){
864 /*----------------------------------------------------------------------
868 radio_help(int line
, int column
, HelpType help
)
872 /* assumption here is that HelpType is char ** */
877 MoveCursor(line
+ 1, column
);
880 PutLine0(line
+ 1, column
, text
[0]);
882 MoveCursor(line
+ 2, column
);
885 PutLine0(line
+ 2, column
, text
[1]);
891 /*----------------------------------------------------------------------
892 Paint the screen with the radio buttons prompt
895 draw_radio_prompt(int line
, unsigned start_c
, unsigned max_c
, char *q
)
898 unsigned x
, width
, got_width
;
899 char *tmpq
= NULL
, *useq
;
901 width
= utf8_width(q
);
902 if(width
> max_c
- start_c
+ 1){
903 tmpq
= (char *) fs_get((len
=(strlen(q
)+1)) * sizeof(char));
904 (void) utf8_to_width(tmpq
, q
, len
, max_c
- start_c
+ 1, &got_width
);
911 PutLine0(line
, start_c
, useq
);
914 while(x
++ < ps_global
->ttyo
->screen_cols
)
917 MoveCursor(line
, start_c
+ width
);
920 fs_give((void **) &tmpq
);