15382d832SPeter Avalos /*
2*a8e38dc0SAntonio Huete Jimenez * $Id: util.c,v 1.308 2022/04/08 21:01:51 tom Exp $
35382d832SPeter Avalos *
45382d832SPeter Avalos * util.c -- miscellaneous utilities for dialog
55382d832SPeter Avalos *
6*a8e38dc0SAntonio Huete Jimenez * Copyright 2000-2021,2022 Thomas E. Dickey
75382d832SPeter Avalos *
85382d832SPeter Avalos * This program is free software; you can redistribute it and/or modify
95382d832SPeter Avalos * it under the terms of the GNU Lesser General Public License, version 2.1
105382d832SPeter Avalos * as published by the Free Software Foundation.
115382d832SPeter Avalos *
125382d832SPeter Avalos * This program is distributed in the hope that it will be useful, but
135382d832SPeter Avalos * WITHOUT ANY WARRANTY; without even the implied warranty of
145382d832SPeter Avalos * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
155382d832SPeter Avalos * Lesser General Public License for more details.
165382d832SPeter Avalos *
175382d832SPeter Avalos * You should have received a copy of the GNU Lesser General Public
185382d832SPeter Avalos * License along with this program; if not, write to
195382d832SPeter Avalos * Free Software Foundation, Inc.
205382d832SPeter Avalos * 51 Franklin St., Fifth Floor
215382d832SPeter Avalos * Boston, MA 02110, USA.
225382d832SPeter Avalos *
235382d832SPeter Avalos * An earlier version of this program lists as authors
245382d832SPeter Avalos * Savio Lam (lam836@cs.cuhk.hk)
255382d832SPeter Avalos */
265382d832SPeter Avalos
275940c9abSDaniel Fojt #include <dlg_internals.h>
28*a8e38dc0SAntonio Huete Jimenez #include <dlg_keys.h>
295940c9abSDaniel Fojt
30*a8e38dc0SAntonio Huete Jimenez #if defined(NCURSES_VERSION)
31*a8e38dc0SAntonio Huete Jimenez #define CAN_KEEP_TITE 1
32*a8e38dc0SAntonio Huete Jimenez #elif defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 800000000)
33*a8e38dc0SAntonio Huete Jimenez #define CAN_KEEP_TITE 1
34*a8e38dc0SAntonio Huete Jimenez #else
35*a8e38dc0SAntonio Huete Jimenez #define CAN_KEEP_TITE 0
365382d832SPeter Avalos #endif
375382d832SPeter Avalos
38*a8e38dc0SAntonio Huete Jimenez #if CAN_KEEP_TITE
39*a8e38dc0SAntonio Huete Jimenez #if defined(NCURSES_VERSION) && defined(HAVE_NCURSESW_TERM_H)
405382d832SPeter Avalos #include <ncursesw/term.h>
41*a8e38dc0SAntonio Huete Jimenez #elif defined(NCURSES_VERSION) && defined(HAVE_NCURSES_TERM_H)
425382d832SPeter Avalos #include <ncurses/term.h>
435382d832SPeter Avalos #else
445382d832SPeter Avalos #include <term.h>
455382d832SPeter Avalos #endif
465382d832SPeter Avalos #endif
475382d832SPeter Avalos
485382d832SPeter Avalos #if defined(HAVE_WCHGAT)
495382d832SPeter Avalos # if defined(NCURSES_VERSION_PATCH)
505382d832SPeter Avalos # if NCURSES_VERSION_PATCH >= 20060715
515382d832SPeter Avalos # define USE_WCHGAT 1
525382d832SPeter Avalos # else
535382d832SPeter Avalos # define USE_WCHGAT 0
545382d832SPeter Avalos # endif
555382d832SPeter Avalos # else
565382d832SPeter Avalos # define USE_WCHGAT 1
575382d832SPeter Avalos # endif
585382d832SPeter Avalos #else
595382d832SPeter Avalos # define USE_WCHGAT 0
605382d832SPeter Avalos #endif
615382d832SPeter Avalos
625382d832SPeter Avalos /* globals */
635382d832SPeter Avalos DIALOG_STATE dialog_state;
645382d832SPeter Avalos DIALOG_VARS dialog_vars;
655382d832SPeter Avalos
665382d832SPeter Avalos #if !(defined(HAVE_WGETPARENT) && defined(HAVE_WINDOW__PARENT))
675382d832SPeter Avalos #define NEED_WGETPARENT 1
685382d832SPeter Avalos #else
695382d832SPeter Avalos #undef NEED_WGETPARENT
705382d832SPeter Avalos #endif
715382d832SPeter Avalos
725382d832SPeter Avalos #define concat(a,b) a##b
735382d832SPeter Avalos
745382d832SPeter Avalos #ifdef HAVE_RC_FILE
755382d832SPeter Avalos #define RC_DATA(name,comment) , #name "_color", comment " color"
765382d832SPeter Avalos #else
775382d832SPeter Avalos #define RC_DATA(name,comment) /*nothing */
785382d832SPeter Avalos #endif
795382d832SPeter Avalos
805382d832SPeter Avalos #ifdef HAVE_COLOR
815382d832SPeter Avalos #include <dlg_colors.h>
825940c9abSDaniel Fojt #ifdef HAVE_RC_FILE2
835940c9abSDaniel Fojt #define COLOR_DATA(upr) , \
845940c9abSDaniel Fojt concat(DLGC_FG_,upr), \
855940c9abSDaniel Fojt concat(DLGC_BG_,upr), \
865940c9abSDaniel Fojt concat(DLGC_HL_,upr), \
875940c9abSDaniel Fojt concat(DLGC_UL_,upr), \
885940c9abSDaniel Fojt concat(DLGC_RV_,upr)
895940c9abSDaniel Fojt #else /* HAVE_RC_FILE2 */
905382d832SPeter Avalos #define COLOR_DATA(upr) , \
915382d832SPeter Avalos concat(DLGC_FG_,upr), \
925382d832SPeter Avalos concat(DLGC_BG_,upr), \
935382d832SPeter Avalos concat(DLGC_HL_,upr)
945940c9abSDaniel Fojt #endif /* HAVE_RC_FILE2 */
955940c9abSDaniel Fojt #else /* HAVE_COLOR */
965382d832SPeter Avalos #define COLOR_DATA(upr) /*nothing */
975940c9abSDaniel Fojt #endif /* HAVE_COLOR */
985382d832SPeter Avalos
995382d832SPeter Avalos #define UseShadow(dw) ((dw) != 0 && (dw)->normal != 0 && (dw)->shadow != 0)
1005382d832SPeter Avalos
1015382d832SPeter Avalos /*
1025382d832SPeter Avalos * Table of color and attribute values, default is for mono display.
1035382d832SPeter Avalos * The order matches the DIALOG_ATR() values.
1045382d832SPeter Avalos */
1055940c9abSDaniel Fojt #define DATA(atr,upr,lwr,cmt) { atr COLOR_DATA(upr) RC_DATA(lwr,cmt) }
1065382d832SPeter Avalos /* *INDENT-OFF* */
1075382d832SPeter Avalos DIALOG_COLORS dlg_color_table[] =
1085382d832SPeter Avalos {
1095382d832SPeter Avalos DATA(A_NORMAL, SCREEN, screen, "Screen"),
1105382d832SPeter Avalos DATA(A_NORMAL, SHADOW, shadow, "Shadow"),
1115382d832SPeter Avalos DATA(A_REVERSE, DIALOG, dialog, "Dialog box"),
1125382d832SPeter Avalos DATA(A_REVERSE, TITLE, title, "Dialog box title"),
1135382d832SPeter Avalos DATA(A_REVERSE, BORDER, border, "Dialog box border"),
1145382d832SPeter Avalos DATA(A_BOLD, BUTTON_ACTIVE, button_active, "Active button"),
1155382d832SPeter Avalos DATA(A_DIM, BUTTON_INACTIVE, button_inactive, "Inactive button"),
1165382d832SPeter Avalos DATA(A_UNDERLINE, BUTTON_KEY_ACTIVE, button_key_active, "Active button key"),
1175382d832SPeter Avalos DATA(A_UNDERLINE, BUTTON_KEY_INACTIVE, button_key_inactive, "Inactive button key"),
1185382d832SPeter Avalos DATA(A_NORMAL, BUTTON_LABEL_ACTIVE, button_label_active, "Active button label"),
1195382d832SPeter Avalos DATA(A_NORMAL, BUTTON_LABEL_INACTIVE, button_label_inactive, "Inactive button label"),
1205382d832SPeter Avalos DATA(A_REVERSE, INPUTBOX, inputbox, "Input box"),
1215382d832SPeter Avalos DATA(A_REVERSE, INPUTBOX_BORDER, inputbox_border, "Input box border"),
1225382d832SPeter Avalos DATA(A_REVERSE, SEARCHBOX, searchbox, "Search box"),
1235382d832SPeter Avalos DATA(A_REVERSE, SEARCHBOX_TITLE, searchbox_title, "Search box title"),
1245382d832SPeter Avalos DATA(A_REVERSE, SEARCHBOX_BORDER, searchbox_border, "Search box border"),
1255382d832SPeter Avalos DATA(A_REVERSE, POSITION_INDICATOR, position_indicator, "File position indicator"),
1265382d832SPeter Avalos DATA(A_REVERSE, MENUBOX, menubox, "Menu box"),
1275382d832SPeter Avalos DATA(A_REVERSE, MENUBOX_BORDER, menubox_border, "Menu box border"),
1285382d832SPeter Avalos DATA(A_REVERSE, ITEM, item, "Item"),
1295382d832SPeter Avalos DATA(A_NORMAL, ITEM_SELECTED, item_selected, "Selected item"),
1305382d832SPeter Avalos DATA(A_REVERSE, TAG, tag, "Tag"),
1315382d832SPeter Avalos DATA(A_REVERSE, TAG_SELECTED, tag_selected, "Selected tag"),
1325382d832SPeter Avalos DATA(A_NORMAL, TAG_KEY, tag_key, "Tag key"),
1335382d832SPeter Avalos DATA(A_BOLD, TAG_KEY_SELECTED, tag_key_selected, "Selected tag key"),
1345382d832SPeter Avalos DATA(A_REVERSE, CHECK, check, "Check box"),
1355382d832SPeter Avalos DATA(A_REVERSE, CHECK_SELECTED, check_selected, "Selected check box"),
1365382d832SPeter Avalos DATA(A_REVERSE, UARROW, uarrow, "Up arrow"),
1375382d832SPeter Avalos DATA(A_REVERSE, DARROW, darrow, "Down arrow"),
1385382d832SPeter Avalos DATA(A_NORMAL, ITEMHELP, itemhelp, "Item help-text"),
1395382d832SPeter Avalos DATA(A_BOLD, FORM_ACTIVE_TEXT, form_active_text, "Active form text"),
1405382d832SPeter Avalos DATA(A_REVERSE, FORM_TEXT, form_text, "Form text"),
1415382d832SPeter Avalos DATA(A_NORMAL, FORM_ITEM_READONLY, form_item_readonly, "Readonly form item"),
1425382d832SPeter Avalos DATA(A_REVERSE, GAUGE, gauge, "Dialog box gauge"),
1435382d832SPeter Avalos DATA(A_REVERSE, BORDER2, border2, "Dialog box border2"),
1445382d832SPeter Avalos DATA(A_REVERSE, INPUTBOX_BORDER2, inputbox_border2, "Input box border2"),
1455382d832SPeter Avalos DATA(A_REVERSE, SEARCHBOX_BORDER2, searchbox_border2, "Search box border2"),
1465382d832SPeter Avalos DATA(A_REVERSE, MENUBOX_BORDER2, menubox_border2, "Menu box border2")
1475382d832SPeter Avalos };
1485940c9abSDaniel Fojt #undef DATA
1495382d832SPeter Avalos /* *INDENT-ON* */
1505382d832SPeter Avalos
1515382d832SPeter Avalos /*
1525382d832SPeter Avalos * Maintain a list of subwindows so that we can delete them to cleanup.
1535382d832SPeter Avalos * More important, this provides a fallback when wgetparent() is not available.
1545382d832SPeter Avalos */
1555382d832SPeter Avalos static void
add_subwindow(WINDOW * parent,WINDOW * child)1565382d832SPeter Avalos add_subwindow(WINDOW *parent, WINDOW *child)
1575382d832SPeter Avalos {
1585382d832SPeter Avalos DIALOG_WINDOWS *p = dlg_calloc(DIALOG_WINDOWS, 1);
1595382d832SPeter Avalos
1605382d832SPeter Avalos if (p != 0) {
1615382d832SPeter Avalos p->normal = parent;
1625382d832SPeter Avalos p->shadow = child;
1635940c9abSDaniel Fojt p->getc_timeout = WTIMEOUT_OFF;
1645382d832SPeter Avalos p->next = dialog_state.all_subwindows;
1655382d832SPeter Avalos dialog_state.all_subwindows = p;
1665382d832SPeter Avalos }
1675382d832SPeter Avalos }
1685382d832SPeter Avalos
1695382d832SPeter Avalos static void
del_subwindows(WINDOW * parent)1705382d832SPeter Avalos del_subwindows(WINDOW *parent)
1715382d832SPeter Avalos {
1725382d832SPeter Avalos DIALOG_WINDOWS *p = dialog_state.all_subwindows;
1735382d832SPeter Avalos DIALOG_WINDOWS *q = 0;
1745382d832SPeter Avalos DIALOG_WINDOWS *r;
1755382d832SPeter Avalos
1765382d832SPeter Avalos while (p != 0) {
1775382d832SPeter Avalos if (p->normal == parent) {
1785382d832SPeter Avalos delwin(p->shadow);
1795382d832SPeter Avalos r = p->next;
1805382d832SPeter Avalos if (q == 0) {
1815382d832SPeter Avalos dialog_state.all_subwindows = r;
1825382d832SPeter Avalos } else {
1835382d832SPeter Avalos q->next = r;
1845382d832SPeter Avalos }
1855382d832SPeter Avalos free(p);
1865382d832SPeter Avalos p = r;
1875382d832SPeter Avalos } else {
1885382d832SPeter Avalos q = p;
1895382d832SPeter Avalos p = p->next;
1905382d832SPeter Avalos }
1915382d832SPeter Avalos }
1925382d832SPeter Avalos }
1935382d832SPeter Avalos
1945382d832SPeter Avalos /*
1955382d832SPeter Avalos * Display background title if it exists ...
1965382d832SPeter Avalos */
1975382d832SPeter Avalos void
dlg_put_backtitle(void)1985382d832SPeter Avalos dlg_put_backtitle(void)
1995382d832SPeter Avalos {
2005382d832SPeter Avalos
2015382d832SPeter Avalos if (dialog_vars.backtitle != NULL) {
2025382d832SPeter Avalos chtype attr = A_NORMAL;
2035382d832SPeter Avalos int backwidth = dlg_count_columns(dialog_vars.backtitle);
2045940c9abSDaniel Fojt int i;
2055382d832SPeter Avalos
2065940c9abSDaniel Fojt dlg_attrset(stdscr, screen_attr);
2075382d832SPeter Avalos (void) wmove(stdscr, 0, 1);
2085382d832SPeter Avalos dlg_print_text(stdscr, dialog_vars.backtitle, COLS - 2, &attr);
2095382d832SPeter Avalos for (i = 0; i < COLS - backwidth; i++)
2105382d832SPeter Avalos (void) waddch(stdscr, ' ');
2115382d832SPeter Avalos (void) wmove(stdscr, 1, 1);
2125382d832SPeter Avalos for (i = 0; i < COLS - 2; i++)
2135382d832SPeter Avalos (void) waddch(stdscr, dlg_boxchar(ACS_HLINE));
2145382d832SPeter Avalos }
2155382d832SPeter Avalos
2165382d832SPeter Avalos (void) wnoutrefresh(stdscr);
2175382d832SPeter Avalos }
2185382d832SPeter Avalos
2195382d832SPeter Avalos /*
2205382d832SPeter Avalos * Set window to attribute 'attr'. There are more efficient ways to do this,
2215382d832SPeter Avalos * but will not work on older/buggy ncurses versions.
2225382d832SPeter Avalos */
2235382d832SPeter Avalos void
dlg_attr_clear(WINDOW * win,int height,int width,chtype attr)2245382d832SPeter Avalos dlg_attr_clear(WINDOW *win, int height, int width, chtype attr)
2255382d832SPeter Avalos {
2265382d832SPeter Avalos int i, j;
2275382d832SPeter Avalos
2285940c9abSDaniel Fojt dlg_attrset(win, attr);
2295382d832SPeter Avalos for (i = 0; i < height; i++) {
2305382d832SPeter Avalos (void) wmove(win, i, 0);
2315382d832SPeter Avalos for (j = 0; j < width; j++)
2325382d832SPeter Avalos (void) waddch(win, ' ');
2335382d832SPeter Avalos }
2345382d832SPeter Avalos (void) touchwin(win);
2355382d832SPeter Avalos }
2365382d832SPeter Avalos
2375382d832SPeter Avalos void
dlg_clear(void)2385382d832SPeter Avalos dlg_clear(void)
2395382d832SPeter Avalos {
2405382d832SPeter Avalos dlg_attr_clear(stdscr, LINES, COLS, screen_attr);
2415382d832SPeter Avalos }
2425382d832SPeter Avalos
2435940c9abSDaniel Fojt #ifdef KEY_RESIZE
2445940c9abSDaniel Fojt void
_dlg_resize_cleanup(WINDOW * w)2455940c9abSDaniel Fojt _dlg_resize_cleanup(WINDOW *w)
2465940c9abSDaniel Fojt {
2475940c9abSDaniel Fojt dlg_clear();
2485940c9abSDaniel Fojt dlg_put_backtitle();
2495940c9abSDaniel Fojt dlg_del_window(w);
2505940c9abSDaniel Fojt dlg_mouse_free_regions();
2515940c9abSDaniel Fojt }
2525940c9abSDaniel Fojt #endif /* KEY_RESIZE */
2535940c9abSDaniel Fojt
2545382d832SPeter Avalos #define isprivate(s) ((s) != 0 && strstr(s, "\033[?") != 0)
2555382d832SPeter Avalos
2565382d832SPeter Avalos #define TTY_DEVICE "/dev/tty"
2575382d832SPeter Avalos
2585382d832SPeter Avalos /*
2595382d832SPeter Avalos * If $DIALOG_TTY exists, allow the program to try to open the terminal
2605382d832SPeter Avalos * directly when stdout is redirected. By default we require the "--stdout"
2615382d832SPeter Avalos * option to be given, but some scripts were written making use of the
2625382d832SPeter Avalos * behavior of dialog which tried opening the terminal anyway.
2635382d832SPeter Avalos */
264*a8e38dc0SAntonio Huete Jimenez #define dialog_tty() (dlg_getenv_num("DIALOG_TTY", (int *)0) > 0)
2655382d832SPeter Avalos
2665382d832SPeter Avalos /*
2675382d832SPeter Avalos * Open the terminal directly. If one of stdin, stdout or stderr really points
2685382d832SPeter Avalos * to a tty, use it. Otherwise give up and open /dev/tty.
2695382d832SPeter Avalos */
2705382d832SPeter Avalos static int
open_terminal(char ** result,int mode)2715382d832SPeter Avalos open_terminal(char **result, int mode)
2725382d832SPeter Avalos {
2735382d832SPeter Avalos const char *device = TTY_DEVICE;
2745382d832SPeter Avalos if (!isatty(fileno(stderr))
2755382d832SPeter Avalos || (device = ttyname(fileno(stderr))) == 0) {
2765382d832SPeter Avalos if (!isatty(fileno(stdout))
2775382d832SPeter Avalos || (device = ttyname(fileno(stdout))) == 0) {
2785382d832SPeter Avalos if (!isatty(fileno(stdin))
2795382d832SPeter Avalos || (device = ttyname(fileno(stdin))) == 0) {
2805382d832SPeter Avalos device = TTY_DEVICE;
2815382d832SPeter Avalos }
2825382d832SPeter Avalos }
2835382d832SPeter Avalos }
2845382d832SPeter Avalos *result = dlg_strclone(device);
2855382d832SPeter Avalos return open(device, mode);
2865382d832SPeter Avalos }
2875382d832SPeter Avalos
288*a8e38dc0SAntonio Huete Jimenez #if CAN_KEEP_TITE
2891ef6786aSJohn Marino static int
my_putc(int ch)2901ef6786aSJohn Marino my_putc(int ch)
2911ef6786aSJohn Marino {
2921ef6786aSJohn Marino char buffer[2];
2931ef6786aSJohn Marino int fd = fileno(dialog_state.screen_output);
2941ef6786aSJohn Marino
2951ef6786aSJohn Marino buffer[0] = (char) ch;
2961ef6786aSJohn Marino return (int) write(fd, buffer, (size_t) 1);
2971ef6786aSJohn Marino }
2981ef6786aSJohn Marino #endif
2991ef6786aSJohn Marino
3005382d832SPeter Avalos /*
3015382d832SPeter Avalos * Do some initialization for dialog.
3025382d832SPeter Avalos *
3035382d832SPeter Avalos * 'input' is the real tty input of dialog. Usually it is stdin, but if
3045382d832SPeter Avalos * --input-fd option is used, it may be anything.
3055382d832SPeter Avalos *
3065382d832SPeter Avalos * 'output' is where dialog will send its result. Usually it is stderr, but
3075382d832SPeter Avalos * if --stdout or --output-fd is used, it may be anything. We are concerned
3085382d832SPeter Avalos * mainly with the case where it happens to be the same as stdout.
3095382d832SPeter Avalos */
3105382d832SPeter Avalos void
init_dialog(FILE * input,FILE * output)3115382d832SPeter Avalos init_dialog(FILE *input, FILE *output)
3125382d832SPeter Avalos {
3135382d832SPeter Avalos int fd1, fd2;
3145382d832SPeter Avalos char *device = 0;
3155382d832SPeter Avalos
3165382d832SPeter Avalos setlocale(LC_ALL, "");
3175382d832SPeter Avalos
3185382d832SPeter Avalos dialog_state.output = output;
319*a8e38dc0SAntonio Huete Jimenez if (dialog_state.tab_len == 0)
3205382d832SPeter Avalos dialog_state.tab_len = TAB_LEN;
321*a8e38dc0SAntonio Huete Jimenez if (dialog_state.aspect_ratio == 0)
3225382d832SPeter Avalos dialog_state.aspect_ratio = DEFAULT_ASPECT_RATIO;
3235382d832SPeter Avalos #ifdef HAVE_COLOR
3245382d832SPeter Avalos dialog_state.use_colors = USE_COLORS; /* use colors by default? */
3255382d832SPeter Avalos dialog_state.use_shadow = USE_SHADOW; /* shadow dialog boxes by default? */
3265382d832SPeter Avalos #endif
3275382d832SPeter Avalos
3285382d832SPeter Avalos #ifdef HAVE_RC_FILE
3295382d832SPeter Avalos if (dlg_parse_rc() == -1) /* Read the configuration file */
3305382d832SPeter Avalos dlg_exiterr("init_dialog: dlg_parse_rc");
3315382d832SPeter Avalos #endif
3325382d832SPeter Avalos
3335382d832SPeter Avalos /*
3345382d832SPeter Avalos * Some widgets (such as gauge) may read from the standard input. Pipes
3355382d832SPeter Avalos * only connect stdout/stdin, so there is not much choice. But reading a
3365382d832SPeter Avalos * pipe would get in the way of curses' normal reading stdin for getch.
3375382d832SPeter Avalos *
3385382d832SPeter Avalos * As in the --stdout (see below), reopening the terminal does not always
3395382d832SPeter Avalos * work properly. dialog provides a --pipe-fd option for this purpose. We
3405382d832SPeter Avalos * test that case first (differing fileno's for input/stdin). If the
3415382d832SPeter Avalos * fileno's are equal, but we're not reading from a tty, see if we can open
3425382d832SPeter Avalos * /dev/tty.
3435382d832SPeter Avalos */
3445382d832SPeter Avalos dialog_state.pipe_input = stdin;
3455382d832SPeter Avalos if (fileno(input) != fileno(stdin)) {
3465382d832SPeter Avalos if ((fd1 = dup(fileno(input))) >= 0
3475382d832SPeter Avalos && (fd2 = dup(fileno(stdin))) >= 0) {
3485382d832SPeter Avalos (void) dup2(fileno(input), fileno(stdin));
3495382d832SPeter Avalos dialog_state.pipe_input = fdopen(fd2, "r");
3505382d832SPeter Avalos if (fileno(stdin) != 0) /* some functions may read fd #0 */
3515382d832SPeter Avalos (void) dup2(fileno(stdin), 0);
3525382d832SPeter Avalos } else {
3535382d832SPeter Avalos dlg_exiterr("cannot open tty-input");
3545382d832SPeter Avalos }
3555382d832SPeter Avalos close(fd1);
3565382d832SPeter Avalos } else if (!isatty(fileno(stdin))) {
3575382d832SPeter Avalos if ((fd1 = open_terminal(&device, O_RDONLY)) >= 0) {
3585382d832SPeter Avalos if ((fd2 = dup(fileno(stdin))) >= 0) {
3595382d832SPeter Avalos dialog_state.pipe_input = fdopen(fd2, "r");
3605382d832SPeter Avalos if (freopen(device, "r", stdin) == 0)
3615382d832SPeter Avalos dlg_exiterr("cannot open tty-input");
3625382d832SPeter Avalos if (fileno(stdin) != 0) /* some functions may read fd #0 */
3635382d832SPeter Avalos (void) dup2(fileno(stdin), 0);
3645382d832SPeter Avalos }
3655382d832SPeter Avalos close(fd1);
3665382d832SPeter Avalos }
3675382d832SPeter Avalos free(device);
3685382d832SPeter Avalos }
3695382d832SPeter Avalos
3705382d832SPeter Avalos /*
3715382d832SPeter Avalos * If stdout is not a tty and dialog is called with the --stdout option, we
3725382d832SPeter Avalos * have to provide for a way to write to the screen.
3735382d832SPeter Avalos *
3745382d832SPeter Avalos * The curses library normally writes its output to stdout, leaving stderr
3755382d832SPeter Avalos * free for scripting. Scripts are simpler when stdout is redirected. The
3765382d832SPeter Avalos * newterm function is useful; it allows us to specify where the output
3775382d832SPeter Avalos * goes. Reopening the terminal is not portable since several
3785382d832SPeter Avalos * configurations do not allow this to work properly:
3795382d832SPeter Avalos *
3805382d832SPeter Avalos * a) some getty implementations (and possibly broken tty drivers, e.g., on
3815382d832SPeter Avalos * HPUX 10 and 11) cause stdin to act as if it is still in cooked mode
3825382d832SPeter Avalos * even though results from ioctl's state that it is successfully
3835382d832SPeter Avalos * altered to raw mode. Broken is the proper term.
3845382d832SPeter Avalos *
3855382d832SPeter Avalos * b) the user may not have permissions on the device, e.g., if one su's
3865382d832SPeter Avalos * from the login user to another non-privileged user.
3875382d832SPeter Avalos */
3885382d832SPeter Avalos if (!isatty(fileno(stdout))
3895382d832SPeter Avalos && (fileno(stdout) == fileno(output) || dialog_tty())) {
3905382d832SPeter Avalos if ((fd1 = open_terminal(&device, O_WRONLY)) >= 0
3915382d832SPeter Avalos && (dialog_state.screen_output = fdopen(fd1, "w")) != 0) {
3925382d832SPeter Avalos if (newterm(NULL, dialog_state.screen_output, stdin) == 0) {
3935382d832SPeter Avalos dlg_exiterr("cannot initialize curses");
3945382d832SPeter Avalos }
3955382d832SPeter Avalos free(device);
3965382d832SPeter Avalos } else {
3975382d832SPeter Avalos dlg_exiterr("cannot open tty-output");
3985382d832SPeter Avalos }
3995382d832SPeter Avalos } else {
4005382d832SPeter Avalos dialog_state.screen_output = stdout;
4015382d832SPeter Avalos (void) initscr();
4025382d832SPeter Avalos }
403*a8e38dc0SAntonio Huete Jimenez dlg_keep_tite(dialog_state.screen_output);
4045382d832SPeter Avalos #ifdef HAVE_FLUSHINP
4055382d832SPeter Avalos (void) flushinp();
4065382d832SPeter Avalos #endif
4075382d832SPeter Avalos (void) keypad(stdscr, TRUE);
4085382d832SPeter Avalos (void) cbreak();
4095382d832SPeter Avalos (void) noecho();
4105382d832SPeter Avalos
4115382d832SPeter Avalos if (!dialog_state.no_mouse) {
4125382d832SPeter Avalos mouse_open();
4135382d832SPeter Avalos }
4145382d832SPeter Avalos
4155382d832SPeter Avalos dialog_state.screen_initialized = TRUE;
4165382d832SPeter Avalos
4175382d832SPeter Avalos #ifdef HAVE_COLOR
4185382d832SPeter Avalos if (dialog_state.use_colors || dialog_state.use_shadow)
4195382d832SPeter Avalos dlg_color_setup(); /* Set up colors */
4205382d832SPeter Avalos #endif
4215382d832SPeter Avalos
4225382d832SPeter Avalos /* Set screen to screen attribute */
4235382d832SPeter Avalos dlg_clear();
4245382d832SPeter Avalos }
4255382d832SPeter Avalos
426*a8e38dc0SAntonio Huete Jimenez void
dlg_keep_tite(FILE * output)427*a8e38dc0SAntonio Huete Jimenez dlg_keep_tite(FILE *output)
428*a8e38dc0SAntonio Huete Jimenez {
429*a8e38dc0SAntonio Huete Jimenez if (!dialog_vars.keep_tite) {
430*a8e38dc0SAntonio Huete Jimenez #if CAN_KEEP_TITE
431*a8e38dc0SAntonio Huete Jimenez /*
432*a8e38dc0SAntonio Huete Jimenez * Cancel xterm's alternate-screen mode.
433*a8e38dc0SAntonio Huete Jimenez */
434*a8e38dc0SAntonio Huete Jimenez if ((fileno(output) != fileno(stdout)
435*a8e38dc0SAntonio Huete Jimenez || isatty(fileno(output)))
436*a8e38dc0SAntonio Huete Jimenez && key_mouse != 0 /* xterm and kindred */
437*a8e38dc0SAntonio Huete Jimenez && isprivate(enter_ca_mode)
438*a8e38dc0SAntonio Huete Jimenez && isprivate(exit_ca_mode)) {
439*a8e38dc0SAntonio Huete Jimenez FILE *save = dialog_state.screen_output;
440*a8e38dc0SAntonio Huete Jimenez
441*a8e38dc0SAntonio Huete Jimenez /*
442*a8e38dc0SAntonio Huete Jimenez * initscr() or newterm() already wrote enter_ca_mode as a side
443*a8e38dc0SAntonio Huete Jimenez * effect of initializing the screen. It would be nice to not even
444*a8e38dc0SAntonio Huete Jimenez * do that, but we do not really have access to the correct copy of
445*a8e38dc0SAntonio Huete Jimenez * the terminfo description until those functions have been
446*a8e38dc0SAntonio Huete Jimenez * invoked.
447*a8e38dc0SAntonio Huete Jimenez */
448*a8e38dc0SAntonio Huete Jimenez (void) refresh();
449*a8e38dc0SAntonio Huete Jimenez dialog_state.screen_output = output;
450*a8e38dc0SAntonio Huete Jimenez (void) tputs(exit_ca_mode, 0, my_putc);
451*a8e38dc0SAntonio Huete Jimenez (void) tputs(clear_screen, 0, my_putc);
452*a8e38dc0SAntonio Huete Jimenez dialog_state.screen_output = save;
453*a8e38dc0SAntonio Huete Jimenez
454*a8e38dc0SAntonio Huete Jimenez /*
455*a8e38dc0SAntonio Huete Jimenez * Prevent ncurses from switching "back" to the normal screen when
456*a8e38dc0SAntonio Huete Jimenez * exiting from dialog. That would move the cursor to the original
457*a8e38dc0SAntonio Huete Jimenez * location saved in xterm. Normally curses sets the cursor
458*a8e38dc0SAntonio Huete Jimenez * position to the first line after the display, but the alternate
459*a8e38dc0SAntonio Huete Jimenez * screen switching is done after that point.
460*a8e38dc0SAntonio Huete Jimenez *
461*a8e38dc0SAntonio Huete Jimenez * Cancelling the strings altogether also works around the buggy
462*a8e38dc0SAntonio Huete Jimenez * implementation of alternate-screen in rxvt, etc., which clear
463*a8e38dc0SAntonio Huete Jimenez * more of the display than they should.
464*a8e38dc0SAntonio Huete Jimenez */
465*a8e38dc0SAntonio Huete Jimenez enter_ca_mode = 0;
466*a8e38dc0SAntonio Huete Jimenez exit_ca_mode = 0;
467*a8e38dc0SAntonio Huete Jimenez }
468*a8e38dc0SAntonio Huete Jimenez #else
469*a8e38dc0SAntonio Huete Jimenez /*
470*a8e38dc0SAntonio Huete Jimenez * For other implementations, there are no useful answers:
471*a8e38dc0SAntonio Huete Jimenez * + SVr4 curses "could" support a similar approach, but the clue about
472*a8e38dc0SAntonio Huete Jimenez * xterm is absent from its terminal database.
473*a8e38dc0SAntonio Huete Jimenez * + PDCurses does not provide terminfo.
474*a8e38dc0SAntonio Huete Jimenez */
475*a8e38dc0SAntonio Huete Jimenez (void) output;
476*a8e38dc0SAntonio Huete Jimenez #endif
477*a8e38dc0SAntonio Huete Jimenez }
478*a8e38dc0SAntonio Huete Jimenez }
479*a8e38dc0SAntonio Huete Jimenez
4805382d832SPeter Avalos #ifdef HAVE_COLOR
4815382d832SPeter Avalos static int defined_colors = 1; /* pair-0 is reserved */
4825382d832SPeter Avalos /*
4835382d832SPeter Avalos * Setup for color display
4845382d832SPeter Avalos */
4855382d832SPeter Avalos void
dlg_color_setup(void)4865382d832SPeter Avalos dlg_color_setup(void)
4875382d832SPeter Avalos {
4885940c9abSDaniel Fojt if (has_colors()) { /* Terminal supports color? */
4895382d832SPeter Avalos unsigned i;
4905382d832SPeter Avalos
4915382d832SPeter Avalos (void) start_color();
4925382d832SPeter Avalos
4935382d832SPeter Avalos #if defined(HAVE_USE_DEFAULT_COLORS)
4945382d832SPeter Avalos use_default_colors();
4955382d832SPeter Avalos #endif
4965382d832SPeter Avalos
4975382d832SPeter Avalos #if defined(__NetBSD__) && defined(_CURSES_)
4985382d832SPeter Avalos #define C_ATTR(x,y) (((x) != 0 ? A_BOLD : 0) | COLOR_PAIR((y)))
4995382d832SPeter Avalos /* work around bug in NetBSD curses */
5005382d832SPeter Avalos for (i = 0; i < sizeof(dlg_color_table) /
5015382d832SPeter Avalos sizeof(dlg_color_table[0]); i++) {
5025382d832SPeter Avalos
5035382d832SPeter Avalos /* Initialize color pairs */
5045382d832SPeter Avalos (void) init_pair(i + 1,
5055382d832SPeter Avalos dlg_color_table[i].fg,
5065382d832SPeter Avalos dlg_color_table[i].bg);
5075382d832SPeter Avalos
5085382d832SPeter Avalos /* Setup color attributes */
5095382d832SPeter Avalos dlg_color_table[i].atr = C_ATTR(dlg_color_table[i].hilite, i + 1);
5105382d832SPeter Avalos }
5115382d832SPeter Avalos defined_colors = i + 1;
5125382d832SPeter Avalos #else
5135382d832SPeter Avalos for (i = 0; i < sizeof(dlg_color_table) /
5145382d832SPeter Avalos sizeof(dlg_color_table[0]); i++) {
5155382d832SPeter Avalos
5165382d832SPeter Avalos /* Initialize color pairs */
5175940c9abSDaniel Fojt chtype atr = dlg_color_pair(dlg_color_table[i].fg,
5185382d832SPeter Avalos dlg_color_table[i].bg);
5195382d832SPeter Avalos
5205940c9abSDaniel Fojt atr |= (dlg_color_table[i].hilite ? A_BOLD : 0);
5215940c9abSDaniel Fojt #ifdef HAVE_RC_FILE2
5225940c9abSDaniel Fojt atr |= (dlg_color_table[i].ul ? A_UNDERLINE : 0);
5235940c9abSDaniel Fojt atr |= (dlg_color_table[i].rv ? A_REVERSE : 0);
5245940c9abSDaniel Fojt #endif /* HAVE_RC_FILE2 */
5255940c9abSDaniel Fojt
5265940c9abSDaniel Fojt dlg_color_table[i].atr = atr;
5275382d832SPeter Avalos }
5285382d832SPeter Avalos #endif
5295382d832SPeter Avalos } else {
5305382d832SPeter Avalos dialog_state.use_colors = FALSE;
5315382d832SPeter Avalos dialog_state.use_shadow = FALSE;
5325382d832SPeter Avalos }
5335382d832SPeter Avalos }
5345382d832SPeter Avalos
5355382d832SPeter Avalos int
dlg_color_count(void)5365382d832SPeter Avalos dlg_color_count(void)
5375382d832SPeter Avalos {
5385940c9abSDaniel Fojt return TableSize(dlg_color_table);
5395382d832SPeter Avalos }
5405382d832SPeter Avalos
5415382d832SPeter Avalos /*
5425382d832SPeter Avalos * Wrapper for getattrs(), or the more cumbersome X/Open wattr_get().
5435382d832SPeter Avalos */
5445382d832SPeter Avalos chtype
dlg_get_attrs(WINDOW * win)5455382d832SPeter Avalos dlg_get_attrs(WINDOW *win)
5465382d832SPeter Avalos {
5475382d832SPeter Avalos chtype result;
5485382d832SPeter Avalos #ifdef HAVE_GETATTRS
5495382d832SPeter Avalos result = (chtype) getattrs(win);
5505382d832SPeter Avalos #else
5515382d832SPeter Avalos attr_t my_result;
5525382d832SPeter Avalos short my_pair;
5535382d832SPeter Avalos wattr_get(win, &my_result, &my_pair, NULL);
5545382d832SPeter Avalos result = my_result;
5555382d832SPeter Avalos #endif
5565382d832SPeter Avalos return result;
5575382d832SPeter Avalos }
5585382d832SPeter Avalos
5595382d832SPeter Avalos /*
5605382d832SPeter Avalos * Reuse color pairs (they are limited), returning a COLOR_PAIR() value if we
5615382d832SPeter Avalos * have (or can) define a pair with the given color as foreground on the
5625382d832SPeter Avalos * window's defined background.
5635382d832SPeter Avalos */
5645382d832SPeter Avalos chtype
dlg_color_pair(int foreground,int background)5655382d832SPeter Avalos dlg_color_pair(int foreground, int background)
5665382d832SPeter Avalos {
5675382d832SPeter Avalos chtype result = 0;
5685382d832SPeter Avalos int pair;
5695382d832SPeter Avalos short fg, bg;
5705382d832SPeter Avalos bool found = FALSE;
5715382d832SPeter Avalos
5725382d832SPeter Avalos for (pair = 1; pair < defined_colors; ++pair) {
5735382d832SPeter Avalos if (pair_content((short) pair, &fg, &bg) != ERR
5745382d832SPeter Avalos && fg == foreground
5755382d832SPeter Avalos && bg == background) {
5765382d832SPeter Avalos result = (chtype) COLOR_PAIR(pair);
5775382d832SPeter Avalos found = TRUE;
5785382d832SPeter Avalos break;
5795382d832SPeter Avalos }
5805382d832SPeter Avalos }
5815382d832SPeter Avalos if (!found && (defined_colors + 1) < COLOR_PAIRS) {
5825382d832SPeter Avalos pair = defined_colors++;
5835382d832SPeter Avalos (void) init_pair((short) pair, (short) foreground, (short) background);
5845382d832SPeter Avalos result = (chtype) COLOR_PAIR(pair);
5855382d832SPeter Avalos }
5865382d832SPeter Avalos return result;
5875382d832SPeter Avalos }
5885382d832SPeter Avalos
5895382d832SPeter Avalos /*
5905382d832SPeter Avalos * Reuse color pairs (they are limited), returning a COLOR_PAIR() value if we
5915382d832SPeter Avalos * have (or can) define a pair with the given color as foreground on the
5925382d832SPeter Avalos * window's defined background.
5935382d832SPeter Avalos */
5945382d832SPeter Avalos static chtype
define_color(WINDOW * win,int foreground)5955382d832SPeter Avalos define_color(WINDOW *win, int foreground)
5965382d832SPeter Avalos {
5975940c9abSDaniel Fojt short fg, bg, background;
5985940c9abSDaniel Fojt if (dialog_state.text_only) {
5995940c9abSDaniel Fojt background = COLOR_BLACK;
6005940c9abSDaniel Fojt } else {
6015382d832SPeter Avalos chtype attrs = dlg_get_attrs(win);
6025382d832SPeter Avalos int pair;
6035382d832SPeter Avalos
6045382d832SPeter Avalos if ((pair = PAIR_NUMBER(attrs)) != 0
6055382d832SPeter Avalos && pair_content((short) pair, &fg, &bg) != ERR) {
6065382d832SPeter Avalos background = bg;
6075382d832SPeter Avalos } else {
6085382d832SPeter Avalos background = COLOR_BLACK;
6095382d832SPeter Avalos }
6105940c9abSDaniel Fojt }
6115382d832SPeter Avalos return dlg_color_pair(foreground, background);
6125382d832SPeter Avalos }
6135382d832SPeter Avalos #endif
6145382d832SPeter Avalos
6155382d832SPeter Avalos /*
6165382d832SPeter Avalos * End using dialog functions.
6175382d832SPeter Avalos */
6185382d832SPeter Avalos void
end_dialog(void)6195382d832SPeter Avalos end_dialog(void)
6205382d832SPeter Avalos {
6215382d832SPeter Avalos if (dialog_state.screen_initialized) {
6225382d832SPeter Avalos dialog_state.screen_initialized = FALSE;
623*a8e38dc0SAntonio Huete Jimenez if (dialog_vars.erase_on_exit) {
624*a8e38dc0SAntonio Huete Jimenez /*
625*a8e38dc0SAntonio Huete Jimenez * Clear the screen to the native background color, and leave the
626*a8e38dc0SAntonio Huete Jimenez * terminal cursor at the lower-left corner of the screen.
627*a8e38dc0SAntonio Huete Jimenez */
628*a8e38dc0SAntonio Huete Jimenez werase(stdscr);
629*a8e38dc0SAntonio Huete Jimenez wrefresh(stdscr);
630*a8e38dc0SAntonio Huete Jimenez }
6315382d832SPeter Avalos mouse_close();
6325382d832SPeter Avalos (void) endwin();
6335382d832SPeter Avalos (void) fflush(stdout);
6345382d832SPeter Avalos }
6355382d832SPeter Avalos }
6365382d832SPeter Avalos
6375382d832SPeter Avalos #define ESCAPE_LEN 3
6385382d832SPeter Avalos #define isOurEscape(p) (((p)[0] == '\\') && ((p)[1] == 'Z') && ((p)[2] != 0))
6395382d832SPeter Avalos
6405382d832SPeter Avalos int
dlg_count_real_columns(const char * text)6415382d832SPeter Avalos dlg_count_real_columns(const char *text)
6425382d832SPeter Avalos {
6431ef6786aSJohn Marino int result = 0;
6441ef6786aSJohn Marino if (*text) {
6451ef6786aSJohn Marino result = dlg_count_columns(text);
6465382d832SPeter Avalos if (result && dialog_vars.colors) {
6475382d832SPeter Avalos int hidden = 0;
6485382d832SPeter Avalos while (*text) {
649*a8e38dc0SAntonio Huete Jimenez if (isOurEscape(text)) {
6505382d832SPeter Avalos hidden += ESCAPE_LEN;
6515382d832SPeter Avalos text += ESCAPE_LEN;
6525382d832SPeter Avalos } else {
6535382d832SPeter Avalos ++text;
6545382d832SPeter Avalos }
6555382d832SPeter Avalos }
6565382d832SPeter Avalos result -= hidden;
6575382d832SPeter Avalos }
6581ef6786aSJohn Marino }
6595382d832SPeter Avalos return result;
6605382d832SPeter Avalos }
6615382d832SPeter Avalos
6625382d832SPeter Avalos static int
centered(int width,const char * string)6635382d832SPeter Avalos centered(int width, const char *string)
6645382d832SPeter Avalos {
6655382d832SPeter Avalos int need = dlg_count_real_columns(string);
6665382d832SPeter Avalos int left;
6675382d832SPeter Avalos
6685382d832SPeter Avalos left = (width - need) / 2 - 1;
6695382d832SPeter Avalos if (left < 0)
6705382d832SPeter Avalos left = 0;
6715382d832SPeter Avalos return left;
6725382d832SPeter Avalos }
6735382d832SPeter Avalos
6745382d832SPeter Avalos #ifdef USE_WIDE_CURSES
6755382d832SPeter Avalos static bool
is_combining(const char * txt,int * combined)6765382d832SPeter Avalos is_combining(const char *txt, int *combined)
6775382d832SPeter Avalos {
6785382d832SPeter Avalos bool result = FALSE;
6795382d832SPeter Avalos
6805382d832SPeter Avalos if (*combined == 0) {
6815382d832SPeter Avalos if (UCH(*txt) >= 128) {
6825382d832SPeter Avalos wchar_t wch;
6835382d832SPeter Avalos mbstate_t state;
6845382d832SPeter Avalos size_t given = strlen(txt);
6855382d832SPeter Avalos size_t len;
6865382d832SPeter Avalos
6875382d832SPeter Avalos memset(&state, 0, sizeof(state));
6885382d832SPeter Avalos len = mbrtowc(&wch, txt, given, &state);
6895382d832SPeter Avalos if ((int) len > 0 && wcwidth(wch) == 0) {
6905382d832SPeter Avalos *combined = (int) len - 1;
6915382d832SPeter Avalos result = TRUE;
6925382d832SPeter Avalos }
6935382d832SPeter Avalos }
6945382d832SPeter Avalos } else {
6955382d832SPeter Avalos result = TRUE;
6965382d832SPeter Avalos *combined -= 1;
6975382d832SPeter Avalos }
6985382d832SPeter Avalos return result;
6995382d832SPeter Avalos }
7005382d832SPeter Avalos #endif
7015382d832SPeter Avalos
7025382d832SPeter Avalos /*
7035382d832SPeter Avalos * Print the name (tag) or text from a DIALOG_LISTITEM, highlighting the
7045382d832SPeter Avalos * first character if selected.
7055382d832SPeter Avalos */
7065382d832SPeter Avalos void
dlg_print_listitem(WINDOW * win,const char * text,int climit,bool first,int selected)7075382d832SPeter Avalos dlg_print_listitem(WINDOW *win,
7085382d832SPeter Avalos const char *text,
7095382d832SPeter Avalos int climit,
7105382d832SPeter Avalos bool first,
7115382d832SPeter Avalos int selected)
7125382d832SPeter Avalos {
7135382d832SPeter Avalos chtype attr = A_NORMAL;
7145382d832SPeter Avalos int limit;
7155382d832SPeter Avalos chtype attrs[4];
7165382d832SPeter Avalos
7171ef6786aSJohn Marino if (text == 0)
7181ef6786aSJohn Marino text = "";
7191ef6786aSJohn Marino
720*a8e38dc0SAntonio Huete Jimenez if (first && !dialog_vars.no_hot_list) {
7211ef6786aSJohn Marino const int *indx = dlg_index_wchars(text);
7225382d832SPeter Avalos attrs[3] = tag_key_selected_attr;
7235382d832SPeter Avalos attrs[2] = tag_key_attr;
7245382d832SPeter Avalos attrs[1] = tag_selected_attr;
7255382d832SPeter Avalos attrs[0] = tag_attr;
7265382d832SPeter Avalos
7275940c9abSDaniel Fojt dlg_attrset(win, selected ? attrs[3] : attrs[2]);
7285940c9abSDaniel Fojt if (*text != '\0') {
7295382d832SPeter Avalos (void) waddnstr(win, text, indx[1]);
7305382d832SPeter Avalos
7315382d832SPeter Avalos if ((int) strlen(text) > indx[1]) {
7325382d832SPeter Avalos limit = dlg_limit_columns(text, climit, 1);
7335382d832SPeter Avalos if (limit > 1) {
7345940c9abSDaniel Fojt dlg_attrset(win, selected ? attrs[1] : attrs[0]);
7355382d832SPeter Avalos (void) waddnstr(win,
7365382d832SPeter Avalos text + indx[1],
7375382d832SPeter Avalos indx[limit] - indx[1]);
7385382d832SPeter Avalos }
7395382d832SPeter Avalos }
7405940c9abSDaniel Fojt }
7415382d832SPeter Avalos } else {
7425940c9abSDaniel Fojt const int *cols;
7435940c9abSDaniel Fojt
7445382d832SPeter Avalos attrs[1] = item_selected_attr;
7455382d832SPeter Avalos attrs[0] = item_attr;
7465382d832SPeter Avalos
7475382d832SPeter Avalos cols = dlg_index_columns(text);
7485382d832SPeter Avalos limit = dlg_limit_columns(text, climit, 0);
7495382d832SPeter Avalos
7505382d832SPeter Avalos if (limit > 0) {
7515940c9abSDaniel Fojt dlg_attrset(win, selected ? attrs[1] : attrs[0]);
7525382d832SPeter Avalos dlg_print_text(win, text, cols[limit], &attr);
7535382d832SPeter Avalos }
7545382d832SPeter Avalos }
7555382d832SPeter Avalos }
7565382d832SPeter Avalos
7575382d832SPeter Avalos /*
7585382d832SPeter Avalos * Print up to 'cols' columns from 'text', optionally rendering our escape
7595382d832SPeter Avalos * sequence for attributes and color.
7605382d832SPeter Avalos */
7615382d832SPeter Avalos void
dlg_print_text(WINDOW * win,const char * txt,int cols,chtype * attr)7625382d832SPeter Avalos dlg_print_text(WINDOW *win, const char *txt, int cols, chtype *attr)
7635382d832SPeter Avalos {
7645382d832SPeter Avalos int y_origin, x_origin;
7655382d832SPeter Avalos int y_before, x_before = 0;
7665382d832SPeter Avalos int y_after, x_after;
7675382d832SPeter Avalos int tabbed = 0;
7685382d832SPeter Avalos bool ended = FALSE;
7695382d832SPeter Avalos #ifdef USE_WIDE_CURSES
7705382d832SPeter Avalos int combined = 0;
7715382d832SPeter Avalos #endif
7725382d832SPeter Avalos
7735940c9abSDaniel Fojt if (dialog_state.text_only) {
7745940c9abSDaniel Fojt y_origin = y_after = 0;
7755940c9abSDaniel Fojt x_origin = x_after = 0;
7765940c9abSDaniel Fojt } else {
7775940c9abSDaniel Fojt y_after = 0;
7785940c9abSDaniel Fojt x_after = 0;
7795382d832SPeter Avalos getyx(win, y_origin, x_origin);
7805940c9abSDaniel Fojt }
7815382d832SPeter Avalos while (cols > 0 && (*txt != '\0')) {
7825940c9abSDaniel Fojt bool thisTab;
7835940c9abSDaniel Fojt chtype useattr;
7845940c9abSDaniel Fojt
7855382d832SPeter Avalos if (dialog_vars.colors) {
7865382d832SPeter Avalos while (isOurEscape(txt)) {
7875382d832SPeter Avalos int code;
7885382d832SPeter Avalos
7895382d832SPeter Avalos txt += 2;
790*a8e38dc0SAntonio Huete Jimenez switch (code = UCH(*txt)) {
7915382d832SPeter Avalos #ifdef HAVE_COLOR
7925382d832SPeter Avalos case '0':
7935382d832SPeter Avalos case '1':
7945382d832SPeter Avalos case '2':
7955382d832SPeter Avalos case '3':
7965382d832SPeter Avalos case '4':
7975382d832SPeter Avalos case '5':
7985382d832SPeter Avalos case '6':
7995382d832SPeter Avalos case '7':
8005382d832SPeter Avalos *attr &= ~A_COLOR;
8015382d832SPeter Avalos *attr |= define_color(win, code - '0');
8025382d832SPeter Avalos break;
8035382d832SPeter Avalos #endif
8045382d832SPeter Avalos case 'B':
8055382d832SPeter Avalos *attr &= ~A_BOLD;
8065382d832SPeter Avalos break;
8075382d832SPeter Avalos case 'b':
8085382d832SPeter Avalos *attr |= A_BOLD;
8095382d832SPeter Avalos break;
8105382d832SPeter Avalos case 'R':
8115382d832SPeter Avalos *attr &= ~A_REVERSE;
8125382d832SPeter Avalos break;
8135382d832SPeter Avalos case 'r':
8145382d832SPeter Avalos *attr |= A_REVERSE;
8155382d832SPeter Avalos break;
8165382d832SPeter Avalos case 'U':
8175382d832SPeter Avalos *attr &= ~A_UNDERLINE;
8185382d832SPeter Avalos break;
8195382d832SPeter Avalos case 'u':
8205382d832SPeter Avalos *attr |= A_UNDERLINE;
8215382d832SPeter Avalos break;
8225382d832SPeter Avalos case 'n':
8235382d832SPeter Avalos *attr = A_NORMAL;
8245382d832SPeter Avalos break;
8255940c9abSDaniel Fojt default:
8265940c9abSDaniel Fojt break;
8275382d832SPeter Avalos }
8285382d832SPeter Avalos ++txt;
8295382d832SPeter Avalos }
8305382d832SPeter Avalos }
8315382d832SPeter Avalos if (ended || *txt == '\n' || *txt == '\0')
8325382d832SPeter Avalos break;
8335382d832SPeter Avalos useattr = (*attr) & A_ATTRIBUTES;
8345382d832SPeter Avalos #ifdef HAVE_COLOR
8355382d832SPeter Avalos /*
8365382d832SPeter Avalos * Prevent this from making text invisible when the foreground and
8375382d832SPeter Avalos * background colors happen to be the same, and there's no bold
8385382d832SPeter Avalos * attribute.
8395382d832SPeter Avalos */
8405382d832SPeter Avalos if ((useattr & A_COLOR) != 0 && (useattr & A_BOLD) == 0) {
8415382d832SPeter Avalos short pair = (short) PAIR_NUMBER(useattr);
8425382d832SPeter Avalos short fg, bg;
8435382d832SPeter Avalos if (pair_content(pair, &fg, &bg) != ERR
8445382d832SPeter Avalos && fg == bg) {
8455382d832SPeter Avalos useattr &= ~A_COLOR;
8465382d832SPeter Avalos useattr |= dlg_color_pair(fg, ((bg == COLOR_BLACK)
8475382d832SPeter Avalos ? COLOR_WHITE
8485382d832SPeter Avalos : COLOR_BLACK));
8495382d832SPeter Avalos }
8505382d832SPeter Avalos }
8515382d832SPeter Avalos #endif
8525382d832SPeter Avalos /*
8535382d832SPeter Avalos * Write the character, using curses to tell exactly how wide it
8545382d832SPeter Avalos * is. If it is a tab, discount that, since the caller thinks
8555382d832SPeter Avalos * tabs are nonprinting, and curses will expand tabs to one or
8565382d832SPeter Avalos * more blanks.
8575382d832SPeter Avalos */
858*a8e38dc0SAntonio Huete Jimenez thisTab = (UCH(*txt) == TAB);
8595940c9abSDaniel Fojt if (dialog_state.text_only) {
8605940c9abSDaniel Fojt x_before = x_after;
8615940c9abSDaniel Fojt } else {
8625382d832SPeter Avalos if (thisTab) {
8635382d832SPeter Avalos getyx(win, y_before, x_before);
8645382d832SPeter Avalos (void) y_before;
8655382d832SPeter Avalos }
8665940c9abSDaniel Fojt }
8675940c9abSDaniel Fojt if (dialog_state.text_only) {
868*a8e38dc0SAntonio Huete Jimenez int ch = UCH(*txt++);
8695940c9abSDaniel Fojt if (thisTab) {
8705940c9abSDaniel Fojt while ((x_after++) % 8) {
8715940c9abSDaniel Fojt fputc(' ', dialog_state.output);
8725940c9abSDaniel Fojt }
8735940c9abSDaniel Fojt } else {
8745940c9abSDaniel Fojt fputc(ch, dialog_state.output);
8755940c9abSDaniel Fojt x_after++; /* FIXME: handle meta per locale */
8765940c9abSDaniel Fojt }
8775940c9abSDaniel Fojt } else {
878*a8e38dc0SAntonio Huete Jimenez (void) waddch(win, UCH(*txt++) | useattr);
8795382d832SPeter Avalos getyx(win, y_after, x_after);
8805940c9abSDaniel Fojt }
8815382d832SPeter Avalos if (thisTab && (y_after == y_origin))
8825382d832SPeter Avalos tabbed += (x_after - x_before);
8835382d832SPeter Avalos if ((y_after != y_origin) ||
8845382d832SPeter Avalos (x_after >= (cols + tabbed + x_origin)
8855382d832SPeter Avalos #ifdef USE_WIDE_CURSES
8865382d832SPeter Avalos && !is_combining(txt, &combined)
8875382d832SPeter Avalos #endif
8885382d832SPeter Avalos )) {
8895382d832SPeter Avalos ended = TRUE;
8905382d832SPeter Avalos }
8915382d832SPeter Avalos }
8925940c9abSDaniel Fojt if (dialog_state.text_only) {
8935940c9abSDaniel Fojt fputc('\n', dialog_state.output);
8945940c9abSDaniel Fojt }
8955382d832SPeter Avalos }
8965382d832SPeter Avalos
8975382d832SPeter Avalos /*
8985382d832SPeter Avalos * Print one line of the prompt in the window within the limits of the
8995382d832SPeter Avalos * specified right margin. The line will end on a word boundary and a pointer
9005382d832SPeter Avalos * to the start of the next line is returned, or a NULL pointer if the end of
9015382d832SPeter Avalos * *prompt is reached.
9025382d832SPeter Avalos */
9035382d832SPeter Avalos const char *
dlg_print_line(WINDOW * win,chtype * attr,const char * prompt,int lm,int rm,int * x)9045382d832SPeter Avalos dlg_print_line(WINDOW *win,
9055382d832SPeter Avalos chtype *attr,
9065382d832SPeter Avalos const char *prompt,
9075382d832SPeter Avalos int lm, int rm, int *x)
9085382d832SPeter Avalos {
9095382d832SPeter Avalos const char *wrap_ptr;
9105382d832SPeter Avalos const char *test_ptr;
9115382d832SPeter Avalos const char *hide_ptr = 0;
9125382d832SPeter Avalos const int *cols = dlg_index_columns(prompt);
9135382d832SPeter Avalos const int *indx = dlg_index_wchars(prompt);
9145382d832SPeter Avalos int wrap_inx = 0;
9155382d832SPeter Avalos int test_inx = 0;
9165382d832SPeter Avalos int cur_x = lm;
9175382d832SPeter Avalos int hidden = 0;
9185382d832SPeter Avalos int limit = dlg_count_wchars(prompt);
9195382d832SPeter Avalos int n;
9205382d832SPeter Avalos int tabbed = 0;
9215382d832SPeter Avalos
9225382d832SPeter Avalos *x = 1;
9235382d832SPeter Avalos
9245382d832SPeter Avalos /*
9255382d832SPeter Avalos * Set *test_ptr to the end of the line or the right margin (rm), whichever
9265382d832SPeter Avalos * is less, and set wrap_ptr to the end of the last word in the line.
9275382d832SPeter Avalos */
9285382d832SPeter Avalos for (n = 0; n < limit; ++n) {
9295940c9abSDaniel Fojt int ch = *(test_ptr = prompt + indx[test_inx]);
9305940c9abSDaniel Fojt if (ch == '\n' || ch == '\0' || cur_x >= (rm + hidden))
9315382d832SPeter Avalos break;
9325940c9abSDaniel Fojt if (ch == TAB && n == 0) {
9335382d832SPeter Avalos tabbed = 8; /* workaround for leading tabs */
9345940c9abSDaniel Fojt } else if (isblank(UCH(ch))
9355940c9abSDaniel Fojt && n != 0
9365940c9abSDaniel Fojt && !isblank(UCH(prompt[indx[n - 1]]))) {
9375382d832SPeter Avalos wrap_inx = n;
9385382d832SPeter Avalos *x = cur_x;
9395382d832SPeter Avalos } else if (dialog_vars.colors && isOurEscape(test_ptr)) {
9405382d832SPeter Avalos hide_ptr = test_ptr;
9415382d832SPeter Avalos hidden += ESCAPE_LEN;
9425382d832SPeter Avalos n += (ESCAPE_LEN - 1);
9435382d832SPeter Avalos }
9445382d832SPeter Avalos cur_x = lm + tabbed + cols[n + 1];
9455382d832SPeter Avalos if (cur_x > (rm + hidden))
9465382d832SPeter Avalos break;
9475382d832SPeter Avalos test_inx = n + 1;
9485382d832SPeter Avalos }
9495382d832SPeter Avalos
9505382d832SPeter Avalos /*
9515382d832SPeter Avalos * If the line doesn't reach the right margin in the middle of a word, then
9525382d832SPeter Avalos * we don't have to wrap it at the end of the previous word.
9535382d832SPeter Avalos */
9545382d832SPeter Avalos test_ptr = prompt + indx[test_inx];
9555940c9abSDaniel Fojt if (*test_ptr == '\n' || isblank(UCH(*test_ptr)) || *test_ptr == '\0') {
9565382d832SPeter Avalos wrap_inx = test_inx;
9575940c9abSDaniel Fojt while (wrap_inx > 0 && isblank(UCH(prompt[indx[wrap_inx - 1]]))) {
9585382d832SPeter Avalos wrap_inx--;
9595382d832SPeter Avalos }
9605382d832SPeter Avalos *x = lm + indx[wrap_inx];
9615382d832SPeter Avalos } else if (*x == 1 && cur_x >= rm) {
9625382d832SPeter Avalos /*
9635382d832SPeter Avalos * If the line has no spaces, then wrap it anyway at the right margin
9645382d832SPeter Avalos */
9655382d832SPeter Avalos *x = rm;
9665382d832SPeter Avalos wrap_inx = test_inx;
9675382d832SPeter Avalos }
9685382d832SPeter Avalos wrap_ptr = prompt + indx[wrap_inx];
9695382d832SPeter Avalos #ifdef USE_WIDE_CURSES
9705382d832SPeter Avalos if (UCH(*wrap_ptr) >= 128) {
9715382d832SPeter Avalos int combined = 0;
9725382d832SPeter Avalos while (is_combining(wrap_ptr, &combined)) {
9735382d832SPeter Avalos ++wrap_ptr;
9745382d832SPeter Avalos }
9755382d832SPeter Avalos }
9765382d832SPeter Avalos #endif
9775382d832SPeter Avalos
9785382d832SPeter Avalos /*
9795382d832SPeter Avalos * If we found hidden text past the last point that we will display,
9805382d832SPeter Avalos * discount that from the displayed length.
9815382d832SPeter Avalos */
9825382d832SPeter Avalos if ((hide_ptr != 0) && (hide_ptr >= wrap_ptr)) {
9835382d832SPeter Avalos hidden -= ESCAPE_LEN;
9845382d832SPeter Avalos test_ptr = wrap_ptr;
9855382d832SPeter Avalos while (test_ptr < wrap_ptr) {
9865382d832SPeter Avalos if (dialog_vars.colors && isOurEscape(test_ptr)) {
9875382d832SPeter Avalos hidden -= ESCAPE_LEN;
9885382d832SPeter Avalos test_ptr += ESCAPE_LEN;
9895382d832SPeter Avalos } else {
9905382d832SPeter Avalos ++test_ptr;
9915382d832SPeter Avalos }
9925382d832SPeter Avalos }
9935382d832SPeter Avalos }
9945382d832SPeter Avalos
9955382d832SPeter Avalos /*
9965382d832SPeter Avalos * Print the line if we have a window pointer. Otherwise this routine
9975382d832SPeter Avalos * is just being called for sizing the window.
9985382d832SPeter Avalos */
9995940c9abSDaniel Fojt if (dialog_state.text_only || win) {
10005382d832SPeter Avalos dlg_print_text(win, prompt, (cols[wrap_inx] - hidden), attr);
10015382d832SPeter Avalos }
10025382d832SPeter Avalos
10035382d832SPeter Avalos /* *x tells the calling function how long the line was */
10045940c9abSDaniel Fojt if (*x == 1) {
10055382d832SPeter Avalos *x = rm;
10065940c9abSDaniel Fojt }
10075382d832SPeter Avalos
10085382d832SPeter Avalos *x -= hidden;
10095382d832SPeter Avalos
10105382d832SPeter Avalos /* Find the start of the next line and return a pointer to it */
10115382d832SPeter Avalos test_ptr = wrap_ptr;
10125940c9abSDaniel Fojt while (isblank(UCH(*test_ptr)))
10135382d832SPeter Avalos test_ptr++;
10145382d832SPeter Avalos if (*test_ptr == '\n')
10155382d832SPeter Avalos test_ptr++;
10161ef6786aSJohn Marino dlg_finish_string(prompt);
10175382d832SPeter Avalos return (test_ptr);
10185382d832SPeter Avalos }
10195382d832SPeter Avalos
10205382d832SPeter Avalos static void
justify_text(WINDOW * win,const char * prompt,int limit_y,int limit_x,int * high,int * wide)10215382d832SPeter Avalos justify_text(WINDOW *win,
10225382d832SPeter Avalos const char *prompt,
10235382d832SPeter Avalos int limit_y,
10245382d832SPeter Avalos int limit_x,
10255382d832SPeter Avalos int *high, int *wide)
10265382d832SPeter Avalos {
10275382d832SPeter Avalos chtype attr = A_NORMAL;
10285940c9abSDaniel Fojt int x;
10295382d832SPeter Avalos int y = MARGIN;
10305382d832SPeter Avalos int max_x = 2;
10315382d832SPeter Avalos int lm = (2 * MARGIN); /* left margin (box-border plus a space) */
10325382d832SPeter Avalos int rm = limit_x; /* right margin */
10335382d832SPeter Avalos int bm = limit_y; /* bottom margin */
10345382d832SPeter Avalos int last_y = 0, last_x = 0;
10355382d832SPeter Avalos
10365940c9abSDaniel Fojt dialog_state.text_height = 0;
10375940c9abSDaniel Fojt dialog_state.text_width = 0;
10385940c9abSDaniel Fojt if (dialog_state.text_only || win) {
10395382d832SPeter Avalos rm -= (2 * MARGIN);
10405382d832SPeter Avalos bm -= (2 * MARGIN);
10415382d832SPeter Avalos }
10425382d832SPeter Avalos if (prompt == 0)
10435382d832SPeter Avalos prompt = "";
10445382d832SPeter Avalos
10455382d832SPeter Avalos if (win != 0)
10465382d832SPeter Avalos getyx(win, last_y, last_x);
10475382d832SPeter Avalos while (y <= bm && *prompt) {
10485382d832SPeter Avalos x = lm;
10495382d832SPeter Avalos
10505382d832SPeter Avalos if (*prompt == '\n') {
10515382d832SPeter Avalos while (*prompt == '\n' && y < bm) {
10525382d832SPeter Avalos if (*(prompt + 1) != '\0') {
10535382d832SPeter Avalos ++y;
10545382d832SPeter Avalos if (win != 0)
10555382d832SPeter Avalos (void) wmove(win, y, lm);
10565382d832SPeter Avalos }
10575382d832SPeter Avalos prompt++;
10585382d832SPeter Avalos }
10595382d832SPeter Avalos } else if (win != 0)
10605382d832SPeter Avalos (void) wmove(win, y, lm);
10615382d832SPeter Avalos
10625382d832SPeter Avalos if (*prompt) {
10635382d832SPeter Avalos prompt = dlg_print_line(win, &attr, prompt, lm, rm, &x);
10645382d832SPeter Avalos if (win != 0)
10655382d832SPeter Avalos getyx(win, last_y, last_x);
10665382d832SPeter Avalos }
10675382d832SPeter Avalos if (*prompt) {
10685382d832SPeter Avalos ++y;
10695382d832SPeter Avalos if (win != 0)
10705382d832SPeter Avalos (void) wmove(win, y, lm);
10715382d832SPeter Avalos }
10725382d832SPeter Avalos max_x = MAX(max_x, x);
10735382d832SPeter Avalos }
10745382d832SPeter Avalos /* Move back to the last position after drawing prompt, for msgbox. */
10755382d832SPeter Avalos if (win != 0)
10765382d832SPeter Avalos (void) wmove(win, last_y, last_x);
10775382d832SPeter Avalos
10785382d832SPeter Avalos /* Set the final height and width for the calling function */
10795382d832SPeter Avalos if (high != 0)
10805382d832SPeter Avalos *high = y;
10815382d832SPeter Avalos if (wide != 0)
10825382d832SPeter Avalos *wide = max_x;
10835382d832SPeter Avalos }
10845382d832SPeter Avalos
10855382d832SPeter Avalos /*
10865382d832SPeter Avalos * Print a string of text in a window, automatically wrap around to the next
10875382d832SPeter Avalos * line if the string is too long to fit on one line. Note that the string may
10885382d832SPeter Avalos * contain embedded newlines.
10895382d832SPeter Avalos */
10905382d832SPeter Avalos void
dlg_print_autowrap(WINDOW * win,const char * prompt,int height,int width)10915382d832SPeter Avalos dlg_print_autowrap(WINDOW *win, const char *prompt, int height, int width)
10925382d832SPeter Avalos {
10935382d832SPeter Avalos justify_text(win, prompt,
10945382d832SPeter Avalos height,
10955382d832SPeter Avalos width,
10965382d832SPeter Avalos (int *) 0, (int *) 0);
10975382d832SPeter Avalos }
10985382d832SPeter Avalos
10995382d832SPeter Avalos /*
11005382d832SPeter Avalos * Display the message in a scrollable window. Actually the way it works is
11015382d832SPeter Avalos * that we create a "tall" window of the proper width, let the text wrap within
11025382d832SPeter Avalos * that, and copy a slice of the result to the dialog.
11035382d832SPeter Avalos *
11045382d832SPeter Avalos * It works for ncurses. Other curses implementations show only blanks (Tru64)
11055382d832SPeter Avalos * or garbage (NetBSD).
11065382d832SPeter Avalos */
11075382d832SPeter Avalos int
dlg_print_scrolled(WINDOW * win,const char * prompt,int offset,int height,int width,int pauseopt)11085382d832SPeter Avalos dlg_print_scrolled(WINDOW *win,
11095382d832SPeter Avalos const char *prompt,
11105382d832SPeter Avalos int offset,
11115382d832SPeter Avalos int height,
11125382d832SPeter Avalos int width,
11135382d832SPeter Avalos int pauseopt)
11145382d832SPeter Avalos {
11155382d832SPeter Avalos int oldy, oldx;
11165382d832SPeter Avalos int last = 0;
11175382d832SPeter Avalos
11185382d832SPeter Avalos (void) pauseopt; /* used only for ncurses */
11195382d832SPeter Avalos
11205382d832SPeter Avalos getyx(win, oldy, oldx);
11215382d832SPeter Avalos #ifdef NCURSES_VERSION
11225382d832SPeter Avalos if (pauseopt) {
11235382d832SPeter Avalos int wide = width - (2 * MARGIN);
11245382d832SPeter Avalos int high = LINES;
11255382d832SPeter Avalos int len;
11265382d832SPeter Avalos WINDOW *dummy;
11275382d832SPeter Avalos
11285382d832SPeter Avalos #if defined(NCURSES_VERSION_PATCH) && NCURSES_VERSION_PATCH >= 20040417
11295382d832SPeter Avalos /*
11305382d832SPeter Avalos * If we're not limited by the screensize, allow text to possibly be
11315382d832SPeter Avalos * one character per line.
11325382d832SPeter Avalos */
11335382d832SPeter Avalos if ((len = dlg_count_columns(prompt)) > high)
11345382d832SPeter Avalos high = len;
11355382d832SPeter Avalos #endif
11365382d832SPeter Avalos dummy = newwin(high, width, 0, 0);
11375382d832SPeter Avalos if (dummy == 0) {
11385940c9abSDaniel Fojt dlg_attrset(win, dialog_attr);
11395382d832SPeter Avalos dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width);
11405382d832SPeter Avalos last = 0;
11415382d832SPeter Avalos } else {
11425940c9abSDaniel Fojt int y, x;
11435940c9abSDaniel Fojt
11445382d832SPeter Avalos wbkgdset(dummy, dialog_attr | ' ');
11455940c9abSDaniel Fojt dlg_attrset(dummy, dialog_attr);
11465382d832SPeter Avalos werase(dummy);
11475382d832SPeter Avalos dlg_print_autowrap(dummy, prompt, high, width);
11485382d832SPeter Avalos getyx(dummy, y, x);
11495382d832SPeter Avalos (void) x;
11505382d832SPeter Avalos
11515382d832SPeter Avalos copywin(dummy, /* srcwin */
11525382d832SPeter Avalos win, /* dstwin */
11535382d832SPeter Avalos offset + MARGIN, /* sminrow */
11545382d832SPeter Avalos MARGIN, /* smincol */
11555382d832SPeter Avalos MARGIN, /* dminrow */
11565382d832SPeter Avalos MARGIN, /* dmincol */
11575382d832SPeter Avalos height, /* dmaxrow */
11585382d832SPeter Avalos wide, /* dmaxcol */
11595382d832SPeter Avalos FALSE);
11605382d832SPeter Avalos
11615382d832SPeter Avalos delwin(dummy);
11625382d832SPeter Avalos
11635382d832SPeter Avalos /* if the text is incomplete, or we have scrolled, show the percentage */
11645382d832SPeter Avalos if (y > 0 && wide > 4) {
11655940c9abSDaniel Fojt int percent = (int) ((height + offset) * 100.0 / y);
11665940c9abSDaniel Fojt
11675382d832SPeter Avalos if (percent < 0)
11685382d832SPeter Avalos percent = 0;
11695382d832SPeter Avalos if (percent > 100)
11705382d832SPeter Avalos percent = 100;
11715940c9abSDaniel Fojt
11725382d832SPeter Avalos if (offset != 0 || percent != 100) {
11735940c9abSDaniel Fojt char buffer[5];
11745940c9abSDaniel Fojt
11755940c9abSDaniel Fojt dlg_attrset(win, position_indicator_attr);
11765382d832SPeter Avalos (void) wmove(win, MARGIN + height, wide - 4);
11775382d832SPeter Avalos (void) sprintf(buffer, "%d%%", percent);
11785382d832SPeter Avalos (void) waddstr(win, buffer);
11795382d832SPeter Avalos if ((len = (int) strlen(buffer)) < 4) {
11805940c9abSDaniel Fojt dlg_attrset(win, border_attr);
11815382d832SPeter Avalos whline(win, dlg_boxchar(ACS_HLINE), 4 - len);
11825382d832SPeter Avalos }
11835382d832SPeter Avalos }
11845382d832SPeter Avalos }
11855382d832SPeter Avalos last = (y - height);
11865382d832SPeter Avalos }
11875382d832SPeter Avalos } else
11885382d832SPeter Avalos #endif
11895382d832SPeter Avalos {
11905382d832SPeter Avalos (void) offset;
11915940c9abSDaniel Fojt dlg_attrset(win, dialog_attr);
11925382d832SPeter Avalos dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width);
11935382d832SPeter Avalos last = 0;
11945382d832SPeter Avalos }
11955382d832SPeter Avalos wmove(win, oldy, oldx);
11965382d832SPeter Avalos return last;
11975382d832SPeter Avalos }
11985382d832SPeter Avalos
11995382d832SPeter Avalos int
dlg_check_scrolled(int key,int last,int page,bool * show,int * offset)12005382d832SPeter Avalos dlg_check_scrolled(int key, int last, int page, bool * show, int *offset)
12015382d832SPeter Avalos {
12025382d832SPeter Avalos int code = 0;
12035382d832SPeter Avalos
12045382d832SPeter Avalos *show = FALSE;
12055382d832SPeter Avalos
12065382d832SPeter Avalos switch (key) {
12075382d832SPeter Avalos case DLGK_PAGE_FIRST:
12085382d832SPeter Avalos if (*offset > 0) {
12095382d832SPeter Avalos *offset = 0;
12105382d832SPeter Avalos *show = TRUE;
12115382d832SPeter Avalos }
12125382d832SPeter Avalos break;
12135382d832SPeter Avalos case DLGK_PAGE_LAST:
12145382d832SPeter Avalos if (*offset < last) {
12155382d832SPeter Avalos *offset = last;
12165382d832SPeter Avalos *show = TRUE;
12175382d832SPeter Avalos }
12185382d832SPeter Avalos break;
12195382d832SPeter Avalos case DLGK_GRID_UP:
12205382d832SPeter Avalos if (*offset > 0) {
12215382d832SPeter Avalos --(*offset);
12225382d832SPeter Avalos *show = TRUE;
12235382d832SPeter Avalos }
12245382d832SPeter Avalos break;
12255382d832SPeter Avalos case DLGK_GRID_DOWN:
12265382d832SPeter Avalos if (*offset < last) {
12275382d832SPeter Avalos ++(*offset);
12285382d832SPeter Avalos *show = TRUE;
12295382d832SPeter Avalos }
12305382d832SPeter Avalos break;
12315382d832SPeter Avalos case DLGK_PAGE_PREV:
12325382d832SPeter Avalos if (*offset > 0) {
12335382d832SPeter Avalos *offset -= page;
12345382d832SPeter Avalos if (*offset < 0)
12355382d832SPeter Avalos *offset = 0;
12365382d832SPeter Avalos *show = TRUE;
12375382d832SPeter Avalos }
12385382d832SPeter Avalos break;
12395382d832SPeter Avalos case DLGK_PAGE_NEXT:
12405382d832SPeter Avalos if (*offset < last) {
12415382d832SPeter Avalos *offset += page;
12425382d832SPeter Avalos if (*offset > last)
12435382d832SPeter Avalos *offset = last;
12445382d832SPeter Avalos *show = TRUE;
12455382d832SPeter Avalos }
12465382d832SPeter Avalos break;
12475382d832SPeter Avalos default:
12485382d832SPeter Avalos code = -1;
12495382d832SPeter Avalos break;
12505382d832SPeter Avalos }
12515382d832SPeter Avalos return code;
12525382d832SPeter Avalos }
12535382d832SPeter Avalos
12545382d832SPeter Avalos /*
12555382d832SPeter Avalos * Calculate the window size for preformatted text. This will calculate box
12565382d832SPeter Avalos * dimensions that are at or close to the specified aspect ratio for the prompt
12575382d832SPeter Avalos * string with all spaces and newlines preserved and additional newlines added
12585382d832SPeter Avalos * as necessary.
12595382d832SPeter Avalos */
12605382d832SPeter Avalos static void
auto_size_preformatted(const char * prompt,int * height,int * width)12615382d832SPeter Avalos auto_size_preformatted(const char *prompt, int *height, int *width)
12625382d832SPeter Avalos {
12635382d832SPeter Avalos int high = 0, wide = 0;
12645382d832SPeter Avalos float car; /* Calculated Aspect Ratio */
12655382d832SPeter Avalos int max_y = SLINES - 1;
12665382d832SPeter Avalos int max_x = SCOLS - 2;
12675382d832SPeter Avalos int max_width = max_x;
12685382d832SPeter Avalos int ar = dialog_state.aspect_ratio;
12695382d832SPeter Avalos
12705382d832SPeter Avalos /* Get the initial dimensions */
12715382d832SPeter Avalos justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide);
12725382d832SPeter Avalos car = (float) (wide / high);
12735382d832SPeter Avalos
12745382d832SPeter Avalos /*
12755382d832SPeter Avalos * If the aspect ratio is greater than it should be, then decrease the
12765382d832SPeter Avalos * width proportionately.
12775382d832SPeter Avalos */
12785382d832SPeter Avalos if (car > ar) {
12795940c9abSDaniel Fojt float diff = car / (float) ar;
12805382d832SPeter Avalos max_x = (int) ((float) wide / diff + 4);
12815382d832SPeter Avalos justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide);
12825382d832SPeter Avalos car = (float) wide / (float) high;
12835382d832SPeter Avalos }
12845382d832SPeter Avalos
12855382d832SPeter Avalos /*
12865382d832SPeter Avalos * If the aspect ratio is too small after decreasing the width, then
12875382d832SPeter Avalos * incrementally increase the width until the aspect ratio is equal to or
12885382d832SPeter Avalos * greater than the specified aspect ratio.
12895382d832SPeter Avalos */
12905382d832SPeter Avalos while (car < ar && max_x < max_width) {
12915382d832SPeter Avalos max_x += 4;
12925382d832SPeter Avalos justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide);
12935382d832SPeter Avalos car = (float) (wide / high);
12945382d832SPeter Avalos }
12955382d832SPeter Avalos
12965382d832SPeter Avalos *height = high;
12975382d832SPeter Avalos *width = wide;
12985382d832SPeter Avalos }
12995382d832SPeter Avalos
13005382d832SPeter Avalos /*
13015382d832SPeter Avalos * Find the length of the longest "word" in the given string. By setting the
13025382d832SPeter Avalos * widget width at least this long, we can avoid splitting a word on the
13035382d832SPeter Avalos * margin.
13045382d832SPeter Avalos */
13055382d832SPeter Avalos static int
longest_word(const char * string)13065382d832SPeter Avalos longest_word(const char *string)
13075382d832SPeter Avalos {
13085940c9abSDaniel Fojt int result = 0;
13095382d832SPeter Avalos
13105382d832SPeter Avalos while (*string != '\0') {
13115940c9abSDaniel Fojt int length = 0;
13125382d832SPeter Avalos while (*string != '\0' && !isspace(UCH(*string))) {
13135382d832SPeter Avalos length++;
13145382d832SPeter Avalos string++;
13155382d832SPeter Avalos }
13165382d832SPeter Avalos result = MAX(result, length);
13175382d832SPeter Avalos if (*string != '\0')
13185382d832SPeter Avalos string++;
13195382d832SPeter Avalos }
13205382d832SPeter Avalos return result;
13215382d832SPeter Avalos }
13225382d832SPeter Avalos
13235382d832SPeter Avalos /*
13245382d832SPeter Avalos * if (height or width == -1) Maximize()
13255382d832SPeter Avalos * if (height or width == 0), justify and return actual limits.
13265382d832SPeter Avalos */
13275382d832SPeter Avalos static void
real_auto_size(const char * title,const char * prompt,int * height,int * width,int boxlines,int mincols)13285382d832SPeter Avalos real_auto_size(const char *title,
13295382d832SPeter Avalos const char *prompt,
13305382d832SPeter Avalos int *height, int *width,
13315382d832SPeter Avalos int boxlines, int mincols)
13325382d832SPeter Avalos {
13335382d832SPeter Avalos int x = (dialog_vars.begin_set ? dialog_vars.begin_x : 2);
13345382d832SPeter Avalos int y = (dialog_vars.begin_set ? dialog_vars.begin_y : 1);
13355382d832SPeter Avalos int title_length = title ? dlg_count_columns(title) : 0;
13365382d832SPeter Avalos int high;
13375382d832SPeter Avalos int save_high = *height;
13385382d832SPeter Avalos int save_wide = *width;
13395940c9abSDaniel Fojt int max_high;
13405940c9abSDaniel Fojt int max_wide;
13415382d832SPeter Avalos
13425382d832SPeter Avalos if (prompt == 0) {
13435382d832SPeter Avalos if (*height == 0)
13445382d832SPeter Avalos *height = -1;
13455382d832SPeter Avalos if (*width == 0)
13465382d832SPeter Avalos *width = -1;
13475382d832SPeter Avalos }
13485382d832SPeter Avalos
13495940c9abSDaniel Fojt max_high = (*height < 0);
13505940c9abSDaniel Fojt max_wide = (*width < 0);
13515940c9abSDaniel Fojt
13525382d832SPeter Avalos if (*height > 0) {
13535382d832SPeter Avalos high = *height;
13545382d832SPeter Avalos } else {
13555382d832SPeter Avalos high = SLINES - y;
13565382d832SPeter Avalos }
13575382d832SPeter Avalos
13585382d832SPeter Avalos if (*width <= 0) {
13595940c9abSDaniel Fojt int wide;
13605940c9abSDaniel Fojt
13615382d832SPeter Avalos if (prompt != 0) {
13625382d832SPeter Avalos wide = MAX(title_length, mincols);
13635382d832SPeter Avalos if (strchr(prompt, '\n') == 0) {
13645382d832SPeter Avalos double val = (dialog_state.aspect_ratio *
13655382d832SPeter Avalos dlg_count_real_columns(prompt));
13665382d832SPeter Avalos double xxx = sqrt(val);
13675382d832SPeter Avalos int tmp = (int) xxx;
13685382d832SPeter Avalos wide = MAX(wide, tmp);
13695382d832SPeter Avalos wide = MAX(wide, longest_word(prompt));
13705382d832SPeter Avalos justify_text((WINDOW *) 0, prompt, high, wide, height, width);
13715382d832SPeter Avalos } else {
13725382d832SPeter Avalos auto_size_preformatted(prompt, height, width);
13735382d832SPeter Avalos }
13745382d832SPeter Avalos } else {
13755382d832SPeter Avalos wide = SCOLS - x;
13765382d832SPeter Avalos justify_text((WINDOW *) 0, prompt, high, wide, height, width);
13775382d832SPeter Avalos }
13785382d832SPeter Avalos }
13795382d832SPeter Avalos
13805382d832SPeter Avalos if (*width < title_length) {
13815382d832SPeter Avalos justify_text((WINDOW *) 0, prompt, high, title_length, height, width);
13825382d832SPeter Avalos *width = title_length;
13835382d832SPeter Avalos }
13845382d832SPeter Avalos
13855940c9abSDaniel Fojt dialog_state.text_height = *height;
13865940c9abSDaniel Fojt dialog_state.text_width = *width;
13875940c9abSDaniel Fojt
13885382d832SPeter Avalos if (*width < mincols && save_wide == 0)
13895382d832SPeter Avalos *width = mincols;
13905382d832SPeter Avalos if (prompt != 0) {
13915940c9abSDaniel Fojt *width += ((2 * MARGIN) + SHADOW_COLS);
13925940c9abSDaniel Fojt *height += boxlines + (2 * MARGIN);
13935382d832SPeter Avalos }
13945940c9abSDaniel Fojt
13955382d832SPeter Avalos if (save_high > 0)
13965382d832SPeter Avalos *height = save_high;
13975382d832SPeter Avalos if (save_wide > 0)
13985382d832SPeter Avalos *width = save_wide;
13995940c9abSDaniel Fojt
14005940c9abSDaniel Fojt if (max_high)
14015940c9abSDaniel Fojt *height = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0);
14025940c9abSDaniel Fojt if (max_wide)
14035940c9abSDaniel Fojt *width = SCOLS - (dialog_vars.begin_set ? dialog_vars.begin_x : 0);
14045382d832SPeter Avalos }
14055382d832SPeter Avalos
14065382d832SPeter Avalos /* End of real_auto_size() */
14075382d832SPeter Avalos
14085382d832SPeter Avalos void
dlg_auto_size(const char * title,const char * prompt,int * height,int * width,int boxlines,int mincols)14095382d832SPeter Avalos dlg_auto_size(const char *title,
14105382d832SPeter Avalos const char *prompt,
14115382d832SPeter Avalos int *height,
14125382d832SPeter Avalos int *width,
14135382d832SPeter Avalos int boxlines,
14145382d832SPeter Avalos int mincols)
14155382d832SPeter Avalos {
14165940c9abSDaniel Fojt DLG_TRACE(("# dlg_auto_size(%d,%d) limits %d,%d\n",
14175940c9abSDaniel Fojt *height, *width,
14185940c9abSDaniel Fojt boxlines, mincols));
14195940c9abSDaniel Fojt
14205382d832SPeter Avalos real_auto_size(title, prompt, height, width, boxlines, mincols);
14215382d832SPeter Avalos
14225382d832SPeter Avalos if (*width > SCOLS) {
14235382d832SPeter Avalos (*height)++;
14245382d832SPeter Avalos *width = SCOLS;
14255382d832SPeter Avalos }
14265382d832SPeter Avalos
14275940c9abSDaniel Fojt if (*height > SLINES) {
14285382d832SPeter Avalos *height = SLINES;
14295382d832SPeter Avalos }
14305940c9abSDaniel Fojt DLG_TRACE(("# ...dlg_auto_size(%d,%d) also %d,%d\n",
14315940c9abSDaniel Fojt *height, *width,
14325940c9abSDaniel Fojt dialog_state.text_height, dialog_state.text_width));
14335940c9abSDaniel Fojt }
14345382d832SPeter Avalos
14355382d832SPeter Avalos /*
14365382d832SPeter Avalos * if (height or width == -1) Maximize()
14375382d832SPeter Avalos * if (height or width == 0)
14385382d832SPeter Avalos * height=MIN(SLINES, num.lines in fd+n);
14395382d832SPeter Avalos * width=MIN(SCOLS, MAX(longer line+n, mincols));
14405382d832SPeter Avalos */
14415382d832SPeter Avalos void
dlg_auto_sizefile(const char * title,const char * file,int * height,int * width,int boxlines,int mincols)14425382d832SPeter Avalos dlg_auto_sizefile(const char *title,
14435382d832SPeter Avalos const char *file,
14445382d832SPeter Avalos int *height,
14455382d832SPeter Avalos int *width,
14465382d832SPeter Avalos int boxlines,
14475382d832SPeter Avalos int mincols)
14485382d832SPeter Avalos {
14495382d832SPeter Avalos int count = 0;
14505382d832SPeter Avalos int len = title ? dlg_count_columns(title) : 0;
14515382d832SPeter Avalos int nc = 4;
14525382d832SPeter Avalos int numlines = 2;
14535382d832SPeter Avalos FILE *fd;
14545382d832SPeter Avalos
14555382d832SPeter Avalos /* Open input file for reading */
14565382d832SPeter Avalos if ((fd = fopen(file, "rb")) == NULL)
14575382d832SPeter Avalos dlg_exiterr("dlg_auto_sizefile: Cannot open input file %s", file);
14585382d832SPeter Avalos
14595382d832SPeter Avalos if ((*height == -1) || (*width == -1)) {
14605382d832SPeter Avalos *height = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0);
14615382d832SPeter Avalos *width = SCOLS - (dialog_vars.begin_set ? dialog_vars.begin_x : 0);
14625382d832SPeter Avalos }
14635382d832SPeter Avalos if ((*height != 0) && (*width != 0)) {
14645382d832SPeter Avalos (void) fclose(fd);
14655382d832SPeter Avalos if (*width > SCOLS)
14665382d832SPeter Avalos *width = SCOLS;
14675382d832SPeter Avalos if (*height > SLINES)
14685382d832SPeter Avalos *height = SLINES;
14695382d832SPeter Avalos return;
14705382d832SPeter Avalos }
14715382d832SPeter Avalos
14725382d832SPeter Avalos while (!feof(fd)) {
14735940c9abSDaniel Fojt int ch;
14745940c9abSDaniel Fojt long offset;
14755940c9abSDaniel Fojt
14765940c9abSDaniel Fojt if (ferror(fd))
14775940c9abSDaniel Fojt break;
14785940c9abSDaniel Fojt
14795382d832SPeter Avalos offset = 0;
14805940c9abSDaniel Fojt while (((ch = getc(fd)) != '\n') && !feof(fd)) {
14815940c9abSDaniel Fojt if ((ch == TAB) && (dialog_vars.tab_correct)) {
14825382d832SPeter Avalos offset += dialog_state.tab_len - (offset % dialog_state.tab_len);
14835940c9abSDaniel Fojt } else {
14845382d832SPeter Avalos offset++;
14855940c9abSDaniel Fojt }
14865940c9abSDaniel Fojt }
14875382d832SPeter Avalos
14885382d832SPeter Avalos if (offset > len)
14895382d832SPeter Avalos len = (int) offset;
14905382d832SPeter Avalos
14915382d832SPeter Avalos count++;
14925382d832SPeter Avalos }
14935382d832SPeter Avalos
14945382d832SPeter Avalos /* now 'count' has the number of lines of fd and 'len' the max length */
14955382d832SPeter Avalos
14965382d832SPeter Avalos *height = MIN(SLINES, count + numlines + boxlines);
14975382d832SPeter Avalos *width = MIN(SCOLS, MAX((len + nc), mincols));
14985382d832SPeter Avalos /* here width and height can be maximized if > SCOLS|SLINES because
14995382d832SPeter Avalos textbox-like widgets don't put all <file> on the screen.
15005382d832SPeter Avalos Msgbox-like widget instead have to put all <text> correctly. */
15015382d832SPeter Avalos
15025382d832SPeter Avalos (void) fclose(fd);
15035382d832SPeter Avalos }
15045382d832SPeter Avalos
15055382d832SPeter Avalos /*
15065382d832SPeter Avalos * Draw a rectangular box with line drawing characters.
15075382d832SPeter Avalos *
15085382d832SPeter Avalos * borderchar is used to color the upper/left edges.
15095382d832SPeter Avalos *
15105382d832SPeter Avalos * boxchar is used to color the right/lower edges. It also is fill-color used
15115382d832SPeter Avalos * for the box contents.
15125382d832SPeter Avalos *
15135382d832SPeter Avalos * Normally, if you are drawing a scrollable box, use menubox_border_attr for
15145382d832SPeter Avalos * boxchar, and menubox_attr for borderchar since the scroll-arrows are drawn
15155382d832SPeter Avalos * with menubox_attr at the top, and menubox_border_attr at the bottom. That
15165382d832SPeter Avalos * also (given the default color choices) produces a recessed effect.
15175382d832SPeter Avalos *
15185382d832SPeter Avalos * If you want a raised effect (and are not going to use the scroll-arrows),
15195382d832SPeter Avalos * reverse this choice.
15205382d832SPeter Avalos */
15215382d832SPeter Avalos void
dlg_draw_box2(WINDOW * win,int y,int x,int height,int width,chtype boxchar,chtype borderchar,chtype borderchar2)15225382d832SPeter Avalos dlg_draw_box2(WINDOW *win, int y, int x, int height, int width,
15235382d832SPeter Avalos chtype boxchar, chtype borderchar, chtype borderchar2)
15245382d832SPeter Avalos {
15255382d832SPeter Avalos int i, j;
15265382d832SPeter Avalos chtype save = dlg_get_attrs(win);
15275382d832SPeter Avalos
15285940c9abSDaniel Fojt dlg_attrset(win, 0);
15295382d832SPeter Avalos for (i = 0; i < height; i++) {
15305382d832SPeter Avalos (void) wmove(win, y + i, x);
15315382d832SPeter Avalos for (j = 0; j < width; j++)
15325382d832SPeter Avalos if (!i && !j)
15335382d832SPeter Avalos (void) waddch(win, borderchar | dlg_boxchar(ACS_ULCORNER));
15345382d832SPeter Avalos else if (i == height - 1 && !j)
15355382d832SPeter Avalos (void) waddch(win, borderchar | dlg_boxchar(ACS_LLCORNER));
15365382d832SPeter Avalos else if (!i && j == width - 1)
15375382d832SPeter Avalos (void) waddch(win, borderchar2 | dlg_boxchar(ACS_URCORNER));
15385382d832SPeter Avalos else if (i == height - 1 && j == width - 1)
15395382d832SPeter Avalos (void) waddch(win, borderchar2 | dlg_boxchar(ACS_LRCORNER));
15405382d832SPeter Avalos else if (!i)
15415382d832SPeter Avalos (void) waddch(win, borderchar | dlg_boxchar(ACS_HLINE));
15425382d832SPeter Avalos else if (i == height - 1)
15435382d832SPeter Avalos (void) waddch(win, borderchar2 | dlg_boxchar(ACS_HLINE));
15445382d832SPeter Avalos else if (!j)
15455382d832SPeter Avalos (void) waddch(win, borderchar | dlg_boxchar(ACS_VLINE));
15465382d832SPeter Avalos else if (j == width - 1)
15475382d832SPeter Avalos (void) waddch(win, borderchar2 | dlg_boxchar(ACS_VLINE));
15485382d832SPeter Avalos else
15495382d832SPeter Avalos (void) waddch(win, boxchar | ' ');
15505382d832SPeter Avalos }
15515940c9abSDaniel Fojt dlg_attrset(win, save);
15525382d832SPeter Avalos }
15535382d832SPeter Avalos
15545382d832SPeter Avalos void
dlg_draw_box(WINDOW * win,int y,int x,int height,int width,chtype boxchar,chtype borderchar)15555382d832SPeter Avalos dlg_draw_box(WINDOW *win, int y, int x, int height, int width,
15565382d832SPeter Avalos chtype boxchar, chtype borderchar)
15575382d832SPeter Avalos {
15585382d832SPeter Avalos dlg_draw_box2(win, y, x, height, width, boxchar, borderchar, boxchar);
15595382d832SPeter Avalos }
15605382d832SPeter Avalos
1561*a8e38dc0SAntonio Huete Jimenez /*
1562*a8e38dc0SAntonio Huete Jimenez * Search the given 'list' for the given window 'win'. Typically 'win' is an
1563*a8e38dc0SAntonio Huete Jimenez * input-window, i.e., a window where we might use wgetch.
1564*a8e38dc0SAntonio Huete Jimenez *
1565*a8e38dc0SAntonio Huete Jimenez * The all-windows list has normal- and shadow-windows. Since we never use the
1566*a8e38dc0SAntonio Huete Jimenez * shadow as an input window, normally we just look for the normal-window.
1567*a8e38dc0SAntonio Huete Jimenez *
1568*a8e38dc0SAntonio Huete Jimenez * However, the all-subwindows list stores parent/child windows rather than
1569*a8e38dc0SAntonio Huete Jimenez * normal/shadow windows. When searching that list, we look for the child
1570*a8e38dc0SAntonio Huete Jimenez * window (in the .shadow field).
1571*a8e38dc0SAntonio Huete Jimenez */
15725382d832SPeter Avalos static DIALOG_WINDOWS *
find_window(DIALOG_WINDOWS * list,WINDOW * win,bool normal)1573*a8e38dc0SAntonio Huete Jimenez find_window(DIALOG_WINDOWS * list, WINDOW *win, bool normal)
15745382d832SPeter Avalos {
15755382d832SPeter Avalos DIALOG_WINDOWS *result = 0;
15765382d832SPeter Avalos DIALOG_WINDOWS *p;
15775382d832SPeter Avalos
1578*a8e38dc0SAntonio Huete Jimenez for (p = list; p != 0; p = p->next) {
1579*a8e38dc0SAntonio Huete Jimenez WINDOW *check = normal ? p->normal : p->shadow;
1580*a8e38dc0SAntonio Huete Jimenez if (check == win) {
15815382d832SPeter Avalos result = p;
15825382d832SPeter Avalos break;
15835382d832SPeter Avalos }
15845382d832SPeter Avalos }
15855382d832SPeter Avalos return result;
15865382d832SPeter Avalos }
15875382d832SPeter Avalos
1588*a8e38dc0SAntonio Huete Jimenez #define SearchTopWindows(win) find_window(dialog_state.all_windows, win, TRUE)
1589*a8e38dc0SAntonio Huete Jimenez #define SearchSubWindows(win) find_window(dialog_state.all_subwindows, win, FALSE)
1590*a8e38dc0SAntonio Huete Jimenez
1591*a8e38dc0SAntonio Huete Jimenez /*
1592*a8e38dc0SAntonio Huete Jimenez * Check for the existence of a window, e.g., when used for input or updating
1593*a8e38dc0SAntonio Huete Jimenez * the display. This is used in dlg_getc() and related functions, to guard
1594*a8e38dc0SAntonio Huete Jimenez * against an asynchronous window-deletion that might invalidate the input
1595*a8e38dc0SAntonio Huete Jimenez * window used in dlg_getc().
1596*a8e38dc0SAntonio Huete Jimenez */
1597*a8e38dc0SAntonio Huete Jimenez DIALOG_WINDOWS *
_dlg_find_window(WINDOW * win)1598*a8e38dc0SAntonio Huete Jimenez _dlg_find_window(WINDOW *win)
1599*a8e38dc0SAntonio Huete Jimenez {
1600*a8e38dc0SAntonio Huete Jimenez DIALOG_WINDOWS *result = 0;
1601*a8e38dc0SAntonio Huete Jimenez
1602*a8e38dc0SAntonio Huete Jimenez if ((result = SearchTopWindows(win)) == NULL)
1603*a8e38dc0SAntonio Huete Jimenez result = SearchSubWindows(win);
1604*a8e38dc0SAntonio Huete Jimenez return result;
1605*a8e38dc0SAntonio Huete Jimenez }
1606*a8e38dc0SAntonio Huete Jimenez
16075382d832SPeter Avalos #ifdef HAVE_COLOR
16085382d832SPeter Avalos /*
16095382d832SPeter Avalos * If we have wchgat(), use that for updating shadow attributes, to work with
16105382d832SPeter Avalos * wide-character data.
16115382d832SPeter Avalos */
16125382d832SPeter Avalos
16135382d832SPeter Avalos /*
16145382d832SPeter Avalos * Check if the given point is "in" the given window. If so, return the window
16155382d832SPeter Avalos * pointer, otherwise null.
16165382d832SPeter Avalos */
16175382d832SPeter Avalos static WINDOW *
in_window(WINDOW * win,int y,int x)16185382d832SPeter Avalos in_window(WINDOW *win, int y, int x)
16195382d832SPeter Avalos {
16205382d832SPeter Avalos WINDOW *result = 0;
16215382d832SPeter Avalos int y_base = getbegy(win);
16225382d832SPeter Avalos int x_base = getbegx(win);
16235382d832SPeter Avalos int y_last = getmaxy(win) + y_base;
16245382d832SPeter Avalos int x_last = getmaxx(win) + x_base;
16255382d832SPeter Avalos
16265382d832SPeter Avalos if (y >= y_base && y <= y_last && x >= x_base && x <= x_last)
16275382d832SPeter Avalos result = win;
16285382d832SPeter Avalos return result;
16295382d832SPeter Avalos }
16305382d832SPeter Avalos
16315382d832SPeter Avalos static WINDOW *
window_at_cell(DIALOG_WINDOWS * dw,int y,int x)16325382d832SPeter Avalos window_at_cell(DIALOG_WINDOWS * dw, int y, int x)
16335382d832SPeter Avalos {
16345382d832SPeter Avalos WINDOW *result = 0;
16355382d832SPeter Avalos DIALOG_WINDOWS *p;
16365382d832SPeter Avalos int y_want = y + getbegy(dw->shadow);
16375382d832SPeter Avalos int x_want = x + getbegx(dw->shadow);
16385382d832SPeter Avalos
16395382d832SPeter Avalos for (p = dialog_state.all_windows; p != 0; p = p->next) {
16405382d832SPeter Avalos if (dw->normal != p->normal
16415382d832SPeter Avalos && dw->shadow != p->normal
16425382d832SPeter Avalos && (result = in_window(p->normal, y_want, x_want)) != 0) {
16435382d832SPeter Avalos break;
16445382d832SPeter Avalos }
16455382d832SPeter Avalos }
16465382d832SPeter Avalos if (result == 0) {
16475382d832SPeter Avalos result = stdscr;
16485382d832SPeter Avalos }
16495382d832SPeter Avalos return result;
16505382d832SPeter Avalos }
16515382d832SPeter Avalos
16525382d832SPeter Avalos static bool
in_shadow(WINDOW * normal,WINDOW * shadow,int y,int x)16535382d832SPeter Avalos in_shadow(WINDOW *normal, WINDOW *shadow, int y, int x)
16545382d832SPeter Avalos {
16555382d832SPeter Avalos bool result = FALSE;
16565382d832SPeter Avalos int ybase = getbegy(normal);
16575382d832SPeter Avalos int ylast = getmaxy(normal) + ybase;
16585382d832SPeter Avalos int xbase = getbegx(normal);
16595382d832SPeter Avalos int xlast = getmaxx(normal) + xbase;
16605382d832SPeter Avalos
16615382d832SPeter Avalos y += getbegy(shadow);
16625382d832SPeter Avalos x += getbegx(shadow);
16635382d832SPeter Avalos
16645382d832SPeter Avalos if (y >= ybase + SHADOW_ROWS
16655382d832SPeter Avalos && y < ylast + SHADOW_ROWS
16665382d832SPeter Avalos && x >= xlast
16675382d832SPeter Avalos && x < xlast + SHADOW_COLS) {
16685382d832SPeter Avalos /* in the right-side */
16695382d832SPeter Avalos result = TRUE;
16705382d832SPeter Avalos } else if (y >= ylast
16715382d832SPeter Avalos && y < ylast + SHADOW_ROWS
16725382d832SPeter Avalos && x >= ybase + SHADOW_COLS
16735382d832SPeter Avalos && x < ylast + SHADOW_COLS) {
16745382d832SPeter Avalos /* check the bottom */
16755382d832SPeter Avalos result = TRUE;
16765382d832SPeter Avalos }
16775382d832SPeter Avalos
16785382d832SPeter Avalos return result;
16795382d832SPeter Avalos }
16805382d832SPeter Avalos
16815382d832SPeter Avalos /*
16825382d832SPeter Avalos * When erasing a shadow, check each cell to make sure that it is not part of
16835382d832SPeter Avalos * another box's shadow. This is a little complicated since most shadows are
16845382d832SPeter Avalos * merged onto stdscr.
16855382d832SPeter Avalos */
16865382d832SPeter Avalos static bool
last_shadow(DIALOG_WINDOWS * dw,int y,int x)16875382d832SPeter Avalos last_shadow(DIALOG_WINDOWS * dw, int y, int x)
16885382d832SPeter Avalos {
16895382d832SPeter Avalos DIALOG_WINDOWS *p;
16905382d832SPeter Avalos bool result = TRUE;
16915382d832SPeter Avalos
16925382d832SPeter Avalos for (p = dialog_state.all_windows; p != 0; p = p->next) {
16935382d832SPeter Avalos if (p->normal != dw->normal
16945382d832SPeter Avalos && in_shadow(p->normal, dw->shadow, y, x)) {
16955382d832SPeter Avalos result = FALSE;
16965382d832SPeter Avalos break;
16975382d832SPeter Avalos }
16985382d832SPeter Avalos }
16995382d832SPeter Avalos return result;
17005382d832SPeter Avalos }
17015382d832SPeter Avalos
17025382d832SPeter Avalos static void
repaint_cell(DIALOG_WINDOWS * dw,bool draw,int y,int x)17035382d832SPeter Avalos repaint_cell(DIALOG_WINDOWS * dw, bool draw, int y, int x)
17045382d832SPeter Avalos {
17055382d832SPeter Avalos WINDOW *win = dw->shadow;
17065382d832SPeter Avalos WINDOW *cellwin;
17075382d832SPeter Avalos int y2, x2;
17085382d832SPeter Avalos
17095382d832SPeter Avalos if ((cellwin = window_at_cell(dw, y, x)) != 0
17105382d832SPeter Avalos && (draw || last_shadow(dw, y, x))
17115382d832SPeter Avalos && (y2 = (y + getbegy(win) - getbegy(cellwin))) >= 0
17125382d832SPeter Avalos && (x2 = (x + getbegx(win) - getbegx(cellwin))) >= 0
17135382d832SPeter Avalos && wmove(cellwin, y2, x2) != ERR) {
17145382d832SPeter Avalos chtype the_cell = dlg_get_attrs(cellwin);
17155382d832SPeter Avalos chtype the_attr = (draw ? shadow_attr : the_cell);
17165382d832SPeter Avalos
17175940c9abSDaniel Fojt if (winch(cellwin) & A_ALTCHARSET) {
17185382d832SPeter Avalos the_attr |= A_ALTCHARSET;
17195382d832SPeter Avalos }
17205382d832SPeter Avalos #if USE_WCHGAT
17215382d832SPeter Avalos wchgat(cellwin, 1,
17225382d832SPeter Avalos the_attr & (chtype) (~A_COLOR),
17235382d832SPeter Avalos (short) PAIR_NUMBER(the_attr),
17245382d832SPeter Avalos NULL);
17255382d832SPeter Avalos #else
17265382d832SPeter Avalos {
17275382d832SPeter Avalos chtype the_char = ((winch(cellwin) & A_CHARTEXT) | the_attr);
17285382d832SPeter Avalos (void) waddch(cellwin, the_char);
17295382d832SPeter Avalos }
17305382d832SPeter Avalos #endif
17315382d832SPeter Avalos wnoutrefresh(cellwin);
17325382d832SPeter Avalos }
17335382d832SPeter Avalos }
17345382d832SPeter Avalos
17355382d832SPeter Avalos #define RepaintCell(dw, draw, y, x) repaint_cell(dw, draw, y, x)
17365382d832SPeter Avalos
17375382d832SPeter Avalos static void
repaint_shadow(DIALOG_WINDOWS * dw,bool draw,int y,int x,int height,int width)17385382d832SPeter Avalos repaint_shadow(DIALOG_WINDOWS * dw, bool draw, int y, int x, int height, int width)
17395382d832SPeter Avalos {
17405940c9abSDaniel Fojt if (UseShadow(dw)) {
17415382d832SPeter Avalos int i, j;
17425382d832SPeter Avalos
17435382d832SPeter Avalos #if !USE_WCHGAT
17445382d832SPeter Avalos chtype save = dlg_get_attrs(dw->shadow);
17455940c9abSDaniel Fojt dlg_attrset(dw->shadow, draw ? shadow_attr : screen_attr);
17465382d832SPeter Avalos #endif
17475382d832SPeter Avalos for (i = 0; i < SHADOW_ROWS; ++i) {
17485382d832SPeter Avalos for (j = 0; j < width; ++j) {
17495382d832SPeter Avalos RepaintCell(dw, draw, i + y + height, j + x + SHADOW_COLS);
17505382d832SPeter Avalos }
17515382d832SPeter Avalos }
17525382d832SPeter Avalos for (i = 0; i < height; i++) {
17535382d832SPeter Avalos for (j = 0; j < SHADOW_COLS; ++j) {
17545382d832SPeter Avalos RepaintCell(dw, draw, i + y + SHADOW_ROWS, j + x + width);
17555382d832SPeter Avalos }
17565382d832SPeter Avalos }
17575382d832SPeter Avalos (void) wnoutrefresh(dw->shadow);
17585382d832SPeter Avalos #if !USE_WCHGAT
17595940c9abSDaniel Fojt dlg_attrset(dw->shadow, save);
17605382d832SPeter Avalos #endif
17615382d832SPeter Avalos }
17625382d832SPeter Avalos }
17635382d832SPeter Avalos
17645382d832SPeter Avalos /*
17655382d832SPeter Avalos * Draw a shadow on the parent window corresponding to the right- and
17665382d832SPeter Avalos * bottom-edge of the child window, to give a 3-dimensional look.
17675382d832SPeter Avalos */
17685382d832SPeter Avalos static void
draw_childs_shadow(DIALOG_WINDOWS * dw)17695382d832SPeter Avalos draw_childs_shadow(DIALOG_WINDOWS * dw)
17705382d832SPeter Avalos {
17715382d832SPeter Avalos if (UseShadow(dw)) {
17725382d832SPeter Avalos repaint_shadow(dw,
17735382d832SPeter Avalos TRUE,
17745382d832SPeter Avalos getbegy(dw->normal) - getbegy(dw->shadow),
17755382d832SPeter Avalos getbegx(dw->normal) - getbegx(dw->shadow),
17765382d832SPeter Avalos getmaxy(dw->normal),
17775382d832SPeter Avalos getmaxx(dw->normal));
17785382d832SPeter Avalos }
17795382d832SPeter Avalos }
17805382d832SPeter Avalos
17815382d832SPeter Avalos /*
17825382d832SPeter Avalos * Erase a shadow on the parent window corresponding to the right- and
17835382d832SPeter Avalos * bottom-edge of the child window.
17845382d832SPeter Avalos */
17855382d832SPeter Avalos static void
erase_childs_shadow(DIALOG_WINDOWS * dw)17865382d832SPeter Avalos erase_childs_shadow(DIALOG_WINDOWS * dw)
17875382d832SPeter Avalos {
17885382d832SPeter Avalos if (UseShadow(dw)) {
17895382d832SPeter Avalos repaint_shadow(dw,
17905382d832SPeter Avalos FALSE,
17915382d832SPeter Avalos getbegy(dw->normal) - getbegy(dw->shadow),
17925382d832SPeter Avalos getbegx(dw->normal) - getbegx(dw->shadow),
17935382d832SPeter Avalos getmaxy(dw->normal),
17945382d832SPeter Avalos getmaxx(dw->normal));
17955382d832SPeter Avalos }
17965382d832SPeter Avalos }
17975382d832SPeter Avalos
17985382d832SPeter Avalos /*
17995382d832SPeter Avalos * Draw shadows along the right and bottom edge to give a more 3D look
18005382d832SPeter Avalos * to the boxes.
18015382d832SPeter Avalos */
18025382d832SPeter Avalos void
dlg_draw_shadow(WINDOW * win,int y,int x,int height,int width)18035382d832SPeter Avalos dlg_draw_shadow(WINDOW *win, int y, int x, int height, int width)
18045382d832SPeter Avalos {
1805*a8e38dc0SAntonio Huete Jimenez repaint_shadow(SearchTopWindows(win), TRUE, y, x, height, width);
18065382d832SPeter Avalos }
18075382d832SPeter Avalos #endif /* HAVE_COLOR */
18085382d832SPeter Avalos
18095382d832SPeter Avalos /*
18105382d832SPeter Avalos * Allow shell scripts to remap the exit codes so they can distinguish ESC
18115382d832SPeter Avalos * from ERROR.
18125382d832SPeter Avalos */
18135382d832SPeter Avalos void
dlg_exit(int code)18145382d832SPeter Avalos dlg_exit(int code)
18155382d832SPeter Avalos {
18165382d832SPeter Avalos /* *INDENT-OFF* */
18175382d832SPeter Avalos static const struct {
18185382d832SPeter Avalos int code;
18195382d832SPeter Avalos const char *name;
18205382d832SPeter Avalos } table[] = {
18215382d832SPeter Avalos { DLG_EXIT_CANCEL, "DIALOG_CANCEL" },
18225382d832SPeter Avalos { DLG_EXIT_ERROR, "DIALOG_ERROR" },
18235382d832SPeter Avalos { DLG_EXIT_ESC, "DIALOG_ESC" },
18245382d832SPeter Avalos { DLG_EXIT_EXTRA, "DIALOG_EXTRA" },
18255382d832SPeter Avalos { DLG_EXIT_HELP, "DIALOG_HELP" },
18265382d832SPeter Avalos { DLG_EXIT_OK, "DIALOG_OK" },
18275382d832SPeter Avalos { DLG_EXIT_ITEM_HELP, "DIALOG_ITEM_HELP" },
1828*a8e38dc0SAntonio Huete Jimenez { DLG_EXIT_TIMEOUT, "DIALOG_TIMEOUT" },
18295382d832SPeter Avalos };
18305382d832SPeter Avalos /* *INDENT-ON* */
18315382d832SPeter Avalos
18325382d832SPeter Avalos unsigned n;
18335382d832SPeter Avalos bool overridden = FALSE;
18345382d832SPeter Avalos
18355382d832SPeter Avalos retry:
18365940c9abSDaniel Fojt for (n = 0; n < TableSize(table); n++) {
18375382d832SPeter Avalos if (table[n].code == code) {
1838*a8e38dc0SAntonio Huete Jimenez if (dlg_getenv_num(table[n].name, &code)) {
18395382d832SPeter Avalos overridden = TRUE;
18405382d832SPeter Avalos }
18415382d832SPeter Avalos break;
18425382d832SPeter Avalos }
18435382d832SPeter Avalos }
18445382d832SPeter Avalos
18455382d832SPeter Avalos /*
18465382d832SPeter Avalos * Prior to 2004/12/19, a widget using --item-help would exit with "OK"
18475382d832SPeter Avalos * if the help button were selected. Now we want to exit with "HELP",
18485382d832SPeter Avalos * but allow the environment variable to override.
18495382d832SPeter Avalos */
18505382d832SPeter Avalos if (code == DLG_EXIT_ITEM_HELP && !overridden) {
18515382d832SPeter Avalos code = DLG_EXIT_HELP;
18525382d832SPeter Avalos goto retry;
18535382d832SPeter Avalos }
18545382d832SPeter Avalos #ifdef HAVE_DLG_TRACE
18555382d832SPeter Avalos dlg_trace((const char *) 0); /* close it */
18565382d832SPeter Avalos #endif
18575382d832SPeter Avalos
18585382d832SPeter Avalos #ifdef NO_LEAKS
18595382d832SPeter Avalos _dlg_inputstr_leaks();
1860*a8e38dc0SAntonio Huete Jimenez #if defined(NCURSES_VERSION) && (defined(HAVE_EXIT_CURSES) || defined(HAVE__NC_FREE_AND_EXIT))
1861*a8e38dc0SAntonio Huete Jimenez exit_curses(code);
18625382d832SPeter Avalos #endif
18635382d832SPeter Avalos #endif
18645382d832SPeter Avalos
18655382d832SPeter Avalos if (dialog_state.input == stdin) {
18665382d832SPeter Avalos exit(code);
18675382d832SPeter Avalos } else {
18685382d832SPeter Avalos /*
18695382d832SPeter Avalos * Just in case of using --input-fd option, do not
18705382d832SPeter Avalos * call atexit functions of ncurses which may hang.
18715382d832SPeter Avalos */
18725382d832SPeter Avalos if (dialog_state.input) {
18735382d832SPeter Avalos fclose(dialog_state.input);
18745382d832SPeter Avalos dialog_state.input = 0;
18755382d832SPeter Avalos }
18765382d832SPeter Avalos if (dialog_state.pipe_input) {
18775382d832SPeter Avalos if (dialog_state.pipe_input != stdin) {
18785382d832SPeter Avalos fclose(dialog_state.pipe_input);
18795382d832SPeter Avalos dialog_state.pipe_input = 0;
18805382d832SPeter Avalos }
18815382d832SPeter Avalos }
18825382d832SPeter Avalos _exit(code);
18835382d832SPeter Avalos }
18845382d832SPeter Avalos }
18855382d832SPeter Avalos
18865940c9abSDaniel Fojt #define DATA(name) { DLG_EXIT_ ## name, #name }
18875940c9abSDaniel Fojt /* *INDENT-OFF* */
18885940c9abSDaniel Fojt static struct {
18895940c9abSDaniel Fojt int code;
18905940c9abSDaniel Fojt const char *name;
18915940c9abSDaniel Fojt } exit_codenames[] = {
18925940c9abSDaniel Fojt DATA(ESC),
18935940c9abSDaniel Fojt DATA(UNKNOWN),
18945940c9abSDaniel Fojt DATA(ERROR),
18955940c9abSDaniel Fojt DATA(OK),
18965940c9abSDaniel Fojt DATA(CANCEL),
18975940c9abSDaniel Fojt DATA(HELP),
18985940c9abSDaniel Fojt DATA(EXTRA),
18995940c9abSDaniel Fojt DATA(ITEM_HELP),
19005940c9abSDaniel Fojt };
19015940c9abSDaniel Fojt #undef DATA
19025940c9abSDaniel Fojt /* *INDENT-ON* */
19035940c9abSDaniel Fojt
19045940c9abSDaniel Fojt const char *
dlg_exitcode2s(int code)19055940c9abSDaniel Fojt dlg_exitcode2s(int code)
19065940c9abSDaniel Fojt {
19075940c9abSDaniel Fojt const char *result = "?";
19085940c9abSDaniel Fojt size_t n;
19095940c9abSDaniel Fojt
19105940c9abSDaniel Fojt for (n = 0; n < TableSize(exit_codenames); ++n) {
19115940c9abSDaniel Fojt if (exit_codenames[n].code == code) {
19125940c9abSDaniel Fojt result = exit_codenames[n].name;
19135940c9abSDaniel Fojt break;
19145940c9abSDaniel Fojt }
19155940c9abSDaniel Fojt }
19165940c9abSDaniel Fojt return result;
19175940c9abSDaniel Fojt }
19185940c9abSDaniel Fojt
19195940c9abSDaniel Fojt int
dlg_exitname2n(const char * name)19205940c9abSDaniel Fojt dlg_exitname2n(const char *name)
19215940c9abSDaniel Fojt {
19225940c9abSDaniel Fojt int result = DLG_EXIT_UNKNOWN;
19235940c9abSDaniel Fojt size_t n;
19245940c9abSDaniel Fojt
19255940c9abSDaniel Fojt for (n = 0; n < TableSize(exit_codenames); ++n) {
19265940c9abSDaniel Fojt if (!dlg_strcmp(exit_codenames[n].name, name)) {
19275940c9abSDaniel Fojt result = exit_codenames[n].code;
19285940c9abSDaniel Fojt break;
19295940c9abSDaniel Fojt }
19305940c9abSDaniel Fojt }
19315940c9abSDaniel Fojt return result;
19325940c9abSDaniel Fojt }
19335940c9abSDaniel Fojt
19345382d832SPeter Avalos /* quit program killing all tailbg */
19355382d832SPeter Avalos void
dlg_exiterr(const char * fmt,...)19365382d832SPeter Avalos dlg_exiterr(const char *fmt, ...)
19375382d832SPeter Avalos {
19385382d832SPeter Avalos int retval;
19395382d832SPeter Avalos va_list ap;
19405382d832SPeter Avalos
19415382d832SPeter Avalos end_dialog();
19425382d832SPeter Avalos
19435382d832SPeter Avalos (void) fputc('\n', stderr);
19445382d832SPeter Avalos va_start(ap, fmt);
19455382d832SPeter Avalos (void) vfprintf(stderr, fmt, ap);
19465382d832SPeter Avalos va_end(ap);
19475382d832SPeter Avalos (void) fputc('\n', stderr);
19485382d832SPeter Avalos
19495940c9abSDaniel Fojt #ifdef HAVE_DLG_TRACE
19505940c9abSDaniel Fojt va_start(ap, fmt);
19515940c9abSDaniel Fojt dlg_trace_msg("## Error: ");
19525940c9abSDaniel Fojt dlg_trace_va_msg(fmt, ap);
19535940c9abSDaniel Fojt va_end(ap);
19545940c9abSDaniel Fojt #endif
19555940c9abSDaniel Fojt
19565382d832SPeter Avalos dlg_killall_bg(&retval);
19575382d832SPeter Avalos
19585382d832SPeter Avalos (void) fflush(stderr);
19595382d832SPeter Avalos (void) fflush(stdout);
1960*a8e38dc0SAntonio Huete Jimenez dlg_exit(strcmp(fmt, "timeout") == 0 ? DLG_EXIT_TIMEOUT : DLG_EXIT_ERROR);
1961*a8e38dc0SAntonio Huete Jimenez }
1962*a8e38dc0SAntonio Huete Jimenez
1963*a8e38dc0SAntonio Huete Jimenez /*
1964*a8e38dc0SAntonio Huete Jimenez * Get a string from the environment, rejecting those which are entirely blank.
1965*a8e38dc0SAntonio Huete Jimenez */
1966*a8e38dc0SAntonio Huete Jimenez char *
dlg_getenv_str(const char * name)1967*a8e38dc0SAntonio Huete Jimenez dlg_getenv_str(const char *name)
1968*a8e38dc0SAntonio Huete Jimenez {
1969*a8e38dc0SAntonio Huete Jimenez char *result = getenv(name);
1970*a8e38dc0SAntonio Huete Jimenez if (result != NULL) {
1971*a8e38dc0SAntonio Huete Jimenez while (*result != '\0' && isspace(UCH(*result)))
1972*a8e38dc0SAntonio Huete Jimenez ++result;
1973*a8e38dc0SAntonio Huete Jimenez if (*result == '\0')
1974*a8e38dc0SAntonio Huete Jimenez result = NULL;
1975*a8e38dc0SAntonio Huete Jimenez }
1976*a8e38dc0SAntonio Huete Jimenez return result;
1977*a8e38dc0SAntonio Huete Jimenez }
1978*a8e38dc0SAntonio Huete Jimenez
1979*a8e38dc0SAntonio Huete Jimenez /*
1980*a8e38dc0SAntonio Huete Jimenez * Get a number from the environment:
1981*a8e38dc0SAntonio Huete Jimenez * + If the caller provides a pointer in the second parameter, return
1982*a8e38dc0SAntonio Huete Jimenez * success/failure for the function return, and the actual value via the
1983*a8e38dc0SAntonio Huete Jimenez * pointer. Use this for decoding arbitrary numbers, e.g., negative or zero.
1984*a8e38dc0SAntonio Huete Jimenez * + If the caller does not provide a pointer, return the decoded value for
1985*a8e38dc0SAntonio Huete Jimenez * the function-return. Use this when only values greater than zero are
1986*a8e38dc0SAntonio Huete Jimenez * useful.
1987*a8e38dc0SAntonio Huete Jimenez */
1988*a8e38dc0SAntonio Huete Jimenez int
dlg_getenv_num(const char * name,int * value)1989*a8e38dc0SAntonio Huete Jimenez dlg_getenv_num(const char *name, int *value)
1990*a8e38dc0SAntonio Huete Jimenez {
1991*a8e38dc0SAntonio Huete Jimenez int result = 0;
1992*a8e38dc0SAntonio Huete Jimenez char *data = getenv(name);
1993*a8e38dc0SAntonio Huete Jimenez if (data != NULL) {
1994*a8e38dc0SAntonio Huete Jimenez char *temp = NULL;
1995*a8e38dc0SAntonio Huete Jimenez long check = strtol(data, &temp, 0);
1996*a8e38dc0SAntonio Huete Jimenez if (temp != 0 && temp != data && *temp == '\0') {
1997*a8e38dc0SAntonio Huete Jimenez result = (int) check;
1998*a8e38dc0SAntonio Huete Jimenez if (value != NULL) {
1999*a8e38dc0SAntonio Huete Jimenez *value = result;
2000*a8e38dc0SAntonio Huete Jimenez result = 1;
2001*a8e38dc0SAntonio Huete Jimenez }
2002*a8e38dc0SAntonio Huete Jimenez }
2003*a8e38dc0SAntonio Huete Jimenez }
2004*a8e38dc0SAntonio Huete Jimenez return result;
20055382d832SPeter Avalos }
20065382d832SPeter Avalos
20075382d832SPeter Avalos void
dlg_beeping(void)20085382d832SPeter Avalos dlg_beeping(void)
20095382d832SPeter Avalos {
20105382d832SPeter Avalos if (dialog_vars.beep_signal) {
20115382d832SPeter Avalos (void) beep();
20125382d832SPeter Avalos dialog_vars.beep_signal = 0;
20135382d832SPeter Avalos }
20145382d832SPeter Avalos }
20155382d832SPeter Avalos
20165382d832SPeter Avalos void
dlg_print_size(int height,int width)20175382d832SPeter Avalos dlg_print_size(int height, int width)
20185382d832SPeter Avalos {
20195940c9abSDaniel Fojt if (dialog_vars.print_siz) {
20205382d832SPeter Avalos fprintf(dialog_state.output, "Size: %d, %d\n", height, width);
20215940c9abSDaniel Fojt DLG_TRACE(("# print size: %dx%d\n", height, width));
20225940c9abSDaniel Fojt }
20235382d832SPeter Avalos }
20245382d832SPeter Avalos
20255382d832SPeter Avalos void
dlg_ctl_size(int height,int width)20265382d832SPeter Avalos dlg_ctl_size(int height, int width)
20275382d832SPeter Avalos {
20285382d832SPeter Avalos if (dialog_vars.size_err) {
20295382d832SPeter Avalos if ((width > COLS) || (height > LINES)) {
20305382d832SPeter Avalos dlg_exiterr("Window too big. (height, width) = (%d, %d). Max allowed (%d, %d).",
20315382d832SPeter Avalos height, width, LINES, COLS);
20325382d832SPeter Avalos }
20335382d832SPeter Avalos #ifdef HAVE_COLOR
20345382d832SPeter Avalos else if ((dialog_state.use_shadow)
20355382d832SPeter Avalos && ((width > SCOLS || height > SLINES))) {
20365382d832SPeter Avalos if ((width <= COLS) && (height <= LINES)) {
20375382d832SPeter Avalos /* try again, without shadows */
20385382d832SPeter Avalos dialog_state.use_shadow = 0;
20395382d832SPeter Avalos } else {
20405382d832SPeter Avalos dlg_exiterr("Window+Shadow too big. (height, width) = (%d, %d). Max allowed (%d, %d).",
20415382d832SPeter Avalos height, width, SLINES, SCOLS);
20425382d832SPeter Avalos }
20435382d832SPeter Avalos }
20445382d832SPeter Avalos #endif
20455382d832SPeter Avalos }
20465382d832SPeter Avalos }
20475382d832SPeter Avalos
20485382d832SPeter Avalos /*
20495382d832SPeter Avalos * If the --tab-correct was not selected, convert tabs to single spaces.
20505382d832SPeter Avalos */
20515382d832SPeter Avalos void
dlg_tab_correct_str(char * prompt)20525382d832SPeter Avalos dlg_tab_correct_str(char *prompt)
20535382d832SPeter Avalos {
20545382d832SPeter Avalos char *ptr;
20555382d832SPeter Avalos
20565382d832SPeter Avalos if (dialog_vars.tab_correct) {
20575382d832SPeter Avalos while ((ptr = strchr(prompt, TAB)) != NULL) {
20585382d832SPeter Avalos *ptr = ' ';
20595382d832SPeter Avalos prompt = ptr;
20605382d832SPeter Avalos }
20615382d832SPeter Avalos }
20625382d832SPeter Avalos }
20635382d832SPeter Avalos
20645382d832SPeter Avalos void
dlg_calc_listh(int * height,int * list_height,int item_no)20655382d832SPeter Avalos dlg_calc_listh(int *height, int *list_height, int item_no)
20665382d832SPeter Avalos {
20675382d832SPeter Avalos /* calculate new height and list_height */
20685382d832SPeter Avalos int rows = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0);
20695382d832SPeter Avalos if (rows - (*height) > 0) {
20705382d832SPeter Avalos if (rows - (*height) > item_no)
20715382d832SPeter Avalos *list_height = item_no;
20725382d832SPeter Avalos else
20735382d832SPeter Avalos *list_height = rows - (*height);
20745382d832SPeter Avalos }
20755382d832SPeter Avalos (*height) += (*list_height);
20765382d832SPeter Avalos }
20775382d832SPeter Avalos
20785382d832SPeter Avalos /* obsolete */
20795382d832SPeter Avalos int
dlg_calc_listw(int item_no,char ** items,int group)20805382d832SPeter Avalos dlg_calc_listw(int item_no, char **items, int group)
20815382d832SPeter Avalos {
20825940c9abSDaniel Fojt int i, len1 = 0, len2 = 0;
20835940c9abSDaniel Fojt
20845382d832SPeter Avalos for (i = 0; i < (item_no * group); i += group) {
20855940c9abSDaniel Fojt int n;
20865940c9abSDaniel Fojt
20875382d832SPeter Avalos if ((n = dlg_count_columns(items[i])) > len1)
20885382d832SPeter Avalos len1 = n;
20895382d832SPeter Avalos if ((n = dlg_count_columns(items[i + 1])) > len2)
20905382d832SPeter Avalos len2 = n;
20915382d832SPeter Avalos }
20925382d832SPeter Avalos return len1 + len2;
20935382d832SPeter Avalos }
20945382d832SPeter Avalos
20955382d832SPeter Avalos int
dlg_calc_list_width(int item_no,DIALOG_LISTITEM * items)20965382d832SPeter Avalos dlg_calc_list_width(int item_no, DIALOG_LISTITEM * items)
20975382d832SPeter Avalos {
20985382d832SPeter Avalos int n, i, len1 = 0, len2 = 0;
20995382d832SPeter Avalos int bits = ((dialog_vars.no_tags ? 1 : 0)
21005382d832SPeter Avalos + (dialog_vars.no_items ? 2 : 0));
21015382d832SPeter Avalos
21025382d832SPeter Avalos for (i = 0; i < item_no; ++i) {
21035382d832SPeter Avalos switch (bits) {
21045382d832SPeter Avalos case 0:
21055382d832SPeter Avalos /* FALLTHRU */
21065382d832SPeter Avalos case 1:
21075382d832SPeter Avalos if ((n = dlg_count_columns(items[i].name)) > len1)
21085382d832SPeter Avalos len1 = n;
21095382d832SPeter Avalos if ((n = dlg_count_columns(items[i].text)) > len2)
21105382d832SPeter Avalos len2 = n;
21115382d832SPeter Avalos break;
21125382d832SPeter Avalos case 2:
21135382d832SPeter Avalos /* FALLTHRU */
21145382d832SPeter Avalos case 3:
21155382d832SPeter Avalos if ((n = dlg_count_columns(items[i].name)) > len1)
21165382d832SPeter Avalos len1 = n;
21175382d832SPeter Avalos break;
21185382d832SPeter Avalos }
21195382d832SPeter Avalos }
21205382d832SPeter Avalos return len1 + len2;
21215382d832SPeter Avalos }
21225382d832SPeter Avalos
21235382d832SPeter Avalos char *
dlg_strempty(void)21245382d832SPeter Avalos dlg_strempty(void)
21255382d832SPeter Avalos {
21265382d832SPeter Avalos static char empty[] = "";
21275382d832SPeter Avalos return empty;
21285382d832SPeter Avalos }
21295382d832SPeter Avalos
21305382d832SPeter Avalos char *
dlg_strclone(const char * cprompt)21315382d832SPeter Avalos dlg_strclone(const char *cprompt)
21325382d832SPeter Avalos {
21331ef6786aSJohn Marino char *prompt = 0;
21341ef6786aSJohn Marino if (cprompt != 0) {
21351ef6786aSJohn Marino prompt = dlg_malloc(char, strlen(cprompt) + 1);
21365382d832SPeter Avalos assert_ptr(prompt, "dlg_strclone");
21375382d832SPeter Avalos strcpy(prompt, cprompt);
21381ef6786aSJohn Marino }
21395382d832SPeter Avalos return prompt;
21405382d832SPeter Avalos }
21415382d832SPeter Avalos
21425382d832SPeter Avalos chtype
dlg_asciibox(chtype ch)21435382d832SPeter Avalos dlg_asciibox(chtype ch)
21445382d832SPeter Avalos {
21455382d832SPeter Avalos chtype result = 0;
21465382d832SPeter Avalos
21475382d832SPeter Avalos if (ch == ACS_ULCORNER)
21485382d832SPeter Avalos result = '+';
21495382d832SPeter Avalos else if (ch == ACS_LLCORNER)
21505382d832SPeter Avalos result = '+';
21515382d832SPeter Avalos else if (ch == ACS_URCORNER)
21525382d832SPeter Avalos result = '+';
21535382d832SPeter Avalos else if (ch == ACS_LRCORNER)
21545382d832SPeter Avalos result = '+';
21555382d832SPeter Avalos else if (ch == ACS_HLINE)
21565382d832SPeter Avalos result = '-';
21575382d832SPeter Avalos else if (ch == ACS_VLINE)
21585382d832SPeter Avalos result = '|';
21595382d832SPeter Avalos else if (ch == ACS_LTEE)
21605382d832SPeter Avalos result = '+';
21615382d832SPeter Avalos else if (ch == ACS_RTEE)
21625382d832SPeter Avalos result = '+';
21635382d832SPeter Avalos else if (ch == ACS_UARROW)
21645382d832SPeter Avalos result = '^';
21655382d832SPeter Avalos else if (ch == ACS_DARROW)
21665382d832SPeter Avalos result = 'v';
21675382d832SPeter Avalos
21685382d832SPeter Avalos return result;
21695382d832SPeter Avalos }
21705382d832SPeter Avalos
21715382d832SPeter Avalos chtype
dlg_boxchar(chtype ch)21725382d832SPeter Avalos dlg_boxchar(chtype ch)
21735382d832SPeter Avalos {
21745382d832SPeter Avalos chtype result = dlg_asciibox(ch);
21755382d832SPeter Avalos
21765382d832SPeter Avalos if (result != 0) {
21775382d832SPeter Avalos if (dialog_vars.ascii_lines)
21785382d832SPeter Avalos ch = result;
21795382d832SPeter Avalos else if (dialog_vars.no_lines)
21805382d832SPeter Avalos ch = ' ';
21815382d832SPeter Avalos }
21825382d832SPeter Avalos return ch;
21835382d832SPeter Avalos }
21845382d832SPeter Avalos
21855382d832SPeter Avalos int
dlg_box_x_ordinate(int width)21865382d832SPeter Avalos dlg_box_x_ordinate(int width)
21875382d832SPeter Avalos {
21885382d832SPeter Avalos int x;
21895382d832SPeter Avalos
21905382d832SPeter Avalos if (dialog_vars.begin_set == 1) {
21915382d832SPeter Avalos x = dialog_vars.begin_x;
21925382d832SPeter Avalos } else {
21935382d832SPeter Avalos /* center dialog box on screen unless --begin-set */
21945382d832SPeter Avalos x = (SCOLS - width) / 2;
21955382d832SPeter Avalos }
21965382d832SPeter Avalos return x;
21975382d832SPeter Avalos }
21985382d832SPeter Avalos
21995382d832SPeter Avalos int
dlg_box_y_ordinate(int height)22005382d832SPeter Avalos dlg_box_y_ordinate(int height)
22015382d832SPeter Avalos {
22025382d832SPeter Avalos int y;
22035382d832SPeter Avalos
22045382d832SPeter Avalos if (dialog_vars.begin_set == 1) {
22055382d832SPeter Avalos y = dialog_vars.begin_y;
22065382d832SPeter Avalos } else {
22075382d832SPeter Avalos /* center dialog box on screen unless --begin-set */
22085382d832SPeter Avalos y = (SLINES - height) / 2;
22095382d832SPeter Avalos }
22105382d832SPeter Avalos return y;
22115382d832SPeter Avalos }
22125382d832SPeter Avalos
22135382d832SPeter Avalos void
dlg_draw_title(WINDOW * win,const char * title)22145382d832SPeter Avalos dlg_draw_title(WINDOW *win, const char *title)
22155382d832SPeter Avalos {
22165382d832SPeter Avalos if (title != NULL) {
22175382d832SPeter Avalos chtype attr = A_NORMAL;
22185382d832SPeter Avalos chtype save = dlg_get_attrs(win);
22195382d832SPeter Avalos int x = centered(getmaxx(win), title);
22205382d832SPeter Avalos
22215940c9abSDaniel Fojt dlg_attrset(win, title_attr);
22225382d832SPeter Avalos wmove(win, 0, x);
22235382d832SPeter Avalos dlg_print_text(win, title, getmaxx(win) - x, &attr);
22245940c9abSDaniel Fojt dlg_attrset(win, save);
22251ef6786aSJohn Marino dlg_finish_string(title);
22265382d832SPeter Avalos }
22275382d832SPeter Avalos }
22285382d832SPeter Avalos
22295382d832SPeter Avalos void
dlg_draw_bottom_box2(WINDOW * win,chtype on_left,chtype on_right,chtype on_inside)22305382d832SPeter Avalos dlg_draw_bottom_box2(WINDOW *win, chtype on_left, chtype on_right, chtype on_inside)
22315382d832SPeter Avalos {
22325382d832SPeter Avalos int width = getmaxx(win);
22335382d832SPeter Avalos int height = getmaxy(win);
22345382d832SPeter Avalos int i;
22355382d832SPeter Avalos
22365940c9abSDaniel Fojt dlg_attrset(win, on_left);
22375382d832SPeter Avalos (void) wmove(win, height - 3, 0);
22385382d832SPeter Avalos (void) waddch(win, dlg_boxchar(ACS_LTEE));
22395382d832SPeter Avalos for (i = 0; i < width - 2; i++)
22405382d832SPeter Avalos (void) waddch(win, dlg_boxchar(ACS_HLINE));
22415940c9abSDaniel Fojt dlg_attrset(win, on_right);
22425382d832SPeter Avalos (void) waddch(win, dlg_boxchar(ACS_RTEE));
22435940c9abSDaniel Fojt dlg_attrset(win, on_inside);
22445382d832SPeter Avalos (void) wmove(win, height - 2, 1);
22455382d832SPeter Avalos for (i = 0; i < width - 2; i++)
22465382d832SPeter Avalos (void) waddch(win, ' ');
22475382d832SPeter Avalos }
22485382d832SPeter Avalos
22495382d832SPeter Avalos void
dlg_draw_bottom_box(WINDOW * win)22505382d832SPeter Avalos dlg_draw_bottom_box(WINDOW *win)
22515382d832SPeter Avalos {
22525382d832SPeter Avalos dlg_draw_bottom_box2(win, border_attr, dialog_attr, dialog_attr);
22535382d832SPeter Avalos }
22545382d832SPeter Avalos
22555382d832SPeter Avalos /*
22565382d832SPeter Avalos * Remove a window, repainting everything else. This would be simpler if we
22575382d832SPeter Avalos * used the panel library, but that is not _always_ available.
22585382d832SPeter Avalos */
22595382d832SPeter Avalos void
dlg_del_window(WINDOW * win)22605382d832SPeter Avalos dlg_del_window(WINDOW *win)
22615382d832SPeter Avalos {
22625382d832SPeter Avalos DIALOG_WINDOWS *p, *q, *r;
22635382d832SPeter Avalos
22645382d832SPeter Avalos /*
22655382d832SPeter Avalos * If --keep-window was set, do not delete/repaint the windows.
22665382d832SPeter Avalos */
22675382d832SPeter Avalos if (dialog_vars.keep_window)
22685382d832SPeter Avalos return;
22695382d832SPeter Avalos
22705382d832SPeter Avalos /* Leave the main window untouched if there are no background windows.
22715382d832SPeter Avalos * We do this so the current window will not be cleared on exit, allowing
22725382d832SPeter Avalos * things like the infobox demo to run without flicker.
22735382d832SPeter Avalos */
22745382d832SPeter Avalos if (dialog_state.getc_callbacks != 0) {
22755382d832SPeter Avalos touchwin(stdscr);
22765382d832SPeter Avalos wnoutrefresh(stdscr);
22775382d832SPeter Avalos }
22785382d832SPeter Avalos
22795382d832SPeter Avalos for (p = dialog_state.all_windows, q = r = 0; p != 0; r = p, p = p->next) {
22805382d832SPeter Avalos if (p->normal == win) {
22815382d832SPeter Avalos q = p; /* found a match - should be only one */
22825382d832SPeter Avalos if (r == 0) {
22835382d832SPeter Avalos dialog_state.all_windows = p->next;
22845382d832SPeter Avalos } else {
22855382d832SPeter Avalos r->next = p->next;
22865382d832SPeter Avalos }
22875382d832SPeter Avalos } else {
22885382d832SPeter Avalos if (p->shadow != 0) {
22895382d832SPeter Avalos touchwin(p->shadow);
22905382d832SPeter Avalos wnoutrefresh(p->shadow);
22915382d832SPeter Avalos }
22925382d832SPeter Avalos touchwin(p->normal);
22935382d832SPeter Avalos wnoutrefresh(p->normal);
22945382d832SPeter Avalos }
22955382d832SPeter Avalos }
22965382d832SPeter Avalos
22975382d832SPeter Avalos if (q) {
22985382d832SPeter Avalos if (dialog_state.all_windows != 0)
22995382d832SPeter Avalos erase_childs_shadow(q);
23005382d832SPeter Avalos del_subwindows(q->normal);
23015382d832SPeter Avalos dlg_unregister_window(q->normal);
23025382d832SPeter Avalos delwin(q->normal);
23035382d832SPeter Avalos free(q);
23045382d832SPeter Avalos }
23055382d832SPeter Avalos doupdate();
23065382d832SPeter Avalos }
23075382d832SPeter Avalos
23085382d832SPeter Avalos /*
23095382d832SPeter Avalos * Create a window, optionally with a shadow.
23105382d832SPeter Avalos */
23115382d832SPeter Avalos WINDOW *
dlg_new_window(int height,int width,int y,int x)23125382d832SPeter Avalos dlg_new_window(int height, int width, int y, int x)
23135382d832SPeter Avalos {
23145382d832SPeter Avalos return dlg_new_modal_window(stdscr, height, width, y, x);
23155382d832SPeter Avalos }
23165382d832SPeter Avalos
23175382d832SPeter Avalos /*
23185382d832SPeter Avalos * "Modal" windows differ from normal ones by having a shadow in a window
23195382d832SPeter Avalos * separate from the standard screen.
23205382d832SPeter Avalos */
23215382d832SPeter Avalos WINDOW *
dlg_new_modal_window(WINDOW * parent,int height,int width,int y,int x)23225382d832SPeter Avalos dlg_new_modal_window(WINDOW *parent, int height, int width, int y, int x)
23235382d832SPeter Avalos {
23245382d832SPeter Avalos WINDOW *win;
23255382d832SPeter Avalos DIALOG_WINDOWS *p = dlg_calloc(DIALOG_WINDOWS, 1);
23265382d832SPeter Avalos
23275382d832SPeter Avalos (void) parent;
23285382d832SPeter Avalos if (p == 0
23295382d832SPeter Avalos || (win = newwin(height, width, y, x)) == 0) {
23305382d832SPeter Avalos dlg_exiterr("Can't make new window at (%d,%d), size (%d,%d).\n",
23315382d832SPeter Avalos y, x, height, width);
23325382d832SPeter Avalos }
23335382d832SPeter Avalos p->next = dialog_state.all_windows;
23345382d832SPeter Avalos p->normal = win;
23355940c9abSDaniel Fojt p->getc_timeout = WTIMEOUT_OFF;
23365382d832SPeter Avalos dialog_state.all_windows = p;
23375382d832SPeter Avalos #ifdef HAVE_COLOR
23385382d832SPeter Avalos if (dialog_state.use_shadow) {
23395382d832SPeter Avalos p->shadow = parent;
23405382d832SPeter Avalos draw_childs_shadow(p);
23415382d832SPeter Avalos }
23425382d832SPeter Avalos #endif
23435382d832SPeter Avalos
23445382d832SPeter Avalos (void) keypad(win, TRUE);
23455382d832SPeter Avalos return win;
23465382d832SPeter Avalos }
23475382d832SPeter Avalos
23485382d832SPeter Avalos /*
23495940c9abSDaniel Fojt * dlg_getc() uses the return-value to determine how to handle an ERR return
23505940c9abSDaniel Fojt * from a non-blocking read:
23515940c9abSDaniel Fojt * a) if greater than zero, there was an expired timeout (blocking for a short
23525940c9abSDaniel Fojt * time), or
23535940c9abSDaniel Fojt * b) if zero, it was a non-blocking read, or
23545940c9abSDaniel Fojt * c) if negative, an error occurred on a blocking read.
23555940c9abSDaniel Fojt */
23565940c9abSDaniel Fojt int
dlg_set_timeout(WINDOW * win,bool will_getc)23575940c9abSDaniel Fojt dlg_set_timeout(WINDOW *win, bool will_getc)
23585940c9abSDaniel Fojt {
23595940c9abSDaniel Fojt DIALOG_WINDOWS *p;
23605940c9abSDaniel Fojt int result = 0;
23615940c9abSDaniel Fojt
2362*a8e38dc0SAntonio Huete Jimenez if ((p = SearchTopWindows(win)) != NULL) {
2363*a8e38dc0SAntonio Huete Jimenez int interval = (dialog_vars.timeout_secs * 1000);
23645940c9abSDaniel Fojt
2365*a8e38dc0SAntonio Huete Jimenez if (will_getc || dialog_vars.pause_secs) {
23665940c9abSDaniel Fojt interval = WTIMEOUT_VAL;
23675940c9abSDaniel Fojt } else {
23685940c9abSDaniel Fojt result = interval;
23695940c9abSDaniel Fojt if (interval <= 0) {
23705940c9abSDaniel Fojt interval = WTIMEOUT_OFF;
23715940c9abSDaniel Fojt }
23725940c9abSDaniel Fojt }
23735940c9abSDaniel Fojt wtimeout(win, interval);
23745940c9abSDaniel Fojt p->getc_timeout = interval;
23755940c9abSDaniel Fojt }
23765940c9abSDaniel Fojt return result;
23775940c9abSDaniel Fojt }
23785940c9abSDaniel Fojt
23795940c9abSDaniel Fojt void
dlg_reset_timeout(WINDOW * win)23805940c9abSDaniel Fojt dlg_reset_timeout(WINDOW *win)
23815940c9abSDaniel Fojt {
23825940c9abSDaniel Fojt DIALOG_WINDOWS *p;
23835940c9abSDaniel Fojt
2384*a8e38dc0SAntonio Huete Jimenez if ((p = SearchTopWindows(win)) != NULL) {
23855940c9abSDaniel Fojt wtimeout(win, p->getc_timeout);
23865940c9abSDaniel Fojt } else {
23875940c9abSDaniel Fojt wtimeout(win, WTIMEOUT_OFF);
23885940c9abSDaniel Fojt }
23895940c9abSDaniel Fojt }
23905940c9abSDaniel Fojt
23915940c9abSDaniel Fojt /*
23925382d832SPeter Avalos * Move/Resize a window, optionally with a shadow.
23935382d832SPeter Avalos */
23945382d832SPeter Avalos #ifdef KEY_RESIZE
23955382d832SPeter Avalos void
dlg_move_window(WINDOW * win,int height,int width,int y,int x)23965382d832SPeter Avalos dlg_move_window(WINDOW *win, int height, int width, int y, int x)
23975382d832SPeter Avalos {
23985940c9abSDaniel Fojt if (win != 0) {
23995382d832SPeter Avalos DIALOG_WINDOWS *p;
24005382d832SPeter Avalos
24015382d832SPeter Avalos dlg_ctl_size(height, width);
24025382d832SPeter Avalos
2403*a8e38dc0SAntonio Huete Jimenez if ((p = SearchTopWindows(win)) != 0) {
24045382d832SPeter Avalos (void) wresize(win, height, width);
24055382d832SPeter Avalos (void) mvwin(win, y, x);
24065382d832SPeter Avalos #ifdef HAVE_COLOR
24075382d832SPeter Avalos if (p->shadow != 0) {
24085382d832SPeter Avalos if (dialog_state.use_shadow) {
24095382d832SPeter Avalos (void) mvwin(p->shadow, y + SHADOW_ROWS, x + SHADOW_COLS);
24105382d832SPeter Avalos } else {
24115382d832SPeter Avalos p->shadow = 0;
24125382d832SPeter Avalos }
24135382d832SPeter Avalos }
24145382d832SPeter Avalos #endif
24155382d832SPeter Avalos (void) refresh();
24165382d832SPeter Avalos
24175382d832SPeter Avalos #ifdef HAVE_COLOR
24185382d832SPeter Avalos draw_childs_shadow(p);
24195382d832SPeter Avalos #endif
24205382d832SPeter Avalos }
24215382d832SPeter Avalos }
24225382d832SPeter Avalos }
24235940c9abSDaniel Fojt
24245940c9abSDaniel Fojt /*
24255940c9abSDaniel Fojt * Having just received a KEY_RESIZE, wait a short time to ignore followup
24265940c9abSDaniel Fojt * KEY_RESIZE events.
24275940c9abSDaniel Fojt */
24285940c9abSDaniel Fojt void
dlg_will_resize(WINDOW * win)24295940c9abSDaniel Fojt dlg_will_resize(WINDOW *win)
24305940c9abSDaniel Fojt {
24315940c9abSDaniel Fojt int n, base;
24325940c9abSDaniel Fojt int caught = 0;
24335940c9abSDaniel Fojt
24345940c9abSDaniel Fojt dialog_state.had_resize = TRUE;
24355940c9abSDaniel Fojt dlg_trace_win(win);
24365940c9abSDaniel Fojt wtimeout(win, WTIMEOUT_VAL * 5);
24375940c9abSDaniel Fojt
24385940c9abSDaniel Fojt for (n = base = 0; n < base + 10; ++n) {
24395940c9abSDaniel Fojt int ch;
24405940c9abSDaniel Fojt
24415940c9abSDaniel Fojt if ((ch = wgetch(win)) != ERR) {
24425940c9abSDaniel Fojt if (ch == KEY_RESIZE) {
24435940c9abSDaniel Fojt base = n;
24445940c9abSDaniel Fojt ++caught;
24455940c9abSDaniel Fojt } else if (ch != ERR) {
24465940c9abSDaniel Fojt ungetch(ch);
24475940c9abSDaniel Fojt break;
24485940c9abSDaniel Fojt }
24495940c9abSDaniel Fojt }
24505940c9abSDaniel Fojt }
24515940c9abSDaniel Fojt dlg_reset_timeout(win);
24525940c9abSDaniel Fojt DLG_TRACE(("# caught %d KEY_RESIZE key%s\n",
24535940c9abSDaniel Fojt 1 + caught,
24545940c9abSDaniel Fojt caught == 1 ? "" : "s"));
24555940c9abSDaniel Fojt }
24565382d832SPeter Avalos #endif /* KEY_RESIZE */
24575382d832SPeter Avalos
24585382d832SPeter Avalos WINDOW *
dlg_der_window(WINDOW * parent,int height,int width,int y,int x)2459*a8e38dc0SAntonio Huete Jimenez dlg_der_window(WINDOW *parent, int height, int width, int y, int x)
2460*a8e38dc0SAntonio Huete Jimenez {
2461*a8e38dc0SAntonio Huete Jimenez WINDOW *win;
2462*a8e38dc0SAntonio Huete Jimenez
2463*a8e38dc0SAntonio Huete Jimenez /* existing uses of derwin are (almost) guaranteed to succeed, and the
2464*a8e38dc0SAntonio Huete Jimenez * caller has to allow for failure.
2465*a8e38dc0SAntonio Huete Jimenez */
2466*a8e38dc0SAntonio Huete Jimenez if ((win = derwin(parent, height, width, y, x)) != 0) {
2467*a8e38dc0SAntonio Huete Jimenez add_subwindow(parent, win);
2468*a8e38dc0SAntonio Huete Jimenez (void) keypad(win, TRUE);
2469*a8e38dc0SAntonio Huete Jimenez }
2470*a8e38dc0SAntonio Huete Jimenez return win;
2471*a8e38dc0SAntonio Huete Jimenez }
2472*a8e38dc0SAntonio Huete Jimenez
2473*a8e38dc0SAntonio Huete Jimenez WINDOW *
dlg_sub_window(WINDOW * parent,int height,int width,int y,int x)24745382d832SPeter Avalos dlg_sub_window(WINDOW *parent, int height, int width, int y, int x)
24755382d832SPeter Avalos {
24765382d832SPeter Avalos WINDOW *win;
24775382d832SPeter Avalos
24785382d832SPeter Avalos if ((win = subwin(parent, height, width, y, x)) == 0) {
24795382d832SPeter Avalos dlg_exiterr("Can't make sub-window at (%d,%d), size (%d,%d).\n",
24805382d832SPeter Avalos y, x, height, width);
24815382d832SPeter Avalos }
24825382d832SPeter Avalos
24835382d832SPeter Avalos add_subwindow(parent, win);
24845382d832SPeter Avalos (void) keypad(win, TRUE);
24855382d832SPeter Avalos return win;
24865382d832SPeter Avalos }
24875382d832SPeter Avalos
24885382d832SPeter Avalos /* obsolete */
24895382d832SPeter Avalos int
dlg_default_item(char ** items,int llen)24905382d832SPeter Avalos dlg_default_item(char **items, int llen)
24915382d832SPeter Avalos {
24925382d832SPeter Avalos int result = 0;
24935382d832SPeter Avalos
24945382d832SPeter Avalos if (dialog_vars.default_item != 0) {
24955382d832SPeter Avalos int count = 0;
24965382d832SPeter Avalos while (*items != 0) {
24975382d832SPeter Avalos if (!strcmp(dialog_vars.default_item, *items)) {
24985382d832SPeter Avalos result = count;
24995382d832SPeter Avalos break;
25005382d832SPeter Avalos }
25015382d832SPeter Avalos items += llen;
25025382d832SPeter Avalos count++;
25035382d832SPeter Avalos }
25045382d832SPeter Avalos }
25055382d832SPeter Avalos return result;
25065382d832SPeter Avalos }
25075382d832SPeter Avalos
25085382d832SPeter Avalos int
dlg_default_listitem(DIALOG_LISTITEM * items)25095382d832SPeter Avalos dlg_default_listitem(DIALOG_LISTITEM * items)
25105382d832SPeter Avalos {
25115382d832SPeter Avalos int result = 0;
25125382d832SPeter Avalos
25135382d832SPeter Avalos if (dialog_vars.default_item != 0) {
25145382d832SPeter Avalos int count = 0;
25155382d832SPeter Avalos while (items->name != 0) {
25165382d832SPeter Avalos if (!strcmp(dialog_vars.default_item, items->name)) {
25175382d832SPeter Avalos result = count;
25185382d832SPeter Avalos break;
25195382d832SPeter Avalos }
25205382d832SPeter Avalos ++items;
25215382d832SPeter Avalos count++;
25225382d832SPeter Avalos }
25235382d832SPeter Avalos }
25245382d832SPeter Avalos return result;
25255382d832SPeter Avalos }
25265382d832SPeter Avalos
25275382d832SPeter Avalos /*
25285382d832SPeter Avalos * Draw the string for item_help
25295382d832SPeter Avalos */
25305382d832SPeter Avalos void
dlg_item_help(const char * txt)25315382d832SPeter Avalos dlg_item_help(const char *txt)
25325382d832SPeter Avalos {
25335382d832SPeter Avalos if (USE_ITEM_HELP(txt)) {
25345382d832SPeter Avalos chtype attr = A_NORMAL;
25355382d832SPeter Avalos
25365940c9abSDaniel Fojt dlg_attrset(stdscr, itemhelp_attr);
25375382d832SPeter Avalos (void) wmove(stdscr, LINES - 1, 0);
25385382d832SPeter Avalos (void) wclrtoeol(stdscr);
25395382d832SPeter Avalos (void) addch(' ');
25405382d832SPeter Avalos dlg_print_text(stdscr, txt, COLS - 1, &attr);
25415940c9abSDaniel Fojt
25425382d832SPeter Avalos if (itemhelp_attr & A_COLOR) {
25435940c9abSDaniel Fojt int y, x;
25445382d832SPeter Avalos /* fill the remainder of the line with the window's attributes */
25455382d832SPeter Avalos getyx(stdscr, y, x);
25465382d832SPeter Avalos (void) y;
25475382d832SPeter Avalos while (x < COLS) {
25485382d832SPeter Avalos (void) addch(' ');
25495382d832SPeter Avalos ++x;
25505382d832SPeter Avalos }
25515382d832SPeter Avalos }
25525382d832SPeter Avalos (void) wnoutrefresh(stdscr);
25535382d832SPeter Avalos }
25545382d832SPeter Avalos }
25555382d832SPeter Avalos
25565382d832SPeter Avalos #ifndef HAVE_STRCASECMP
25575382d832SPeter Avalos int
dlg_strcmp(const char * a,const char * b)25585382d832SPeter Avalos dlg_strcmp(const char *a, const char *b)
25595382d832SPeter Avalos {
25605382d832SPeter Avalos int ac, bc, cmp;
25615382d832SPeter Avalos
25625382d832SPeter Avalos for (;;) {
25635382d832SPeter Avalos ac = UCH(*a++);
25645382d832SPeter Avalos bc = UCH(*b++);
25655382d832SPeter Avalos if (isalpha(ac) && islower(ac))
25665382d832SPeter Avalos ac = _toupper(ac);
25675382d832SPeter Avalos if (isalpha(bc) && islower(bc))
25685382d832SPeter Avalos bc = _toupper(bc);
25695382d832SPeter Avalos cmp = ac - bc;
25705382d832SPeter Avalos if (ac == 0 || bc == 0 || cmp != 0)
25715382d832SPeter Avalos break;
25725382d832SPeter Avalos }
25735382d832SPeter Avalos return cmp;
25745382d832SPeter Avalos }
25755382d832SPeter Avalos #endif
25765382d832SPeter Avalos
25775382d832SPeter Avalos /*
25785382d832SPeter Avalos * Returns true if 'dst' points to a blank which follows another blank which
25795382d832SPeter Avalos * is not a leading blank on a line.
25805382d832SPeter Avalos */
25815382d832SPeter Avalos static bool
trim_blank(char * base,char * dst)25825382d832SPeter Avalos trim_blank(char *base, char *dst)
25835382d832SPeter Avalos {
25845940c9abSDaniel Fojt int count = !!isblank(UCH(*dst));
25855382d832SPeter Avalos
25865382d832SPeter Avalos while (dst-- != base) {
25875382d832SPeter Avalos if (*dst == '\n') {
25885940c9abSDaniel Fojt break;
25895940c9abSDaniel Fojt } else if (isblank(UCH(*dst))) {
25905382d832SPeter Avalos count++;
25915940c9abSDaniel Fojt } else {
25925940c9abSDaniel Fojt break;
25935382d832SPeter Avalos }
25945382d832SPeter Avalos }
25955940c9abSDaniel Fojt return (count > 1);
25965382d832SPeter Avalos }
25975382d832SPeter Avalos
25985382d832SPeter Avalos /*
25995382d832SPeter Avalos * Change embedded "\n" substrings to '\n' characters and tabs to single
26005382d832SPeter Avalos * spaces. If there are no "\n"s, it will strip all extra spaces, for
26015382d832SPeter Avalos * justification. If it has "\n"'s, it will preserve extra spaces. If cr_wrap
26025382d832SPeter Avalos * is set, it will preserve '\n's.
26035382d832SPeter Avalos */
26045382d832SPeter Avalos void
dlg_trim_string(char * s)26055382d832SPeter Avalos dlg_trim_string(char *s)
26065382d832SPeter Avalos {
26075382d832SPeter Avalos char *base = s;
26085382d832SPeter Avalos char *p1;
26095382d832SPeter Avalos char *p = s;
26105382d832SPeter Avalos int has_newlines = !dialog_vars.no_nl_expand && (strstr(s, "\\n") != 0);
26115382d832SPeter Avalos
26125382d832SPeter Avalos while (*p != '\0') {
26135382d832SPeter Avalos if (*p == TAB && !dialog_vars.nocollapse)
26145382d832SPeter Avalos *p = ' ';
26155382d832SPeter Avalos
26165382d832SPeter Avalos if (has_newlines) { /* If prompt contains "\n" strings */
26175382d832SPeter Avalos if (*p == '\\' && *(p + 1) == 'n') {
26185382d832SPeter Avalos *s++ = '\n';
26195382d832SPeter Avalos p += 2;
26205382d832SPeter Avalos p1 = p;
26215382d832SPeter Avalos /*
26225382d832SPeter Avalos * Handle end of lines intelligently. If '\n' follows "\n"
26235382d832SPeter Avalos * then ignore the '\n'. This eliminates the need to escape
26245382d832SPeter Avalos * the '\n' character (no need to use "\n\").
26255382d832SPeter Avalos */
26265940c9abSDaniel Fojt while (isblank(UCH(*p1)))
26275382d832SPeter Avalos p1++;
26285382d832SPeter Avalos if (*p1 == '\n')
26295382d832SPeter Avalos p = p1 + 1;
26305382d832SPeter Avalos } else if (*p == '\n') {
26315382d832SPeter Avalos if (dialog_vars.cr_wrap)
26325382d832SPeter Avalos *s++ = *p++;
26335382d832SPeter Avalos else {
26345382d832SPeter Avalos /* Replace the '\n' with a space if cr_wrap is not set */
26355940c9abSDaniel Fojt if (!trim_blank(base, p))
26365382d832SPeter Avalos *s++ = ' ';
26375382d832SPeter Avalos p++;
26385382d832SPeter Avalos }
26395382d832SPeter Avalos } else /* If *p != '\n' */
26405382d832SPeter Avalos *s++ = *p++;
26415382d832SPeter Avalos } else if (dialog_vars.trim_whitespace) {
26425940c9abSDaniel Fojt if (isblank(UCH(*p))) {
26435940c9abSDaniel Fojt if (!isblank(UCH(*(s - 1)))) {
26445382d832SPeter Avalos *s++ = ' ';
26455382d832SPeter Avalos p++;
26465382d832SPeter Avalos } else
26475382d832SPeter Avalos p++;
26485382d832SPeter Avalos } else if (*p == '\n') {
26495382d832SPeter Avalos if (dialog_vars.cr_wrap)
26505382d832SPeter Avalos *s++ = *p++;
26515940c9abSDaniel Fojt else if (!isblank(UCH(*(s - 1)))) {
26525382d832SPeter Avalos /* Strip '\n's if cr_wrap is not set. */
26535382d832SPeter Avalos *s++ = ' ';
26545382d832SPeter Avalos p++;
26555382d832SPeter Avalos } else
26565382d832SPeter Avalos p++;
26575382d832SPeter Avalos } else
26585382d832SPeter Avalos *s++ = *p++;
26595382d832SPeter Avalos } else { /* If there are no "\n" strings */
26605940c9abSDaniel Fojt if (isblank(UCH(*p)) && !dialog_vars.nocollapse) {
26615940c9abSDaniel Fojt if (!trim_blank(base, p))
26625382d832SPeter Avalos *s++ = *p;
26635382d832SPeter Avalos p++;
26645382d832SPeter Avalos } else
26655382d832SPeter Avalos *s++ = *p++;
26665382d832SPeter Avalos }
26675382d832SPeter Avalos }
26685382d832SPeter Avalos
26695382d832SPeter Avalos *s = '\0';
26705382d832SPeter Avalos }
26715382d832SPeter Avalos
26725382d832SPeter Avalos void
dlg_set_focus(WINDOW * parent,WINDOW * win)26735382d832SPeter Avalos dlg_set_focus(WINDOW *parent, WINDOW *win)
26745382d832SPeter Avalos {
26755382d832SPeter Avalos if (win != 0) {
26765382d832SPeter Avalos (void) wmove(parent,
26775382d832SPeter Avalos getpary(win) + getcury(win),
26785382d832SPeter Avalos getparx(win) + getcurx(win));
26795382d832SPeter Avalos (void) wnoutrefresh(win);
26805382d832SPeter Avalos (void) doupdate();
26815382d832SPeter Avalos }
26825382d832SPeter Avalos }
26835382d832SPeter Avalos
26845382d832SPeter Avalos /*
2685*a8e38dc0SAntonio Huete Jimenez * Returns the nominal maximum buffer size, given the caller's estimate of
2686*a8e38dc0SAntonio Huete Jimenez * the needed size. If the parameter is not greater than zero, return the
2687*a8e38dc0SAntonio Huete Jimenez * configured buffer size.
26885382d832SPeter Avalos */
26895382d832SPeter Avalos int
dlg_max_input(int max_len)26905382d832SPeter Avalos dlg_max_input(int max_len)
26915382d832SPeter Avalos {
2692*a8e38dc0SAntonio Huete Jimenez int limit = ((dialog_vars.max_input > 0)
2693*a8e38dc0SAntonio Huete Jimenez ? dialog_vars.max_input
2694*a8e38dc0SAntonio Huete Jimenez : MAX_LEN);
2695*a8e38dc0SAntonio Huete Jimenez
2696*a8e38dc0SAntonio Huete Jimenez if (max_len > limit || max_len <= 0)
2697*a8e38dc0SAntonio Huete Jimenez max_len = limit;
26985382d832SPeter Avalos
26995382d832SPeter Avalos return max_len;
27005382d832SPeter Avalos }
27015382d832SPeter Avalos
27025382d832SPeter Avalos /*
27035382d832SPeter Avalos * Free storage used for the result buffer.
27045382d832SPeter Avalos */
27055382d832SPeter Avalos void
dlg_clr_result(void)27065382d832SPeter Avalos dlg_clr_result(void)
27075382d832SPeter Avalos {
27085382d832SPeter Avalos if (dialog_vars.input_length) {
27095382d832SPeter Avalos dialog_vars.input_length = 0;
27105382d832SPeter Avalos if (dialog_vars.input_result)
27115382d832SPeter Avalos free(dialog_vars.input_result);
27125382d832SPeter Avalos }
27135382d832SPeter Avalos dialog_vars.input_result = 0;
27145382d832SPeter Avalos }
27155382d832SPeter Avalos
27165382d832SPeter Avalos /*
27175382d832SPeter Avalos * Setup a fixed-buffer for the result.
27185382d832SPeter Avalos */
27195382d832SPeter Avalos char *
dlg_set_result(const char * string)27205382d832SPeter Avalos dlg_set_result(const char *string)
27215382d832SPeter Avalos {
27225382d832SPeter Avalos unsigned need = string ? (unsigned) strlen(string) + 1 : 0;
27235382d832SPeter Avalos
27245382d832SPeter Avalos /* inputstr.c needs a fixed buffer */
27255382d832SPeter Avalos if (need < MAX_LEN)
27265382d832SPeter Avalos need = MAX_LEN;
27275382d832SPeter Avalos
27285382d832SPeter Avalos /*
27295382d832SPeter Avalos * If the buffer is not big enough, allocate a new one.
27305382d832SPeter Avalos */
27315382d832SPeter Avalos if (dialog_vars.input_length != 0
27325382d832SPeter Avalos || dialog_vars.input_result == 0
27335382d832SPeter Avalos || need > MAX_LEN) {
27345382d832SPeter Avalos
27355382d832SPeter Avalos dlg_clr_result();
27365382d832SPeter Avalos
27375382d832SPeter Avalos dialog_vars.input_length = need;
27385382d832SPeter Avalos dialog_vars.input_result = dlg_malloc(char, need);
27395382d832SPeter Avalos assert_ptr(dialog_vars.input_result, "dlg_set_result");
27405382d832SPeter Avalos }
27415382d832SPeter Avalos
27425382d832SPeter Avalos strcpy(dialog_vars.input_result, string ? string : "");
27435382d832SPeter Avalos
27445382d832SPeter Avalos return dialog_vars.input_result;
27455382d832SPeter Avalos }
27465382d832SPeter Avalos
27475382d832SPeter Avalos /*
27485382d832SPeter Avalos * Accumulate results in dynamically allocated buffer.
27495382d832SPeter Avalos * If input_length is zero, it is a MAX_LEN buffer belonging to the caller.
27505382d832SPeter Avalos */
27515382d832SPeter Avalos void
dlg_add_result(const char * string)27525382d832SPeter Avalos dlg_add_result(const char *string)
27535382d832SPeter Avalos {
27545382d832SPeter Avalos unsigned have = (dialog_vars.input_result
27555382d832SPeter Avalos ? (unsigned) strlen(dialog_vars.input_result)
27565382d832SPeter Avalos : 0);
27575382d832SPeter Avalos unsigned want = (unsigned) strlen(string) + 1 + have;
27585382d832SPeter Avalos
27595382d832SPeter Avalos if ((want >= MAX_LEN)
27605382d832SPeter Avalos || (dialog_vars.input_length != 0)
27615382d832SPeter Avalos || (dialog_vars.input_result == 0)) {
27625382d832SPeter Avalos
27635382d832SPeter Avalos if (dialog_vars.input_length == 0
27645382d832SPeter Avalos || dialog_vars.input_result == 0) {
27655382d832SPeter Avalos
27665382d832SPeter Avalos char *save_result = dialog_vars.input_result;
27675382d832SPeter Avalos
27685382d832SPeter Avalos dialog_vars.input_length = want * 2;
27695382d832SPeter Avalos dialog_vars.input_result = dlg_malloc(char, dialog_vars.input_length);
27705382d832SPeter Avalos assert_ptr(dialog_vars.input_result, "dlg_add_result malloc");
27715382d832SPeter Avalos dialog_vars.input_result[0] = '\0';
27725382d832SPeter Avalos if (save_result != 0)
27735382d832SPeter Avalos strcpy(dialog_vars.input_result, save_result);
27745382d832SPeter Avalos } else if (want >= dialog_vars.input_length) {
27755382d832SPeter Avalos dialog_vars.input_length = want * 2;
27765382d832SPeter Avalos dialog_vars.input_result = dlg_realloc(char,
27775382d832SPeter Avalos dialog_vars.input_length,
27785382d832SPeter Avalos dialog_vars.input_result);
27795382d832SPeter Avalos assert_ptr(dialog_vars.input_result, "dlg_add_result realloc");
27805382d832SPeter Avalos }
27815382d832SPeter Avalos }
27825382d832SPeter Avalos strcat(dialog_vars.input_result, string);
27835382d832SPeter Avalos }
27845382d832SPeter Avalos
27855382d832SPeter Avalos /*
27865382d832SPeter Avalos * These are characters that (aside from the quote-delimiter) will have to
27875382d832SPeter Avalos * be escaped in a single- or double-quoted string.
27885382d832SPeter Avalos */
27895382d832SPeter Avalos #define FIX_SINGLE "\n\\"
27905382d832SPeter Avalos #define FIX_DOUBLE FIX_SINGLE "[]{}?*;`~#$^&()|<>"
27915382d832SPeter Avalos
27925382d832SPeter Avalos /*
27935382d832SPeter Avalos * Returns the quote-delimiter.
27945382d832SPeter Avalos */
27955382d832SPeter Avalos static const char *
quote_delimiter(void)27965382d832SPeter Avalos quote_delimiter(void)
27975382d832SPeter Avalos {
27985382d832SPeter Avalos return dialog_vars.single_quoted ? "'" : "\"";
27995382d832SPeter Avalos }
28005382d832SPeter Avalos
28015382d832SPeter Avalos /*
28025382d832SPeter Avalos * Returns true if we should quote the given string.
28035382d832SPeter Avalos */
28045382d832SPeter Avalos static bool
must_quote(char * string)28055382d832SPeter Avalos must_quote(char *string)
28065382d832SPeter Avalos {
28075382d832SPeter Avalos bool code = FALSE;
28085382d832SPeter Avalos
28095382d832SPeter Avalos if (*string != '\0') {
28105382d832SPeter Avalos size_t len = strlen(string);
28115382d832SPeter Avalos if (strcspn(string, quote_delimiter()) != len)
28125382d832SPeter Avalos code = TRUE;
28135382d832SPeter Avalos else if (strcspn(string, "\n\t ") != len)
28145382d832SPeter Avalos code = TRUE;
28155382d832SPeter Avalos else
28165382d832SPeter Avalos code = (strcspn(string, FIX_DOUBLE) != len);
28175382d832SPeter Avalos } else {
28185382d832SPeter Avalos code = TRUE;
28195382d832SPeter Avalos }
28205382d832SPeter Avalos
28215382d832SPeter Avalos return code;
28225382d832SPeter Avalos }
28235382d832SPeter Avalos
28245382d832SPeter Avalos /*
28255382d832SPeter Avalos * Add a quoted string to the result buffer.
28265382d832SPeter Avalos */
28275382d832SPeter Avalos void
dlg_add_quoted(char * string)28285382d832SPeter Avalos dlg_add_quoted(char *string)
28295382d832SPeter Avalos {
28305382d832SPeter Avalos char temp[2];
28315382d832SPeter Avalos const char *my_quote = quote_delimiter();
28325382d832SPeter Avalos const char *must_fix = (dialog_vars.single_quoted
28335382d832SPeter Avalos ? FIX_SINGLE
28345382d832SPeter Avalos : FIX_DOUBLE);
28355382d832SPeter Avalos
28365382d832SPeter Avalos if (must_quote(string)) {
28375382d832SPeter Avalos temp[1] = '\0';
28385382d832SPeter Avalos dlg_add_result(my_quote);
28395382d832SPeter Avalos while (*string != '\0') {
28405382d832SPeter Avalos temp[0] = *string++;
28411ef6786aSJohn Marino if ((strchr) (my_quote, *temp) || (strchr) (must_fix, *temp))
28425382d832SPeter Avalos dlg_add_result("\\");
28435382d832SPeter Avalos dlg_add_result(temp);
28445382d832SPeter Avalos }
28455382d832SPeter Avalos dlg_add_result(my_quote);
28465382d832SPeter Avalos } else {
28475382d832SPeter Avalos dlg_add_result(string);
28485382d832SPeter Avalos }
28495382d832SPeter Avalos }
28505382d832SPeter Avalos
28515382d832SPeter Avalos /*
28525382d832SPeter Avalos * When adding a result, make that depend on whether "--quoted" is used.
28535382d832SPeter Avalos */
28545382d832SPeter Avalos void
dlg_add_string(char * string)28555382d832SPeter Avalos dlg_add_string(char *string)
28565382d832SPeter Avalos {
28575382d832SPeter Avalos if (dialog_vars.quoted) {
28585382d832SPeter Avalos dlg_add_quoted(string);
28595382d832SPeter Avalos } else {
28605382d832SPeter Avalos dlg_add_result(string);
28615382d832SPeter Avalos }
28625382d832SPeter Avalos }
28635382d832SPeter Avalos
28645382d832SPeter Avalos bool
dlg_need_separator(void)28655382d832SPeter Avalos dlg_need_separator(void)
28665382d832SPeter Avalos {
28675382d832SPeter Avalos bool result = FALSE;
28685382d832SPeter Avalos
28695382d832SPeter Avalos if (dialog_vars.output_separator) {
28705382d832SPeter Avalos result = TRUE;
28715382d832SPeter Avalos } else if (dialog_vars.input_result && *(dialog_vars.input_result)) {
28725382d832SPeter Avalos result = TRUE;
28735382d832SPeter Avalos }
28745382d832SPeter Avalos return result;
28755382d832SPeter Avalos }
28765382d832SPeter Avalos
28775382d832SPeter Avalos void
dlg_add_separator(void)28785382d832SPeter Avalos dlg_add_separator(void)
28795382d832SPeter Avalos {
28805382d832SPeter Avalos const char *separator = (dialog_vars.separate_output) ? "\n" : " ";
28815382d832SPeter Avalos
28825382d832SPeter Avalos if (dialog_vars.output_separator)
28835382d832SPeter Avalos separator = dialog_vars.output_separator;
28845382d832SPeter Avalos
28855382d832SPeter Avalos dlg_add_result(separator);
28865382d832SPeter Avalos }
28875382d832SPeter Avalos
28881ef6786aSJohn Marino #define HELP_PREFIX "HELP "
28891ef6786aSJohn Marino
28901ef6786aSJohn Marino void
dlg_add_help_listitem(int * result,char ** tag,DIALOG_LISTITEM * item)28911ef6786aSJohn Marino dlg_add_help_listitem(int *result, char **tag, DIALOG_LISTITEM * item)
28921ef6786aSJohn Marino {
28931ef6786aSJohn Marino dlg_add_result(HELP_PREFIX);
28941ef6786aSJohn Marino if (USE_ITEM_HELP(item->help)) {
28951ef6786aSJohn Marino *tag = dialog_vars.help_tags ? item->name : item->help;
28961ef6786aSJohn Marino *result = DLG_EXIT_ITEM_HELP;
28971ef6786aSJohn Marino } else {
28981ef6786aSJohn Marino *tag = item->name;
28991ef6786aSJohn Marino }
29001ef6786aSJohn Marino }
29011ef6786aSJohn Marino
29021ef6786aSJohn Marino void
dlg_add_help_formitem(int * result,char ** tag,DIALOG_FORMITEM * item)29031ef6786aSJohn Marino dlg_add_help_formitem(int *result, char **tag, DIALOG_FORMITEM * item)
29041ef6786aSJohn Marino {
29051ef6786aSJohn Marino dlg_add_result(HELP_PREFIX);
29061ef6786aSJohn Marino if (USE_ITEM_HELP(item->help)) {
29071ef6786aSJohn Marino *tag = dialog_vars.help_tags ? item->name : item->help;
29081ef6786aSJohn Marino *result = DLG_EXIT_ITEM_HELP;
29091ef6786aSJohn Marino } else {
29101ef6786aSJohn Marino *tag = item->name;
29111ef6786aSJohn Marino }
29121ef6786aSJohn Marino }
29131ef6786aSJohn Marino
29145382d832SPeter Avalos /*
29155382d832SPeter Avalos * Some widgets support only one value of a given variable - save/restore the
29165382d832SPeter Avalos * global dialog_vars so we can override it consistently.
29175382d832SPeter Avalos */
29185382d832SPeter Avalos void
dlg_save_vars(DIALOG_VARS * vars)29195382d832SPeter Avalos dlg_save_vars(DIALOG_VARS * vars)
29205382d832SPeter Avalos {
29215382d832SPeter Avalos *vars = dialog_vars;
29225382d832SPeter Avalos }
29235382d832SPeter Avalos
29245382d832SPeter Avalos /*
29255382d832SPeter Avalos * Most of the data in DIALOG_VARS is normally set by command-line options.
29265382d832SPeter Avalos * The input_result member is an exception; it is normally set by the dialog
29275382d832SPeter Avalos * library to return result values.
29285382d832SPeter Avalos */
29295382d832SPeter Avalos void
dlg_restore_vars(DIALOG_VARS * vars)29305382d832SPeter Avalos dlg_restore_vars(DIALOG_VARS * vars)
29315382d832SPeter Avalos {
29325382d832SPeter Avalos char *save_result = dialog_vars.input_result;
29335382d832SPeter Avalos unsigned save_length = dialog_vars.input_length;
29345382d832SPeter Avalos
29355382d832SPeter Avalos dialog_vars = *vars;
29365382d832SPeter Avalos dialog_vars.input_result = save_result;
29375382d832SPeter Avalos dialog_vars.input_length = save_length;
29385382d832SPeter Avalos }
29395382d832SPeter Avalos
29405382d832SPeter Avalos /*
29415382d832SPeter Avalos * Called each time a widget is invoked which may do output, increment a count.
29425382d832SPeter Avalos */
29435382d832SPeter Avalos void
dlg_does_output(void)29445382d832SPeter Avalos dlg_does_output(void)
29455382d832SPeter Avalos {
29465382d832SPeter Avalos dialog_state.output_count += 1;
29475382d832SPeter Avalos }
29485382d832SPeter Avalos
29495382d832SPeter Avalos /*
29505382d832SPeter Avalos * Compatibility for different versions of curses.
29515382d832SPeter Avalos */
29525382d832SPeter Avalos #if !(defined(HAVE_GETBEGX) && defined(HAVE_GETBEGY))
29535382d832SPeter Avalos int
dlg_getbegx(WINDOW * win)29545382d832SPeter Avalos dlg_getbegx(WINDOW *win)
29555382d832SPeter Avalos {
29565382d832SPeter Avalos int y, x;
29575382d832SPeter Avalos getbegyx(win, y, x);
2958*a8e38dc0SAntonio Huete Jimenez (void) y;
29595382d832SPeter Avalos return x;
29605382d832SPeter Avalos }
29615382d832SPeter Avalos int
dlg_getbegy(WINDOW * win)29625382d832SPeter Avalos dlg_getbegy(WINDOW *win)
29635382d832SPeter Avalos {
29645382d832SPeter Avalos int y, x;
29655382d832SPeter Avalos getbegyx(win, y, x);
2966*a8e38dc0SAntonio Huete Jimenez (void) x;
29675382d832SPeter Avalos return y;
29685382d832SPeter Avalos }
29695382d832SPeter Avalos #endif
29705382d832SPeter Avalos
29715382d832SPeter Avalos #if !(defined(HAVE_GETCURX) && defined(HAVE_GETCURY))
29725382d832SPeter Avalos int
dlg_getcurx(WINDOW * win)29735382d832SPeter Avalos dlg_getcurx(WINDOW *win)
29745382d832SPeter Avalos {
29755382d832SPeter Avalos int y, x;
29765382d832SPeter Avalos getyx(win, y, x);
2977*a8e38dc0SAntonio Huete Jimenez (void) y;
29785382d832SPeter Avalos return x;
29795382d832SPeter Avalos }
29805382d832SPeter Avalos int
dlg_getcury(WINDOW * win)29815382d832SPeter Avalos dlg_getcury(WINDOW *win)
29825382d832SPeter Avalos {
29835382d832SPeter Avalos int y, x;
29845382d832SPeter Avalos getyx(win, y, x);
2985*a8e38dc0SAntonio Huete Jimenez (void) x;
29865382d832SPeter Avalos return y;
29875382d832SPeter Avalos }
29885382d832SPeter Avalos #endif
29895382d832SPeter Avalos
29905382d832SPeter Avalos #if !(defined(HAVE_GETMAXX) && defined(HAVE_GETMAXY))
29915382d832SPeter Avalos int
dlg_getmaxx(WINDOW * win)29925382d832SPeter Avalos dlg_getmaxx(WINDOW *win)
29935382d832SPeter Avalos {
29945382d832SPeter Avalos int y, x;
29955382d832SPeter Avalos getmaxyx(win, y, x);
2996*a8e38dc0SAntonio Huete Jimenez (void) y;
29975382d832SPeter Avalos return x;
29985382d832SPeter Avalos }
29995382d832SPeter Avalos int
dlg_getmaxy(WINDOW * win)30005382d832SPeter Avalos dlg_getmaxy(WINDOW *win)
30015382d832SPeter Avalos {
30025382d832SPeter Avalos int y, x;
30035382d832SPeter Avalos getmaxyx(win, y, x);
3004*a8e38dc0SAntonio Huete Jimenez (void) x;
30055382d832SPeter Avalos return y;
30065382d832SPeter Avalos }
30075382d832SPeter Avalos #endif
30085382d832SPeter Avalos
30095382d832SPeter Avalos #if !(defined(HAVE_GETPARX) && defined(HAVE_GETPARY))
30105382d832SPeter Avalos int
dlg_getparx(WINDOW * win)30115382d832SPeter Avalos dlg_getparx(WINDOW *win)
30125382d832SPeter Avalos {
30135382d832SPeter Avalos int y, x;
30145382d832SPeter Avalos getparyx(win, y, x);
3015*a8e38dc0SAntonio Huete Jimenez (void) y;
30165382d832SPeter Avalos return x;
30175382d832SPeter Avalos }
30185382d832SPeter Avalos int
dlg_getpary(WINDOW * win)30195382d832SPeter Avalos dlg_getpary(WINDOW *win)
30205382d832SPeter Avalos {
30215382d832SPeter Avalos int y, x;
30225382d832SPeter Avalos getparyx(win, y, x);
3023*a8e38dc0SAntonio Huete Jimenez (void) x;
30245382d832SPeter Avalos return y;
30255382d832SPeter Avalos }
30265382d832SPeter Avalos #endif
30275382d832SPeter Avalos
30285382d832SPeter Avalos #ifdef NEED_WGETPARENT
30295382d832SPeter Avalos WINDOW *
dlg_wgetparent(WINDOW * win)30305382d832SPeter Avalos dlg_wgetparent(WINDOW *win)
30315382d832SPeter Avalos {
30325382d832SPeter Avalos #undef wgetparent
30335382d832SPeter Avalos WINDOW *result = 0;
30345382d832SPeter Avalos DIALOG_WINDOWS *p;
30355382d832SPeter Avalos
30365382d832SPeter Avalos for (p = dialog_state.all_subwindows; p != 0; p = p->next) {
30375382d832SPeter Avalos if (p->shadow == win) {
30385382d832SPeter Avalos result = p->normal;
30395382d832SPeter Avalos break;
30405382d832SPeter Avalos }
30415382d832SPeter Avalos }
30425382d832SPeter Avalos return result;
30435382d832SPeter Avalos }
30445382d832SPeter Avalos #endif
3045