1 #if !defined(lint) && !defined(DOS)
2 static char rcsid
[] = "$Id: radio.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $";
6 * ========================================================================
7 * Copyright 2006-2007 University of Washington
8 * Copyright 2013-2015 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
27 #include "../pith/state.h"
28 #include "../pith/conf.h"
29 #include "../pith/newmail.h"
30 #include "../pith/util.h"
36 int pre_screen_config_want_to(char *, int, int);
37 ESCKEY_S
*construct_combined_esclist(ESCKEY_S
*, ESCKEY_S
*);
38 void radio_help(int, int, HelpType
);
39 void draw_radio_prompt(int, unsigned, unsigned, char *);
43 #define WANT_TO_BUF 2500
47 * want_to's array passed to radio_buttions...
49 static ESCKEY_S yorn
[] = {
50 {'y', 'y', "Y", N_("Yes")},
51 {'n', 'n', "N", N_("No")},
56 pre_screen_config_want_to(char *question
, int dflt
, int on_ctrl_C
)
59 char rep
[WANT_TO_BUF
], *p
;
63 if(strlen(question
) + 3 < WANT_TO_BUF
){
64 snprintf(rep
, sizeof(rep
), "%s ?", question
);
65 rep
[sizeof(rep
)-1] = '\0';
68 switch (mswin_yesno_utf8 (*rep
? rep
: question
)) {
70 case 0: return (on_ctrl_C
);
76 fprintf(stdout
, "%s? [%c]:", question
, dflt
);
77 fgets(rep
, WANT_TO_BUF
, stdin
);
78 if((p
= strpbrk(rep
, "\r\n")) != NULL
)
100 /*----------------------------------------------------------------------
101 Ask a yes/no question in the status line
103 Args: question -- string to prompt user with
104 dflt -- The default answer to the question (should probably
106 on_ctrl_C -- Answer returned on ^C
107 help -- Two line help text
108 flags -- Flags to modify behavior
109 WT_FLUSH_IN - Discard pending input.
110 WT_SEQ_SENSITIVE - Caller is sensitive to sequence
111 number changes caused by
112 unsolicited expunges while we're
115 Result: Messes up the status line,
116 returns y, n, dflt, on_ctrl_C, or SEQ_EXCEPTION
119 want_to(char *question
, int dflt
, int on_ctrl_C
, HelpType help
, int flags
)
121 char *free_this
= NULL
, *free_this2
= NULL
, *prompt
;
126 return(pre_screen_config_want_to(question
, dflt
, on_ctrl_C
));
128 if (mswin_usedialog ()) {
130 switch (mswin_yesno_utf8 (question
)) {
132 case 0: return (on_ctrl_C
);
133 case 1: return ('y');
134 case 2: return ('n');
140 One problem with adding the (y/n) here is that shrinking the
141 screen while in radio_buttons() will cause it to get chopped
142 off. It would be better to truncate the question passed in
143 here and leave the full "(y/n) [x] : " on.
146 len
= strlen(question
) + 4;
147 free_this
= (char *) fs_get(len
);
148 width
= utf8_width(question
);
150 if(width
+ 2 < ps_global
->ttyo
->screen_cols
){
151 snprintf(free_this
, len
, "%s? ", question
);
152 free_this
[len
-1] = '\0';
155 else if(width
+ 1 < ps_global
->ttyo
->screen_cols
){
156 snprintf(free_this
, len
, "%s?", question
);
157 free_this
[len
-1] = '\0';
160 else if(width
< ps_global
->ttyo
->screen_cols
){
161 snprintf(free_this
, len
, "%s", question
);
162 free_this
[len
-1] = '\0';
166 free_this2
= (char *) fs_get(len
);
167 snprintf(free_this2
, len
, "%s? ", question
);
168 prompt
= short_str(free_this2
, free_this
, len
, ps_global
->ttyo
->screen_cols
-1, MidDots
);
171 if(on_ctrl_C
== 'n') /* don't ever let cancel == 'n' */
174 rv
= radio_buttons(prompt
,
175 (ps_global
->ttyo
->screen_rows
> 4) ? - FOOTER_ROWS(ps_global
) : -1,
176 yorn
, dflt
, on_ctrl_C
, help
, flags
);
179 fs_give((void **) &free_this
);
182 fs_give((void **) &free_this2
);
189 one_try_want_to(char *question
, int dflt
, int on_ctrl_C
, HelpType help
, int flags
)
195 l
= strlen(question
) + 5;
196 q2
= fs_get((l
+1) * sizeof(char));
197 strncpy(q2
, question
, l
);
199 (void) utf8_truncate(q2
, ps_global
->ttyo
->screen_cols
- 6);
200 strncat(q2
, "? ", l
+1 - strlen(q2
) - 1);
202 rv
= radio_buttons(q2
,
203 (ps_global
->ttyo
->screen_rows
> 4) ? - FOOTER_ROWS(ps_global
) : -1,
204 yorn
, dflt
, on_ctrl_C
, help
, flags
| RB_ONE_TRY
);
205 fs_give((void **) &q2
);
211 /*----------------------------------------------------------------------
212 Prompt user for a choice among alternatives
214 Args -- utf8prompt: The prompt for the question/selection
215 line: The line to prompt on, if negative then relative to bottom
216 esc_list: ESC_KEY_S list of keys
217 dflt: The selection when the <CR> is pressed (should probably
218 be one of the chars in esc_list)
219 on_ctrl_C: The selection when ^C is pressed
220 help_text: Text to be displayed on bottom two lines
221 flags: Logically OR'd flags modifying our behavior to:
222 RB_FLUSH_IN - Discard any pending input chars.
223 RB_ONE_TRY - Only give one chance to answer. Returns
224 on_ctrl_C value if not answered acceptably
226 RB_NO_NEWMAIL - Quell the usual newmail check.
227 RB_SEQ_SENSITIVE - The caller is sensitive to sequence number
228 changes so return on_ctrl_C if an
229 unsolicited expunge happens while we're
231 RB_RET_HELP - Instead of the regular internal handling
232 way of handling help_text, this just causes
233 radio_buttons to return 3 when help is
234 asked for, so that the caller handles it
237 Note: If there are enough keys in the esc_list to need a second
238 screen, and there is no help, then the 13th key will be
239 put in the help position.
241 Result -- Returns the letter pressed. Will be one of the characters in the
242 esc_list argument, or dflt, or on_ctrl_C, or SEQ_EXCEPTION.
244 This will pause for any new status message to be seen and then prompt the user.
245 The prompt will be truncated to fit on the screen. Redraw and resize are
246 handled along with ^Z suspension. Typing ^G will toggle the help text on and
247 off. Character types that are not buttons will result in a beep (unless one_try
251 radio_buttons(char *utf8prompt
, int line
, ESCKEY_S
*esc_list
, int dflt
,
252 int on_ctrl_C
, HelpType help_text
, int flags
)
255 register int ch
, real_line
;
258 int max_label
, i
, start
, fkey_table
[12];
260 struct key rb_keys
[12];
261 struct key_menu rb_keymenu
;
263 struct variable
*vars
= ps_global
->vars
;
264 COLOR_PAIR
*lastc
= NULL
, *promptc
= NULL
;
269 if (mswin_usedialog()){
270 MDlgButton button_list
[25];
271 LPTSTR free_names
[25];
272 LPTSTR free_labels
[25];
276 memset(&free_names
, 0, sizeof(LPTSTR
) * 25);
277 memset(&free_labels
, 0, sizeof(LPTSTR
) * 25);
278 memset(&button_list
, 0, sizeof (MDlgButton
) * 25);
281 if(flags
& RB_RET_HELP
){
282 if(help_text
!= NO_HELP
)
283 alpine_panic("RET_HELP and help in radio_buttons!");
285 button_list
[b
].ch
= '?';
286 button_list
[b
].rval
= 3;
287 button_list
[b
].name
= TEXT("?");
288 free_labels
[b
] = utf8_to_lptstr(N_("Help"));
289 button_list
[b
].label
= free_labels
[b
];
293 for(i
= 0; esc_list
&& esc_list
[i
].ch
!= -1 && i
< 23; ++i
){
294 if(esc_list
[i
].ch
!= -2){
295 button_list
[b
].ch
= esc_list
[i
].ch
;
296 button_list
[b
].rval
= esc_list
[i
].rval
;
297 free_names
[b
] = utf8_to_lptstr(esc_list
[i
].name
);
298 button_list
[b
].name
= free_names
[b
];
299 free_labels
[b
] = utf8_to_lptstr(esc_list
[i
].label
);
300 button_list
[b
].label
= free_labels
[b
];
305 button_list
[b
].ch
= -1;
307 /* assumption here is that HelpType is char ** */
310 ret
= mswin_select(utf8prompt
, button_list
, dflt
, on_ctrl_C
, help
, flags
);
311 for(i
= 0; i
< 25; i
++){
313 fs_give((void **) &free_names
[i
]);
315 fs_give((void **) &free_labels
[i
]);
321 #endif /* _WINDOWS */
324 flush_ordered_messages(); /* show user previous status msgs */
325 mark_status_dirty(); /* clear message next display call */
326 real_line
= line
> 0 ? line
: ps_global
->ttyo
->screen_rows
+ line
;
327 MoveCursor(real_line
, RAD_BUT_COL
);
330 /*---- Find widest label ----*/
332 for(i
= 0; esc_list
&& esc_list
[i
].ch
!= -1 && i
< 11; i
++){
333 if(esc_list
[i
].ch
== -2) /* -2 means to skip this key and leave blank */
336 max_label
= MAX(max_label
, utf8_width(esc_list
[i
].name
));
339 if(ps_global
->ttyo
->screen_cols
- max_label
- 1 > 0)
340 maxcol
= ps_global
->ttyo
->screen_cols
- max_label
- 1;
345 * We need to be able to truncate q, so copy it in case it is
348 q
= cpystr(utf8prompt
);
350 /*---- Init structs for keymenu ----*/
351 for(i
= 0; i
< 12; i
++)
352 memset((void *)&rb_keys
[i
], 0, sizeof(struct key
));
354 memset((void *)&rb_keymenu
, 0, sizeof(struct key_menu
));
355 rb_keymenu
.how_many
= 1;
356 rb_keymenu
.keys
= rb_keys
;
358 /*---- Setup key menu ----*/
361 memset(fkey_table
, NO_OP_COMMAND
, 12 * sizeof(int));
362 if(flags
& RB_RET_HELP
&& help_text
!= NO_HELP
)
363 alpine_panic("RET_HELP and help in radio_buttons!");
365 /* if shown, always at position 0 */
366 if(help_text
!= NO_HELP
|| flags
& RB_RET_HELP
){
367 rb_keymenu
.keys
[0].name
= "?";
368 rb_keymenu
.keys
[0].label
= N_("Help");
370 fkey_table
[0] = ctrl('G');
375 rb_keymenu
.keys
[1].name
= "^C";
376 rb_keymenu
.keys
[1].label
= N_("Cancel");
378 fkey_table
[1] = ctrl('C');
382 start
= start
? 2 : 0;
383 /*---- Show the usual possible keys ----*/
384 for(i
=start
; esc_list
&& esc_list
[i
-start
].ch
!= -1; i
++){
386 * If we have an esc_list item we'd like to put in the non-existent
387 * 13th slot, and there is no help, we put it in the help slot
388 * instead. We're hacking now...!
390 * We may also have invisible esc_list items that don't show up
391 * on the screen. We use this when we have two different keys
392 * which are synonyms, like ^P and KEY_UP. If all the slots are
393 * already full we can still fit invisible keys off the screen to
394 * the right. A key is invisible if it's label is "".
397 if(esc_list
[i
-start
].label
398 && esc_list
[i
-start
].label
[0] != '\0'){ /* visible */
399 if(i
== 12){ /* special case where we put it in help slot */
400 if(help_text
!= NO_HELP
)
401 alpine_panic("Programming botch in radio_buttons(): too many keys");
403 if(esc_list
[i
-start
].ch
!= -2)
404 setbitn(0, bitmap
); /* the help slot */
406 fkey_table
[0] = esc_list
[i
-start
].ch
;
407 rb_keymenu
.keys
[0].name
= esc_list
[i
-start
].name
;
408 if(esc_list
[i
-start
].ch
!= -2
409 && esc_list
[i
-start
].rval
== dflt
410 && esc_list
[i
-start
].label
){
413 l
= strlen(esc_list
[i
-start
].label
) + 2;
414 ds
= (char *)fs_get((l
+1) * sizeof(char));
415 snprintf(ds
, l
+1, "[%s]", esc_list
[i
-start
].label
);
417 rb_keymenu
.keys
[0].label
= ds
;
420 rb_keymenu
.keys
[0].label
= esc_list
[i
-start
].label
;
423 alpine_panic("Botch in radio_buttons(): too many keys");
427 if(esc_list
[i
-start
].ch
!= -2)
430 fkey_table
[i
] = esc_list
[i
-start
].ch
;
431 rb_keymenu
.keys
[i
].name
= esc_list
[i
-start
].name
;
432 if(esc_list
[i
-start
].ch
!= -2
433 && esc_list
[i
-start
].rval
== dflt
434 && esc_list
[i
-start
].label
){
437 l
= strlen(esc_list
[i
-start
].label
) + 2;
438 ds
= (char *)fs_get((l
+1) * sizeof(char));
439 snprintf(ds
, l
+1, "[%s]", esc_list
[i
-start
].label
);
441 rb_keymenu
.keys
[i
].label
= ds
;
444 rb_keymenu
.keys
[i
].label
= esc_list
[i
-start
].label
;
449 rb_keymenu
.keys
[i
].name
= NULL
;
451 ps_global
->mangled_footer
= 1;
454 cursor_shown
= mswin_showcaret(1);
457 if(pico_usingcolor() && VAR_PROMPT_FORE_COLOR
&&
458 VAR_PROMPT_BACK_COLOR
&&
459 pico_is_good_color(VAR_PROMPT_FORE_COLOR
) &&
460 pico_is_good_color(VAR_PROMPT_BACK_COLOR
)){
461 lastc
= pico_get_cur_color();
463 promptc
= new_color_pair(VAR_PROMPT_FORE_COLOR
,
464 VAR_PROMPT_BACK_COLOR
);
465 (void)pico_set_colorp(promptc
, PSC_NONE
);
471 draw_radio_prompt(real_line
, RAD_BUT_COL
, maxcol
, q
);
476 /*---- Paint the keymenu ----*/
478 (void)pico_set_colorp(lastc
, PSC_NONE
);
482 draw_keymenu(&rb_keymenu
, bitmap
, ps_global
->ttyo
->screen_cols
,
483 1 - FOOTER_ROWS(ps_global
), 0, FirstMenu
);
485 (void)pico_set_colorp(promptc
, PSC_NONE
);
489 MoveCursor(real_line
, MIN(RAD_BUT_COL
+utf8_width(q
), maxcol
+1));
491 if(flags
& RB_FLUSH_IN
)
495 /* Timeout 5 min to keep imap mail stream alive */
496 ucs
= read_char(600);
498 "Want_to read: %s (0x%x)\n", pretty_command(ucs
), ucs
));
499 if((ucs
< 0x80) && isupper((unsigned char) ucs
))
500 ucs
= tolower((unsigned char) ucs
);
502 if(F_ON(F_USE_FK
,ps_global
)
503 && (((ucs
< 0x80) && isalpha((unsigned char) ucs
) && !strchr("YyNn",(int) ucs
))
504 || ((ucs
>= PF1
&& ucs
<= PF12
)
505 && (ucs
= fkey_table
[ucs
- PF1
]) == NO_OP_COMMAND
))){
507 * The funky test above does two things. It maps
508 * esc_list character commands to function keys, *and* prevents
509 * character commands from input while in function key mode.
510 * NOTE: this breaks if we ever need more than the first
511 * twelve function keys...
513 if(flags
& RB_ONE_TRY
){
514 ch
= ucs
= on_ctrl_C
;
525 for(i
= 0; esc_list
&& esc_list
[i
].ch
!= -1; i
++)
526 if(ucs
== esc_list
[i
].ch
){
529 MoveCursor(real_line
,len
=MIN(RAD_BUT_COL
+utf8_width(q
),maxcol
+1));
530 for(n
= 0, len
= ps_global
->ttyo
->screen_cols
- len
;
531 esc_list
[i
].label
&& esc_list
[i
].label
[n
] && len
> 0;
533 Writechar(esc_list
[i
].label
[n
], 0);
535 ch
= esc_list
[i
].rval
;
539 if(flags
& RB_ONE_TRY
){
550 for(i
= 0; esc_list
&& esc_list
[i
].ch
!= -1; i
++)
551 if(ch
== esc_list
[i
].rval
){
554 MoveCursor(real_line
,len
=MIN(RAD_BUT_COL
+utf8_width(q
),maxcol
+1));
555 for(n
= 0, len
= ps_global
->ttyo
->screen_cols
- len
;
556 esc_list
[i
].label
&& esc_list
[i
].label
[n
] && len
> 0;
558 Writechar(esc_list
[i
].label
[n
], 0);
565 if(on_ctrl_C
|| (flags
& RB_ONE_TRY
)){
576 if(FOOTER_ROWS(ps_global
) == 1 && km_popped
== 0){
578 FOOTER_ROWS(ps_global
) = 3;
580 real_line
= ps_global
->ttyo
->screen_rows
+ line
;
582 (void)pico_set_colorp(lastc
, PSC_NONE
);
586 clearfooter(ps_global
);
588 (void)pico_set_colorp(promptc
, PSC_NONE
);
592 draw_radio_prompt(real_line
, RAD_BUT_COL
, maxcol
, q
);
596 if(flags
& RB_RET_HELP
){
600 else if(help_text
!= NO_HELP
&& FOOTER_ROWS(ps_global
) > 1){
601 mark_keymenu_dirty();
603 (void)pico_set_colorp(lastc
, PSC_NONE
);
607 MoveCursor(real_line
+ 1, RAD_BUT_COL
);
609 MoveCursor(real_line
+ 2, RAD_BUT_COL
);
611 radio_help(real_line
, RAD_BUT_COL
, help_text
);
613 MoveCursor(real_line
, MIN(RAD_BUT_COL
+utf8_width(q
), maxcol
+1));
615 (void)pico_set_colorp(promptc
, PSC_NONE
);
626 goto newcmd
; /* misunderstood escape? */
628 case NO_OP_IDLE
: /* UNODIR, keep the stream alive */
629 if(flags
& RB_NO_NEWMAIL
)
632 i
= new_mail(0, VeryBadTime
, NM_DEFER_SORT
);
633 if(sp_expunge_count(ps_global
->mail_stream
)
634 && flags
& RB_SEQ_SENSITIVE
){
644 break; /* no changes, get on with life */
645 /* Else fall into redraw to adjust displayed numbers and such */
650 real_line
= line
> 0 ? line
: ps_global
->ttyo
->screen_rows
+ line
;
652 (void)pico_set_colorp(lastc
, PSC_NONE
);
658 if(ps_global
->redrawer
!= NULL
)
659 (*ps_global
->redrawer
)();
660 if(FOOTER_ROWS(ps_global
) == 3 || km_popped
)
663 if(ps_global
->ttyo
->screen_cols
- max_label
- 1 > 0)
664 maxcol
= ps_global
->ttyo
->screen_cols
- max_label
- 1;
669 (void)pico_set_colorp(promptc
, PSC_NONE
);
673 draw_radio_prompt(real_line
, RAD_BUT_COL
, maxcol
, q
);
686 fs_give((void **) &q
);
688 fs_give((void **) &ds
);
691 (void) pico_set_colorp(lastc
, PSC_NONE
);
692 free_color_pair(&lastc
);
694 free_color_pair(&promptc
);
702 FOOTER_ROWS(ps_global
) = 1;
703 clearfooter(ps_global
);
704 ps_global
->mangled_body
= 1;
711 #define OTHER_RETURN_VAL 1300
712 #define KEYS_PER_LIST 8
715 * This should really be part of radio_buttons itself, I suppose. It was
716 * easier to do it this way. This is for when there are more than 12
717 * possible commands. We could have all the radio_buttons calls call this
718 * instead of radio_buttons, or rename this to radio_buttons.
720 * Radio_buttons is limited to 10 visible commands unless there is no Help,
721 * in which case it is 11 visible commands.
722 * Double_radio_buttons is limited to 16 visible commands because it uses
723 * slots 3 and 4 for readability and the OTHER CMD.
726 double_radio_buttons(char *prompt
, int line
, ESCKEY_S
*esc_list
, int dflt
, int on_ctrl_C
, HelpType help_text
, int flags
)
728 ESCKEY_S
*list
= NULL
, *list1
= NULL
, *list2
= NULL
;
730 int v
= OTHER_RETURN_VAL
, listnum
= 0;
733 if(mswin_usedialog())
734 return(radio_buttons(prompt
, line
, esc_list
, dflt
, on_ctrl_C
,
738 /* check to see if it will all fit in one */
739 while(esc_list
&& esc_list
[i
].ch
!= -1)
743 if(help_text
!= NO_HELP
)
747 return(radio_buttons(prompt
, line
, esc_list
, dflt
, on_ctrl_C
,
751 * Won't fit, split it into two lists.
753 * We can fit at most 8 items in the visible list. The rest of
754 * the commands have to be invisible. Each of list1 and list2 should
755 * have no more than 8 visible (name != "" || label != "") items.
757 list1
= (ESCKEY_S
*)fs_get((KEYS_PER_LIST
+1) * sizeof(*list1
));
758 memset(list1
, 0, (KEYS_PER_LIST
+1) * sizeof(*list1
));
759 list2
= (ESCKEY_S
*)fs_get((KEYS_PER_LIST
+1) * sizeof(*list2
));
760 memset(list2
, 0, (KEYS_PER_LIST
+1) * sizeof(*list2
));
762 for(j
=0,i
=0; esc_list
[i
].ch
!= -1 && j
< KEYS_PER_LIST
; j
++,i
++)
763 list1
[j
] = esc_list
[i
];
767 for(j
=0; esc_list
[i
].ch
!= -1 && j
< KEYS_PER_LIST
; j
++,i
++)
768 list2
[j
] = esc_list
[i
];
772 list
= construct_combined_esclist(list1
, list2
);
774 while(v
== OTHER_RETURN_VAL
){
775 v
= radio_buttons(prompt
,line
,list
,dflt
,on_ctrl_C
,help_text
,flags
);
776 if(v
== OTHER_RETURN_VAL
){
777 fs_give((void **) &list
);
778 listnum
= 1 - listnum
;
779 list
= construct_combined_esclist(listnum
? list2
: list1
,
780 listnum
? list1
: list2
);
785 fs_give((void **) &list
);
787 fs_give((void **) &list1
);
789 fs_give((void **) &list2
);
796 construct_combined_esclist(ESCKEY_S
*list1
, ESCKEY_S
*list2
)
801 count
= 2; /* for blank key and for OTHER key */
802 for(i
=0; list1
&& list1
[i
].ch
!= -1; i
++)
804 for(i
=0; list2
&& list2
[i
].ch
!= -1; i
++)
807 list
= (ESCKEY_S
*) fs_get((count
+ 1) * sizeof(*list
));
808 memset(list
, 0, (count
+ 1) * sizeof(*list
));
810 list
[j
].ch
= -2; /* leave blank */
813 list
[j
++].label
= NULL
;
816 list
[j
].rval
= OTHER_RETURN_VAL
;
818 list
[j
].label
= N_("OTHER CMDS");
821 * Make sure that O for OTHER CMD or the return val for OTHER CMD
822 * isn't used for something else.
824 for(i
=0; list1
&& list1
[i
].ch
!= -1; i
++){
825 if(list1
[i
].rval
== list
[j
].rval
)
826 alpine_panic("1bad rval in d_r");
827 if(F_OFF(F_USE_FK
,ps_global
) && list1
[i
].ch
== list
[j
].ch
)
828 alpine_panic("1bad ch in ccl");
831 for(i
=0; list2
&& list2
[i
].ch
!= -1; i
++){
832 if(list2
[i
].rval
== list
[j
].rval
)
833 alpine_panic("2bad rval in d_r");
834 if(F_OFF(F_USE_FK
,ps_global
) && list2
[i
].ch
== list
[j
].ch
)
835 alpine_panic("2bad ch in ccl");
840 /* the visible set */
841 for(i
=0; list1
&& list1
[i
].ch
!= -1; i
++){
842 if(i
>= KEYS_PER_LIST
&& list1
[i
].label
[0] != '\0')
843 alpine_panic("too many visible keys in ccl");
845 list
[j
++] = list1
[i
];
848 /* the rest are invisible */
849 for(i
=0; list2
&& list2
[i
].ch
!= -1; i
++){
861 /*----------------------------------------------------------------------
865 radio_help(int line
, int column
, HelpType help
)
869 /* assumption here is that HelpType is char ** */
874 MoveCursor(line
+ 1, column
);
877 PutLine0(line
+ 1, column
, text
[0]);
879 MoveCursor(line
+ 2, column
);
882 PutLine0(line
+ 2, column
, text
[1]);
888 /*----------------------------------------------------------------------
889 Paint the screen with the radio buttons prompt
892 draw_radio_prompt(int line
, unsigned start_c
, unsigned max_c
, char *q
)
895 unsigned x
, width
, got_width
;
896 char *tmpq
= NULL
, *useq
;
898 width
= utf8_width(q
);
899 if(width
> max_c
- start_c
+ 1){
900 tmpq
= (char *) fs_get((len
=(strlen(q
)+1)) * sizeof(char));
901 (void) utf8_to_width(tmpq
, q
, len
, max_c
- start_c
+ 1, &got_width
);
908 PutLine0(line
, start_c
, useq
);
911 while(x
++ < ps_global
->ttyo
->screen_cols
)
914 MoveCursor(line
, start_c
+ width
);
917 fs_give((void **) &tmpq
);