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 2013-2021 Eduardo Chappa
8 * Copyright 2006-2007 University of Washington
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 if(fprintf(stdout
, "%s? [%c]:", question
, dflt
) < 0
77 || fgets(rep
, WANT_TO_BUF
, stdin
) == NULL
)
78 alpine_panic(_("error on fprintf() or fgets()"));
79 if((p
= strpbrk(rep
, "\r\n")) != NULL
)
101 /*----------------------------------------------------------------------
102 Ask a yes/no question in the status line
104 Args: question -- string to prompt user with
105 dflt -- The default answer to the question (should probably
107 on_ctrl_C -- Answer returned on ^C
108 help -- Two line help text
109 flags -- Flags to modify behavior
110 WT_DING - ding the bell when asking.
111 WT_FLUSH_IN - Discard pending input.
112 WT_SEQ_SENSITIVE - Caller is sensitive to sequence
113 number changes caused by
114 unsolicited expunges while we're
117 Result: Messes up the status line,
118 returns y, n, dflt, on_ctrl_C, or SEQ_EXCEPTION
121 want_to(char *question
, int dflt
, int on_ctrl_C
, HelpType help
, int flags
)
123 char *free_this
= NULL
, *free_this2
= NULL
, *prompt
;
127 if((flags
& WT_DING
) && F_OFF(F_QUELL_BEEPS
, ps_global
)){
133 return(pre_screen_config_want_to(question
, dflt
, on_ctrl_C
));
135 if (mswin_usedialog ()) {
137 switch (mswin_yesno_utf8 (question
)) {
139 case 0: return (on_ctrl_C
);
140 case 1: return ('y');
141 case 2: return ('n');
147 One problem with adding the (y/n) here is that shrinking the
148 screen while in radio_buttons() will cause it to get chopped
149 off. It would be better to truncate the question passed in
150 here and leave the full "(y/n) [x] : " on.
153 len
= strlen(question
) + 4;
154 free_this
= (char *) fs_get(len
);
155 width
= utf8_width(question
);
157 if(width
+ 2 < ps_global
->ttyo
->screen_cols
){
158 snprintf(free_this
, len
, "%s? ", question
);
159 free_this
[len
-1] = '\0';
162 else if(width
+ 1 < ps_global
->ttyo
->screen_cols
){
163 snprintf(free_this
, len
, "%s?", question
);
164 free_this
[len
-1] = '\0';
167 else if(width
< ps_global
->ttyo
->screen_cols
){
168 snprintf(free_this
, len
, "%s", question
);
169 free_this
[len
-1] = '\0';
173 free_this2
= (char *) fs_get(len
);
174 snprintf(free_this2
, len
, "%s? ", question
);
175 prompt
= short_str(free_this2
, free_this
, len
, ps_global
->ttyo
->screen_cols
-1, MidDots
);
178 if(on_ctrl_C
== 'n') /* don't ever let cancel == 'n' */
181 rv
= radio_buttons(prompt
,
182 (ps_global
->ttyo
->screen_rows
> 4) ? - FOOTER_ROWS(ps_global
) : -1,
183 yorn
, dflt
, on_ctrl_C
, help
, flags
);
186 fs_give((void **) &free_this
);
189 fs_give((void **) &free_this2
);
196 one_try_want_to(char *question
, int dflt
, int on_ctrl_C
, HelpType help
, int flags
)
202 l
= strlen(question
) + 5;
203 q2
= fs_get((l
+1) * sizeof(char));
204 strncpy(q2
, question
, l
);
206 (void) utf8_truncate(q2
, ps_global
->ttyo
->screen_cols
- 6);
207 strncat(q2
, "? ", l
+1 - strlen(q2
) - 1);
209 rv
= radio_buttons(q2
,
210 (ps_global
->ttyo
->screen_rows
> 4) ? - FOOTER_ROWS(ps_global
) : -1,
211 yorn
, dflt
, on_ctrl_C
, help
, flags
| RB_ONE_TRY
);
212 fs_give((void **) &q2
);
218 /*----------------------------------------------------------------------
219 Prompt user for a choice among alternatives
221 Args -- utf8prompt: The prompt for the question/selection
222 line: The line to prompt on, if negative then relative to bottom
223 esc_list: ESC_KEY_S list of keys
224 dflt: The selection when the <CR> is pressed (should probably
225 be one of the chars in esc_list)
226 on_ctrl_C: The selection when ^C is pressed
227 help_text: Text to be displayed on bottom two lines
228 flags: Logically OR'd flags modifying our behavior to:
229 RB_FLUSH_IN - Discard any pending input chars.
230 RB_ONE_TRY - Only give one chance to answer. Returns
231 on_ctrl_C value if not answered acceptably
233 RB_NO_NEWMAIL - Quell the usual newmail check.
234 RB_SEQ_SENSITIVE - The caller is sensitive to sequence number
235 changes so return on_ctrl_C if an
236 unsolicited expunge happens while we're
238 RB_RET_HELP - Instead of the regular internal handling
239 way of handling help_text, this just causes
240 radio_buttons to return 3 when help is
241 asked for, so that the caller handles it
244 Note: If there are enough keys in the esc_list to need a second
245 screen, and there is no help, then the 13th key will be
246 put in the help position.
248 Result -- Returns the letter pressed. Will be one of the characters in the
249 esc_list argument, or dflt, or on_ctrl_C, or SEQ_EXCEPTION.
251 This will pause for any new status message to be seen and then prompt the user.
252 The prompt will be truncated to fit on the screen. Redraw and resize are
253 handled along with ^Z suspension. Typing ^G will toggle the help text on and
254 off. Character types that are not buttons will result in a beep (unless one_try
258 radio_buttons(char *utf8prompt
, int line
, ESCKEY_S
*esc_list
, int dflt
,
259 int on_ctrl_C
, HelpType help_text
, int flags
)
262 register int ch
, real_line
;
265 int max_label
, i
, start
, fkey_table
[12];
267 struct key rb_keys
[12];
268 struct key_menu rb_keymenu
;
270 struct variable
*vars
= ps_global
->vars
;
271 COLOR_PAIR
*lastc
= NULL
, *promptc
= NULL
;
276 if (mswin_usedialog()){
277 MDlgButton button_list
[25];
278 LPTSTR free_names
[25];
279 LPTSTR free_labels
[25];
283 memset(&free_names
, 0, sizeof(LPTSTR
) * 25);
284 memset(&free_labels
, 0, sizeof(LPTSTR
) * 25);
285 memset(&button_list
, 0, sizeof (MDlgButton
) * 25);
288 if(flags
& RB_RET_HELP
){
289 if(help_text
!= NO_HELP
)
290 alpine_panic("RET_HELP and help in radio_buttons!");
292 button_list
[b
].ch
= '?';
293 button_list
[b
].rval
= 3;
294 button_list
[b
].name
= TEXT("?");
295 free_labels
[b
] = utf8_to_lptstr(N_("Help"));
296 button_list
[b
].label
= free_labels
[b
];
300 for(i
= 0; esc_list
&& esc_list
[i
].ch
!= -1 && i
< 23; ++i
){
301 if(esc_list
[i
].ch
!= -2){
302 button_list
[b
].ch
= esc_list
[i
].ch
;
303 button_list
[b
].rval
= esc_list
[i
].rval
;
304 free_names
[b
] = utf8_to_lptstr(esc_list
[i
].name
);
305 button_list
[b
].name
= free_names
[b
];
306 free_labels
[b
] = utf8_to_lptstr(esc_list
[i
].label
);
307 button_list
[b
].label
= free_labels
[b
];
312 button_list
[b
].ch
= -1;
314 /* assumption here is that HelpType is char ** */
317 ret
= mswin_select(utf8prompt
, button_list
, dflt
, on_ctrl_C
, help
, flags
);
318 for(i
= 0; i
< 25; i
++){
320 fs_give((void **) &free_names
[i
]);
322 fs_give((void **) &free_labels
[i
]);
328 #endif /* _WINDOWS */
331 flush_ordered_messages(); /* show user previous status msgs */
332 mark_status_dirty(); /* clear message next display call */
333 real_line
= line
> 0 ? line
: ps_global
->ttyo
->screen_rows
+ line
;
334 MoveCursor(real_line
, RAD_BUT_COL
);
337 /*---- Find widest label ----*/
339 for(i
= 0; esc_list
&& esc_list
[i
].ch
!= -1 && i
< 11; i
++){
340 if(esc_list
[i
].ch
== -2) /* -2 means to skip this key and leave blank */
343 max_label
= MAX(max_label
, utf8_width(esc_list
[i
].name
));
346 if(ps_global
->ttyo
->screen_cols
- max_label
- 1 > 0)
347 maxcol
= ps_global
->ttyo
->screen_cols
- max_label
- 1;
352 * We need to be able to truncate q, so copy it in case it is
355 q
= cpystr(utf8prompt
);
357 /*---- Init structs for keymenu ----*/
358 for(i
= 0; i
< 12; i
++)
359 memset((void *)&rb_keys
[i
], 0, sizeof(struct key
));
361 memset((void *)&rb_keymenu
, 0, sizeof(struct key_menu
));
362 rb_keymenu
.how_many
= 1;
363 rb_keymenu
.keys
= rb_keys
;
365 /*---- Setup key menu ----*/
368 memset(fkey_table
, NO_OP_COMMAND
, 12 * sizeof(int));
369 if(flags
& RB_RET_HELP
&& help_text
!= NO_HELP
)
370 alpine_panic("RET_HELP and help in radio_buttons!");
372 /* if shown, always at position 0 */
373 if(help_text
!= NO_HELP
|| flags
& RB_RET_HELP
){
374 rb_keymenu
.keys
[0].name
= "?";
375 rb_keymenu
.keys
[0].label
= N_("Help");
377 fkey_table
[0] = ctrl('G');
382 rb_keymenu
.keys
[1].name
= "^C";
383 rb_keymenu
.keys
[1].label
= N_("Cancel");
385 fkey_table
[1] = ctrl('C');
389 start
= start
? 2 : 0;
390 /*---- Show the usual possible keys ----*/
391 for(i
=start
; esc_list
&& esc_list
[i
-start
].ch
!= -1; i
++){
393 * If we have an esc_list item we'd like to put in the non-existent
394 * 13th slot, and there is no help, we put it in the help slot
395 * instead. We're hacking now...!
397 * We may also have invisible esc_list items that don't show up
398 * on the screen. We use this when we have two different keys
399 * which are synonyms, like ^P and KEY_UP. If all the slots are
400 * already full we can still fit invisible keys off the screen to
401 * the right. A key is invisible if it's label is "".
404 if(esc_list
[i
-start
].label
405 && esc_list
[i
-start
].label
[0] != '\0'){ /* visible */
406 if(i
== 12){ /* special case where we put it in help slot */
407 if(help_text
!= NO_HELP
)
408 alpine_panic("Programming botch in radio_buttons(): too many keys");
410 if(esc_list
[i
-start
].ch
!= -2)
411 setbitn(0, bitmap
); /* the help slot */
413 fkey_table
[0] = esc_list
[i
-start
].ch
;
414 rb_keymenu
.keys
[0].name
= esc_list
[i
-start
].name
;
415 if(esc_list
[i
-start
].ch
!= -2
416 && esc_list
[i
-start
].rval
== dflt
417 && esc_list
[i
-start
].label
){
420 l
= strlen(esc_list
[i
-start
].label
) + 2;
421 ds
= (char *)fs_get((l
+1) * sizeof(char));
422 snprintf(ds
, l
+1, "[%s]", esc_list
[i
-start
].label
);
424 rb_keymenu
.keys
[0].label
= ds
;
427 rb_keymenu
.keys
[0].label
= esc_list
[i
-start
].label
;
430 alpine_panic("Botch in radio_buttons(): too many keys");
434 if(esc_list
[i
-start
].ch
!= -2)
437 fkey_table
[i
] = esc_list
[i
-start
].ch
;
438 rb_keymenu
.keys
[i
].name
= esc_list
[i
-start
].name
;
439 if(esc_list
[i
-start
].ch
!= -2
440 && esc_list
[i
-start
].rval
== dflt
441 && esc_list
[i
-start
].label
){
444 l
= strlen(esc_list
[i
-start
].label
) + 2;
445 ds
= (char *)fs_get((l
+1) * sizeof(char));
446 snprintf(ds
, l
+1, "[%s]", esc_list
[i
-start
].label
);
448 rb_keymenu
.keys
[i
].label
= ds
;
451 rb_keymenu
.keys
[i
].label
= esc_list
[i
-start
].label
;
456 rb_keymenu
.keys
[i
].name
= NULL
;
458 ps_global
->mangled_footer
= 1;
461 cursor_shown
= mswin_showcaret(1);
464 if(pico_usingcolor() && VAR_PROMPT_FORE_COLOR
&&
465 VAR_PROMPT_BACK_COLOR
&&
466 pico_is_good_color(VAR_PROMPT_FORE_COLOR
) &&
467 pico_is_good_color(VAR_PROMPT_BACK_COLOR
)){
468 lastc
= pico_get_cur_color();
470 promptc
= new_color_pair(VAR_PROMPT_FORE_COLOR
,
471 VAR_PROMPT_BACK_COLOR
);
472 (void)pico_set_colorp(promptc
, PSC_NONE
);
478 draw_radio_prompt(real_line
, RAD_BUT_COL
, maxcol
, q
);
483 /*---- Paint the keymenu ----*/
485 (void)pico_set_colorp(lastc
, PSC_NONE
);
489 draw_keymenu(&rb_keymenu
, bitmap
, ps_global
->ttyo
->screen_cols
,
490 1 - FOOTER_ROWS(ps_global
), 0, FirstMenu
);
492 (void)pico_set_colorp(promptc
, PSC_NONE
);
496 MoveCursor(real_line
, MIN(RAD_BUT_COL
+utf8_width(q
), maxcol
+1));
498 if(flags
& RB_FLUSH_IN
)
502 /* Timeout 5 min to keep imap mail stream alive */
503 ucs
= read_char(600);
505 "Want_to read: %s (0x%x)\n", pretty_command(ucs
), ucs
));
506 if((ucs
< 0x80) && isupper((unsigned char) ucs
))
507 ucs
= tolower((unsigned char) ucs
);
509 if(F_ON(F_USE_FK
,ps_global
)
510 && (((ucs
< 0x80) && isalpha((unsigned char) ucs
) && !strchr("YyNn",(int) ucs
))
511 || ((ucs
>= PF1
&& ucs
<= PF12
)
512 && (ucs
= fkey_table
[ucs
- PF1
]) == NO_OP_COMMAND
))){
514 * The funky test above does two things. It maps
515 * esc_list character commands to function keys, *and* prevents
516 * character commands from input while in function key mode.
517 * NOTE: this breaks if we ever need more than the first
518 * twelve function keys...
520 if(flags
& RB_ONE_TRY
){
521 ch
= ucs
= on_ctrl_C
;
532 for(i
= 0; esc_list
&& esc_list
[i
].ch
!= -1; i
++)
533 if(ucs
== esc_list
[i
].ch
){
536 MoveCursor(real_line
,len
=MIN(RAD_BUT_COL
+utf8_width(q
),maxcol
+1));
537 for(n
= 0, len
= ps_global
->ttyo
->screen_cols
- len
;
538 esc_list
[i
].label
&& esc_list
[i
].label
[n
] && len
> 0;
540 Writechar(esc_list
[i
].label
[n
], 0);
542 ch
= esc_list
[i
].rval
;
546 if(flags
& RB_ONE_TRY
){
557 for(i
= 0; esc_list
&& esc_list
[i
].ch
!= -1; i
++)
558 if(ch
== esc_list
[i
].rval
){
561 MoveCursor(real_line
,len
=MIN(RAD_BUT_COL
+utf8_width(q
),maxcol
+1));
562 for(n
= 0, len
= ps_global
->ttyo
->screen_cols
- len
;
563 esc_list
[i
].label
&& esc_list
[i
].label
[n
] && len
> 0;
565 Writechar(esc_list
[i
].label
[n
], 0);
572 if(on_ctrl_C
|| (flags
& RB_ONE_TRY
)){
583 if(FOOTER_ROWS(ps_global
) == 1 && km_popped
== 0){
585 FOOTER_ROWS(ps_global
) = 3;
587 real_line
= ps_global
->ttyo
->screen_rows
+ line
;
589 (void)pico_set_colorp(lastc
, PSC_NONE
);
593 clearfooter(ps_global
);
595 (void)pico_set_colorp(promptc
, PSC_NONE
);
599 draw_radio_prompt(real_line
, RAD_BUT_COL
, maxcol
, q
);
603 if(flags
& RB_RET_HELP
){
607 else if(help_text
!= NO_HELP
&& FOOTER_ROWS(ps_global
) > 1){
608 mark_keymenu_dirty();
610 (void)pico_set_colorp(lastc
, PSC_NONE
);
614 MoveCursor(real_line
+ 1, RAD_BUT_COL
);
616 MoveCursor(real_line
+ 2, RAD_BUT_COL
);
618 radio_help(real_line
, RAD_BUT_COL
, help_text
);
620 MoveCursor(real_line
, MIN(RAD_BUT_COL
+utf8_width(q
), maxcol
+1));
622 (void)pico_set_colorp(promptc
, PSC_NONE
);
633 goto newcmd
; /* misunderstood escape? */
635 case NO_OP_IDLE
: /* UNODIR, keep the stream alive */
636 if(flags
& RB_NO_NEWMAIL
)
639 i
= new_mail(0, VeryBadTime
, NM_DEFER_SORT
);
640 if(sp_expunge_count(ps_global
->mail_stream
)
641 && flags
& RB_SEQ_SENSITIVE
){
651 break; /* no changes, get on with life */
652 /* Else fall into redraw to adjust displayed numbers and such */
657 real_line
= line
> 0 ? line
: ps_global
->ttyo
->screen_rows
+ line
;
659 (void)pico_set_colorp(lastc
, PSC_NONE
);
665 if(ps_global
->redrawer
!= NULL
)
666 (*ps_global
->redrawer
)();
667 if(FOOTER_ROWS(ps_global
) == 3 || km_popped
)
670 if(ps_global
->ttyo
->screen_cols
- max_label
- 1 > 0)
671 maxcol
= ps_global
->ttyo
->screen_cols
- max_label
- 1;
676 (void)pico_set_colorp(promptc
, PSC_NONE
);
680 draw_radio_prompt(real_line
, RAD_BUT_COL
, maxcol
, q
);
693 fs_give((void **) &q
);
695 fs_give((void **) &ds
);
698 (void) pico_set_colorp(lastc
, PSC_NONE
);
699 free_color_pair(&lastc
);
701 free_color_pair(&promptc
);
709 FOOTER_ROWS(ps_global
) = 1;
710 clearfooter(ps_global
);
711 ps_global
->mangled_body
= 1;
718 #define OTHER_RETURN_VAL 1300
719 #define KEYS_PER_LIST 8
722 * This should really be part of radio_buttons itself, I suppose. It was
723 * easier to do it this way. This is for when there are more than 12
724 * possible commands. We could have all the radio_buttons calls call this
725 * instead of radio_buttons, or rename this to radio_buttons.
727 * Radio_buttons is limited to 10 visible commands unless there is no Help,
728 * in which case it is 11 visible commands.
729 * Double_radio_buttons is limited to 16 visible commands because it uses
730 * slots 3 and 4 for readability and the OTHER CMD.
733 double_radio_buttons(char *prompt
, int line
, ESCKEY_S
*esc_list
, int dflt
, int on_ctrl_C
, HelpType help_text
, int flags
)
735 ESCKEY_S
*list
= NULL
, *list1
= NULL
, *list2
= NULL
;
737 int v
= OTHER_RETURN_VAL
, listnum
= 0;
740 if(mswin_usedialog())
741 return(radio_buttons(prompt
, line
, esc_list
, dflt
, on_ctrl_C
,
745 /* check to see if it will all fit in one */
746 while(esc_list
&& esc_list
[i
].ch
!= -1)
750 if(help_text
!= NO_HELP
)
754 return(radio_buttons(prompt
, line
, esc_list
, dflt
, on_ctrl_C
,
758 * Won't fit, split it into two lists.
760 * We can fit at most 8 items in the visible list. The rest of
761 * the commands have to be invisible. Each of list1 and list2 should
762 * have no more than 8 visible (name != "" || label != "") items.
764 list1
= (ESCKEY_S
*)fs_get((KEYS_PER_LIST
+1) * sizeof(*list1
));
765 memset(list1
, 0, (KEYS_PER_LIST
+1) * sizeof(*list1
));
766 list2
= (ESCKEY_S
*)fs_get((KEYS_PER_LIST
+1) * sizeof(*list2
));
767 memset(list2
, 0, (KEYS_PER_LIST
+1) * sizeof(*list2
));
769 for(j
=0,i
=0; esc_list
[i
].ch
!= -1 && j
< KEYS_PER_LIST
; j
++,i
++)
770 list1
[j
] = esc_list
[i
];
774 for(j
=0; esc_list
[i
].ch
!= -1 && j
< KEYS_PER_LIST
; j
++,i
++)
775 list2
[j
] = esc_list
[i
];
779 list
= construct_combined_esclist(list1
, list2
);
781 while(v
== OTHER_RETURN_VAL
){
782 v
= radio_buttons(prompt
,line
,list
,dflt
,on_ctrl_C
,help_text
,flags
);
783 if(v
== OTHER_RETURN_VAL
){
784 fs_give((void **) &list
);
785 listnum
= 1 - listnum
;
786 list
= construct_combined_esclist(listnum
? list2
: list1
,
787 listnum
? list1
: list2
);
792 fs_give((void **) &list
);
794 fs_give((void **) &list1
);
796 fs_give((void **) &list2
);
803 construct_combined_esclist(ESCKEY_S
*list1
, ESCKEY_S
*list2
)
808 count
= 2; /* for blank key and for OTHER key */
809 for(i
=0; list1
&& list1
[i
].ch
!= -1; i
++)
811 for(i
=0; list2
&& list2
[i
].ch
!= -1; i
++)
814 list
= (ESCKEY_S
*) fs_get((count
+ 1) * sizeof(*list
));
815 memset(list
, 0, (count
+ 1) * sizeof(*list
));
817 list
[j
].ch
= -2; /* leave blank */
820 list
[j
++].label
= NULL
;
823 list
[j
].rval
= OTHER_RETURN_VAL
;
825 list
[j
].label
= N_("OTHER CMDS");
828 * Make sure that O for OTHER CMD or the return val for OTHER CMD
829 * isn't used for something else.
831 for(i
=0; list1
&& list1
[i
].ch
!= -1; i
++){
832 if(list1
[i
].rval
== list
[j
].rval
)
833 alpine_panic("1bad rval in d_r");
834 if(F_OFF(F_USE_FK
,ps_global
) && list1
[i
].ch
== list
[j
].ch
)
835 alpine_panic("1bad ch in ccl");
838 for(i
=0; list2
&& list2
[i
].ch
!= -1; i
++){
839 if(list2
[i
].rval
== list
[j
].rval
)
840 alpine_panic("2bad rval in d_r");
841 if(F_OFF(F_USE_FK
,ps_global
) && list2
[i
].ch
== list
[j
].ch
)
842 alpine_panic("2bad ch in ccl");
847 /* the visible set */
848 for(i
=0; list1
&& list1
[i
].ch
!= -1; i
++){
849 if(i
>= KEYS_PER_LIST
&& list1
[i
].label
[0] != '\0')
850 alpine_panic("too many visible keys in ccl");
852 list
[j
++] = list1
[i
];
855 /* the rest are invisible */
856 for(i
=0; list2
&& list2
[i
].ch
!= -1; i
++){
868 /*----------------------------------------------------------------------
872 radio_help(int line
, int column
, HelpType help
)
876 /* assumption here is that HelpType is char ** */
881 MoveCursor(line
+ 1, column
);
884 PutLine0(line
+ 1, column
, text
[0]);
886 MoveCursor(line
+ 2, column
);
889 PutLine0(line
+ 2, column
, text
[1]);
895 /*----------------------------------------------------------------------
896 Paint the screen with the radio buttons prompt
899 draw_radio_prompt(int line
, unsigned start_c
, unsigned max_c
, char *q
)
902 unsigned x
, width
, got_width
;
903 char *tmpq
= NULL
, *useq
;
905 width
= utf8_width(q
);
906 if(width
> max_c
- start_c
+ 1){
907 tmpq
= (char *) fs_get((len
=(strlen(q
)+1)) * sizeof(char));
908 (void) utf8_to_width(tmpq
, q
, len
, max_c
- start_c
+ 1, &got_width
);
915 PutLine0(line
, start_c
, useq
);
918 while(x
++ < ps_global
->ttyo
->screen_cols
)
921 MoveCursor(line
, start_c
+ width
);
924 fs_give((void **) &tmpq
);