14c8945a0SNathan Whitehorn /* 2*f4f33ea0SBaptiste Daroussin * $Id: util.c,v 1.272 2018/06/21 23:47:10 tom Exp $ 34c8945a0SNathan Whitehorn * 44c8945a0SNathan Whitehorn * util.c -- miscellaneous utilities for dialog 54c8945a0SNathan Whitehorn * 6*f4f33ea0SBaptiste Daroussin * Copyright 2000-2016,2018 Thomas E. Dickey 74c8945a0SNathan Whitehorn * 84c8945a0SNathan Whitehorn * This program is free software; you can redistribute it and/or modify 94c8945a0SNathan Whitehorn * it under the terms of the GNU Lesser General Public License, version 2.1 104c8945a0SNathan Whitehorn * as published by the Free Software Foundation. 114c8945a0SNathan Whitehorn * 124c8945a0SNathan Whitehorn * This program is distributed in the hope that it will be useful, but 134c8945a0SNathan Whitehorn * WITHOUT ANY WARRANTY; without even the implied warranty of 144c8945a0SNathan Whitehorn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 154c8945a0SNathan Whitehorn * Lesser General Public License for more details. 164c8945a0SNathan Whitehorn * 174c8945a0SNathan Whitehorn * You should have received a copy of the GNU Lesser General Public 184c8945a0SNathan Whitehorn * License along with this program; if not, write to 194c8945a0SNathan Whitehorn * Free Software Foundation, Inc. 204c8945a0SNathan Whitehorn * 51 Franklin St., Fifth Floor 214c8945a0SNathan Whitehorn * Boston, MA 02110, USA. 224c8945a0SNathan Whitehorn * 234c8945a0SNathan Whitehorn * An earlier version of this program lists as authors 244c8945a0SNathan Whitehorn * Savio Lam (lam836@cs.cuhk.hk) 254c8945a0SNathan Whitehorn */ 264c8945a0SNathan Whitehorn 274c8945a0SNathan Whitehorn #include <dialog.h> 284c8945a0SNathan Whitehorn #include <dlg_keys.h> 294c8945a0SNathan Whitehorn 302a3e3873SBaptiste Daroussin #ifdef HAVE_SETLOCALE 312a3e3873SBaptiste Daroussin #include <locale.h> 322a3e3873SBaptiste Daroussin #endif 332a3e3873SBaptiste Daroussin 342a3e3873SBaptiste Daroussin #ifdef NEED_WCHAR_H 352a3e3873SBaptiste Daroussin #include <wchar.h> 362a3e3873SBaptiste Daroussin #endif 372a3e3873SBaptiste Daroussin 384c8945a0SNathan Whitehorn #ifdef NCURSES_VERSION 394c8945a0SNathan Whitehorn #if defined(HAVE_NCURSESW_TERM_H) 404c8945a0SNathan Whitehorn #include <ncursesw/term.h> 414c8945a0SNathan Whitehorn #elif defined(HAVE_NCURSES_TERM_H) 424c8945a0SNathan Whitehorn #include <ncurses/term.h> 434c8945a0SNathan Whitehorn #else 444c8945a0SNathan Whitehorn #include <term.h> 454c8945a0SNathan Whitehorn #endif 464c8945a0SNathan Whitehorn #endif 474c8945a0SNathan Whitehorn 48682c9e0fSNathan Whitehorn #if defined(HAVE_WCHGAT) 49682c9e0fSNathan Whitehorn # if defined(NCURSES_VERSION_PATCH) 50682c9e0fSNathan Whitehorn # if NCURSES_VERSION_PATCH >= 20060715 51682c9e0fSNathan Whitehorn # define USE_WCHGAT 1 52682c9e0fSNathan Whitehorn # else 53682c9e0fSNathan Whitehorn # define USE_WCHGAT 0 54682c9e0fSNathan Whitehorn # endif 55682c9e0fSNathan Whitehorn # else 56682c9e0fSNathan Whitehorn # define USE_WCHGAT 1 57682c9e0fSNathan Whitehorn # endif 58682c9e0fSNathan Whitehorn #else 59682c9e0fSNathan Whitehorn # define USE_WCHGAT 0 60682c9e0fSNathan Whitehorn #endif 61682c9e0fSNathan Whitehorn 624c8945a0SNathan Whitehorn /* globals */ 634c8945a0SNathan Whitehorn DIALOG_STATE dialog_state; 644c8945a0SNathan Whitehorn DIALOG_VARS dialog_vars; 654c8945a0SNathan Whitehorn 662a3e3873SBaptiste Daroussin #if !(defined(HAVE_WGETPARENT) && defined(HAVE_WINDOW__PARENT)) 672a3e3873SBaptiste Daroussin #define NEED_WGETPARENT 1 682a3e3873SBaptiste Daroussin #else 692a3e3873SBaptiste Daroussin #undef NEED_WGETPARENT 702a3e3873SBaptiste Daroussin #endif 712a3e3873SBaptiste Daroussin 724c8945a0SNathan Whitehorn #define concat(a,b) a##b 734c8945a0SNathan Whitehorn 744c8945a0SNathan Whitehorn #ifdef HAVE_RC_FILE 754c8945a0SNathan Whitehorn #define RC_DATA(name,comment) , #name "_color", comment " color" 764c8945a0SNathan Whitehorn #else 774c8945a0SNathan Whitehorn #define RC_DATA(name,comment) /*nothing */ 784c8945a0SNathan Whitehorn #endif 794c8945a0SNathan Whitehorn 804c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 814c8945a0SNathan Whitehorn #include <dlg_colors.h> 824c8945a0SNathan Whitehorn #define COLOR_DATA(upr) , \ 834c8945a0SNathan Whitehorn concat(DLGC_FG_,upr), \ 844c8945a0SNathan Whitehorn concat(DLGC_BG_,upr), \ 854c8945a0SNathan Whitehorn concat(DLGC_HL_,upr) 864c8945a0SNathan Whitehorn #else 874c8945a0SNathan Whitehorn #define COLOR_DATA(upr) /*nothing */ 884c8945a0SNathan Whitehorn #endif 894c8945a0SNathan Whitehorn 904c8945a0SNathan Whitehorn #define DATA(atr,upr,lwr,cmt) { atr COLOR_DATA(upr) RC_DATA(lwr,cmt) } 914c8945a0SNathan Whitehorn 92682c9e0fSNathan Whitehorn #define UseShadow(dw) ((dw) != 0 && (dw)->normal != 0 && (dw)->shadow != 0) 93682c9e0fSNathan Whitehorn 944c8945a0SNathan Whitehorn /* 954c8945a0SNathan Whitehorn * Table of color and attribute values, default is for mono display. 962a3e3873SBaptiste Daroussin * The order matches the DIALOG_ATR() values. 974c8945a0SNathan Whitehorn */ 984c8945a0SNathan Whitehorn /* *INDENT-OFF* */ 994c8945a0SNathan Whitehorn DIALOG_COLORS dlg_color_table[] = 1004c8945a0SNathan Whitehorn { 1014c8945a0SNathan Whitehorn DATA(A_NORMAL, SCREEN, screen, "Screen"), 1024c8945a0SNathan Whitehorn DATA(A_NORMAL, SHADOW, shadow, "Shadow"), 1034c8945a0SNathan Whitehorn DATA(A_REVERSE, DIALOG, dialog, "Dialog box"), 1044c8945a0SNathan Whitehorn DATA(A_REVERSE, TITLE, title, "Dialog box title"), 1054c8945a0SNathan Whitehorn DATA(A_REVERSE, BORDER, border, "Dialog box border"), 1064c8945a0SNathan Whitehorn DATA(A_BOLD, BUTTON_ACTIVE, button_active, "Active button"), 1074c8945a0SNathan Whitehorn DATA(A_DIM, BUTTON_INACTIVE, button_inactive, "Inactive button"), 1084c8945a0SNathan Whitehorn DATA(A_UNDERLINE, BUTTON_KEY_ACTIVE, button_key_active, "Active button key"), 1094c8945a0SNathan Whitehorn DATA(A_UNDERLINE, BUTTON_KEY_INACTIVE, button_key_inactive, "Inactive button key"), 1104c8945a0SNathan Whitehorn DATA(A_NORMAL, BUTTON_LABEL_ACTIVE, button_label_active, "Active button label"), 1114c8945a0SNathan Whitehorn DATA(A_NORMAL, BUTTON_LABEL_INACTIVE, button_label_inactive, "Inactive button label"), 1124c8945a0SNathan Whitehorn DATA(A_REVERSE, INPUTBOX, inputbox, "Input box"), 1134c8945a0SNathan Whitehorn DATA(A_REVERSE, INPUTBOX_BORDER, inputbox_border, "Input box border"), 1144c8945a0SNathan Whitehorn DATA(A_REVERSE, SEARCHBOX, searchbox, "Search box"), 1154c8945a0SNathan Whitehorn DATA(A_REVERSE, SEARCHBOX_TITLE, searchbox_title, "Search box title"), 1164c8945a0SNathan Whitehorn DATA(A_REVERSE, SEARCHBOX_BORDER, searchbox_border, "Search box border"), 1174c8945a0SNathan Whitehorn DATA(A_REVERSE, POSITION_INDICATOR, position_indicator, "File position indicator"), 1184c8945a0SNathan Whitehorn DATA(A_REVERSE, MENUBOX, menubox, "Menu box"), 1194c8945a0SNathan Whitehorn DATA(A_REVERSE, MENUBOX_BORDER, menubox_border, "Menu box border"), 1204c8945a0SNathan Whitehorn DATA(A_REVERSE, ITEM, item, "Item"), 1214c8945a0SNathan Whitehorn DATA(A_NORMAL, ITEM_SELECTED, item_selected, "Selected item"), 1224c8945a0SNathan Whitehorn DATA(A_REVERSE, TAG, tag, "Tag"), 1234c8945a0SNathan Whitehorn DATA(A_REVERSE, TAG_SELECTED, tag_selected, "Selected tag"), 1244c8945a0SNathan Whitehorn DATA(A_NORMAL, TAG_KEY, tag_key, "Tag key"), 1254c8945a0SNathan Whitehorn DATA(A_BOLD, TAG_KEY_SELECTED, tag_key_selected, "Selected tag key"), 1264c8945a0SNathan Whitehorn DATA(A_REVERSE, CHECK, check, "Check box"), 1274c8945a0SNathan Whitehorn DATA(A_REVERSE, CHECK_SELECTED, check_selected, "Selected check box"), 1284c8945a0SNathan Whitehorn DATA(A_REVERSE, UARROW, uarrow, "Up arrow"), 1294c8945a0SNathan Whitehorn DATA(A_REVERSE, DARROW, darrow, "Down arrow"), 1304c8945a0SNathan Whitehorn DATA(A_NORMAL, ITEMHELP, itemhelp, "Item help-text"), 1314c8945a0SNathan Whitehorn DATA(A_BOLD, FORM_ACTIVE_TEXT, form_active_text, "Active form text"), 1324c8945a0SNathan Whitehorn DATA(A_REVERSE, FORM_TEXT, form_text, "Form text"), 1337a1c0d96SNathan Whitehorn DATA(A_NORMAL, FORM_ITEM_READONLY, form_item_readonly, "Readonly form item"), 1342a3e3873SBaptiste Daroussin DATA(A_REVERSE, GAUGE, gauge, "Dialog box gauge"), 1352a3e3873SBaptiste Daroussin DATA(A_REVERSE, BORDER2, border2, "Dialog box border2"), 1362a3e3873SBaptiste Daroussin DATA(A_REVERSE, INPUTBOX_BORDER2, inputbox_border2, "Input box border2"), 1372a3e3873SBaptiste Daroussin DATA(A_REVERSE, SEARCHBOX_BORDER2, searchbox_border2, "Search box border2"), 1382a3e3873SBaptiste Daroussin DATA(A_REVERSE, MENUBOX_BORDER2, menubox_border2, "Menu box border2") 1394c8945a0SNathan Whitehorn }; 1404c8945a0SNathan Whitehorn /* *INDENT-ON* */ 1414c8945a0SNathan Whitehorn 1424c8945a0SNathan Whitehorn /* 1432a3e3873SBaptiste Daroussin * Maintain a list of subwindows so that we can delete them to cleanup. 1442a3e3873SBaptiste Daroussin * More important, this provides a fallback when wgetparent() is not available. 1452a3e3873SBaptiste Daroussin */ 1462a3e3873SBaptiste Daroussin static void 1472a3e3873SBaptiste Daroussin add_subwindow(WINDOW *parent, WINDOW *child) 1482a3e3873SBaptiste Daroussin { 1492a3e3873SBaptiste Daroussin DIALOG_WINDOWS *p = dlg_calloc(DIALOG_WINDOWS, 1); 1502a3e3873SBaptiste Daroussin 1512a3e3873SBaptiste Daroussin if (p != 0) { 1522a3e3873SBaptiste Daroussin p->normal = parent; 1532a3e3873SBaptiste Daroussin p->shadow = child; 1542a3e3873SBaptiste Daroussin p->next = dialog_state.all_subwindows; 1552a3e3873SBaptiste Daroussin dialog_state.all_subwindows = p; 1562a3e3873SBaptiste Daroussin } 1572a3e3873SBaptiste Daroussin } 1582a3e3873SBaptiste Daroussin 1592a3e3873SBaptiste Daroussin static void 1602a3e3873SBaptiste Daroussin del_subwindows(WINDOW *parent) 1612a3e3873SBaptiste Daroussin { 1622a3e3873SBaptiste Daroussin DIALOG_WINDOWS *p = dialog_state.all_subwindows; 1632a3e3873SBaptiste Daroussin DIALOG_WINDOWS *q = 0; 1642a3e3873SBaptiste Daroussin DIALOG_WINDOWS *r; 1652a3e3873SBaptiste Daroussin 1662a3e3873SBaptiste Daroussin while (p != 0) { 1672a3e3873SBaptiste Daroussin if (p->normal == parent) { 1682a3e3873SBaptiste Daroussin delwin(p->shadow); 1692a3e3873SBaptiste Daroussin r = p->next; 1702a3e3873SBaptiste Daroussin if (q == 0) { 1712a3e3873SBaptiste Daroussin dialog_state.all_subwindows = r; 1722a3e3873SBaptiste Daroussin } else { 1732a3e3873SBaptiste Daroussin q->next = r; 1742a3e3873SBaptiste Daroussin } 1752a3e3873SBaptiste Daroussin free(p); 1762a3e3873SBaptiste Daroussin p = r; 1772a3e3873SBaptiste Daroussin } else { 1782a3e3873SBaptiste Daroussin q = p; 1792a3e3873SBaptiste Daroussin p = p->next; 1802a3e3873SBaptiste Daroussin } 1812a3e3873SBaptiste Daroussin } 1822a3e3873SBaptiste Daroussin } 1832a3e3873SBaptiste Daroussin 1842a3e3873SBaptiste Daroussin /* 1854c8945a0SNathan Whitehorn * Display background title if it exists ... 1864c8945a0SNathan Whitehorn */ 1874c8945a0SNathan Whitehorn void 1884c8945a0SNathan Whitehorn dlg_put_backtitle(void) 1894c8945a0SNathan Whitehorn { 1904c8945a0SNathan Whitehorn int i; 1914c8945a0SNathan Whitehorn 1924c8945a0SNathan Whitehorn if (dialog_vars.backtitle != NULL) { 1934c8945a0SNathan Whitehorn chtype attr = A_NORMAL; 1944c8945a0SNathan Whitehorn int backwidth = dlg_count_columns(dialog_vars.backtitle); 1954c8945a0SNathan Whitehorn 196*f4f33ea0SBaptiste Daroussin dlg_attrset(stdscr, screen_attr); 1974c8945a0SNathan Whitehorn (void) wmove(stdscr, 0, 1); 1984c8945a0SNathan Whitehorn dlg_print_text(stdscr, dialog_vars.backtitle, COLS - 2, &attr); 1994c8945a0SNathan Whitehorn for (i = 0; i < COLS - backwidth; i++) 2004c8945a0SNathan Whitehorn (void) waddch(stdscr, ' '); 2014c8945a0SNathan Whitehorn (void) wmove(stdscr, 1, 1); 2024c8945a0SNathan Whitehorn for (i = 0; i < COLS - 2; i++) 2034c8945a0SNathan Whitehorn (void) waddch(stdscr, dlg_boxchar(ACS_HLINE)); 2044c8945a0SNathan Whitehorn } 2054c8945a0SNathan Whitehorn 2064c8945a0SNathan Whitehorn (void) wnoutrefresh(stdscr); 2074c8945a0SNathan Whitehorn } 2084c8945a0SNathan Whitehorn 2094c8945a0SNathan Whitehorn /* 2104c8945a0SNathan Whitehorn * Set window to attribute 'attr'. There are more efficient ways to do this, 2114c8945a0SNathan Whitehorn * but will not work on older/buggy ncurses versions. 2124c8945a0SNathan Whitehorn */ 2134c8945a0SNathan Whitehorn void 2144c8945a0SNathan Whitehorn dlg_attr_clear(WINDOW *win, int height, int width, chtype attr) 2154c8945a0SNathan Whitehorn { 2164c8945a0SNathan Whitehorn int i, j; 2174c8945a0SNathan Whitehorn 218*f4f33ea0SBaptiste Daroussin dlg_attrset(win, attr); 2194c8945a0SNathan Whitehorn for (i = 0; i < height; i++) { 2204c8945a0SNathan Whitehorn (void) wmove(win, i, 0); 2214c8945a0SNathan Whitehorn for (j = 0; j < width; j++) 2224c8945a0SNathan Whitehorn (void) waddch(win, ' '); 2234c8945a0SNathan Whitehorn } 2244c8945a0SNathan Whitehorn (void) touchwin(win); 2254c8945a0SNathan Whitehorn } 2264c8945a0SNathan Whitehorn 2274c8945a0SNathan Whitehorn void 2284c8945a0SNathan Whitehorn dlg_clear(void) 2294c8945a0SNathan Whitehorn { 2304c8945a0SNathan Whitehorn dlg_attr_clear(stdscr, LINES, COLS, screen_attr); 2314c8945a0SNathan Whitehorn } 2324c8945a0SNathan Whitehorn 2334c8945a0SNathan Whitehorn #define isprivate(s) ((s) != 0 && strstr(s, "\033[?") != 0) 2344c8945a0SNathan Whitehorn 2354c8945a0SNathan Whitehorn #define TTY_DEVICE "/dev/tty" 2364c8945a0SNathan Whitehorn 2374c8945a0SNathan Whitehorn /* 2384c8945a0SNathan Whitehorn * If $DIALOG_TTY exists, allow the program to try to open the terminal 2394c8945a0SNathan Whitehorn * directly when stdout is redirected. By default we require the "--stdout" 2404c8945a0SNathan Whitehorn * option to be given, but some scripts were written making use of the 2414c8945a0SNathan Whitehorn * behavior of dialog which tried opening the terminal anyway. 2424c8945a0SNathan Whitehorn */ 2434c8945a0SNathan Whitehorn static char * 2444c8945a0SNathan Whitehorn dialog_tty(void) 2454c8945a0SNathan Whitehorn { 2464c8945a0SNathan Whitehorn char *result = getenv("DIALOG_TTY"); 2474c8945a0SNathan Whitehorn if (result != 0 && atoi(result) == 0) 2484c8945a0SNathan Whitehorn result = 0; 2494c8945a0SNathan Whitehorn return result; 2504c8945a0SNathan Whitehorn } 2514c8945a0SNathan Whitehorn 2524c8945a0SNathan Whitehorn /* 2534c8945a0SNathan Whitehorn * Open the terminal directly. If one of stdin, stdout or stderr really points 2544c8945a0SNathan Whitehorn * to a tty, use it. Otherwise give up and open /dev/tty. 2554c8945a0SNathan Whitehorn */ 2564c8945a0SNathan Whitehorn static int 2574c8945a0SNathan Whitehorn open_terminal(char **result, int mode) 2584c8945a0SNathan Whitehorn { 2594c8945a0SNathan Whitehorn const char *device = TTY_DEVICE; 2604c8945a0SNathan Whitehorn if (!isatty(fileno(stderr)) 2614c8945a0SNathan Whitehorn || (device = ttyname(fileno(stderr))) == 0) { 2624c8945a0SNathan Whitehorn if (!isatty(fileno(stdout)) 2634c8945a0SNathan Whitehorn || (device = ttyname(fileno(stdout))) == 0) { 2644c8945a0SNathan Whitehorn if (!isatty(fileno(stdin)) 2654c8945a0SNathan Whitehorn || (device = ttyname(fileno(stdin))) == 0) { 2664c8945a0SNathan Whitehorn device = TTY_DEVICE; 2674c8945a0SNathan Whitehorn } 2684c8945a0SNathan Whitehorn } 2694c8945a0SNathan Whitehorn } 2704c8945a0SNathan Whitehorn *result = dlg_strclone(device); 2714c8945a0SNathan Whitehorn return open(device, mode); 2724c8945a0SNathan Whitehorn } 2734c8945a0SNathan Whitehorn 2742a3e3873SBaptiste Daroussin #ifdef NCURSES_VERSION 2752a3e3873SBaptiste Daroussin static int 2762a3e3873SBaptiste Daroussin my_putc(int ch) 2772a3e3873SBaptiste Daroussin { 2782a3e3873SBaptiste Daroussin char buffer[2]; 2792a3e3873SBaptiste Daroussin int fd = fileno(dialog_state.screen_output); 2802a3e3873SBaptiste Daroussin 2812a3e3873SBaptiste Daroussin buffer[0] = (char) ch; 2822a3e3873SBaptiste Daroussin return (int) write(fd, buffer, (size_t) 1); 2832a3e3873SBaptiste Daroussin } 2842a3e3873SBaptiste Daroussin #endif 2852a3e3873SBaptiste Daroussin 2864c8945a0SNathan Whitehorn /* 2874c8945a0SNathan Whitehorn * Do some initialization for dialog. 2884c8945a0SNathan Whitehorn * 2894c8945a0SNathan Whitehorn * 'input' is the real tty input of dialog. Usually it is stdin, but if 2904c8945a0SNathan Whitehorn * --input-fd option is used, it may be anything. 2914c8945a0SNathan Whitehorn * 2924c8945a0SNathan Whitehorn * 'output' is where dialog will send its result. Usually it is stderr, but 2934c8945a0SNathan Whitehorn * if --stdout or --output-fd is used, it may be anything. We are concerned 2944c8945a0SNathan Whitehorn * mainly with the case where it happens to be the same as stdout. 2954c8945a0SNathan Whitehorn */ 2964c8945a0SNathan Whitehorn void 2974c8945a0SNathan Whitehorn init_dialog(FILE *input, FILE *output) 2984c8945a0SNathan Whitehorn { 2994c8945a0SNathan Whitehorn int fd1, fd2; 3004c8945a0SNathan Whitehorn char *device = 0; 3014c8945a0SNathan Whitehorn 3022a3e3873SBaptiste Daroussin setlocale(LC_ALL, ""); 3032a3e3873SBaptiste Daroussin 3044c8945a0SNathan Whitehorn dialog_state.output = output; 3054c8945a0SNathan Whitehorn dialog_state.tab_len = TAB_LEN; 3064c8945a0SNathan Whitehorn dialog_state.aspect_ratio = DEFAULT_ASPECT_RATIO; 3074c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 3084c8945a0SNathan Whitehorn dialog_state.use_colors = USE_COLORS; /* use colors by default? */ 3094c8945a0SNathan Whitehorn dialog_state.use_shadow = USE_SHADOW; /* shadow dialog boxes by default? */ 3104c8945a0SNathan Whitehorn #endif 3114c8945a0SNathan Whitehorn 3124c8945a0SNathan Whitehorn #ifdef HAVE_RC_FILE 3134c8945a0SNathan Whitehorn if (dlg_parse_rc() == -1) /* Read the configuration file */ 3144c8945a0SNathan Whitehorn dlg_exiterr("init_dialog: dlg_parse_rc"); 3154c8945a0SNathan Whitehorn #endif 3164c8945a0SNathan Whitehorn 3174c8945a0SNathan Whitehorn /* 3184c8945a0SNathan Whitehorn * Some widgets (such as gauge) may read from the standard input. Pipes 3194c8945a0SNathan Whitehorn * only connect stdout/stdin, so there is not much choice. But reading a 3204c8945a0SNathan Whitehorn * pipe would get in the way of curses' normal reading stdin for getch. 3214c8945a0SNathan Whitehorn * 3224c8945a0SNathan Whitehorn * As in the --stdout (see below), reopening the terminal does not always 3234c8945a0SNathan Whitehorn * work properly. dialog provides a --pipe-fd option for this purpose. We 3244c8945a0SNathan Whitehorn * test that case first (differing fileno's for input/stdin). If the 3254c8945a0SNathan Whitehorn * fileno's are equal, but we're not reading from a tty, see if we can open 3264c8945a0SNathan Whitehorn * /dev/tty. 3274c8945a0SNathan Whitehorn */ 3284c8945a0SNathan Whitehorn dialog_state.pipe_input = stdin; 3294c8945a0SNathan Whitehorn if (fileno(input) != fileno(stdin)) { 33019718649SNathan Whitehorn if ((fd1 = dup(fileno(input))) >= 0 3314c8945a0SNathan Whitehorn && (fd2 = dup(fileno(stdin))) >= 0) { 3324c8945a0SNathan Whitehorn (void) dup2(fileno(input), fileno(stdin)); 3334c8945a0SNathan Whitehorn dialog_state.pipe_input = fdopen(fd2, "r"); 3344c8945a0SNathan Whitehorn if (fileno(stdin) != 0) /* some functions may read fd #0 */ 3354c8945a0SNathan Whitehorn (void) dup2(fileno(stdin), 0); 3362a3e3873SBaptiste Daroussin } else { 3374c8945a0SNathan Whitehorn dlg_exiterr("cannot open tty-input"); 3382a3e3873SBaptiste Daroussin } 3392a3e3873SBaptiste Daroussin close(fd1); 3404c8945a0SNathan Whitehorn } else if (!isatty(fileno(stdin))) { 3412a3e3873SBaptiste Daroussin if ((fd1 = open_terminal(&device, O_RDONLY)) >= 0) { 3422a3e3873SBaptiste Daroussin if ((fd2 = dup(fileno(stdin))) >= 0) { 3434c8945a0SNathan Whitehorn dialog_state.pipe_input = fdopen(fd2, "r"); 3444c8945a0SNathan Whitehorn if (freopen(device, "r", stdin) == 0) 3454c8945a0SNathan Whitehorn dlg_exiterr("cannot open tty-input"); 3464c8945a0SNathan Whitehorn if (fileno(stdin) != 0) /* some functions may read fd #0 */ 3474c8945a0SNathan Whitehorn (void) dup2(fileno(stdin), 0); 3484c8945a0SNathan Whitehorn } 3492a3e3873SBaptiste Daroussin close(fd1); 3502a3e3873SBaptiste Daroussin } 3514c8945a0SNathan Whitehorn free(device); 3524c8945a0SNathan Whitehorn } 3534c8945a0SNathan Whitehorn 3544c8945a0SNathan Whitehorn /* 3554c8945a0SNathan Whitehorn * If stdout is not a tty and dialog is called with the --stdout option, we 3564c8945a0SNathan Whitehorn * have to provide for a way to write to the screen. 3574c8945a0SNathan Whitehorn * 3584c8945a0SNathan Whitehorn * The curses library normally writes its output to stdout, leaving stderr 3594c8945a0SNathan Whitehorn * free for scripting. Scripts are simpler when stdout is redirected. The 3604c8945a0SNathan Whitehorn * newterm function is useful; it allows us to specify where the output 3614c8945a0SNathan Whitehorn * goes. Reopening the terminal is not portable since several 3624c8945a0SNathan Whitehorn * configurations do not allow this to work properly: 3634c8945a0SNathan Whitehorn * 3644c8945a0SNathan Whitehorn * a) some getty implementations (and possibly broken tty drivers, e.g., on 3654c8945a0SNathan Whitehorn * HPUX 10 and 11) cause stdin to act as if it is still in cooked mode 3664c8945a0SNathan Whitehorn * even though results from ioctl's state that it is successfully 3674c8945a0SNathan Whitehorn * altered to raw mode. Broken is the proper term. 3684c8945a0SNathan Whitehorn * 3694c8945a0SNathan Whitehorn * b) the user may not have permissions on the device, e.g., if one su's 3704c8945a0SNathan Whitehorn * from the login user to another non-privileged user. 3714c8945a0SNathan Whitehorn */ 3724c8945a0SNathan Whitehorn if (!isatty(fileno(stdout)) 3734c8945a0SNathan Whitehorn && (fileno(stdout) == fileno(output) || dialog_tty())) { 3744c8945a0SNathan Whitehorn if ((fd1 = open_terminal(&device, O_WRONLY)) >= 0 3754c8945a0SNathan Whitehorn && (dialog_state.screen_output = fdopen(fd1, "w")) != 0) { 3764c8945a0SNathan Whitehorn if (newterm(NULL, dialog_state.screen_output, stdin) == 0) { 3774c8945a0SNathan Whitehorn dlg_exiterr("cannot initialize curses"); 3784c8945a0SNathan Whitehorn } 3794c8945a0SNathan Whitehorn free(device); 3804c8945a0SNathan Whitehorn } else { 3814c8945a0SNathan Whitehorn dlg_exiterr("cannot open tty-output"); 3824c8945a0SNathan Whitehorn } 3834c8945a0SNathan Whitehorn } else { 3844c8945a0SNathan Whitehorn dialog_state.screen_output = stdout; 3854c8945a0SNathan Whitehorn (void) initscr(); 3864c8945a0SNathan Whitehorn } 3874c8945a0SNathan Whitehorn #ifdef NCURSES_VERSION 3884c8945a0SNathan Whitehorn /* 3894c8945a0SNathan Whitehorn * Cancel xterm's alternate-screen mode. 3904c8945a0SNathan Whitehorn */ 3914c8945a0SNathan Whitehorn if (!dialog_vars.keep_tite 3922a3e3873SBaptiste Daroussin && (fileno(dialog_state.screen_output) != fileno(stdout) 3934c8945a0SNathan Whitehorn || isatty(fileno(dialog_state.screen_output))) 3944c8945a0SNathan Whitehorn && key_mouse != 0 /* xterm and kindred */ 3954c8945a0SNathan Whitehorn && isprivate(enter_ca_mode) 3964c8945a0SNathan Whitehorn && isprivate(exit_ca_mode)) { 3974c8945a0SNathan Whitehorn /* 3982a3e3873SBaptiste Daroussin * initscr() or newterm() already wrote enter_ca_mode as a side 3994c8945a0SNathan Whitehorn * effect of initializing the screen. It would be nice to not even 4004c8945a0SNathan Whitehorn * do that, but we do not really have access to the correct copy of 4014c8945a0SNathan Whitehorn * the terminfo description until those functions have been invoked. 4024c8945a0SNathan Whitehorn */ 4032a3e3873SBaptiste Daroussin (void) refresh(); 4042a3e3873SBaptiste Daroussin (void) tputs(exit_ca_mode, 0, my_putc); 4052a3e3873SBaptiste Daroussin (void) tputs(clear_screen, 0, my_putc); 4064c8945a0SNathan Whitehorn /* 4074c8945a0SNathan Whitehorn * Prevent ncurses from switching "back" to the normal screen when 4084c8945a0SNathan Whitehorn * exiting from dialog. That would move the cursor to the original 4094c8945a0SNathan Whitehorn * location saved in xterm. Normally curses sets the cursor position 4104c8945a0SNathan Whitehorn * to the first line after the display, but the alternate screen 4114c8945a0SNathan Whitehorn * switching is done after that point. 4124c8945a0SNathan Whitehorn * 4134c8945a0SNathan Whitehorn * Cancelling the strings altogether also works around the buggy 4144c8945a0SNathan Whitehorn * implementation of alternate-screen in rxvt, etc., which clear 4154c8945a0SNathan Whitehorn * more of the display than they should. 4164c8945a0SNathan Whitehorn */ 4174c8945a0SNathan Whitehorn enter_ca_mode = 0; 4184c8945a0SNathan Whitehorn exit_ca_mode = 0; 4194c8945a0SNathan Whitehorn } 4204c8945a0SNathan Whitehorn #endif 4214c8945a0SNathan Whitehorn #ifdef HAVE_FLUSHINP 4224c8945a0SNathan Whitehorn (void) flushinp(); 4234c8945a0SNathan Whitehorn #endif 4244c8945a0SNathan Whitehorn (void) keypad(stdscr, TRUE); 4254c8945a0SNathan Whitehorn (void) cbreak(); 4264c8945a0SNathan Whitehorn (void) noecho(); 4277a1c0d96SNathan Whitehorn 4287a1c0d96SNathan Whitehorn if (!dialog_state.no_mouse) { 4294c8945a0SNathan Whitehorn mouse_open(); 4307a1c0d96SNathan Whitehorn } 4317a1c0d96SNathan Whitehorn 4324c8945a0SNathan Whitehorn dialog_state.screen_initialized = TRUE; 4334c8945a0SNathan Whitehorn 4344c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 4354c8945a0SNathan Whitehorn if (dialog_state.use_colors || dialog_state.use_shadow) 4364c8945a0SNathan Whitehorn dlg_color_setup(); /* Set up colors */ 4374c8945a0SNathan Whitehorn #endif 4384c8945a0SNathan Whitehorn 4394c8945a0SNathan Whitehorn /* Set screen to screen attribute */ 4404c8945a0SNathan Whitehorn dlg_clear(); 4414c8945a0SNathan Whitehorn } 4424c8945a0SNathan Whitehorn 4434c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 4444c8945a0SNathan Whitehorn static int defined_colors = 1; /* pair-0 is reserved */ 4454c8945a0SNathan Whitehorn /* 4464c8945a0SNathan Whitehorn * Setup for color display 4474c8945a0SNathan Whitehorn */ 4484c8945a0SNathan Whitehorn void 4494c8945a0SNathan Whitehorn dlg_color_setup(void) 4504c8945a0SNathan Whitehorn { 4514c8945a0SNathan Whitehorn unsigned i; 4524c8945a0SNathan Whitehorn 4534c8945a0SNathan Whitehorn if (has_colors()) { /* Terminal supports color? */ 4544c8945a0SNathan Whitehorn (void) start_color(); 4554c8945a0SNathan Whitehorn 4564c8945a0SNathan Whitehorn #if defined(HAVE_USE_DEFAULT_COLORS) 4574c8945a0SNathan Whitehorn use_default_colors(); 4584c8945a0SNathan Whitehorn #endif 4594c8945a0SNathan Whitehorn 4604c8945a0SNathan Whitehorn #if defined(__NetBSD__) && defined(_CURSES_) 4614c8945a0SNathan Whitehorn #define C_ATTR(x,y) (((x) != 0 ? A_BOLD : 0) | COLOR_PAIR((y))) 4624c8945a0SNathan Whitehorn /* work around bug in NetBSD curses */ 4634c8945a0SNathan Whitehorn for (i = 0; i < sizeof(dlg_color_table) / 4644c8945a0SNathan Whitehorn sizeof(dlg_color_table[0]); i++) { 4654c8945a0SNathan Whitehorn 4664c8945a0SNathan Whitehorn /* Initialize color pairs */ 4674c8945a0SNathan Whitehorn (void) init_pair(i + 1, 4684c8945a0SNathan Whitehorn dlg_color_table[i].fg, 4694c8945a0SNathan Whitehorn dlg_color_table[i].bg); 4704c8945a0SNathan Whitehorn 4714c8945a0SNathan Whitehorn /* Setup color attributes */ 4724c8945a0SNathan Whitehorn dlg_color_table[i].atr = C_ATTR(dlg_color_table[i].hilite, i + 1); 4734c8945a0SNathan Whitehorn } 4744c8945a0SNathan Whitehorn defined_colors = i + 1; 4754c8945a0SNathan Whitehorn #else 4764c8945a0SNathan Whitehorn for (i = 0; i < sizeof(dlg_color_table) / 4774c8945a0SNathan Whitehorn sizeof(dlg_color_table[0]); i++) { 4784c8945a0SNathan Whitehorn 4794c8945a0SNathan Whitehorn /* Initialize color pairs */ 4804c8945a0SNathan Whitehorn chtype color = dlg_color_pair(dlg_color_table[i].fg, 4814c8945a0SNathan Whitehorn dlg_color_table[i].bg); 4824c8945a0SNathan Whitehorn 4834c8945a0SNathan Whitehorn /* Setup color attributes */ 4844c8945a0SNathan Whitehorn dlg_color_table[i].atr = ((dlg_color_table[i].hilite 4854c8945a0SNathan Whitehorn ? A_BOLD 4864c8945a0SNathan Whitehorn : 0) 4874c8945a0SNathan Whitehorn | color); 4884c8945a0SNathan Whitehorn } 4894c8945a0SNathan Whitehorn #endif 4904c8945a0SNathan Whitehorn } else { 4914c8945a0SNathan Whitehorn dialog_state.use_colors = FALSE; 4924c8945a0SNathan Whitehorn dialog_state.use_shadow = FALSE; 4934c8945a0SNathan Whitehorn } 4944c8945a0SNathan Whitehorn } 4954c8945a0SNathan Whitehorn 4964c8945a0SNathan Whitehorn int 4974c8945a0SNathan Whitehorn dlg_color_count(void) 4984c8945a0SNathan Whitehorn { 4994c8945a0SNathan Whitehorn return sizeof(dlg_color_table) / sizeof(dlg_color_table[0]); 5004c8945a0SNathan Whitehorn } 5014c8945a0SNathan Whitehorn 5024c8945a0SNathan Whitehorn /* 5037a1c0d96SNathan Whitehorn * Wrapper for getattrs(), or the more cumbersome X/Open wattr_get(). 5047a1c0d96SNathan Whitehorn */ 5057a1c0d96SNathan Whitehorn chtype 5067a1c0d96SNathan Whitehorn dlg_get_attrs(WINDOW *win) 5077a1c0d96SNathan Whitehorn { 5087a1c0d96SNathan Whitehorn chtype result; 5097a1c0d96SNathan Whitehorn #ifdef HAVE_GETATTRS 510682c9e0fSNathan Whitehorn result = (chtype) getattrs(win); 5117a1c0d96SNathan Whitehorn #else 5127a1c0d96SNathan Whitehorn attr_t my_result; 5137a1c0d96SNathan Whitehorn short my_pair; 5147a1c0d96SNathan Whitehorn wattr_get(win, &my_result, &my_pair, NULL); 5157a1c0d96SNathan Whitehorn result = my_result; 5167a1c0d96SNathan Whitehorn #endif 5177a1c0d96SNathan Whitehorn return result; 5187a1c0d96SNathan Whitehorn } 5197a1c0d96SNathan Whitehorn 5207a1c0d96SNathan Whitehorn /* 5214c8945a0SNathan Whitehorn * Reuse color pairs (they are limited), returning a COLOR_PAIR() value if we 5224c8945a0SNathan Whitehorn * have (or can) define a pair with the given color as foreground on the 5234c8945a0SNathan Whitehorn * window's defined background. 5244c8945a0SNathan Whitehorn */ 5254c8945a0SNathan Whitehorn chtype 5264c8945a0SNathan Whitehorn dlg_color_pair(int foreground, int background) 5274c8945a0SNathan Whitehorn { 5284c8945a0SNathan Whitehorn chtype result = 0; 5294c8945a0SNathan Whitehorn int pair; 5304c8945a0SNathan Whitehorn short fg, bg; 5314c8945a0SNathan Whitehorn bool found = FALSE; 5324c8945a0SNathan Whitehorn 5334c8945a0SNathan Whitehorn for (pair = 1; pair < defined_colors; ++pair) { 5344c8945a0SNathan Whitehorn if (pair_content((short) pair, &fg, &bg) != ERR 5354c8945a0SNathan Whitehorn && fg == foreground 5364c8945a0SNathan Whitehorn && bg == background) { 5374c8945a0SNathan Whitehorn result = (chtype) COLOR_PAIR(pair); 5384c8945a0SNathan Whitehorn found = TRUE; 5394c8945a0SNathan Whitehorn break; 5404c8945a0SNathan Whitehorn } 5414c8945a0SNathan Whitehorn } 5424c8945a0SNathan Whitehorn if (!found && (defined_colors + 1) < COLOR_PAIRS) { 5434c8945a0SNathan Whitehorn pair = defined_colors++; 5444c8945a0SNathan Whitehorn (void) init_pair((short) pair, (short) foreground, (short) background); 5454c8945a0SNathan Whitehorn result = (chtype) COLOR_PAIR(pair); 5464c8945a0SNathan Whitehorn } 5474c8945a0SNathan Whitehorn return result; 5484c8945a0SNathan Whitehorn } 5494c8945a0SNathan Whitehorn 5504c8945a0SNathan Whitehorn /* 5514c8945a0SNathan Whitehorn * Reuse color pairs (they are limited), returning a COLOR_PAIR() value if we 5524c8945a0SNathan Whitehorn * have (or can) define a pair with the given color as foreground on the 5534c8945a0SNathan Whitehorn * window's defined background. 5544c8945a0SNathan Whitehorn */ 5554c8945a0SNathan Whitehorn static chtype 5564c8945a0SNathan Whitehorn define_color(WINDOW *win, int foreground) 5574c8945a0SNathan Whitehorn { 5584c8945a0SNathan Whitehorn int pair; 5594c8945a0SNathan Whitehorn short fg, bg, background; 560*f4f33ea0SBaptiste Daroussin if (dialog_state.text_only) { 561*f4f33ea0SBaptiste Daroussin background = COLOR_BLACK; 562*f4f33ea0SBaptiste Daroussin } else { 563*f4f33ea0SBaptiste Daroussin chtype attrs = dlg_get_attrs(win); 5644c8945a0SNathan Whitehorn 5654c8945a0SNathan Whitehorn if ((pair = PAIR_NUMBER(attrs)) != 0 5664c8945a0SNathan Whitehorn && pair_content((short) pair, &fg, &bg) != ERR) { 5674c8945a0SNathan Whitehorn background = bg; 5684c8945a0SNathan Whitehorn } else { 5694c8945a0SNathan Whitehorn background = COLOR_BLACK; 5704c8945a0SNathan Whitehorn } 571*f4f33ea0SBaptiste Daroussin } 5724c8945a0SNathan Whitehorn return dlg_color_pair(foreground, background); 5734c8945a0SNathan Whitehorn } 5744c8945a0SNathan Whitehorn #endif 5754c8945a0SNathan Whitehorn 5764c8945a0SNathan Whitehorn /* 5774c8945a0SNathan Whitehorn * End using dialog functions. 5784c8945a0SNathan Whitehorn */ 5794c8945a0SNathan Whitehorn void 5804c8945a0SNathan Whitehorn end_dialog(void) 5814c8945a0SNathan Whitehorn { 5824c8945a0SNathan Whitehorn if (dialog_state.screen_initialized) { 5834c8945a0SNathan Whitehorn dialog_state.screen_initialized = FALSE; 5844c8945a0SNathan Whitehorn mouse_close(); 5854c8945a0SNathan Whitehorn (void) endwin(); 5864c8945a0SNathan Whitehorn (void) fflush(stdout); 5874c8945a0SNathan Whitehorn } 5884c8945a0SNathan Whitehorn } 5894c8945a0SNathan Whitehorn 590682c9e0fSNathan Whitehorn #define ESCAPE_LEN 3 5914c8945a0SNathan Whitehorn #define isOurEscape(p) (((p)[0] == '\\') && ((p)[1] == 'Z') && ((p)[2] != 0)) 5924c8945a0SNathan Whitehorn 5932a3e3873SBaptiste Daroussin int 5942a3e3873SBaptiste Daroussin dlg_count_real_columns(const char *text) 5952a3e3873SBaptiste Daroussin { 596febdb468SDevin Teske int result = 0; 597febdb468SDevin Teske if (*text) { 598febdb468SDevin Teske result = dlg_count_columns(text); 5992a3e3873SBaptiste Daroussin if (result && dialog_vars.colors) { 6002a3e3873SBaptiste Daroussin int hidden = 0; 6012a3e3873SBaptiste Daroussin while (*text) { 6022a3e3873SBaptiste Daroussin if (dialog_vars.colors && isOurEscape(text)) { 6032a3e3873SBaptiste Daroussin hidden += ESCAPE_LEN; 6042a3e3873SBaptiste Daroussin text += ESCAPE_LEN; 6052a3e3873SBaptiste Daroussin } else { 6062a3e3873SBaptiste Daroussin ++text; 6072a3e3873SBaptiste Daroussin } 6082a3e3873SBaptiste Daroussin } 6092a3e3873SBaptiste Daroussin result -= hidden; 6102a3e3873SBaptiste Daroussin } 611febdb468SDevin Teske } 6122a3e3873SBaptiste Daroussin return result; 6132a3e3873SBaptiste Daroussin } 6142a3e3873SBaptiste Daroussin 6154c8945a0SNathan Whitehorn static int 6164c8945a0SNathan Whitehorn centered(int width, const char *string) 6174c8945a0SNathan Whitehorn { 6182a3e3873SBaptiste Daroussin int need = dlg_count_real_columns(string); 6194c8945a0SNathan Whitehorn int left; 6204c8945a0SNathan Whitehorn 6212a3e3873SBaptiste Daroussin left = (width - need) / 2 - 1; 6224c8945a0SNathan Whitehorn if (left < 0) 6234c8945a0SNathan Whitehorn left = 0; 6244c8945a0SNathan Whitehorn return left; 6254c8945a0SNathan Whitehorn } 6264c8945a0SNathan Whitehorn 6277a1c0d96SNathan Whitehorn #ifdef USE_WIDE_CURSES 6287a1c0d96SNathan Whitehorn static bool 6297a1c0d96SNathan Whitehorn is_combining(const char *txt, int *combined) 6307a1c0d96SNathan Whitehorn { 6317a1c0d96SNathan Whitehorn bool result = FALSE; 6327a1c0d96SNathan Whitehorn 6337a1c0d96SNathan Whitehorn if (*combined == 0) { 6347a1c0d96SNathan Whitehorn if (UCH(*txt) >= 128) { 6357a1c0d96SNathan Whitehorn wchar_t wch; 6367a1c0d96SNathan Whitehorn mbstate_t state; 6377a1c0d96SNathan Whitehorn size_t given = strlen(txt); 6387a1c0d96SNathan Whitehorn size_t len; 6397a1c0d96SNathan Whitehorn 6407a1c0d96SNathan Whitehorn memset(&state, 0, sizeof(state)); 6417a1c0d96SNathan Whitehorn len = mbrtowc(&wch, txt, given, &state); 6427a1c0d96SNathan Whitehorn if ((int) len > 0 && wcwidth(wch) == 0) { 6437a1c0d96SNathan Whitehorn *combined = (int) len - 1; 6447a1c0d96SNathan Whitehorn result = TRUE; 6457a1c0d96SNathan Whitehorn } 6467a1c0d96SNathan Whitehorn } 6477a1c0d96SNathan Whitehorn } else { 6487a1c0d96SNathan Whitehorn result = TRUE; 6497a1c0d96SNathan Whitehorn *combined -= 1; 6507a1c0d96SNathan Whitehorn } 6517a1c0d96SNathan Whitehorn return result; 6527a1c0d96SNathan Whitehorn } 6537a1c0d96SNathan Whitehorn #endif 6547a1c0d96SNathan Whitehorn 6554c8945a0SNathan Whitehorn /* 6562a3e3873SBaptiste Daroussin * Print the name (tag) or text from a DIALOG_LISTITEM, highlighting the 6572a3e3873SBaptiste Daroussin * first character if selected. 6582a3e3873SBaptiste Daroussin */ 6592a3e3873SBaptiste Daroussin void 6602a3e3873SBaptiste Daroussin dlg_print_listitem(WINDOW *win, 6612a3e3873SBaptiste Daroussin const char *text, 6622a3e3873SBaptiste Daroussin int climit, 6632a3e3873SBaptiste Daroussin bool first, 6642a3e3873SBaptiste Daroussin int selected) 6652a3e3873SBaptiste Daroussin { 6662a3e3873SBaptiste Daroussin chtype attr = A_NORMAL; 6672a3e3873SBaptiste Daroussin int limit; 6682a3e3873SBaptiste Daroussin const int *cols; 6692a3e3873SBaptiste Daroussin chtype attrs[4]; 6702a3e3873SBaptiste Daroussin 6712a3e3873SBaptiste Daroussin if (text == 0) 6722a3e3873SBaptiste Daroussin text = ""; 6732a3e3873SBaptiste Daroussin 6742a3e3873SBaptiste Daroussin if (first) { 6752a3e3873SBaptiste Daroussin const int *indx = dlg_index_wchars(text); 6762a3e3873SBaptiste Daroussin attrs[3] = tag_key_selected_attr; 6772a3e3873SBaptiste Daroussin attrs[2] = tag_key_attr; 6782a3e3873SBaptiste Daroussin attrs[1] = tag_selected_attr; 6792a3e3873SBaptiste Daroussin attrs[0] = tag_attr; 6802a3e3873SBaptiste Daroussin 681*f4f33ea0SBaptiste Daroussin dlg_attrset(win, selected ? attrs[3] : attrs[2]); 6822a3e3873SBaptiste Daroussin (void) waddnstr(win, text, indx[1]); 6832a3e3873SBaptiste Daroussin 6842a3e3873SBaptiste Daroussin if ((int) strlen(text) > indx[1]) { 6852a3e3873SBaptiste Daroussin limit = dlg_limit_columns(text, climit, 1); 6862a3e3873SBaptiste Daroussin if (limit > 1) { 687*f4f33ea0SBaptiste Daroussin dlg_attrset(win, selected ? attrs[1] : attrs[0]); 6882a3e3873SBaptiste Daroussin (void) waddnstr(win, 6892a3e3873SBaptiste Daroussin text + indx[1], 6902a3e3873SBaptiste Daroussin indx[limit] - indx[1]); 6912a3e3873SBaptiste Daroussin } 6922a3e3873SBaptiste Daroussin } 6932a3e3873SBaptiste Daroussin } else { 6942a3e3873SBaptiste Daroussin attrs[1] = item_selected_attr; 6952a3e3873SBaptiste Daroussin attrs[0] = item_attr; 6962a3e3873SBaptiste Daroussin 6972a3e3873SBaptiste Daroussin cols = dlg_index_columns(text); 6982a3e3873SBaptiste Daroussin limit = dlg_limit_columns(text, climit, 0); 6992a3e3873SBaptiste Daroussin 7002a3e3873SBaptiste Daroussin if (limit > 0) { 701*f4f33ea0SBaptiste Daroussin dlg_attrset(win, selected ? attrs[1] : attrs[0]); 7022a3e3873SBaptiste Daroussin dlg_print_text(win, text, cols[limit], &attr); 7032a3e3873SBaptiste Daroussin } 7042a3e3873SBaptiste Daroussin } 7052a3e3873SBaptiste Daroussin } 7062a3e3873SBaptiste Daroussin 7072a3e3873SBaptiste Daroussin /* 7084c8945a0SNathan Whitehorn * Print up to 'cols' columns from 'text', optionally rendering our escape 7094c8945a0SNathan Whitehorn * sequence for attributes and color. 7104c8945a0SNathan Whitehorn */ 7114c8945a0SNathan Whitehorn void 7124c8945a0SNathan Whitehorn dlg_print_text(WINDOW *win, const char *txt, int cols, chtype *attr) 7134c8945a0SNathan Whitehorn { 7144c8945a0SNathan Whitehorn int y_origin, x_origin; 7154c8945a0SNathan Whitehorn int y_before, x_before = 0; 7164c8945a0SNathan Whitehorn int y_after, x_after; 7174c8945a0SNathan Whitehorn int tabbed = 0; 7184c8945a0SNathan Whitehorn bool thisTab; 7194c8945a0SNathan Whitehorn bool ended = FALSE; 7204c8945a0SNathan Whitehorn chtype useattr; 7217a1c0d96SNathan Whitehorn #ifdef USE_WIDE_CURSES 7227a1c0d96SNathan Whitehorn int combined = 0; 7237a1c0d96SNathan Whitehorn #endif 7244c8945a0SNathan Whitehorn 725*f4f33ea0SBaptiste Daroussin if (dialog_state.text_only) { 726*f4f33ea0SBaptiste Daroussin y_origin = y_after = 0; 727*f4f33ea0SBaptiste Daroussin x_origin = x_after = 0; 728*f4f33ea0SBaptiste Daroussin } else { 7294c8945a0SNathan Whitehorn getyx(win, y_origin, x_origin); 730*f4f33ea0SBaptiste Daroussin } 7314c8945a0SNathan Whitehorn while (cols > 0 && (*txt != '\0')) { 7324c8945a0SNathan Whitehorn if (dialog_vars.colors) { 7334c8945a0SNathan Whitehorn while (isOurEscape(txt)) { 7344c8945a0SNathan Whitehorn int code; 7354c8945a0SNathan Whitehorn 7364c8945a0SNathan Whitehorn txt += 2; 7374c8945a0SNathan Whitehorn switch (code = CharOf(*txt)) { 7384c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 7394c8945a0SNathan Whitehorn case '0': 7404c8945a0SNathan Whitehorn case '1': 7414c8945a0SNathan Whitehorn case '2': 7424c8945a0SNathan Whitehorn case '3': 7434c8945a0SNathan Whitehorn case '4': 7444c8945a0SNathan Whitehorn case '5': 7454c8945a0SNathan Whitehorn case '6': 7464c8945a0SNathan Whitehorn case '7': 7474c8945a0SNathan Whitehorn *attr &= ~A_COLOR; 7484c8945a0SNathan Whitehorn *attr |= define_color(win, code - '0'); 7494c8945a0SNathan Whitehorn break; 7504c8945a0SNathan Whitehorn #endif 7514c8945a0SNathan Whitehorn case 'B': 7524c8945a0SNathan Whitehorn *attr &= ~A_BOLD; 7534c8945a0SNathan Whitehorn break; 7544c8945a0SNathan Whitehorn case 'b': 7554c8945a0SNathan Whitehorn *attr |= A_BOLD; 7564c8945a0SNathan Whitehorn break; 7574c8945a0SNathan Whitehorn case 'R': 7584c8945a0SNathan Whitehorn *attr &= ~A_REVERSE; 7594c8945a0SNathan Whitehorn break; 7604c8945a0SNathan Whitehorn case 'r': 7614c8945a0SNathan Whitehorn *attr |= A_REVERSE; 7624c8945a0SNathan Whitehorn break; 7634c8945a0SNathan Whitehorn case 'U': 7644c8945a0SNathan Whitehorn *attr &= ~A_UNDERLINE; 7654c8945a0SNathan Whitehorn break; 7664c8945a0SNathan Whitehorn case 'u': 7674c8945a0SNathan Whitehorn *attr |= A_UNDERLINE; 7684c8945a0SNathan Whitehorn break; 7694c8945a0SNathan Whitehorn case 'n': 7704c8945a0SNathan Whitehorn *attr = A_NORMAL; 7714c8945a0SNathan Whitehorn break; 7724c8945a0SNathan Whitehorn } 7734c8945a0SNathan Whitehorn ++txt; 7744c8945a0SNathan Whitehorn } 7754c8945a0SNathan Whitehorn } 7764c8945a0SNathan Whitehorn if (ended || *txt == '\n' || *txt == '\0') 7774c8945a0SNathan Whitehorn break; 7784c8945a0SNathan Whitehorn useattr = (*attr) & A_ATTRIBUTES; 7794c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 7804c8945a0SNathan Whitehorn /* 7814c8945a0SNathan Whitehorn * Prevent this from making text invisible when the foreground and 7824c8945a0SNathan Whitehorn * background colors happen to be the same, and there's no bold 7834c8945a0SNathan Whitehorn * attribute. 7844c8945a0SNathan Whitehorn */ 7854c8945a0SNathan Whitehorn if ((useattr & A_COLOR) != 0 && (useattr & A_BOLD) == 0) { 7864c8945a0SNathan Whitehorn short pair = (short) PAIR_NUMBER(useattr); 7874c8945a0SNathan Whitehorn short fg, bg; 7884c8945a0SNathan Whitehorn if (pair_content(pair, &fg, &bg) != ERR 7894c8945a0SNathan Whitehorn && fg == bg) { 7904c8945a0SNathan Whitehorn useattr &= ~A_COLOR; 7914c8945a0SNathan Whitehorn useattr |= dlg_color_pair(fg, ((bg == COLOR_BLACK) 7924c8945a0SNathan Whitehorn ? COLOR_WHITE 7934c8945a0SNathan Whitehorn : COLOR_BLACK)); 7944c8945a0SNathan Whitehorn } 7954c8945a0SNathan Whitehorn } 7964c8945a0SNathan Whitehorn #endif 7974c8945a0SNathan Whitehorn /* 7984c8945a0SNathan Whitehorn * Write the character, using curses to tell exactly how wide it 7994c8945a0SNathan Whitehorn * is. If it is a tab, discount that, since the caller thinks 8004c8945a0SNathan Whitehorn * tabs are nonprinting, and curses will expand tabs to one or 8014c8945a0SNathan Whitehorn * more blanks. 8024c8945a0SNathan Whitehorn */ 8034c8945a0SNathan Whitehorn thisTab = (CharOf(*txt) == TAB); 804*f4f33ea0SBaptiste Daroussin if (dialog_state.text_only) { 805*f4f33ea0SBaptiste Daroussin y_before = y_after; 806*f4f33ea0SBaptiste Daroussin x_before = x_after; 807*f4f33ea0SBaptiste Daroussin } else { 8082a3e3873SBaptiste Daroussin if (thisTab) { 8094c8945a0SNathan Whitehorn getyx(win, y_before, x_before); 8102a3e3873SBaptiste Daroussin (void) y_before; 8112a3e3873SBaptiste Daroussin } 812*f4f33ea0SBaptiste Daroussin } 813*f4f33ea0SBaptiste Daroussin if (dialog_state.text_only) { 814*f4f33ea0SBaptiste Daroussin int ch = CharOf(*txt++); 815*f4f33ea0SBaptiste Daroussin if (thisTab) { 816*f4f33ea0SBaptiste Daroussin while ((x_after++) % 8) { 817*f4f33ea0SBaptiste Daroussin fputc(' ', dialog_state.output); 818*f4f33ea0SBaptiste Daroussin } 819*f4f33ea0SBaptiste Daroussin } else { 820*f4f33ea0SBaptiste Daroussin fputc(ch, dialog_state.output); 821*f4f33ea0SBaptiste Daroussin x_after++; /* FIXME: handle meta per locale */ 822*f4f33ea0SBaptiste Daroussin } 823*f4f33ea0SBaptiste Daroussin } else { 8244c8945a0SNathan Whitehorn (void) waddch(win, CharOf(*txt++) | useattr); 8254c8945a0SNathan Whitehorn getyx(win, y_after, x_after); 826*f4f33ea0SBaptiste Daroussin } 8274c8945a0SNathan Whitehorn if (thisTab && (y_after == y_origin)) 8284c8945a0SNathan Whitehorn tabbed += (x_after - x_before); 8297a1c0d96SNathan Whitehorn if ((y_after != y_origin) || 8307a1c0d96SNathan Whitehorn (x_after >= (cols + tabbed + x_origin) 8317a1c0d96SNathan Whitehorn #ifdef USE_WIDE_CURSES 8327a1c0d96SNathan Whitehorn && !is_combining(txt, &combined) 8337a1c0d96SNathan Whitehorn #endif 8347a1c0d96SNathan Whitehorn )) { 8354c8945a0SNathan Whitehorn ended = TRUE; 8364c8945a0SNathan Whitehorn } 8374c8945a0SNathan Whitehorn } 838*f4f33ea0SBaptiste Daroussin if (dialog_state.text_only) { 839*f4f33ea0SBaptiste Daroussin fputc('\n', dialog_state.output); 840*f4f33ea0SBaptiste Daroussin } 8414c8945a0SNathan Whitehorn } 8424c8945a0SNathan Whitehorn 8434c8945a0SNathan Whitehorn /* 8444c8945a0SNathan Whitehorn * Print one line of the prompt in the window within the limits of the 8454c8945a0SNathan Whitehorn * specified right margin. The line will end on a word boundary and a pointer 8464c8945a0SNathan Whitehorn * to the start of the next line is returned, or a NULL pointer if the end of 8474c8945a0SNathan Whitehorn * *prompt is reached. 8484c8945a0SNathan Whitehorn */ 8494c8945a0SNathan Whitehorn const char * 8504c8945a0SNathan Whitehorn dlg_print_line(WINDOW *win, 8514c8945a0SNathan Whitehorn chtype *attr, 8524c8945a0SNathan Whitehorn const char *prompt, 8534c8945a0SNathan Whitehorn int lm, int rm, int *x) 8544c8945a0SNathan Whitehorn { 8552a3e3873SBaptiste Daroussin const char *wrap_ptr; 8562a3e3873SBaptiste Daroussin const char *test_ptr; 857682c9e0fSNathan Whitehorn const char *hide_ptr = 0; 8584c8945a0SNathan Whitehorn const int *cols = dlg_index_columns(prompt); 8594c8945a0SNathan Whitehorn const int *indx = dlg_index_wchars(prompt); 8604c8945a0SNathan Whitehorn int wrap_inx = 0; 8614c8945a0SNathan Whitehorn int test_inx = 0; 8624c8945a0SNathan Whitehorn int cur_x = lm; 8634c8945a0SNathan Whitehorn int hidden = 0; 8644c8945a0SNathan Whitehorn int limit = dlg_count_wchars(prompt); 8654c8945a0SNathan Whitehorn int n; 8664c8945a0SNathan Whitehorn int tabbed = 0; 8674c8945a0SNathan Whitehorn 8684c8945a0SNathan Whitehorn *x = 1; 8694c8945a0SNathan Whitehorn 8704c8945a0SNathan Whitehorn /* 8714c8945a0SNathan Whitehorn * Set *test_ptr to the end of the line or the right margin (rm), whichever 8724c8945a0SNathan Whitehorn * is less, and set wrap_ptr to the end of the last word in the line. 8734c8945a0SNathan Whitehorn */ 8744c8945a0SNathan Whitehorn for (n = 0; n < limit; ++n) { 875*f4f33ea0SBaptiste Daroussin int ch = *(test_ptr = prompt + indx[test_inx]); 876*f4f33ea0SBaptiste Daroussin if (ch == '\n' || ch == '\0' || cur_x >= (rm + hidden)) 8774c8945a0SNathan Whitehorn break; 878*f4f33ea0SBaptiste Daroussin if (ch == TAB && n == 0) { 8794c8945a0SNathan Whitehorn tabbed = 8; /* workaround for leading tabs */ 880*f4f33ea0SBaptiste Daroussin } else if (isblank(UCH(ch)) 881*f4f33ea0SBaptiste Daroussin && n != 0 882*f4f33ea0SBaptiste Daroussin && !isblank(UCH(prompt[indx[n - 1]]))) { 8834c8945a0SNathan Whitehorn wrap_inx = n; 8844c8945a0SNathan Whitehorn *x = cur_x; 8852a3e3873SBaptiste Daroussin } else if (dialog_vars.colors && isOurEscape(test_ptr)) { 886682c9e0fSNathan Whitehorn hide_ptr = test_ptr; 887682c9e0fSNathan Whitehorn hidden += ESCAPE_LEN; 888682c9e0fSNathan Whitehorn n += (ESCAPE_LEN - 1); 8894c8945a0SNathan Whitehorn } 8904c8945a0SNathan Whitehorn cur_x = lm + tabbed + cols[n + 1]; 8914c8945a0SNathan Whitehorn if (cur_x > (rm + hidden)) 8924c8945a0SNathan Whitehorn break; 8934c8945a0SNathan Whitehorn test_inx = n + 1; 8944c8945a0SNathan Whitehorn } 8954c8945a0SNathan Whitehorn 8964c8945a0SNathan Whitehorn /* 8974c8945a0SNathan Whitehorn * If the line doesn't reach the right margin in the middle of a word, then 8984c8945a0SNathan Whitehorn * we don't have to wrap it at the end of the previous word. 8994c8945a0SNathan Whitehorn */ 9004c8945a0SNathan Whitehorn test_ptr = prompt + indx[test_inx]; 901*f4f33ea0SBaptiste Daroussin if (*test_ptr == '\n' || isblank(UCH(*test_ptr)) || *test_ptr == '\0') { 9024c8945a0SNathan Whitehorn wrap_inx = test_inx; 903*f4f33ea0SBaptiste Daroussin while (wrap_inx > 0 && isblank(UCH(prompt[indx[wrap_inx - 1]]))) { 9044c8945a0SNathan Whitehorn wrap_inx--; 9054c8945a0SNathan Whitehorn } 9064c8945a0SNathan Whitehorn *x = lm + indx[wrap_inx]; 9074c8945a0SNathan Whitehorn } else if (*x == 1 && cur_x >= rm) { 9084c8945a0SNathan Whitehorn /* 9094c8945a0SNathan Whitehorn * If the line has no spaces, then wrap it anyway at the right margin 9104c8945a0SNathan Whitehorn */ 9114c8945a0SNathan Whitehorn *x = rm; 9124c8945a0SNathan Whitehorn wrap_inx = test_inx; 9134c8945a0SNathan Whitehorn } 9144c8945a0SNathan Whitehorn wrap_ptr = prompt + indx[wrap_inx]; 9157a1c0d96SNathan Whitehorn #ifdef USE_WIDE_CURSES 9167a1c0d96SNathan Whitehorn if (UCH(*wrap_ptr) >= 128) { 9177a1c0d96SNathan Whitehorn int combined = 0; 9187a1c0d96SNathan Whitehorn while (is_combining(wrap_ptr, &combined)) { 9197a1c0d96SNathan Whitehorn ++wrap_ptr; 9207a1c0d96SNathan Whitehorn } 9217a1c0d96SNathan Whitehorn } 9227a1c0d96SNathan Whitehorn #endif 9234c8945a0SNathan Whitehorn 9244c8945a0SNathan Whitehorn /* 925682c9e0fSNathan Whitehorn * If we found hidden text past the last point that we will display, 926682c9e0fSNathan Whitehorn * discount that from the displayed length. 927682c9e0fSNathan Whitehorn */ 928682c9e0fSNathan Whitehorn if ((hide_ptr != 0) && (hide_ptr >= wrap_ptr)) { 929682c9e0fSNathan Whitehorn hidden -= ESCAPE_LEN; 930682c9e0fSNathan Whitehorn test_ptr = wrap_ptr; 931682c9e0fSNathan Whitehorn while (test_ptr < wrap_ptr) { 9322a3e3873SBaptiste Daroussin if (dialog_vars.colors && isOurEscape(test_ptr)) { 933682c9e0fSNathan Whitehorn hidden -= ESCAPE_LEN; 934682c9e0fSNathan Whitehorn test_ptr += ESCAPE_LEN; 935682c9e0fSNathan Whitehorn } else { 936682c9e0fSNathan Whitehorn ++test_ptr; 937682c9e0fSNathan Whitehorn } 938682c9e0fSNathan Whitehorn } 939682c9e0fSNathan Whitehorn } 940682c9e0fSNathan Whitehorn 941682c9e0fSNathan Whitehorn /* 9424c8945a0SNathan Whitehorn * Print the line if we have a window pointer. Otherwise this routine 9434c8945a0SNathan Whitehorn * is just being called for sizing the window. 9444c8945a0SNathan Whitehorn */ 945*f4f33ea0SBaptiste Daroussin if (dialog_state.text_only || win) { 9464c8945a0SNathan Whitehorn dlg_print_text(win, prompt, (cols[wrap_inx] - hidden), attr); 9474c8945a0SNathan Whitehorn } 9484c8945a0SNathan Whitehorn 9494c8945a0SNathan Whitehorn /* *x tells the calling function how long the line was */ 950*f4f33ea0SBaptiste Daroussin if (*x == 1) { 9514c8945a0SNathan Whitehorn *x = rm; 952*f4f33ea0SBaptiste Daroussin } 9534c8945a0SNathan Whitehorn 954682c9e0fSNathan Whitehorn *x -= hidden; 955682c9e0fSNathan Whitehorn 9564c8945a0SNathan Whitehorn /* Find the start of the next line and return a pointer to it */ 9574c8945a0SNathan Whitehorn test_ptr = wrap_ptr; 958*f4f33ea0SBaptiste Daroussin while (isblank(UCH(*test_ptr))) 9594c8945a0SNathan Whitehorn test_ptr++; 9604c8945a0SNathan Whitehorn if (*test_ptr == '\n') 9614c8945a0SNathan Whitehorn test_ptr++; 962febdb468SDevin Teske dlg_finish_string(prompt); 9634c8945a0SNathan Whitehorn return (test_ptr); 9644c8945a0SNathan Whitehorn } 9654c8945a0SNathan Whitehorn 9664c8945a0SNathan Whitehorn static void 9674c8945a0SNathan Whitehorn justify_text(WINDOW *win, 9684c8945a0SNathan Whitehorn const char *prompt, 9694c8945a0SNathan Whitehorn int limit_y, 9704c8945a0SNathan Whitehorn int limit_x, 9714c8945a0SNathan Whitehorn int *high, int *wide) 9724c8945a0SNathan Whitehorn { 9734c8945a0SNathan Whitehorn chtype attr = A_NORMAL; 9744c8945a0SNathan Whitehorn int x = (2 * MARGIN); 9754c8945a0SNathan Whitehorn int y = MARGIN; 9764c8945a0SNathan Whitehorn int max_x = 2; 9774c8945a0SNathan Whitehorn int lm = (2 * MARGIN); /* left margin (box-border plus a space) */ 9784c8945a0SNathan Whitehorn int rm = limit_x; /* right margin */ 9794c8945a0SNathan Whitehorn int bm = limit_y; /* bottom margin */ 9804c8945a0SNathan Whitehorn int last_y = 0, last_x = 0; 9814c8945a0SNathan Whitehorn 982*f4f33ea0SBaptiste Daroussin dialog_state.text_height = 0; 983*f4f33ea0SBaptiste Daroussin dialog_state.text_width = 0; 984*f4f33ea0SBaptiste Daroussin if (dialog_state.text_only || win) { 9854c8945a0SNathan Whitehorn rm -= (2 * MARGIN); 9864c8945a0SNathan Whitehorn bm -= (2 * MARGIN); 9874c8945a0SNathan Whitehorn } 9884c8945a0SNathan Whitehorn if (prompt == 0) 9894c8945a0SNathan Whitehorn prompt = ""; 9904c8945a0SNathan Whitehorn 9914c8945a0SNathan Whitehorn if (win != 0) 9924c8945a0SNathan Whitehorn getyx(win, last_y, last_x); 9934c8945a0SNathan Whitehorn while (y <= bm && *prompt) { 9944c8945a0SNathan Whitehorn x = lm; 9954c8945a0SNathan Whitehorn 9964c8945a0SNathan Whitehorn if (*prompt == '\n') { 9974c8945a0SNathan Whitehorn while (*prompt == '\n' && y < bm) { 9984c8945a0SNathan Whitehorn if (*(prompt + 1) != '\0') { 9994c8945a0SNathan Whitehorn ++y; 10004c8945a0SNathan Whitehorn if (win != 0) 10014c8945a0SNathan Whitehorn (void) wmove(win, y, lm); 10024c8945a0SNathan Whitehorn } 10034c8945a0SNathan Whitehorn prompt++; 10044c8945a0SNathan Whitehorn } 10054c8945a0SNathan Whitehorn } else if (win != 0) 10064c8945a0SNathan Whitehorn (void) wmove(win, y, lm); 10074c8945a0SNathan Whitehorn 10084c8945a0SNathan Whitehorn if (*prompt) { 10094c8945a0SNathan Whitehorn prompt = dlg_print_line(win, &attr, prompt, lm, rm, &x); 10104c8945a0SNathan Whitehorn if (win != 0) 10114c8945a0SNathan Whitehorn getyx(win, last_y, last_x); 10124c8945a0SNathan Whitehorn } 10134c8945a0SNathan Whitehorn if (*prompt) { 10144c8945a0SNathan Whitehorn ++y; 10154c8945a0SNathan Whitehorn if (win != 0) 10164c8945a0SNathan Whitehorn (void) wmove(win, y, lm); 10174c8945a0SNathan Whitehorn } 10184c8945a0SNathan Whitehorn max_x = MAX(max_x, x); 10194c8945a0SNathan Whitehorn } 10204c8945a0SNathan Whitehorn /* Move back to the last position after drawing prompt, for msgbox. */ 10214c8945a0SNathan Whitehorn if (win != 0) 10224c8945a0SNathan Whitehorn (void) wmove(win, last_y, last_x); 10234c8945a0SNathan Whitehorn 10244c8945a0SNathan Whitehorn /* Set the final height and width for the calling function */ 10254c8945a0SNathan Whitehorn if (high != 0) 10264c8945a0SNathan Whitehorn *high = y; 10274c8945a0SNathan Whitehorn if (wide != 0) 10284c8945a0SNathan Whitehorn *wide = max_x; 10294c8945a0SNathan Whitehorn } 10304c8945a0SNathan Whitehorn 10314c8945a0SNathan Whitehorn /* 10324c8945a0SNathan Whitehorn * Print a string of text in a window, automatically wrap around to the next 10334c8945a0SNathan Whitehorn * line if the string is too long to fit on one line. Note that the string may 10344c8945a0SNathan Whitehorn * contain embedded newlines. 10354c8945a0SNathan Whitehorn */ 10364c8945a0SNathan Whitehorn void 10374c8945a0SNathan Whitehorn dlg_print_autowrap(WINDOW *win, const char *prompt, int height, int width) 10384c8945a0SNathan Whitehorn { 10394c8945a0SNathan Whitehorn justify_text(win, prompt, 10404c8945a0SNathan Whitehorn height, 10414c8945a0SNathan Whitehorn width, 10424c8945a0SNathan Whitehorn (int *) 0, (int *) 0); 10434c8945a0SNathan Whitehorn } 10444c8945a0SNathan Whitehorn 10454c8945a0SNathan Whitehorn /* 10464c8945a0SNathan Whitehorn * Display the message in a scrollable window. Actually the way it works is 10474c8945a0SNathan Whitehorn * that we create a "tall" window of the proper width, let the text wrap within 10484c8945a0SNathan Whitehorn * that, and copy a slice of the result to the dialog. 10494c8945a0SNathan Whitehorn * 10504c8945a0SNathan Whitehorn * It works for ncurses. Other curses implementations show only blanks (Tru64) 10514c8945a0SNathan Whitehorn * or garbage (NetBSD). 10524c8945a0SNathan Whitehorn */ 10534c8945a0SNathan Whitehorn int 10544c8945a0SNathan Whitehorn dlg_print_scrolled(WINDOW *win, 10554c8945a0SNathan Whitehorn const char *prompt, 10564c8945a0SNathan Whitehorn int offset, 10574c8945a0SNathan Whitehorn int height, 10584c8945a0SNathan Whitehorn int width, 10594c8945a0SNathan Whitehorn int pauseopt) 10604c8945a0SNathan Whitehorn { 10614c8945a0SNathan Whitehorn int oldy, oldx; 10624c8945a0SNathan Whitehorn int last = 0; 10634c8945a0SNathan Whitehorn 10647a1c0d96SNathan Whitehorn (void) pauseopt; /* used only for ncurses */ 10657a1c0d96SNathan Whitehorn 10664c8945a0SNathan Whitehorn getyx(win, oldy, oldx); 10674c8945a0SNathan Whitehorn #ifdef NCURSES_VERSION 10684c8945a0SNathan Whitehorn if (pauseopt) { 10694c8945a0SNathan Whitehorn int wide = width - (2 * MARGIN); 10704c8945a0SNathan Whitehorn int high = LINES; 10714c8945a0SNathan Whitehorn int y, x; 10724c8945a0SNathan Whitehorn int len; 10734c8945a0SNathan Whitehorn int percent; 10744c8945a0SNathan Whitehorn WINDOW *dummy; 10754c8945a0SNathan Whitehorn char buffer[5]; 10764c8945a0SNathan Whitehorn 10774c8945a0SNathan Whitehorn #if defined(NCURSES_VERSION_PATCH) && NCURSES_VERSION_PATCH >= 20040417 10784c8945a0SNathan Whitehorn /* 10794c8945a0SNathan Whitehorn * If we're not limited by the screensize, allow text to possibly be 10804c8945a0SNathan Whitehorn * one character per line. 10814c8945a0SNathan Whitehorn */ 10824c8945a0SNathan Whitehorn if ((len = dlg_count_columns(prompt)) > high) 10834c8945a0SNathan Whitehorn high = len; 10844c8945a0SNathan Whitehorn #endif 10854c8945a0SNathan Whitehorn dummy = newwin(high, width, 0, 0); 1086682c9e0fSNathan Whitehorn if (dummy == 0) { 1087*f4f33ea0SBaptiste Daroussin dlg_attrset(win, dialog_attr); 1088682c9e0fSNathan Whitehorn dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width); 1089682c9e0fSNathan Whitehorn last = 0; 1090682c9e0fSNathan Whitehorn } else { 10914c8945a0SNathan Whitehorn wbkgdset(dummy, dialog_attr | ' '); 1092*f4f33ea0SBaptiste Daroussin dlg_attrset(dummy, dialog_attr); 10934c8945a0SNathan Whitehorn werase(dummy); 10944c8945a0SNathan Whitehorn dlg_print_autowrap(dummy, prompt, high, width); 10954c8945a0SNathan Whitehorn getyx(dummy, y, x); 10962a3e3873SBaptiste Daroussin (void) x; 10974c8945a0SNathan Whitehorn 10984c8945a0SNathan Whitehorn copywin(dummy, /* srcwin */ 10994c8945a0SNathan Whitehorn win, /* dstwin */ 11004c8945a0SNathan Whitehorn offset + MARGIN, /* sminrow */ 11014c8945a0SNathan Whitehorn MARGIN, /* smincol */ 11024c8945a0SNathan Whitehorn MARGIN, /* dminrow */ 11034c8945a0SNathan Whitehorn MARGIN, /* dmincol */ 11044c8945a0SNathan Whitehorn height, /* dmaxrow */ 11054c8945a0SNathan Whitehorn wide, /* dmaxcol */ 11064c8945a0SNathan Whitehorn FALSE); 11074c8945a0SNathan Whitehorn 11084c8945a0SNathan Whitehorn delwin(dummy); 11094c8945a0SNathan Whitehorn 11104c8945a0SNathan Whitehorn /* if the text is incomplete, or we have scrolled, show the percentage */ 11114c8945a0SNathan Whitehorn if (y > 0 && wide > 4) { 11124c8945a0SNathan Whitehorn percent = (int) ((height + offset) * 100.0 / y); 11134c8945a0SNathan Whitehorn if (percent < 0) 11144c8945a0SNathan Whitehorn percent = 0; 11154c8945a0SNathan Whitehorn if (percent > 100) 11164c8945a0SNathan Whitehorn percent = 100; 11174c8945a0SNathan Whitehorn if (offset != 0 || percent != 100) { 1118*f4f33ea0SBaptiste Daroussin dlg_attrset(win, position_indicator_attr); 11194c8945a0SNathan Whitehorn (void) wmove(win, MARGIN + height, wide - 4); 11204c8945a0SNathan Whitehorn (void) sprintf(buffer, "%d%%", percent); 11214c8945a0SNathan Whitehorn (void) waddstr(win, buffer); 11224c8945a0SNathan Whitehorn if ((len = (int) strlen(buffer)) < 4) { 1123*f4f33ea0SBaptiste Daroussin dlg_attrset(win, border_attr); 11244c8945a0SNathan Whitehorn whline(win, dlg_boxchar(ACS_HLINE), 4 - len); 11254c8945a0SNathan Whitehorn } 11264c8945a0SNathan Whitehorn } 11274c8945a0SNathan Whitehorn } 11284c8945a0SNathan Whitehorn last = (y - height); 1129682c9e0fSNathan Whitehorn } 11304c8945a0SNathan Whitehorn } else 11314c8945a0SNathan Whitehorn #endif 11324c8945a0SNathan Whitehorn { 11334c8945a0SNathan Whitehorn (void) offset; 1134*f4f33ea0SBaptiste Daroussin dlg_attrset(win, dialog_attr); 11354c8945a0SNathan Whitehorn dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width); 11364c8945a0SNathan Whitehorn last = 0; 11374c8945a0SNathan Whitehorn } 11384c8945a0SNathan Whitehorn wmove(win, oldy, oldx); 11394c8945a0SNathan Whitehorn return last; 11404c8945a0SNathan Whitehorn } 11414c8945a0SNathan Whitehorn 11424c8945a0SNathan Whitehorn int 11434c8945a0SNathan Whitehorn dlg_check_scrolled(int key, int last, int page, bool * show, int *offset) 11444c8945a0SNathan Whitehorn { 11454c8945a0SNathan Whitehorn int code = 0; 11464c8945a0SNathan Whitehorn 11474c8945a0SNathan Whitehorn *show = FALSE; 11484c8945a0SNathan Whitehorn 11494c8945a0SNathan Whitehorn switch (key) { 11504c8945a0SNathan Whitehorn case DLGK_PAGE_FIRST: 11514c8945a0SNathan Whitehorn if (*offset > 0) { 11524c8945a0SNathan Whitehorn *offset = 0; 11534c8945a0SNathan Whitehorn *show = TRUE; 11544c8945a0SNathan Whitehorn } 11554c8945a0SNathan Whitehorn break; 11564c8945a0SNathan Whitehorn case DLGK_PAGE_LAST: 11574c8945a0SNathan Whitehorn if (*offset < last) { 11584c8945a0SNathan Whitehorn *offset = last; 11594c8945a0SNathan Whitehorn *show = TRUE; 11604c8945a0SNathan Whitehorn } 11614c8945a0SNathan Whitehorn break; 11624c8945a0SNathan Whitehorn case DLGK_GRID_UP: 11634c8945a0SNathan Whitehorn if (*offset > 0) { 11644c8945a0SNathan Whitehorn --(*offset); 11654c8945a0SNathan Whitehorn *show = TRUE; 11664c8945a0SNathan Whitehorn } 11674c8945a0SNathan Whitehorn break; 11684c8945a0SNathan Whitehorn case DLGK_GRID_DOWN: 11694c8945a0SNathan Whitehorn if (*offset < last) { 11704c8945a0SNathan Whitehorn ++(*offset); 11714c8945a0SNathan Whitehorn *show = TRUE; 11724c8945a0SNathan Whitehorn } 11734c8945a0SNathan Whitehorn break; 11744c8945a0SNathan Whitehorn case DLGK_PAGE_PREV: 11754c8945a0SNathan Whitehorn if (*offset > 0) { 11764c8945a0SNathan Whitehorn *offset -= page; 11774c8945a0SNathan Whitehorn if (*offset < 0) 11784c8945a0SNathan Whitehorn *offset = 0; 11794c8945a0SNathan Whitehorn *show = TRUE; 11804c8945a0SNathan Whitehorn } 11814c8945a0SNathan Whitehorn break; 11824c8945a0SNathan Whitehorn case DLGK_PAGE_NEXT: 11834c8945a0SNathan Whitehorn if (*offset < last) { 11844c8945a0SNathan Whitehorn *offset += page; 11854c8945a0SNathan Whitehorn if (*offset > last) 11864c8945a0SNathan Whitehorn *offset = last; 11874c8945a0SNathan Whitehorn *show = TRUE; 11884c8945a0SNathan Whitehorn } 11894c8945a0SNathan Whitehorn break; 11904c8945a0SNathan Whitehorn default: 11914c8945a0SNathan Whitehorn code = -1; 11924c8945a0SNathan Whitehorn break; 11934c8945a0SNathan Whitehorn } 11944c8945a0SNathan Whitehorn return code; 11954c8945a0SNathan Whitehorn } 11964c8945a0SNathan Whitehorn 11974c8945a0SNathan Whitehorn /* 11984c8945a0SNathan Whitehorn * Calculate the window size for preformatted text. This will calculate box 11994c8945a0SNathan Whitehorn * dimensions that are at or close to the specified aspect ratio for the prompt 12004c8945a0SNathan Whitehorn * string with all spaces and newlines preserved and additional newlines added 12014c8945a0SNathan Whitehorn * as necessary. 12024c8945a0SNathan Whitehorn */ 12034c8945a0SNathan Whitehorn static void 12044c8945a0SNathan Whitehorn auto_size_preformatted(const char *prompt, int *height, int *width) 12054c8945a0SNathan Whitehorn { 12064c8945a0SNathan Whitehorn int high = 0, wide = 0; 12074c8945a0SNathan Whitehorn float car; /* Calculated Aspect Ratio */ 12084c8945a0SNathan Whitehorn float diff; 12094c8945a0SNathan Whitehorn int max_y = SLINES - 1; 12104c8945a0SNathan Whitehorn int max_x = SCOLS - 2; 12114c8945a0SNathan Whitehorn int max_width = max_x; 12124c8945a0SNathan Whitehorn int ar = dialog_state.aspect_ratio; 12134c8945a0SNathan Whitehorn 12144c8945a0SNathan Whitehorn /* Get the initial dimensions */ 12154c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide); 12164c8945a0SNathan Whitehorn car = (float) (wide / high); 12174c8945a0SNathan Whitehorn 12184c8945a0SNathan Whitehorn /* 12194c8945a0SNathan Whitehorn * If the aspect ratio is greater than it should be, then decrease the 12204c8945a0SNathan Whitehorn * width proportionately. 12214c8945a0SNathan Whitehorn */ 12224c8945a0SNathan Whitehorn if (car > ar) { 12234c8945a0SNathan Whitehorn diff = car / (float) ar; 12244c8945a0SNathan Whitehorn max_x = (int) ((float) wide / diff + 4); 12254c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide); 12264c8945a0SNathan Whitehorn car = (float) wide / (float) high; 12274c8945a0SNathan Whitehorn } 12284c8945a0SNathan Whitehorn 12294c8945a0SNathan Whitehorn /* 12304c8945a0SNathan Whitehorn * If the aspect ratio is too small after decreasing the width, then 12314c8945a0SNathan Whitehorn * incrementally increase the width until the aspect ratio is equal to or 12324c8945a0SNathan Whitehorn * greater than the specified aspect ratio. 12334c8945a0SNathan Whitehorn */ 12344c8945a0SNathan Whitehorn while (car < ar && max_x < max_width) { 12354c8945a0SNathan Whitehorn max_x += 4; 12364c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide); 12374c8945a0SNathan Whitehorn car = (float) (wide / high); 12384c8945a0SNathan Whitehorn } 12394c8945a0SNathan Whitehorn 12404c8945a0SNathan Whitehorn *height = high; 12414c8945a0SNathan Whitehorn *width = wide; 12424c8945a0SNathan Whitehorn } 12434c8945a0SNathan Whitehorn 12444c8945a0SNathan Whitehorn /* 12454c8945a0SNathan Whitehorn * Find the length of the longest "word" in the given string. By setting the 12464c8945a0SNathan Whitehorn * widget width at least this long, we can avoid splitting a word on the 12474c8945a0SNathan Whitehorn * margin. 12484c8945a0SNathan Whitehorn */ 12494c8945a0SNathan Whitehorn static int 12504c8945a0SNathan Whitehorn longest_word(const char *string) 12514c8945a0SNathan Whitehorn { 12524c8945a0SNathan Whitehorn int length, result = 0; 12534c8945a0SNathan Whitehorn 12544c8945a0SNathan Whitehorn while (*string != '\0') { 12554c8945a0SNathan Whitehorn length = 0; 12564c8945a0SNathan Whitehorn while (*string != '\0' && !isspace(UCH(*string))) { 12574c8945a0SNathan Whitehorn length++; 12584c8945a0SNathan Whitehorn string++; 12594c8945a0SNathan Whitehorn } 12604c8945a0SNathan Whitehorn result = MAX(result, length); 12614c8945a0SNathan Whitehorn if (*string != '\0') 12624c8945a0SNathan Whitehorn string++; 12634c8945a0SNathan Whitehorn } 12644c8945a0SNathan Whitehorn return result; 12654c8945a0SNathan Whitehorn } 12664c8945a0SNathan Whitehorn 12674c8945a0SNathan Whitehorn /* 12684c8945a0SNathan Whitehorn * if (height or width == -1) Maximize() 12694c8945a0SNathan Whitehorn * if (height or width == 0), justify and return actual limits. 12704c8945a0SNathan Whitehorn */ 12714c8945a0SNathan Whitehorn static void 12724c8945a0SNathan Whitehorn real_auto_size(const char *title, 12734c8945a0SNathan Whitehorn const char *prompt, 12744c8945a0SNathan Whitehorn int *height, int *width, 12754c8945a0SNathan Whitehorn int boxlines, int mincols) 12764c8945a0SNathan Whitehorn { 12774c8945a0SNathan Whitehorn int x = (dialog_vars.begin_set ? dialog_vars.begin_x : 2); 12784c8945a0SNathan Whitehorn int y = (dialog_vars.begin_set ? dialog_vars.begin_y : 1); 12794c8945a0SNathan Whitehorn int title_length = title ? dlg_count_columns(title) : 0; 12804c8945a0SNathan Whitehorn int high; 12814c8945a0SNathan Whitehorn int wide; 12824c8945a0SNathan Whitehorn int save_high = *height; 12834c8945a0SNathan Whitehorn int save_wide = *width; 1284*f4f33ea0SBaptiste Daroussin int max_high; 1285*f4f33ea0SBaptiste Daroussin int max_wide; 12864c8945a0SNathan Whitehorn 12874c8945a0SNathan Whitehorn if (prompt == 0) { 12884c8945a0SNathan Whitehorn if (*height == 0) 12894c8945a0SNathan Whitehorn *height = -1; 12904c8945a0SNathan Whitehorn if (*width == 0) 12914c8945a0SNathan Whitehorn *width = -1; 12924c8945a0SNathan Whitehorn } 12934c8945a0SNathan Whitehorn 1294*f4f33ea0SBaptiste Daroussin max_high = (*height < 0); 1295*f4f33ea0SBaptiste Daroussin max_wide = (*width < 0); 1296*f4f33ea0SBaptiste Daroussin 12974c8945a0SNathan Whitehorn if (*height > 0) { 12984c8945a0SNathan Whitehorn high = *height; 12994c8945a0SNathan Whitehorn } else { 13004c8945a0SNathan Whitehorn high = SLINES - y; 13014c8945a0SNathan Whitehorn } 13024c8945a0SNathan Whitehorn 13032a3e3873SBaptiste Daroussin if (*width <= 0) { 13042a3e3873SBaptiste Daroussin if (prompt != 0) { 13054c8945a0SNathan Whitehorn wide = MAX(title_length, mincols); 13064c8945a0SNathan Whitehorn if (strchr(prompt, '\n') == 0) { 13072a3e3873SBaptiste Daroussin double val = (dialog_state.aspect_ratio * 13082a3e3873SBaptiste Daroussin dlg_count_real_columns(prompt)); 13094c8945a0SNathan Whitehorn double xxx = sqrt(val); 13104c8945a0SNathan Whitehorn int tmp = (int) xxx; 13114c8945a0SNathan Whitehorn wide = MAX(wide, tmp); 13124c8945a0SNathan Whitehorn wide = MAX(wide, longest_word(prompt)); 13134c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, high, wide, height, width); 13144c8945a0SNathan Whitehorn } else { 13154c8945a0SNathan Whitehorn auto_size_preformatted(prompt, height, width); 13164c8945a0SNathan Whitehorn } 13174c8945a0SNathan Whitehorn } else { 13184c8945a0SNathan Whitehorn wide = SCOLS - x; 13194c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, high, wide, height, width); 13204c8945a0SNathan Whitehorn } 13212a3e3873SBaptiste Daroussin } 13224c8945a0SNathan Whitehorn 13234c8945a0SNathan Whitehorn if (*width < title_length) { 13244c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, high, title_length, height, width); 13254c8945a0SNathan Whitehorn *width = title_length; 13264c8945a0SNathan Whitehorn } 13274c8945a0SNathan Whitehorn 1328*f4f33ea0SBaptiste Daroussin dialog_state.text_height = *height; 1329*f4f33ea0SBaptiste Daroussin dialog_state.text_width = *width; 1330*f4f33ea0SBaptiste Daroussin 13314c8945a0SNathan Whitehorn if (*width < mincols && save_wide == 0) 13324c8945a0SNathan Whitehorn *width = mincols; 13334c8945a0SNathan Whitehorn if (prompt != 0) { 1334*f4f33ea0SBaptiste Daroussin *width += ((2 * MARGIN) + SHADOW_COLS); 1335*f4f33ea0SBaptiste Daroussin *height += boxlines + (2 * MARGIN); 13364c8945a0SNathan Whitehorn } 1337*f4f33ea0SBaptiste Daroussin 13384c8945a0SNathan Whitehorn if (save_high > 0) 13394c8945a0SNathan Whitehorn *height = save_high; 13404c8945a0SNathan Whitehorn if (save_wide > 0) 13414c8945a0SNathan Whitehorn *width = save_wide; 1342*f4f33ea0SBaptiste Daroussin 1343*f4f33ea0SBaptiste Daroussin if (max_high) 1344*f4f33ea0SBaptiste Daroussin *height = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0); 1345*f4f33ea0SBaptiste Daroussin if (max_wide) 1346*f4f33ea0SBaptiste Daroussin *width = SCOLS - (dialog_vars.begin_set ? dialog_vars.begin_x : 0); 13474c8945a0SNathan Whitehorn } 13484c8945a0SNathan Whitehorn 13494c8945a0SNathan Whitehorn /* End of real_auto_size() */ 13504c8945a0SNathan Whitehorn 13514c8945a0SNathan Whitehorn void 13524c8945a0SNathan Whitehorn dlg_auto_size(const char *title, 13534c8945a0SNathan Whitehorn const char *prompt, 13544c8945a0SNathan Whitehorn int *height, 13554c8945a0SNathan Whitehorn int *width, 13564c8945a0SNathan Whitehorn int boxlines, 13574c8945a0SNathan Whitehorn int mincols) 13584c8945a0SNathan Whitehorn { 1359*f4f33ea0SBaptiste Daroussin DLG_TRACE(("# dlg_auto_size(%d,%d) limits %d,%d\n", 1360*f4f33ea0SBaptiste Daroussin *height, *width, 1361*f4f33ea0SBaptiste Daroussin boxlines, mincols)); 1362*f4f33ea0SBaptiste Daroussin 13634c8945a0SNathan Whitehorn real_auto_size(title, prompt, height, width, boxlines, mincols); 13644c8945a0SNathan Whitehorn 13654c8945a0SNathan Whitehorn if (*width > SCOLS) { 13664c8945a0SNathan Whitehorn (*height)++; 13674c8945a0SNathan Whitehorn *width = SCOLS; 13684c8945a0SNathan Whitehorn } 13694c8945a0SNathan Whitehorn 1370*f4f33ea0SBaptiste Daroussin if (*height > SLINES) { 13714c8945a0SNathan Whitehorn *height = SLINES; 13724c8945a0SNathan Whitehorn } 1373*f4f33ea0SBaptiste Daroussin DLG_TRACE(("# ...dlg_auto_size(%d,%d) also %d,%d\n", 1374*f4f33ea0SBaptiste Daroussin *height, *width, 1375*f4f33ea0SBaptiste Daroussin dialog_state.text_height, dialog_state.text_width)); 1376*f4f33ea0SBaptiste Daroussin } 13774c8945a0SNathan Whitehorn 13784c8945a0SNathan Whitehorn /* 13794c8945a0SNathan Whitehorn * if (height or width == -1) Maximize() 13804c8945a0SNathan Whitehorn * if (height or width == 0) 13814c8945a0SNathan Whitehorn * height=MIN(SLINES, num.lines in fd+n); 13824c8945a0SNathan Whitehorn * width=MIN(SCOLS, MAX(longer line+n, mincols)); 13834c8945a0SNathan Whitehorn */ 13844c8945a0SNathan Whitehorn void 13854c8945a0SNathan Whitehorn dlg_auto_sizefile(const char *title, 13864c8945a0SNathan Whitehorn const char *file, 13874c8945a0SNathan Whitehorn int *height, 13884c8945a0SNathan Whitehorn int *width, 13894c8945a0SNathan Whitehorn int boxlines, 13904c8945a0SNathan Whitehorn int mincols) 13914c8945a0SNathan Whitehorn { 13924c8945a0SNathan Whitehorn int count = 0; 13934c8945a0SNathan Whitehorn int len = title ? dlg_count_columns(title) : 0; 13944c8945a0SNathan Whitehorn int nc = 4; 13954c8945a0SNathan Whitehorn int numlines = 2; 13964c8945a0SNathan Whitehorn long offset; 13974c8945a0SNathan Whitehorn int ch; 13984c8945a0SNathan Whitehorn FILE *fd; 13994c8945a0SNathan Whitehorn 14004c8945a0SNathan Whitehorn /* Open input file for reading */ 14014c8945a0SNathan Whitehorn if ((fd = fopen(file, "rb")) == NULL) 14024c8945a0SNathan Whitehorn dlg_exiterr("dlg_auto_sizefile: Cannot open input file %s", file); 14034c8945a0SNathan Whitehorn 14044c8945a0SNathan Whitehorn if ((*height == -1) || (*width == -1)) { 14054c8945a0SNathan Whitehorn *height = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0); 14064c8945a0SNathan Whitehorn *width = SCOLS - (dialog_vars.begin_set ? dialog_vars.begin_x : 0); 14074c8945a0SNathan Whitehorn } 14084c8945a0SNathan Whitehorn if ((*height != 0) && (*width != 0)) { 14094c8945a0SNathan Whitehorn (void) fclose(fd); 14104c8945a0SNathan Whitehorn if (*width > SCOLS) 14114c8945a0SNathan Whitehorn *width = SCOLS; 14124c8945a0SNathan Whitehorn if (*height > SLINES) 14134c8945a0SNathan Whitehorn *height = SLINES; 14144c8945a0SNathan Whitehorn return; 14154c8945a0SNathan Whitehorn } 14164c8945a0SNathan Whitehorn 14174c8945a0SNathan Whitehorn while (!feof(fd)) { 1418*f4f33ea0SBaptiste Daroussin if (ferror(fd)) 1419*f4f33ea0SBaptiste Daroussin break; 14204c8945a0SNathan Whitehorn offset = 0; 1421*f4f33ea0SBaptiste Daroussin while (((ch = getc(fd)) != '\n') && !feof(fd)) { 1422*f4f33ea0SBaptiste Daroussin if ((ch == TAB) && (dialog_vars.tab_correct)) { 14234c8945a0SNathan Whitehorn offset += dialog_state.tab_len - (offset % dialog_state.tab_len); 1424*f4f33ea0SBaptiste Daroussin } else { 14254c8945a0SNathan Whitehorn offset++; 1426*f4f33ea0SBaptiste Daroussin } 1427*f4f33ea0SBaptiste Daroussin } 14284c8945a0SNathan Whitehorn 14294c8945a0SNathan Whitehorn if (offset > len) 14307a1c0d96SNathan Whitehorn len = (int) offset; 14314c8945a0SNathan Whitehorn 14324c8945a0SNathan Whitehorn count++; 14334c8945a0SNathan Whitehorn } 14344c8945a0SNathan Whitehorn 14357a1c0d96SNathan Whitehorn /* now 'count' has the number of lines of fd and 'len' the max length */ 14364c8945a0SNathan Whitehorn 14374c8945a0SNathan Whitehorn *height = MIN(SLINES, count + numlines + boxlines); 14384c8945a0SNathan Whitehorn *width = MIN(SCOLS, MAX((len + nc), mincols)); 14394c8945a0SNathan Whitehorn /* here width and height can be maximized if > SCOLS|SLINES because 14404c8945a0SNathan Whitehorn textbox-like widgets don't put all <file> on the screen. 14414c8945a0SNathan Whitehorn Msgbox-like widget instead have to put all <text> correctly. */ 14424c8945a0SNathan Whitehorn 14434c8945a0SNathan Whitehorn (void) fclose(fd); 14444c8945a0SNathan Whitehorn } 14454c8945a0SNathan Whitehorn 14464c8945a0SNathan Whitehorn /* 14474c8945a0SNathan Whitehorn * Draw a rectangular box with line drawing characters. 14484c8945a0SNathan Whitehorn * 14494c8945a0SNathan Whitehorn * borderchar is used to color the upper/left edges. 14504c8945a0SNathan Whitehorn * 14514c8945a0SNathan Whitehorn * boxchar is used to color the right/lower edges. It also is fill-color used 14524c8945a0SNathan Whitehorn * for the box contents. 14534c8945a0SNathan Whitehorn * 14544c8945a0SNathan Whitehorn * Normally, if you are drawing a scrollable box, use menubox_border_attr for 14554c8945a0SNathan Whitehorn * boxchar, and menubox_attr for borderchar since the scroll-arrows are drawn 14564c8945a0SNathan Whitehorn * with menubox_attr at the top, and menubox_border_attr at the bottom. That 14574c8945a0SNathan Whitehorn * also (given the default color choices) produces a recessed effect. 14584c8945a0SNathan Whitehorn * 14594c8945a0SNathan Whitehorn * If you want a raised effect (and are not going to use the scroll-arrows), 14604c8945a0SNathan Whitehorn * reverse this choice. 14614c8945a0SNathan Whitehorn */ 14624c8945a0SNathan Whitehorn void 14632a3e3873SBaptiste Daroussin dlg_draw_box2(WINDOW *win, int y, int x, int height, int width, 14642a3e3873SBaptiste Daroussin chtype boxchar, chtype borderchar, chtype borderchar2) 14654c8945a0SNathan Whitehorn { 14664c8945a0SNathan Whitehorn int i, j; 14677a1c0d96SNathan Whitehorn chtype save = dlg_get_attrs(win); 14684c8945a0SNathan Whitehorn 1469*f4f33ea0SBaptiste Daroussin dlg_attrset(win, 0); 14704c8945a0SNathan Whitehorn for (i = 0; i < height; i++) { 14714c8945a0SNathan Whitehorn (void) wmove(win, y + i, x); 14724c8945a0SNathan Whitehorn for (j = 0; j < width; j++) 14734c8945a0SNathan Whitehorn if (!i && !j) 14744c8945a0SNathan Whitehorn (void) waddch(win, borderchar | dlg_boxchar(ACS_ULCORNER)); 14754c8945a0SNathan Whitehorn else if (i == height - 1 && !j) 14764c8945a0SNathan Whitehorn (void) waddch(win, borderchar | dlg_boxchar(ACS_LLCORNER)); 14774c8945a0SNathan Whitehorn else if (!i && j == width - 1) 14782a3e3873SBaptiste Daroussin (void) waddch(win, borderchar2 | dlg_boxchar(ACS_URCORNER)); 14794c8945a0SNathan Whitehorn else if (i == height - 1 && j == width - 1) 14802a3e3873SBaptiste Daroussin (void) waddch(win, borderchar2 | dlg_boxchar(ACS_LRCORNER)); 14814c8945a0SNathan Whitehorn else if (!i) 14824c8945a0SNathan Whitehorn (void) waddch(win, borderchar | dlg_boxchar(ACS_HLINE)); 14834c8945a0SNathan Whitehorn else if (i == height - 1) 14842a3e3873SBaptiste Daroussin (void) waddch(win, borderchar2 | dlg_boxchar(ACS_HLINE)); 14854c8945a0SNathan Whitehorn else if (!j) 14864c8945a0SNathan Whitehorn (void) waddch(win, borderchar | dlg_boxchar(ACS_VLINE)); 14874c8945a0SNathan Whitehorn else if (j == width - 1) 14882a3e3873SBaptiste Daroussin (void) waddch(win, borderchar2 | dlg_boxchar(ACS_VLINE)); 14894c8945a0SNathan Whitehorn else 14904c8945a0SNathan Whitehorn (void) waddch(win, boxchar | ' '); 14914c8945a0SNathan Whitehorn } 1492*f4f33ea0SBaptiste Daroussin dlg_attrset(win, save); 14932a3e3873SBaptiste Daroussin } 14942a3e3873SBaptiste Daroussin 14952a3e3873SBaptiste Daroussin void 14962a3e3873SBaptiste Daroussin dlg_draw_box(WINDOW *win, int y, int x, int height, int width, 14972a3e3873SBaptiste Daroussin chtype boxchar, chtype borderchar) 14982a3e3873SBaptiste Daroussin { 14992a3e3873SBaptiste Daroussin dlg_draw_box2(win, y, x, height, width, boxchar, borderchar, boxchar); 15004c8945a0SNathan Whitehorn } 15014c8945a0SNathan Whitehorn 1502682c9e0fSNathan Whitehorn static DIALOG_WINDOWS * 1503682c9e0fSNathan Whitehorn find_window(WINDOW *win) 1504682c9e0fSNathan Whitehorn { 1505682c9e0fSNathan Whitehorn DIALOG_WINDOWS *result = 0; 1506682c9e0fSNathan Whitehorn DIALOG_WINDOWS *p; 1507682c9e0fSNathan Whitehorn 1508682c9e0fSNathan Whitehorn for (p = dialog_state.all_windows; p != 0; p = p->next) { 1509682c9e0fSNathan Whitehorn if (p->normal == win) { 1510682c9e0fSNathan Whitehorn result = p; 1511682c9e0fSNathan Whitehorn break; 1512682c9e0fSNathan Whitehorn } 1513682c9e0fSNathan Whitehorn } 1514682c9e0fSNathan Whitehorn return result; 1515682c9e0fSNathan Whitehorn } 1516682c9e0fSNathan Whitehorn 15174c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 15184c8945a0SNathan Whitehorn /* 1519682c9e0fSNathan Whitehorn * If we have wchgat(), use that for updating shadow attributes, to work with 1520682c9e0fSNathan Whitehorn * wide-character data. 1521682c9e0fSNathan Whitehorn */ 1522682c9e0fSNathan Whitehorn 1523682c9e0fSNathan Whitehorn /* 1524682c9e0fSNathan Whitehorn * Check if the given point is "in" the given window. If so, return the window 1525682c9e0fSNathan Whitehorn * pointer, otherwise null. 1526682c9e0fSNathan Whitehorn */ 1527682c9e0fSNathan Whitehorn static WINDOW * 1528682c9e0fSNathan Whitehorn in_window(WINDOW *win, int y, int x) 1529682c9e0fSNathan Whitehorn { 1530682c9e0fSNathan Whitehorn WINDOW *result = 0; 1531682c9e0fSNathan Whitehorn int y_base = getbegy(win); 1532682c9e0fSNathan Whitehorn int x_base = getbegx(win); 1533682c9e0fSNathan Whitehorn int y_last = getmaxy(win) + y_base; 1534682c9e0fSNathan Whitehorn int x_last = getmaxx(win) + x_base; 1535682c9e0fSNathan Whitehorn 1536682c9e0fSNathan Whitehorn if (y >= y_base && y <= y_last && x >= x_base && x <= x_last) 1537682c9e0fSNathan Whitehorn result = win; 1538682c9e0fSNathan Whitehorn return result; 1539682c9e0fSNathan Whitehorn } 1540682c9e0fSNathan Whitehorn 1541682c9e0fSNathan Whitehorn static WINDOW * 1542682c9e0fSNathan Whitehorn window_at_cell(DIALOG_WINDOWS * dw, int y, int x) 1543682c9e0fSNathan Whitehorn { 1544682c9e0fSNathan Whitehorn WINDOW *result = 0; 1545682c9e0fSNathan Whitehorn DIALOG_WINDOWS *p; 1546682c9e0fSNathan Whitehorn int y_want = y + getbegy(dw->shadow); 1547682c9e0fSNathan Whitehorn int x_want = x + getbegx(dw->shadow); 1548682c9e0fSNathan Whitehorn 1549682c9e0fSNathan Whitehorn for (p = dialog_state.all_windows; p != 0; p = p->next) { 1550682c9e0fSNathan Whitehorn if (dw->normal != p->normal 1551682c9e0fSNathan Whitehorn && dw->shadow != p->normal 1552682c9e0fSNathan Whitehorn && (result = in_window(p->normal, y_want, x_want)) != 0) { 1553682c9e0fSNathan Whitehorn break; 1554682c9e0fSNathan Whitehorn } 1555682c9e0fSNathan Whitehorn } 1556682c9e0fSNathan Whitehorn if (result == 0) { 1557682c9e0fSNathan Whitehorn result = stdscr; 1558682c9e0fSNathan Whitehorn } 1559682c9e0fSNathan Whitehorn return result; 1560682c9e0fSNathan Whitehorn } 1561682c9e0fSNathan Whitehorn 1562682c9e0fSNathan Whitehorn static bool 1563682c9e0fSNathan Whitehorn in_shadow(WINDOW *normal, WINDOW *shadow, int y, int x) 1564682c9e0fSNathan Whitehorn { 1565682c9e0fSNathan Whitehorn bool result = FALSE; 1566682c9e0fSNathan Whitehorn int ybase = getbegy(normal); 1567682c9e0fSNathan Whitehorn int ylast = getmaxy(normal) + ybase; 1568682c9e0fSNathan Whitehorn int xbase = getbegx(normal); 1569682c9e0fSNathan Whitehorn int xlast = getmaxx(normal) + xbase; 1570682c9e0fSNathan Whitehorn 1571682c9e0fSNathan Whitehorn y += getbegy(shadow); 1572682c9e0fSNathan Whitehorn x += getbegx(shadow); 1573682c9e0fSNathan Whitehorn 1574682c9e0fSNathan Whitehorn if (y >= ybase + SHADOW_ROWS 1575682c9e0fSNathan Whitehorn && y < ylast + SHADOW_ROWS 1576682c9e0fSNathan Whitehorn && x >= xlast 1577682c9e0fSNathan Whitehorn && x < xlast + SHADOW_COLS) { 1578682c9e0fSNathan Whitehorn /* in the right-side */ 1579682c9e0fSNathan Whitehorn result = TRUE; 1580682c9e0fSNathan Whitehorn } else if (y >= ylast 1581682c9e0fSNathan Whitehorn && y < ylast + SHADOW_ROWS 1582682c9e0fSNathan Whitehorn && x >= ybase + SHADOW_COLS 1583682c9e0fSNathan Whitehorn && x < ylast + SHADOW_COLS) { 1584682c9e0fSNathan Whitehorn /* check the bottom */ 1585682c9e0fSNathan Whitehorn result = TRUE; 1586682c9e0fSNathan Whitehorn } 1587682c9e0fSNathan Whitehorn 1588682c9e0fSNathan Whitehorn return result; 1589682c9e0fSNathan Whitehorn } 1590682c9e0fSNathan Whitehorn 1591682c9e0fSNathan Whitehorn /* 1592682c9e0fSNathan Whitehorn * When erasing a shadow, check each cell to make sure that it is not part of 1593682c9e0fSNathan Whitehorn * another box's shadow. This is a little complicated since most shadows are 1594682c9e0fSNathan Whitehorn * merged onto stdscr. 1595682c9e0fSNathan Whitehorn */ 1596682c9e0fSNathan Whitehorn static bool 1597682c9e0fSNathan Whitehorn last_shadow(DIALOG_WINDOWS * dw, int y, int x) 1598682c9e0fSNathan Whitehorn { 1599682c9e0fSNathan Whitehorn DIALOG_WINDOWS *p; 1600682c9e0fSNathan Whitehorn bool result = TRUE; 1601682c9e0fSNathan Whitehorn 1602682c9e0fSNathan Whitehorn for (p = dialog_state.all_windows; p != 0; p = p->next) { 1603682c9e0fSNathan Whitehorn if (p->normal != dw->normal 1604682c9e0fSNathan Whitehorn && in_shadow(p->normal, dw->shadow, y, x)) { 1605682c9e0fSNathan Whitehorn result = FALSE; 1606682c9e0fSNathan Whitehorn break; 1607682c9e0fSNathan Whitehorn } 1608682c9e0fSNathan Whitehorn } 1609682c9e0fSNathan Whitehorn return result; 1610682c9e0fSNathan Whitehorn } 1611682c9e0fSNathan Whitehorn 1612682c9e0fSNathan Whitehorn static void 1613682c9e0fSNathan Whitehorn repaint_cell(DIALOG_WINDOWS * dw, bool draw, int y, int x) 1614682c9e0fSNathan Whitehorn { 1615682c9e0fSNathan Whitehorn WINDOW *win = dw->shadow; 1616682c9e0fSNathan Whitehorn WINDOW *cellwin; 1617682c9e0fSNathan Whitehorn int y2, x2; 1618682c9e0fSNathan Whitehorn 1619682c9e0fSNathan Whitehorn if ((cellwin = window_at_cell(dw, y, x)) != 0 1620682c9e0fSNathan Whitehorn && (draw || last_shadow(dw, y, x)) 1621682c9e0fSNathan Whitehorn && (y2 = (y + getbegy(win) - getbegy(cellwin))) >= 0 1622682c9e0fSNathan Whitehorn && (x2 = (x + getbegx(win) - getbegx(cellwin))) >= 0 1623682c9e0fSNathan Whitehorn && wmove(cellwin, y2, x2) != ERR) { 1624682c9e0fSNathan Whitehorn chtype the_cell = dlg_get_attrs(cellwin); 1625682c9e0fSNathan Whitehorn chtype the_attr = (draw ? shadow_attr : the_cell); 1626682c9e0fSNathan Whitehorn 1627*f4f33ea0SBaptiste Daroussin if (winch(cellwin) & A_ALTCHARSET) { 1628682c9e0fSNathan Whitehorn the_attr |= A_ALTCHARSET; 1629682c9e0fSNathan Whitehorn } 1630682c9e0fSNathan Whitehorn #if USE_WCHGAT 1631682c9e0fSNathan Whitehorn wchgat(cellwin, 1, 1632682c9e0fSNathan Whitehorn the_attr & (chtype) (~A_COLOR), 16332a3e3873SBaptiste Daroussin (short) PAIR_NUMBER(the_attr), 1634682c9e0fSNathan Whitehorn NULL); 1635682c9e0fSNathan Whitehorn #else 1636682c9e0fSNathan Whitehorn { 1637682c9e0fSNathan Whitehorn chtype the_char = ((winch(cellwin) & A_CHARTEXT) | the_attr); 1638682c9e0fSNathan Whitehorn (void) waddch(cellwin, the_char); 1639682c9e0fSNathan Whitehorn } 1640682c9e0fSNathan Whitehorn #endif 1641682c9e0fSNathan Whitehorn wnoutrefresh(cellwin); 1642682c9e0fSNathan Whitehorn } 1643682c9e0fSNathan Whitehorn } 1644682c9e0fSNathan Whitehorn 1645682c9e0fSNathan Whitehorn #define RepaintCell(dw, draw, y, x) repaint_cell(dw, draw, y, x) 1646682c9e0fSNathan Whitehorn 1647682c9e0fSNathan Whitehorn static void 1648682c9e0fSNathan Whitehorn repaint_shadow(DIALOG_WINDOWS * dw, bool draw, int y, int x, int height, int width) 1649682c9e0fSNathan Whitehorn { 1650682c9e0fSNathan Whitehorn int i, j; 1651682c9e0fSNathan Whitehorn 1652682c9e0fSNathan Whitehorn if (UseShadow(dw)) { 1653682c9e0fSNathan Whitehorn #if !USE_WCHGAT 1654682c9e0fSNathan Whitehorn chtype save = dlg_get_attrs(dw->shadow); 1655*f4f33ea0SBaptiste Daroussin dlg_attrset(dw->shadow, draw ? shadow_attr : screen_attr); 1656682c9e0fSNathan Whitehorn #endif 1657682c9e0fSNathan Whitehorn for (i = 0; i < SHADOW_ROWS; ++i) { 1658682c9e0fSNathan Whitehorn for (j = 0; j < width; ++j) { 1659682c9e0fSNathan Whitehorn RepaintCell(dw, draw, i + y + height, j + x + SHADOW_COLS); 1660682c9e0fSNathan Whitehorn } 1661682c9e0fSNathan Whitehorn } 1662682c9e0fSNathan Whitehorn for (i = 0; i < height; i++) { 1663682c9e0fSNathan Whitehorn for (j = 0; j < SHADOW_COLS; ++j) { 1664682c9e0fSNathan Whitehorn RepaintCell(dw, draw, i + y + SHADOW_ROWS, j + x + width); 1665682c9e0fSNathan Whitehorn } 1666682c9e0fSNathan Whitehorn } 1667682c9e0fSNathan Whitehorn (void) wnoutrefresh(dw->shadow); 1668682c9e0fSNathan Whitehorn #if !USE_WCHGAT 1669*f4f33ea0SBaptiste Daroussin dlg_attrset(dw->shadow, save); 1670682c9e0fSNathan Whitehorn #endif 1671682c9e0fSNathan Whitehorn } 1672682c9e0fSNathan Whitehorn } 1673682c9e0fSNathan Whitehorn 1674682c9e0fSNathan Whitehorn /* 16754c8945a0SNathan Whitehorn * Draw a shadow on the parent window corresponding to the right- and 16764c8945a0SNathan Whitehorn * bottom-edge of the child window, to give a 3-dimensional look. 16774c8945a0SNathan Whitehorn */ 16784c8945a0SNathan Whitehorn static void 1679682c9e0fSNathan Whitehorn draw_childs_shadow(DIALOG_WINDOWS * dw) 16804c8945a0SNathan Whitehorn { 1681682c9e0fSNathan Whitehorn if (UseShadow(dw)) { 1682682c9e0fSNathan Whitehorn repaint_shadow(dw, 1683682c9e0fSNathan Whitehorn TRUE, 1684682c9e0fSNathan Whitehorn getbegy(dw->normal) - getbegy(dw->shadow), 1685682c9e0fSNathan Whitehorn getbegx(dw->normal) - getbegx(dw->shadow), 1686682c9e0fSNathan Whitehorn getmaxy(dw->normal), 1687682c9e0fSNathan Whitehorn getmaxx(dw->normal)); 1688682c9e0fSNathan Whitehorn } 1689682c9e0fSNathan Whitehorn } 16904c8945a0SNathan Whitehorn 1691682c9e0fSNathan Whitehorn /* 1692682c9e0fSNathan Whitehorn * Erase a shadow on the parent window corresponding to the right- and 1693682c9e0fSNathan Whitehorn * bottom-edge of the child window. 1694682c9e0fSNathan Whitehorn */ 1695682c9e0fSNathan Whitehorn static void 1696682c9e0fSNathan Whitehorn erase_childs_shadow(DIALOG_WINDOWS * dw) 1697682c9e0fSNathan Whitehorn { 1698682c9e0fSNathan Whitehorn if (UseShadow(dw)) { 1699682c9e0fSNathan Whitehorn repaint_shadow(dw, 1700682c9e0fSNathan Whitehorn FALSE, 1701682c9e0fSNathan Whitehorn getbegy(dw->normal) - getbegy(dw->shadow), 1702682c9e0fSNathan Whitehorn getbegx(dw->normal) - getbegx(dw->shadow), 1703682c9e0fSNathan Whitehorn getmaxy(dw->normal), 1704682c9e0fSNathan Whitehorn getmaxx(dw->normal)); 17054c8945a0SNathan Whitehorn } 17064c8945a0SNathan Whitehorn } 17074c8945a0SNathan Whitehorn 17084c8945a0SNathan Whitehorn /* 17094c8945a0SNathan Whitehorn * Draw shadows along the right and bottom edge to give a more 3D look 1710682c9e0fSNathan Whitehorn * to the boxes. 17114c8945a0SNathan Whitehorn */ 17124c8945a0SNathan Whitehorn void 17134c8945a0SNathan Whitehorn dlg_draw_shadow(WINDOW *win, int y, int x, int height, int width) 17144c8945a0SNathan Whitehorn { 1715682c9e0fSNathan Whitehorn repaint_shadow(find_window(win), TRUE, y, x, height, width); 17164c8945a0SNathan Whitehorn } 17174c8945a0SNathan Whitehorn #endif /* HAVE_COLOR */ 17184c8945a0SNathan Whitehorn 17194c8945a0SNathan Whitehorn /* 17204c8945a0SNathan Whitehorn * Allow shell scripts to remap the exit codes so they can distinguish ESC 17214c8945a0SNathan Whitehorn * from ERROR. 17224c8945a0SNathan Whitehorn */ 17234c8945a0SNathan Whitehorn void 17244c8945a0SNathan Whitehorn dlg_exit(int code) 17254c8945a0SNathan Whitehorn { 17264c8945a0SNathan Whitehorn /* *INDENT-OFF* */ 17274c8945a0SNathan Whitehorn static const struct { 17284c8945a0SNathan Whitehorn int code; 17294c8945a0SNathan Whitehorn const char *name; 17304c8945a0SNathan Whitehorn } table[] = { 17314c8945a0SNathan Whitehorn { DLG_EXIT_CANCEL, "DIALOG_CANCEL" }, 17324c8945a0SNathan Whitehorn { DLG_EXIT_ERROR, "DIALOG_ERROR" }, 17334c8945a0SNathan Whitehorn { DLG_EXIT_ESC, "DIALOG_ESC" }, 17344c8945a0SNathan Whitehorn { DLG_EXIT_EXTRA, "DIALOG_EXTRA" }, 17354c8945a0SNathan Whitehorn { DLG_EXIT_HELP, "DIALOG_HELP" }, 17364c8945a0SNathan Whitehorn { DLG_EXIT_OK, "DIALOG_OK" }, 17374c8945a0SNathan Whitehorn { DLG_EXIT_ITEM_HELP, "DIALOG_ITEM_HELP" }, 17384c8945a0SNathan Whitehorn }; 17394c8945a0SNathan Whitehorn /* *INDENT-ON* */ 17404c8945a0SNathan Whitehorn 17414c8945a0SNathan Whitehorn unsigned n; 17424c8945a0SNathan Whitehorn char *name; 17434c8945a0SNathan Whitehorn char *temp; 17444c8945a0SNathan Whitehorn long value; 17454c8945a0SNathan Whitehorn bool overridden = FALSE; 17464c8945a0SNathan Whitehorn 17474c8945a0SNathan Whitehorn retry: 17484c8945a0SNathan Whitehorn for (n = 0; n < sizeof(table) / sizeof(table[0]); n++) { 17494c8945a0SNathan Whitehorn if (table[n].code == code) { 17504c8945a0SNathan Whitehorn if ((name = getenv(table[n].name)) != 0) { 17514c8945a0SNathan Whitehorn value = strtol(name, &temp, 0); 17524c8945a0SNathan Whitehorn if (temp != 0 && temp != name && *temp == '\0') { 17537a1c0d96SNathan Whitehorn code = (int) value; 17544c8945a0SNathan Whitehorn overridden = TRUE; 17554c8945a0SNathan Whitehorn } 17564c8945a0SNathan Whitehorn } 17574c8945a0SNathan Whitehorn break; 17584c8945a0SNathan Whitehorn } 17594c8945a0SNathan Whitehorn } 17604c8945a0SNathan Whitehorn 17614c8945a0SNathan Whitehorn /* 17624c8945a0SNathan Whitehorn * Prior to 2004/12/19, a widget using --item-help would exit with "OK" 17634c8945a0SNathan Whitehorn * if the help button were selected. Now we want to exit with "HELP", 17644c8945a0SNathan Whitehorn * but allow the environment variable to override. 17654c8945a0SNathan Whitehorn */ 17664c8945a0SNathan Whitehorn if (code == DLG_EXIT_ITEM_HELP && !overridden) { 17674c8945a0SNathan Whitehorn code = DLG_EXIT_HELP; 17684c8945a0SNathan Whitehorn goto retry; 17694c8945a0SNathan Whitehorn } 1770682c9e0fSNathan Whitehorn #ifdef HAVE_DLG_TRACE 1771682c9e0fSNathan Whitehorn dlg_trace((const char *) 0); /* close it */ 1772682c9e0fSNathan Whitehorn #endif 1773682c9e0fSNathan Whitehorn 17744c8945a0SNathan Whitehorn #ifdef NO_LEAKS 17754c8945a0SNathan Whitehorn _dlg_inputstr_leaks(); 17764c8945a0SNathan Whitehorn #if defined(NCURSES_VERSION) && defined(HAVE__NC_FREE_AND_EXIT) 17774c8945a0SNathan Whitehorn _nc_free_and_exit(code); 17784c8945a0SNathan Whitehorn #endif 17794c8945a0SNathan Whitehorn #endif 17804c8945a0SNathan Whitehorn 17814c8945a0SNathan Whitehorn if (dialog_state.input == stdin) { 17824c8945a0SNathan Whitehorn exit(code); 17834c8945a0SNathan Whitehorn } else { 17844c8945a0SNathan Whitehorn /* 17854c8945a0SNathan Whitehorn * Just in case of using --input-fd option, do not 17864c8945a0SNathan Whitehorn * call atexit functions of ncurses which may hang. 17874c8945a0SNathan Whitehorn */ 17884c8945a0SNathan Whitehorn if (dialog_state.input) { 17894c8945a0SNathan Whitehorn fclose(dialog_state.input); 17904c8945a0SNathan Whitehorn dialog_state.input = 0; 17914c8945a0SNathan Whitehorn } 17924c8945a0SNathan Whitehorn if (dialog_state.pipe_input) { 17934c8945a0SNathan Whitehorn if (dialog_state.pipe_input != stdin) { 17944c8945a0SNathan Whitehorn fclose(dialog_state.pipe_input); 17954c8945a0SNathan Whitehorn dialog_state.pipe_input = 0; 17964c8945a0SNathan Whitehorn } 17974c8945a0SNathan Whitehorn } 17984c8945a0SNathan Whitehorn _exit(code); 17994c8945a0SNathan Whitehorn } 18004c8945a0SNathan Whitehorn } 18014c8945a0SNathan Whitehorn 18024c8945a0SNathan Whitehorn /* quit program killing all tailbg */ 18034c8945a0SNathan Whitehorn void 18044c8945a0SNathan Whitehorn dlg_exiterr(const char *fmt,...) 18054c8945a0SNathan Whitehorn { 18064c8945a0SNathan Whitehorn int retval; 18074c8945a0SNathan Whitehorn va_list ap; 18084c8945a0SNathan Whitehorn 18094c8945a0SNathan Whitehorn end_dialog(); 18104c8945a0SNathan Whitehorn 18114c8945a0SNathan Whitehorn (void) fputc('\n', stderr); 18124c8945a0SNathan Whitehorn va_start(ap, fmt); 18134c8945a0SNathan Whitehorn (void) vfprintf(stderr, fmt, ap); 18144c8945a0SNathan Whitehorn va_end(ap); 18154c8945a0SNathan Whitehorn (void) fputc('\n', stderr); 18164c8945a0SNathan Whitehorn 18174c8945a0SNathan Whitehorn dlg_killall_bg(&retval); 18184c8945a0SNathan Whitehorn 18194c8945a0SNathan Whitehorn (void) fflush(stderr); 18204c8945a0SNathan Whitehorn (void) fflush(stdout); 18214c8945a0SNathan Whitehorn dlg_exit(DLG_EXIT_ERROR); 18224c8945a0SNathan Whitehorn } 18234c8945a0SNathan Whitehorn 18244c8945a0SNathan Whitehorn void 18254c8945a0SNathan Whitehorn dlg_beeping(void) 18264c8945a0SNathan Whitehorn { 18274c8945a0SNathan Whitehorn if (dialog_vars.beep_signal) { 18284c8945a0SNathan Whitehorn (void) beep(); 18294c8945a0SNathan Whitehorn dialog_vars.beep_signal = 0; 18304c8945a0SNathan Whitehorn } 18314c8945a0SNathan Whitehorn } 18324c8945a0SNathan Whitehorn 18334c8945a0SNathan Whitehorn void 18344c8945a0SNathan Whitehorn dlg_print_size(int height, int width) 18354c8945a0SNathan Whitehorn { 1836*f4f33ea0SBaptiste Daroussin if (dialog_vars.print_siz) { 18374c8945a0SNathan Whitehorn fprintf(dialog_state.output, "Size: %d, %d\n", height, width); 1838*f4f33ea0SBaptiste Daroussin DLG_TRACE(("# print size: %dx%d\n", height, width)); 1839*f4f33ea0SBaptiste Daroussin } 18404c8945a0SNathan Whitehorn } 18414c8945a0SNathan Whitehorn 18424c8945a0SNathan Whitehorn void 18434c8945a0SNathan Whitehorn dlg_ctl_size(int height, int width) 18444c8945a0SNathan Whitehorn { 18454c8945a0SNathan Whitehorn if (dialog_vars.size_err) { 18464c8945a0SNathan Whitehorn if ((width > COLS) || (height > LINES)) { 18474c8945a0SNathan Whitehorn dlg_exiterr("Window too big. (height, width) = (%d, %d). Max allowed (%d, %d).", 18484c8945a0SNathan Whitehorn height, width, LINES, COLS); 18494c8945a0SNathan Whitehorn } 18504c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 18514c8945a0SNathan Whitehorn else if ((dialog_state.use_shadow) 18524c8945a0SNathan Whitehorn && ((width > SCOLS || height > SLINES))) { 18534c8945a0SNathan Whitehorn if ((width <= COLS) && (height <= LINES)) { 18544c8945a0SNathan Whitehorn /* try again, without shadows */ 18554c8945a0SNathan Whitehorn dialog_state.use_shadow = 0; 18564c8945a0SNathan Whitehorn } else { 18574c8945a0SNathan Whitehorn dlg_exiterr("Window+Shadow too big. (height, width) = (%d, %d). Max allowed (%d, %d).", 18584c8945a0SNathan Whitehorn height, width, SLINES, SCOLS); 18594c8945a0SNathan Whitehorn } 18604c8945a0SNathan Whitehorn } 18614c8945a0SNathan Whitehorn #endif 18624c8945a0SNathan Whitehorn } 18634c8945a0SNathan Whitehorn } 18644c8945a0SNathan Whitehorn 18654c8945a0SNathan Whitehorn /* 18664c8945a0SNathan Whitehorn * If the --tab-correct was not selected, convert tabs to single spaces. 18674c8945a0SNathan Whitehorn */ 18684c8945a0SNathan Whitehorn void 18694c8945a0SNathan Whitehorn dlg_tab_correct_str(char *prompt) 18704c8945a0SNathan Whitehorn { 18714c8945a0SNathan Whitehorn char *ptr; 18724c8945a0SNathan Whitehorn 18734c8945a0SNathan Whitehorn if (dialog_vars.tab_correct) { 18744c8945a0SNathan Whitehorn while ((ptr = strchr(prompt, TAB)) != NULL) { 18754c8945a0SNathan Whitehorn *ptr = ' '; 18764c8945a0SNathan Whitehorn prompt = ptr; 18774c8945a0SNathan Whitehorn } 18784c8945a0SNathan Whitehorn } 18794c8945a0SNathan Whitehorn } 18804c8945a0SNathan Whitehorn 18814c8945a0SNathan Whitehorn void 18824c8945a0SNathan Whitehorn dlg_calc_listh(int *height, int *list_height, int item_no) 18834c8945a0SNathan Whitehorn { 18844c8945a0SNathan Whitehorn /* calculate new height and list_height */ 18854c8945a0SNathan Whitehorn int rows = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0); 18864c8945a0SNathan Whitehorn if (rows - (*height) > 0) { 18874c8945a0SNathan Whitehorn if (rows - (*height) > item_no) 18884c8945a0SNathan Whitehorn *list_height = item_no; 18894c8945a0SNathan Whitehorn else 18904c8945a0SNathan Whitehorn *list_height = rows - (*height); 18914c8945a0SNathan Whitehorn } 18924c8945a0SNathan Whitehorn (*height) += (*list_height); 18934c8945a0SNathan Whitehorn } 18944c8945a0SNathan Whitehorn 18954c8945a0SNathan Whitehorn /* obsolete */ 18964c8945a0SNathan Whitehorn int 18974c8945a0SNathan Whitehorn dlg_calc_listw(int item_no, char **items, int group) 18984c8945a0SNathan Whitehorn { 18994c8945a0SNathan Whitehorn int n, i, len1 = 0, len2 = 0; 19004c8945a0SNathan Whitehorn for (i = 0; i < (item_no * group); i += group) { 19014c8945a0SNathan Whitehorn if ((n = dlg_count_columns(items[i])) > len1) 19024c8945a0SNathan Whitehorn len1 = n; 19034c8945a0SNathan Whitehorn if ((n = dlg_count_columns(items[i + 1])) > len2) 19044c8945a0SNathan Whitehorn len2 = n; 19054c8945a0SNathan Whitehorn } 19064c8945a0SNathan Whitehorn return len1 + len2; 19074c8945a0SNathan Whitehorn } 19084c8945a0SNathan Whitehorn 19094c8945a0SNathan Whitehorn int 19104c8945a0SNathan Whitehorn dlg_calc_list_width(int item_no, DIALOG_LISTITEM * items) 19114c8945a0SNathan Whitehorn { 19124c8945a0SNathan Whitehorn int n, i, len1 = 0, len2 = 0; 19132a3e3873SBaptiste Daroussin int bits = ((dialog_vars.no_tags ? 1 : 0) 19142a3e3873SBaptiste Daroussin + (dialog_vars.no_items ? 2 : 0)); 19152a3e3873SBaptiste Daroussin 19164c8945a0SNathan Whitehorn for (i = 0; i < item_no; ++i) { 19172a3e3873SBaptiste Daroussin switch (bits) { 19182a3e3873SBaptiste Daroussin case 0: 19192a3e3873SBaptiste Daroussin /* FALLTHRU */ 19202a3e3873SBaptiste Daroussin case 1: 19214c8945a0SNathan Whitehorn if ((n = dlg_count_columns(items[i].name)) > len1) 19224c8945a0SNathan Whitehorn len1 = n; 19234c8945a0SNathan Whitehorn if ((n = dlg_count_columns(items[i].text)) > len2) 19244c8945a0SNathan Whitehorn len2 = n; 19252a3e3873SBaptiste Daroussin break; 19262a3e3873SBaptiste Daroussin case 2: 19272a3e3873SBaptiste Daroussin /* FALLTHRU */ 19282a3e3873SBaptiste Daroussin case 3: 19292a3e3873SBaptiste Daroussin if ((n = dlg_count_columns(items[i].name)) > len1) 19302a3e3873SBaptiste Daroussin len1 = n; 19312a3e3873SBaptiste Daroussin break; 19322a3e3873SBaptiste Daroussin } 19334c8945a0SNathan Whitehorn } 19344c8945a0SNathan Whitehorn return len1 + len2; 19354c8945a0SNathan Whitehorn } 19364c8945a0SNathan Whitehorn 19374c8945a0SNathan Whitehorn char * 19384c8945a0SNathan Whitehorn dlg_strempty(void) 19394c8945a0SNathan Whitehorn { 19404c8945a0SNathan Whitehorn static char empty[] = ""; 19414c8945a0SNathan Whitehorn return empty; 19424c8945a0SNathan Whitehorn } 19434c8945a0SNathan Whitehorn 19444c8945a0SNathan Whitehorn char * 19454c8945a0SNathan Whitehorn dlg_strclone(const char *cprompt) 19464c8945a0SNathan Whitehorn { 1947*f4f33ea0SBaptiste Daroussin char *prompt = 0; 1948*f4f33ea0SBaptiste Daroussin if (cprompt != 0) { 1949*f4f33ea0SBaptiste Daroussin prompt = dlg_malloc(char, strlen(cprompt) + 1); 19504c8945a0SNathan Whitehorn assert_ptr(prompt, "dlg_strclone"); 19514c8945a0SNathan Whitehorn strcpy(prompt, cprompt); 1952*f4f33ea0SBaptiste Daroussin } 19534c8945a0SNathan Whitehorn return prompt; 19544c8945a0SNathan Whitehorn } 19554c8945a0SNathan Whitehorn 19564c8945a0SNathan Whitehorn chtype 19574c8945a0SNathan Whitehorn dlg_asciibox(chtype ch) 19584c8945a0SNathan Whitehorn { 19594c8945a0SNathan Whitehorn chtype result = 0; 19604c8945a0SNathan Whitehorn 19614c8945a0SNathan Whitehorn if (ch == ACS_ULCORNER) 19624c8945a0SNathan Whitehorn result = '+'; 19634c8945a0SNathan Whitehorn else if (ch == ACS_LLCORNER) 19644c8945a0SNathan Whitehorn result = '+'; 19654c8945a0SNathan Whitehorn else if (ch == ACS_URCORNER) 19664c8945a0SNathan Whitehorn result = '+'; 19674c8945a0SNathan Whitehorn else if (ch == ACS_LRCORNER) 19684c8945a0SNathan Whitehorn result = '+'; 19694c8945a0SNathan Whitehorn else if (ch == ACS_HLINE) 19704c8945a0SNathan Whitehorn result = '-'; 19714c8945a0SNathan Whitehorn else if (ch == ACS_VLINE) 19724c8945a0SNathan Whitehorn result = '|'; 19734c8945a0SNathan Whitehorn else if (ch == ACS_LTEE) 19744c8945a0SNathan Whitehorn result = '+'; 19754c8945a0SNathan Whitehorn else if (ch == ACS_RTEE) 19764c8945a0SNathan Whitehorn result = '+'; 19774c8945a0SNathan Whitehorn else if (ch == ACS_UARROW) 19784c8945a0SNathan Whitehorn result = '^'; 19794c8945a0SNathan Whitehorn else if (ch == ACS_DARROW) 19804c8945a0SNathan Whitehorn result = 'v'; 19814c8945a0SNathan Whitehorn 19824c8945a0SNathan Whitehorn return result; 19834c8945a0SNathan Whitehorn } 19844c8945a0SNathan Whitehorn 19854c8945a0SNathan Whitehorn chtype 19864c8945a0SNathan Whitehorn dlg_boxchar(chtype ch) 19874c8945a0SNathan Whitehorn { 19884c8945a0SNathan Whitehorn chtype result = dlg_asciibox(ch); 19894c8945a0SNathan Whitehorn 19904c8945a0SNathan Whitehorn if (result != 0) { 19914c8945a0SNathan Whitehorn if (dialog_vars.ascii_lines) 19924c8945a0SNathan Whitehorn ch = result; 19934c8945a0SNathan Whitehorn else if (dialog_vars.no_lines) 19944c8945a0SNathan Whitehorn ch = ' '; 19954c8945a0SNathan Whitehorn } 19964c8945a0SNathan Whitehorn return ch; 19974c8945a0SNathan Whitehorn } 19984c8945a0SNathan Whitehorn 19994c8945a0SNathan Whitehorn int 20004c8945a0SNathan Whitehorn dlg_box_x_ordinate(int width) 20014c8945a0SNathan Whitehorn { 20024c8945a0SNathan Whitehorn int x; 20034c8945a0SNathan Whitehorn 20044c8945a0SNathan Whitehorn if (dialog_vars.begin_set == 1) { 20054c8945a0SNathan Whitehorn x = dialog_vars.begin_x; 20064c8945a0SNathan Whitehorn } else { 20074c8945a0SNathan Whitehorn /* center dialog box on screen unless --begin-set */ 20084c8945a0SNathan Whitehorn x = (SCOLS - width) / 2; 20094c8945a0SNathan Whitehorn } 20104c8945a0SNathan Whitehorn return x; 20114c8945a0SNathan Whitehorn } 20124c8945a0SNathan Whitehorn 20134c8945a0SNathan Whitehorn int 20144c8945a0SNathan Whitehorn dlg_box_y_ordinate(int height) 20154c8945a0SNathan Whitehorn { 20164c8945a0SNathan Whitehorn int y; 20174c8945a0SNathan Whitehorn 20184c8945a0SNathan Whitehorn if (dialog_vars.begin_set == 1) { 20194c8945a0SNathan Whitehorn y = dialog_vars.begin_y; 20204c8945a0SNathan Whitehorn } else { 20214c8945a0SNathan Whitehorn /* center dialog box on screen unless --begin-set */ 20224c8945a0SNathan Whitehorn y = (SLINES - height) / 2; 20234c8945a0SNathan Whitehorn } 20244c8945a0SNathan Whitehorn return y; 20254c8945a0SNathan Whitehorn } 20264c8945a0SNathan Whitehorn 20274c8945a0SNathan Whitehorn void 20284c8945a0SNathan Whitehorn dlg_draw_title(WINDOW *win, const char *title) 20294c8945a0SNathan Whitehorn { 20304c8945a0SNathan Whitehorn if (title != NULL) { 20314c8945a0SNathan Whitehorn chtype attr = A_NORMAL; 20327a1c0d96SNathan Whitehorn chtype save = dlg_get_attrs(win); 20334c8945a0SNathan Whitehorn int x = centered(getmaxx(win), title); 20344c8945a0SNathan Whitehorn 2035*f4f33ea0SBaptiste Daroussin dlg_attrset(win, title_attr); 20364c8945a0SNathan Whitehorn wmove(win, 0, x); 20374c8945a0SNathan Whitehorn dlg_print_text(win, title, getmaxx(win) - x, &attr); 2038*f4f33ea0SBaptiste Daroussin dlg_attrset(win, save); 2039febdb468SDevin Teske dlg_finish_string(title); 20404c8945a0SNathan Whitehorn } 20414c8945a0SNathan Whitehorn } 20424c8945a0SNathan Whitehorn 20434c8945a0SNathan Whitehorn void 20442a3e3873SBaptiste Daroussin dlg_draw_bottom_box2(WINDOW *win, chtype on_left, chtype on_right, chtype on_inside) 20454c8945a0SNathan Whitehorn { 20464c8945a0SNathan Whitehorn int width = getmaxx(win); 20474c8945a0SNathan Whitehorn int height = getmaxy(win); 20484c8945a0SNathan Whitehorn int i; 20494c8945a0SNathan Whitehorn 2050*f4f33ea0SBaptiste Daroussin dlg_attrset(win, on_left); 20514c8945a0SNathan Whitehorn (void) wmove(win, height - 3, 0); 20524c8945a0SNathan Whitehorn (void) waddch(win, dlg_boxchar(ACS_LTEE)); 20534c8945a0SNathan Whitehorn for (i = 0; i < width - 2; i++) 20544c8945a0SNathan Whitehorn (void) waddch(win, dlg_boxchar(ACS_HLINE)); 2055*f4f33ea0SBaptiste Daroussin dlg_attrset(win, on_right); 20564c8945a0SNathan Whitehorn (void) waddch(win, dlg_boxchar(ACS_RTEE)); 2057*f4f33ea0SBaptiste Daroussin dlg_attrset(win, on_inside); 20584c8945a0SNathan Whitehorn (void) wmove(win, height - 2, 1); 20594c8945a0SNathan Whitehorn for (i = 0; i < width - 2; i++) 20604c8945a0SNathan Whitehorn (void) waddch(win, ' '); 20614c8945a0SNathan Whitehorn } 20624c8945a0SNathan Whitehorn 20632a3e3873SBaptiste Daroussin void 20642a3e3873SBaptiste Daroussin dlg_draw_bottom_box(WINDOW *win) 20652a3e3873SBaptiste Daroussin { 20662a3e3873SBaptiste Daroussin dlg_draw_bottom_box2(win, border_attr, dialog_attr, dialog_attr); 20672a3e3873SBaptiste Daroussin } 20682a3e3873SBaptiste Daroussin 20694c8945a0SNathan Whitehorn /* 20704c8945a0SNathan Whitehorn * Remove a window, repainting everything else. This would be simpler if we 20714c8945a0SNathan Whitehorn * used the panel library, but that is not _always_ available. 20724c8945a0SNathan Whitehorn */ 20734c8945a0SNathan Whitehorn void 20744c8945a0SNathan Whitehorn dlg_del_window(WINDOW *win) 20754c8945a0SNathan Whitehorn { 20764c8945a0SNathan Whitehorn DIALOG_WINDOWS *p, *q, *r; 20774c8945a0SNathan Whitehorn 20784c8945a0SNathan Whitehorn /* 20794c8945a0SNathan Whitehorn * If --keep-window was set, do not delete/repaint the windows. 20804c8945a0SNathan Whitehorn */ 20814c8945a0SNathan Whitehorn if (dialog_vars.keep_window) 20824c8945a0SNathan Whitehorn return; 20834c8945a0SNathan Whitehorn 20844c8945a0SNathan Whitehorn /* Leave the main window untouched if there are no background windows. 20854c8945a0SNathan Whitehorn * We do this so the current window will not be cleared on exit, allowing 20864c8945a0SNathan Whitehorn * things like the infobox demo to run without flicker. 20874c8945a0SNathan Whitehorn */ 20884c8945a0SNathan Whitehorn if (dialog_state.getc_callbacks != 0) { 20894c8945a0SNathan Whitehorn touchwin(stdscr); 20904c8945a0SNathan Whitehorn wnoutrefresh(stdscr); 20914c8945a0SNathan Whitehorn } 20924c8945a0SNathan Whitehorn 20934c8945a0SNathan Whitehorn for (p = dialog_state.all_windows, q = r = 0; p != 0; r = p, p = p->next) { 20944c8945a0SNathan Whitehorn if (p->normal == win) { 20954c8945a0SNathan Whitehorn q = p; /* found a match - should be only one */ 20964c8945a0SNathan Whitehorn if (r == 0) { 20974c8945a0SNathan Whitehorn dialog_state.all_windows = p->next; 20984c8945a0SNathan Whitehorn } else { 20994c8945a0SNathan Whitehorn r->next = p->next; 21004c8945a0SNathan Whitehorn } 21014c8945a0SNathan Whitehorn } else { 21024c8945a0SNathan Whitehorn if (p->shadow != 0) { 21034c8945a0SNathan Whitehorn touchwin(p->shadow); 21044c8945a0SNathan Whitehorn wnoutrefresh(p->shadow); 21054c8945a0SNathan Whitehorn } 21064c8945a0SNathan Whitehorn touchwin(p->normal); 21074c8945a0SNathan Whitehorn wnoutrefresh(p->normal); 21084c8945a0SNathan Whitehorn } 21094c8945a0SNathan Whitehorn } 21104c8945a0SNathan Whitehorn 21114c8945a0SNathan Whitehorn if (q) { 2112682c9e0fSNathan Whitehorn if (dialog_state.all_windows != 0) 2113682c9e0fSNathan Whitehorn erase_childs_shadow(q); 21142a3e3873SBaptiste Daroussin del_subwindows(q->normal); 21154c8945a0SNathan Whitehorn dlg_unregister_window(q->normal); 21162a3e3873SBaptiste Daroussin delwin(q->normal); 21174c8945a0SNathan Whitehorn free(q); 21184c8945a0SNathan Whitehorn } 21194c8945a0SNathan Whitehorn doupdate(); 21204c8945a0SNathan Whitehorn } 21214c8945a0SNathan Whitehorn 21224c8945a0SNathan Whitehorn /* 21234c8945a0SNathan Whitehorn * Create a window, optionally with a shadow. 21244c8945a0SNathan Whitehorn */ 21254c8945a0SNathan Whitehorn WINDOW * 21264c8945a0SNathan Whitehorn dlg_new_window(int height, int width, int y, int x) 21274c8945a0SNathan Whitehorn { 2128682c9e0fSNathan Whitehorn return dlg_new_modal_window(stdscr, height, width, y, x); 21294c8945a0SNathan Whitehorn } 21304c8945a0SNathan Whitehorn 2131682c9e0fSNathan Whitehorn /* 2132682c9e0fSNathan Whitehorn * "Modal" windows differ from normal ones by having a shadow in a window 2133682c9e0fSNathan Whitehorn * separate from the standard screen. 2134682c9e0fSNathan Whitehorn */ 21354c8945a0SNathan Whitehorn WINDOW * 21364c8945a0SNathan Whitehorn dlg_new_modal_window(WINDOW *parent, int height, int width, int y, int x) 21374c8945a0SNathan Whitehorn { 21384c8945a0SNathan Whitehorn WINDOW *win; 21394c8945a0SNathan Whitehorn DIALOG_WINDOWS *p = dlg_calloc(DIALOG_WINDOWS, 1); 21404c8945a0SNathan Whitehorn 21414c8945a0SNathan Whitehorn (void) parent; 21422a3e3873SBaptiste Daroussin if (p == 0 21432a3e3873SBaptiste Daroussin || (win = newwin(height, width, y, x)) == 0) { 21444c8945a0SNathan Whitehorn dlg_exiterr("Can't make new window at (%d,%d), size (%d,%d).\n", 21454c8945a0SNathan Whitehorn y, x, height, width); 21464c8945a0SNathan Whitehorn } 21474c8945a0SNathan Whitehorn p->next = dialog_state.all_windows; 21484c8945a0SNathan Whitehorn p->normal = win; 21494c8945a0SNathan Whitehorn dialog_state.all_windows = p; 21504c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 21514c8945a0SNathan Whitehorn if (dialog_state.use_shadow) { 2152682c9e0fSNathan Whitehorn p->shadow = parent; 2153682c9e0fSNathan Whitehorn draw_childs_shadow(p); 21544c8945a0SNathan Whitehorn } 21554c8945a0SNathan Whitehorn #endif 21564c8945a0SNathan Whitehorn 21574c8945a0SNathan Whitehorn (void) keypad(win, TRUE); 21584c8945a0SNathan Whitehorn return win; 21594c8945a0SNathan Whitehorn } 21604c8945a0SNathan Whitehorn 21614c8945a0SNathan Whitehorn /* 21624c8945a0SNathan Whitehorn * Move/Resize a window, optionally with a shadow. 21634c8945a0SNathan Whitehorn */ 21644c8945a0SNathan Whitehorn #ifdef KEY_RESIZE 21654c8945a0SNathan Whitehorn void 21664c8945a0SNathan Whitehorn dlg_move_window(WINDOW *win, int height, int width, int y, int x) 21674c8945a0SNathan Whitehorn { 2168682c9e0fSNathan Whitehorn DIALOG_WINDOWS *p; 21694c8945a0SNathan Whitehorn 21704c8945a0SNathan Whitehorn if (win != 0) { 21714c8945a0SNathan Whitehorn dlg_ctl_size(height, width); 21724c8945a0SNathan Whitehorn 2173682c9e0fSNathan Whitehorn if ((p = find_window(win)) != 0) { 21744c8945a0SNathan Whitehorn (void) wresize(win, height, width); 21754c8945a0SNathan Whitehorn (void) mvwin(win, y, x); 21764c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 21774c8945a0SNathan Whitehorn if (p->shadow != 0) { 21784c8945a0SNathan Whitehorn if (dialog_state.use_shadow) { 21794c8945a0SNathan Whitehorn (void) mvwin(p->shadow, y + SHADOW_ROWS, x + SHADOW_COLS); 21804c8945a0SNathan Whitehorn } else { 21814c8945a0SNathan Whitehorn p->shadow = 0; 21824c8945a0SNathan Whitehorn } 21834c8945a0SNathan Whitehorn } 21844c8945a0SNathan Whitehorn #endif 21854c8945a0SNathan Whitehorn (void) refresh(); 21864c8945a0SNathan Whitehorn 21874c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 2188682c9e0fSNathan Whitehorn draw_childs_shadow(p); 21894c8945a0SNathan Whitehorn #endif 21904c8945a0SNathan Whitehorn } 21914c8945a0SNathan Whitehorn } 21924c8945a0SNathan Whitehorn } 2193*f4f33ea0SBaptiste Daroussin 2194*f4f33ea0SBaptiste Daroussin /* 2195*f4f33ea0SBaptiste Daroussin * Having just received a KEY_RESIZE, wait a short time to ignore followup 2196*f4f33ea0SBaptiste Daroussin * KEY_RESIZE events. 2197*f4f33ea0SBaptiste Daroussin */ 2198*f4f33ea0SBaptiste Daroussin void 2199*f4f33ea0SBaptiste Daroussin dlg_will_resize(WINDOW *win) 2200*f4f33ea0SBaptiste Daroussin { 2201*f4f33ea0SBaptiste Daroussin int n, ch, base; 2202*f4f33ea0SBaptiste Daroussin int caught = 0; 2203*f4f33ea0SBaptiste Daroussin 2204*f4f33ea0SBaptiste Daroussin dlg_trace_win(win); 2205*f4f33ea0SBaptiste Daroussin wtimeout(win, 20); 2206*f4f33ea0SBaptiste Daroussin for (n = base = 0; n < base + 10; ++n) { 2207*f4f33ea0SBaptiste Daroussin if ((ch = wgetch(win)) != ERR) { 2208*f4f33ea0SBaptiste Daroussin if (ch == KEY_RESIZE) { 2209*f4f33ea0SBaptiste Daroussin base = n; 2210*f4f33ea0SBaptiste Daroussin ++caught; 2211*f4f33ea0SBaptiste Daroussin } else { 2212*f4f33ea0SBaptiste Daroussin ungetch(ch); 2213*f4f33ea0SBaptiste Daroussin break; 2214*f4f33ea0SBaptiste Daroussin } 2215*f4f33ea0SBaptiste Daroussin } 2216*f4f33ea0SBaptiste Daroussin } 2217*f4f33ea0SBaptiste Daroussin dlg_trace_msg("# caught %d KEY_RESIZE key%s\n", 2218*f4f33ea0SBaptiste Daroussin 1 + caught, 2219*f4f33ea0SBaptiste Daroussin caught == 1 ? "" : "s"); 2220*f4f33ea0SBaptiste Daroussin } 22214c8945a0SNathan Whitehorn #endif /* KEY_RESIZE */ 22224c8945a0SNathan Whitehorn 22234c8945a0SNathan Whitehorn WINDOW * 22244c8945a0SNathan Whitehorn dlg_sub_window(WINDOW *parent, int height, int width, int y, int x) 22254c8945a0SNathan Whitehorn { 22264c8945a0SNathan Whitehorn WINDOW *win; 22274c8945a0SNathan Whitehorn 22284c8945a0SNathan Whitehorn if ((win = subwin(parent, height, width, y, x)) == 0) { 22294c8945a0SNathan Whitehorn dlg_exiterr("Can't make sub-window at (%d,%d), size (%d,%d).\n", 22304c8945a0SNathan Whitehorn y, x, height, width); 22314c8945a0SNathan Whitehorn } 22324c8945a0SNathan Whitehorn 22332a3e3873SBaptiste Daroussin add_subwindow(parent, win); 22344c8945a0SNathan Whitehorn (void) keypad(win, TRUE); 22354c8945a0SNathan Whitehorn return win; 22364c8945a0SNathan Whitehorn } 22374c8945a0SNathan Whitehorn 22384c8945a0SNathan Whitehorn /* obsolete */ 22394c8945a0SNathan Whitehorn int 22404c8945a0SNathan Whitehorn dlg_default_item(char **items, int llen) 22414c8945a0SNathan Whitehorn { 22424c8945a0SNathan Whitehorn int result = 0; 22434c8945a0SNathan Whitehorn 22444c8945a0SNathan Whitehorn if (dialog_vars.default_item != 0) { 22454c8945a0SNathan Whitehorn int count = 0; 22464c8945a0SNathan Whitehorn while (*items != 0) { 22474c8945a0SNathan Whitehorn if (!strcmp(dialog_vars.default_item, *items)) { 22484c8945a0SNathan Whitehorn result = count; 22494c8945a0SNathan Whitehorn break; 22504c8945a0SNathan Whitehorn } 22514c8945a0SNathan Whitehorn items += llen; 22524c8945a0SNathan Whitehorn count++; 22534c8945a0SNathan Whitehorn } 22544c8945a0SNathan Whitehorn } 22554c8945a0SNathan Whitehorn return result; 22564c8945a0SNathan Whitehorn } 22574c8945a0SNathan Whitehorn 22584c8945a0SNathan Whitehorn int 22594c8945a0SNathan Whitehorn dlg_default_listitem(DIALOG_LISTITEM * items) 22604c8945a0SNathan Whitehorn { 22614c8945a0SNathan Whitehorn int result = 0; 22624c8945a0SNathan Whitehorn 22634c8945a0SNathan Whitehorn if (dialog_vars.default_item != 0) { 22644c8945a0SNathan Whitehorn int count = 0; 22654c8945a0SNathan Whitehorn while (items->name != 0) { 22664c8945a0SNathan Whitehorn if (!strcmp(dialog_vars.default_item, items->name)) { 22674c8945a0SNathan Whitehorn result = count; 22684c8945a0SNathan Whitehorn break; 22694c8945a0SNathan Whitehorn } 22704c8945a0SNathan Whitehorn ++items; 22714c8945a0SNathan Whitehorn count++; 22724c8945a0SNathan Whitehorn } 22734c8945a0SNathan Whitehorn } 22744c8945a0SNathan Whitehorn return result; 22754c8945a0SNathan Whitehorn } 22764c8945a0SNathan Whitehorn 22774c8945a0SNathan Whitehorn /* 22784c8945a0SNathan Whitehorn * Draw the string for item_help 22794c8945a0SNathan Whitehorn */ 22804c8945a0SNathan Whitehorn void 22814c8945a0SNathan Whitehorn dlg_item_help(const char *txt) 22824c8945a0SNathan Whitehorn { 22834c8945a0SNathan Whitehorn if (USE_ITEM_HELP(txt)) { 22844c8945a0SNathan Whitehorn chtype attr = A_NORMAL; 22854c8945a0SNathan Whitehorn int y, x; 22864c8945a0SNathan Whitehorn 2287*f4f33ea0SBaptiste Daroussin dlg_attrset(stdscr, itemhelp_attr); 22884c8945a0SNathan Whitehorn (void) wmove(stdscr, LINES - 1, 0); 22894c8945a0SNathan Whitehorn (void) wclrtoeol(stdscr); 22904c8945a0SNathan Whitehorn (void) addch(' '); 22914c8945a0SNathan Whitehorn dlg_print_text(stdscr, txt, COLS - 1, &attr); 22924c8945a0SNathan Whitehorn if (itemhelp_attr & A_COLOR) { 22934c8945a0SNathan Whitehorn /* fill the remainder of the line with the window's attributes */ 22944c8945a0SNathan Whitehorn getyx(stdscr, y, x); 22952a3e3873SBaptiste Daroussin (void) y; 22964c8945a0SNathan Whitehorn while (x < COLS) { 22974c8945a0SNathan Whitehorn (void) addch(' '); 22984c8945a0SNathan Whitehorn ++x; 22994c8945a0SNathan Whitehorn } 23004c8945a0SNathan Whitehorn } 23014c8945a0SNathan Whitehorn (void) wnoutrefresh(stdscr); 23024c8945a0SNathan Whitehorn } 23034c8945a0SNathan Whitehorn } 23044c8945a0SNathan Whitehorn 23054c8945a0SNathan Whitehorn #ifndef HAVE_STRCASECMP 23064c8945a0SNathan Whitehorn int 23074c8945a0SNathan Whitehorn dlg_strcmp(const char *a, const char *b) 23084c8945a0SNathan Whitehorn { 23094c8945a0SNathan Whitehorn int ac, bc, cmp; 23104c8945a0SNathan Whitehorn 23114c8945a0SNathan Whitehorn for (;;) { 23124c8945a0SNathan Whitehorn ac = UCH(*a++); 23134c8945a0SNathan Whitehorn bc = UCH(*b++); 23144c8945a0SNathan Whitehorn if (isalpha(ac) && islower(ac)) 23154c8945a0SNathan Whitehorn ac = _toupper(ac); 23164c8945a0SNathan Whitehorn if (isalpha(bc) && islower(bc)) 23174c8945a0SNathan Whitehorn bc = _toupper(bc); 23184c8945a0SNathan Whitehorn cmp = ac - bc; 23194c8945a0SNathan Whitehorn if (ac == 0 || bc == 0 || cmp != 0) 23204c8945a0SNathan Whitehorn break; 23214c8945a0SNathan Whitehorn } 23224c8945a0SNathan Whitehorn return cmp; 23234c8945a0SNathan Whitehorn } 23244c8945a0SNathan Whitehorn #endif 23254c8945a0SNathan Whitehorn 23264c8945a0SNathan Whitehorn /* 23274c8945a0SNathan Whitehorn * Returns true if 'dst' points to a blank which follows another blank which 23284c8945a0SNathan Whitehorn * is not a leading blank on a line. 23294c8945a0SNathan Whitehorn */ 23304c8945a0SNathan Whitehorn static bool 23314c8945a0SNathan Whitehorn trim_blank(char *base, char *dst) 23324c8945a0SNathan Whitehorn { 2333*f4f33ea0SBaptiste Daroussin int count = isblank(UCH(*dst)); 23344c8945a0SNathan Whitehorn 23354c8945a0SNathan Whitehorn while (dst-- != base) { 23364c8945a0SNathan Whitehorn if (*dst == '\n') { 2337*f4f33ea0SBaptiste Daroussin break; 2338*f4f33ea0SBaptiste Daroussin } else if (isblank(UCH(*dst))) { 23394c8945a0SNathan Whitehorn count++; 2340*f4f33ea0SBaptiste Daroussin } else { 2341*f4f33ea0SBaptiste Daroussin break; 23424c8945a0SNathan Whitehorn } 23434c8945a0SNathan Whitehorn } 2344*f4f33ea0SBaptiste Daroussin return (count > 1); 23454c8945a0SNathan Whitehorn } 23464c8945a0SNathan Whitehorn 23474c8945a0SNathan Whitehorn /* 23484c8945a0SNathan Whitehorn * Change embedded "\n" substrings to '\n' characters and tabs to single 23494c8945a0SNathan Whitehorn * spaces. If there are no "\n"s, it will strip all extra spaces, for 23504c8945a0SNathan Whitehorn * justification. If it has "\n"'s, it will preserve extra spaces. If cr_wrap 23514c8945a0SNathan Whitehorn * is set, it will preserve '\n's. 23524c8945a0SNathan Whitehorn */ 23534c8945a0SNathan Whitehorn void 23544c8945a0SNathan Whitehorn dlg_trim_string(char *s) 23554c8945a0SNathan Whitehorn { 23564c8945a0SNathan Whitehorn char *base = s; 23574c8945a0SNathan Whitehorn char *p1; 23584c8945a0SNathan Whitehorn char *p = s; 2359682c9e0fSNathan Whitehorn int has_newlines = !dialog_vars.no_nl_expand && (strstr(s, "\\n") != 0); 23604c8945a0SNathan Whitehorn 23614c8945a0SNathan Whitehorn while (*p != '\0') { 23624c8945a0SNathan Whitehorn if (*p == TAB && !dialog_vars.nocollapse) 23634c8945a0SNathan Whitehorn *p = ' '; 23644c8945a0SNathan Whitehorn 23654c8945a0SNathan Whitehorn if (has_newlines) { /* If prompt contains "\n" strings */ 23664c8945a0SNathan Whitehorn if (*p == '\\' && *(p + 1) == 'n') { 23674c8945a0SNathan Whitehorn *s++ = '\n'; 23684c8945a0SNathan Whitehorn p += 2; 23694c8945a0SNathan Whitehorn p1 = p; 23704c8945a0SNathan Whitehorn /* 23714c8945a0SNathan Whitehorn * Handle end of lines intelligently. If '\n' follows "\n" 23724c8945a0SNathan Whitehorn * then ignore the '\n'. This eliminates the need to escape 23734c8945a0SNathan Whitehorn * the '\n' character (no need to use "\n\"). 23744c8945a0SNathan Whitehorn */ 2375*f4f33ea0SBaptiste Daroussin while (isblank(UCH(*p1))) 23764c8945a0SNathan Whitehorn p1++; 23774c8945a0SNathan Whitehorn if (*p1 == '\n') 23784c8945a0SNathan Whitehorn p = p1 + 1; 23794c8945a0SNathan Whitehorn } else if (*p == '\n') { 23804c8945a0SNathan Whitehorn if (dialog_vars.cr_wrap) 23814c8945a0SNathan Whitehorn *s++ = *p++; 23824c8945a0SNathan Whitehorn else { 23834c8945a0SNathan Whitehorn /* Replace the '\n' with a space if cr_wrap is not set */ 2384*f4f33ea0SBaptiste Daroussin if (!trim_blank(base, p)) 23854c8945a0SNathan Whitehorn *s++ = ' '; 23864c8945a0SNathan Whitehorn p++; 23874c8945a0SNathan Whitehorn } 23884c8945a0SNathan Whitehorn } else /* If *p != '\n' */ 23894c8945a0SNathan Whitehorn *s++ = *p++; 23904c8945a0SNathan Whitehorn } else if (dialog_vars.trim_whitespace) { 2391*f4f33ea0SBaptiste Daroussin if (isblank(UCH(*p))) { 2392*f4f33ea0SBaptiste Daroussin if (!isblank(UCH(*(s - 1)))) { 23934c8945a0SNathan Whitehorn *s++ = ' '; 23944c8945a0SNathan Whitehorn p++; 23954c8945a0SNathan Whitehorn } else 23964c8945a0SNathan Whitehorn p++; 23974c8945a0SNathan Whitehorn } else if (*p == '\n') { 23984c8945a0SNathan Whitehorn if (dialog_vars.cr_wrap) 23994c8945a0SNathan Whitehorn *s++ = *p++; 2400*f4f33ea0SBaptiste Daroussin else if (!isblank(UCH(*(s - 1)))) { 24014c8945a0SNathan Whitehorn /* Strip '\n's if cr_wrap is not set. */ 24024c8945a0SNathan Whitehorn *s++ = ' '; 24034c8945a0SNathan Whitehorn p++; 24044c8945a0SNathan Whitehorn } else 24054c8945a0SNathan Whitehorn p++; 24064c8945a0SNathan Whitehorn } else 24074c8945a0SNathan Whitehorn *s++ = *p++; 24084c8945a0SNathan Whitehorn } else { /* If there are no "\n" strings */ 2409*f4f33ea0SBaptiste Daroussin if (isblank(UCH(*p)) && !dialog_vars.nocollapse) { 2410*f4f33ea0SBaptiste Daroussin if (!trim_blank(base, p)) 24114c8945a0SNathan Whitehorn *s++ = *p; 24124c8945a0SNathan Whitehorn p++; 24134c8945a0SNathan Whitehorn } else 24144c8945a0SNathan Whitehorn *s++ = *p++; 24154c8945a0SNathan Whitehorn } 24164c8945a0SNathan Whitehorn } 24174c8945a0SNathan Whitehorn 24184c8945a0SNathan Whitehorn *s = '\0'; 24194c8945a0SNathan Whitehorn } 24204c8945a0SNathan Whitehorn 24214c8945a0SNathan Whitehorn void 24224c8945a0SNathan Whitehorn dlg_set_focus(WINDOW *parent, WINDOW *win) 24234c8945a0SNathan Whitehorn { 24244c8945a0SNathan Whitehorn if (win != 0) { 24254c8945a0SNathan Whitehorn (void) wmove(parent, 24264c8945a0SNathan Whitehorn getpary(win) + getcury(win), 24274c8945a0SNathan Whitehorn getparx(win) + getcurx(win)); 24284c8945a0SNathan Whitehorn (void) wnoutrefresh(win); 24294c8945a0SNathan Whitehorn (void) doupdate(); 24304c8945a0SNathan Whitehorn } 24314c8945a0SNathan Whitehorn } 24324c8945a0SNathan Whitehorn 24334c8945a0SNathan Whitehorn /* 24344c8945a0SNathan Whitehorn * Returns the nominal maximum buffer size. 24354c8945a0SNathan Whitehorn */ 24364c8945a0SNathan Whitehorn int 24374c8945a0SNathan Whitehorn dlg_max_input(int max_len) 24384c8945a0SNathan Whitehorn { 24394c8945a0SNathan Whitehorn if (dialog_vars.max_input != 0 && dialog_vars.max_input < MAX_LEN) 24404c8945a0SNathan Whitehorn max_len = dialog_vars.max_input; 24414c8945a0SNathan Whitehorn 24424c8945a0SNathan Whitehorn return max_len; 24434c8945a0SNathan Whitehorn } 24444c8945a0SNathan Whitehorn 24454c8945a0SNathan Whitehorn /* 24464c8945a0SNathan Whitehorn * Free storage used for the result buffer. 24474c8945a0SNathan Whitehorn */ 24484c8945a0SNathan Whitehorn void 24494c8945a0SNathan Whitehorn dlg_clr_result(void) 24504c8945a0SNathan Whitehorn { 24514c8945a0SNathan Whitehorn if (dialog_vars.input_length) { 24524c8945a0SNathan Whitehorn dialog_vars.input_length = 0; 24534c8945a0SNathan Whitehorn if (dialog_vars.input_result) 24544c8945a0SNathan Whitehorn free(dialog_vars.input_result); 24554c8945a0SNathan Whitehorn } 24564c8945a0SNathan Whitehorn dialog_vars.input_result = 0; 24574c8945a0SNathan Whitehorn } 24584c8945a0SNathan Whitehorn 24594c8945a0SNathan Whitehorn /* 24604c8945a0SNathan Whitehorn * Setup a fixed-buffer for the result. 24614c8945a0SNathan Whitehorn */ 24624c8945a0SNathan Whitehorn char * 24634c8945a0SNathan Whitehorn dlg_set_result(const char *string) 24644c8945a0SNathan Whitehorn { 24657a1c0d96SNathan Whitehorn unsigned need = string ? (unsigned) strlen(string) + 1 : 0; 24664c8945a0SNathan Whitehorn 24674c8945a0SNathan Whitehorn /* inputstr.c needs a fixed buffer */ 24684c8945a0SNathan Whitehorn if (need < MAX_LEN) 24694c8945a0SNathan Whitehorn need = MAX_LEN; 24704c8945a0SNathan Whitehorn 24714c8945a0SNathan Whitehorn /* 24724c8945a0SNathan Whitehorn * If the buffer is not big enough, allocate a new one. 24734c8945a0SNathan Whitehorn */ 24744c8945a0SNathan Whitehorn if (dialog_vars.input_length != 0 24754c8945a0SNathan Whitehorn || dialog_vars.input_result == 0 24764c8945a0SNathan Whitehorn || need > MAX_LEN) { 24774c8945a0SNathan Whitehorn 24784c8945a0SNathan Whitehorn dlg_clr_result(); 24794c8945a0SNathan Whitehorn 24804c8945a0SNathan Whitehorn dialog_vars.input_length = need; 24814c8945a0SNathan Whitehorn dialog_vars.input_result = dlg_malloc(char, need); 24824c8945a0SNathan Whitehorn assert_ptr(dialog_vars.input_result, "dlg_set_result"); 24834c8945a0SNathan Whitehorn } 24844c8945a0SNathan Whitehorn 24854c8945a0SNathan Whitehorn strcpy(dialog_vars.input_result, string ? string : ""); 24864c8945a0SNathan Whitehorn 24874c8945a0SNathan Whitehorn return dialog_vars.input_result; 24884c8945a0SNathan Whitehorn } 24894c8945a0SNathan Whitehorn 24904c8945a0SNathan Whitehorn /* 24914c8945a0SNathan Whitehorn * Accumulate results in dynamically allocated buffer. 24924c8945a0SNathan Whitehorn * If input_length is zero, it is a MAX_LEN buffer belonging to the caller. 24934c8945a0SNathan Whitehorn */ 24944c8945a0SNathan Whitehorn void 24954c8945a0SNathan Whitehorn dlg_add_result(const char *string) 24964c8945a0SNathan Whitehorn { 24974c8945a0SNathan Whitehorn unsigned have = (dialog_vars.input_result 24987a1c0d96SNathan Whitehorn ? (unsigned) strlen(dialog_vars.input_result) 24994c8945a0SNathan Whitehorn : 0); 25007a1c0d96SNathan Whitehorn unsigned want = (unsigned) strlen(string) + 1 + have; 25014c8945a0SNathan Whitehorn 25024c8945a0SNathan Whitehorn if ((want >= MAX_LEN) 25034c8945a0SNathan Whitehorn || (dialog_vars.input_length != 0) 25044c8945a0SNathan Whitehorn || (dialog_vars.input_result == 0)) { 25054c8945a0SNathan Whitehorn 25064c8945a0SNathan Whitehorn if (dialog_vars.input_length == 0 25074c8945a0SNathan Whitehorn || dialog_vars.input_result == 0) { 25084c8945a0SNathan Whitehorn 25097a1c0d96SNathan Whitehorn char *save_result = dialog_vars.input_result; 25104c8945a0SNathan Whitehorn 25114c8945a0SNathan Whitehorn dialog_vars.input_length = want * 2; 25124c8945a0SNathan Whitehorn dialog_vars.input_result = dlg_malloc(char, dialog_vars.input_length); 25134c8945a0SNathan Whitehorn assert_ptr(dialog_vars.input_result, "dlg_add_result malloc"); 25147a1c0d96SNathan Whitehorn dialog_vars.input_result[0] = '\0'; 25157a1c0d96SNathan Whitehorn if (save_result != 0) 25167a1c0d96SNathan Whitehorn strcpy(dialog_vars.input_result, save_result); 25174c8945a0SNathan Whitehorn } else if (want >= dialog_vars.input_length) { 25184c8945a0SNathan Whitehorn dialog_vars.input_length = want * 2; 25194c8945a0SNathan Whitehorn dialog_vars.input_result = dlg_realloc(char, 25204c8945a0SNathan Whitehorn dialog_vars.input_length, 25214c8945a0SNathan Whitehorn dialog_vars.input_result); 25224c8945a0SNathan Whitehorn assert_ptr(dialog_vars.input_result, "dlg_add_result realloc"); 25234c8945a0SNathan Whitehorn } 25244c8945a0SNathan Whitehorn } 25254c8945a0SNathan Whitehorn strcat(dialog_vars.input_result, string); 25264c8945a0SNathan Whitehorn } 25274c8945a0SNathan Whitehorn 25284c8945a0SNathan Whitehorn /* 25294c8945a0SNathan Whitehorn * These are characters that (aside from the quote-delimiter) will have to 25304c8945a0SNathan Whitehorn * be escaped in a single- or double-quoted string. 25314c8945a0SNathan Whitehorn */ 25324c8945a0SNathan Whitehorn #define FIX_SINGLE "\n\\" 25334c8945a0SNathan Whitehorn #define FIX_DOUBLE FIX_SINGLE "[]{}?*;`~#$^&()|<>" 25344c8945a0SNathan Whitehorn 25354c8945a0SNathan Whitehorn /* 25364c8945a0SNathan Whitehorn * Returns the quote-delimiter. 25374c8945a0SNathan Whitehorn */ 25384c8945a0SNathan Whitehorn static const char * 25394c8945a0SNathan Whitehorn quote_delimiter(void) 25404c8945a0SNathan Whitehorn { 25414c8945a0SNathan Whitehorn return dialog_vars.single_quoted ? "'" : "\""; 25424c8945a0SNathan Whitehorn } 25434c8945a0SNathan Whitehorn 25444c8945a0SNathan Whitehorn /* 25454c8945a0SNathan Whitehorn * Returns true if we should quote the given string. 25464c8945a0SNathan Whitehorn */ 25474c8945a0SNathan Whitehorn static bool 25484c8945a0SNathan Whitehorn must_quote(char *string) 25494c8945a0SNathan Whitehorn { 25504c8945a0SNathan Whitehorn bool code = FALSE; 25514c8945a0SNathan Whitehorn 25524c8945a0SNathan Whitehorn if (*string != '\0') { 25537a1c0d96SNathan Whitehorn size_t len = strlen(string); 25544c8945a0SNathan Whitehorn if (strcspn(string, quote_delimiter()) != len) 25554c8945a0SNathan Whitehorn code = TRUE; 25564c8945a0SNathan Whitehorn else if (strcspn(string, "\n\t ") != len) 25574c8945a0SNathan Whitehorn code = TRUE; 25584c8945a0SNathan Whitehorn else 25594c8945a0SNathan Whitehorn code = (strcspn(string, FIX_DOUBLE) != len); 25604c8945a0SNathan Whitehorn } else { 25614c8945a0SNathan Whitehorn code = TRUE; 25624c8945a0SNathan Whitehorn } 25634c8945a0SNathan Whitehorn 25644c8945a0SNathan Whitehorn return code; 25654c8945a0SNathan Whitehorn } 25664c8945a0SNathan Whitehorn 25674c8945a0SNathan Whitehorn /* 25684c8945a0SNathan Whitehorn * Add a quoted string to the result buffer. 25694c8945a0SNathan Whitehorn */ 25704c8945a0SNathan Whitehorn void 25714c8945a0SNathan Whitehorn dlg_add_quoted(char *string) 25724c8945a0SNathan Whitehorn { 25734c8945a0SNathan Whitehorn char temp[2]; 25744c8945a0SNathan Whitehorn const char *my_quote = quote_delimiter(); 25754c8945a0SNathan Whitehorn const char *must_fix = (dialog_vars.single_quoted 25764c8945a0SNathan Whitehorn ? FIX_SINGLE 25774c8945a0SNathan Whitehorn : FIX_DOUBLE); 25784c8945a0SNathan Whitehorn 25792a3e3873SBaptiste Daroussin if (must_quote(string)) { 25804c8945a0SNathan Whitehorn temp[1] = '\0'; 25814c8945a0SNathan Whitehorn dlg_add_result(my_quote); 25824c8945a0SNathan Whitehorn while (*string != '\0') { 25834c8945a0SNathan Whitehorn temp[0] = *string++; 2584*f4f33ea0SBaptiste Daroussin if ((strchr) (my_quote, *temp) || (strchr) (must_fix, *temp)) 25854c8945a0SNathan Whitehorn dlg_add_result("\\"); 25864c8945a0SNathan Whitehorn dlg_add_result(temp); 25874c8945a0SNathan Whitehorn } 25884c8945a0SNathan Whitehorn dlg_add_result(my_quote); 25894c8945a0SNathan Whitehorn } else { 25904c8945a0SNathan Whitehorn dlg_add_result(string); 25914c8945a0SNathan Whitehorn } 25924c8945a0SNathan Whitehorn } 25934c8945a0SNathan Whitehorn 25944c8945a0SNathan Whitehorn /* 25954c8945a0SNathan Whitehorn * When adding a result, make that depend on whether "--quoted" is used. 25964c8945a0SNathan Whitehorn */ 25974c8945a0SNathan Whitehorn void 25984c8945a0SNathan Whitehorn dlg_add_string(char *string) 25994c8945a0SNathan Whitehorn { 26004c8945a0SNathan Whitehorn if (dialog_vars.quoted) { 26014c8945a0SNathan Whitehorn dlg_add_quoted(string); 26024c8945a0SNathan Whitehorn } else { 26034c8945a0SNathan Whitehorn dlg_add_result(string); 26044c8945a0SNathan Whitehorn } 26054c8945a0SNathan Whitehorn } 26064c8945a0SNathan Whitehorn 26074c8945a0SNathan Whitehorn bool 26084c8945a0SNathan Whitehorn dlg_need_separator(void) 26094c8945a0SNathan Whitehorn { 26104c8945a0SNathan Whitehorn bool result = FALSE; 26114c8945a0SNathan Whitehorn 26124c8945a0SNathan Whitehorn if (dialog_vars.output_separator) { 26134c8945a0SNathan Whitehorn result = TRUE; 26144c8945a0SNathan Whitehorn } else if (dialog_vars.input_result && *(dialog_vars.input_result)) { 26154c8945a0SNathan Whitehorn result = TRUE; 26164c8945a0SNathan Whitehorn } 26174c8945a0SNathan Whitehorn return result; 26184c8945a0SNathan Whitehorn } 26194c8945a0SNathan Whitehorn 26204c8945a0SNathan Whitehorn void 26214c8945a0SNathan Whitehorn dlg_add_separator(void) 26224c8945a0SNathan Whitehorn { 26234c8945a0SNathan Whitehorn const char *separator = (dialog_vars.separate_output) ? "\n" : " "; 26244c8945a0SNathan Whitehorn 26254c8945a0SNathan Whitehorn if (dialog_vars.output_separator) 26264c8945a0SNathan Whitehorn separator = dialog_vars.output_separator; 26274c8945a0SNathan Whitehorn 26284c8945a0SNathan Whitehorn dlg_add_result(separator); 26294c8945a0SNathan Whitehorn } 26304c8945a0SNathan Whitehorn 2631febdb468SDevin Teske #define HELP_PREFIX "HELP " 2632febdb468SDevin Teske 2633febdb468SDevin Teske void 2634febdb468SDevin Teske dlg_add_help_listitem(int *result, char **tag, DIALOG_LISTITEM * item) 2635febdb468SDevin Teske { 2636febdb468SDevin Teske dlg_add_result(HELP_PREFIX); 2637febdb468SDevin Teske if (USE_ITEM_HELP(item->help)) { 2638febdb468SDevin Teske *tag = dialog_vars.help_tags ? item->name : item->help; 2639febdb468SDevin Teske *result = DLG_EXIT_ITEM_HELP; 2640febdb468SDevin Teske } else { 2641febdb468SDevin Teske *tag = item->name; 2642febdb468SDevin Teske } 2643febdb468SDevin Teske } 2644febdb468SDevin Teske 2645febdb468SDevin Teske void 2646febdb468SDevin Teske dlg_add_help_formitem(int *result, char **tag, DIALOG_FORMITEM * item) 2647febdb468SDevin Teske { 2648febdb468SDevin Teske dlg_add_result(HELP_PREFIX); 2649febdb468SDevin Teske if (USE_ITEM_HELP(item->help)) { 2650febdb468SDevin Teske *tag = dialog_vars.help_tags ? item->name : item->help; 2651febdb468SDevin Teske *result = DLG_EXIT_ITEM_HELP; 2652febdb468SDevin Teske } else { 2653febdb468SDevin Teske *tag = item->name; 2654febdb468SDevin Teske } 2655febdb468SDevin Teske } 2656febdb468SDevin Teske 26574c8945a0SNathan Whitehorn /* 26584c8945a0SNathan Whitehorn * Some widgets support only one value of a given variable - save/restore the 26594c8945a0SNathan Whitehorn * global dialog_vars so we can override it consistently. 26604c8945a0SNathan Whitehorn */ 26614c8945a0SNathan Whitehorn void 26624c8945a0SNathan Whitehorn dlg_save_vars(DIALOG_VARS * vars) 26634c8945a0SNathan Whitehorn { 26644c8945a0SNathan Whitehorn *vars = dialog_vars; 26654c8945a0SNathan Whitehorn } 26664c8945a0SNathan Whitehorn 26677a1c0d96SNathan Whitehorn /* 26687a1c0d96SNathan Whitehorn * Most of the data in DIALOG_VARS is normally set by command-line options. 26697a1c0d96SNathan Whitehorn * The input_result member is an exception; it is normally set by the dialog 26707a1c0d96SNathan Whitehorn * library to return result values. 26717a1c0d96SNathan Whitehorn */ 26724c8945a0SNathan Whitehorn void 26734c8945a0SNathan Whitehorn dlg_restore_vars(DIALOG_VARS * vars) 26744c8945a0SNathan Whitehorn { 26757a1c0d96SNathan Whitehorn char *save_result = dialog_vars.input_result; 26767a1c0d96SNathan Whitehorn unsigned save_length = dialog_vars.input_length; 26777a1c0d96SNathan Whitehorn 26784c8945a0SNathan Whitehorn dialog_vars = *vars; 26797a1c0d96SNathan Whitehorn dialog_vars.input_result = save_result; 26807a1c0d96SNathan Whitehorn dialog_vars.input_length = save_length; 26814c8945a0SNathan Whitehorn } 26824c8945a0SNathan Whitehorn 26834c8945a0SNathan Whitehorn /* 26844c8945a0SNathan Whitehorn * Called each time a widget is invoked which may do output, increment a count. 26854c8945a0SNathan Whitehorn */ 26864c8945a0SNathan Whitehorn void 26874c8945a0SNathan Whitehorn dlg_does_output(void) 26884c8945a0SNathan Whitehorn { 26894c8945a0SNathan Whitehorn dialog_state.output_count += 1; 26904c8945a0SNathan Whitehorn } 26914c8945a0SNathan Whitehorn 26924c8945a0SNathan Whitehorn /* 26934c8945a0SNathan Whitehorn * Compatibility for different versions of curses. 26944c8945a0SNathan Whitehorn */ 26954c8945a0SNathan Whitehorn #if !(defined(HAVE_GETBEGX) && defined(HAVE_GETBEGY)) 26964c8945a0SNathan Whitehorn int 26972a3e3873SBaptiste Daroussin dlg_getbegx(WINDOW *win) 26984c8945a0SNathan Whitehorn { 26994c8945a0SNathan Whitehorn int y, x; 27004c8945a0SNathan Whitehorn getbegyx(win, y, x); 27014c8945a0SNathan Whitehorn return x; 27024c8945a0SNathan Whitehorn } 27034c8945a0SNathan Whitehorn int 27042a3e3873SBaptiste Daroussin dlg_getbegy(WINDOW *win) 27054c8945a0SNathan Whitehorn { 27064c8945a0SNathan Whitehorn int y, x; 27074c8945a0SNathan Whitehorn getbegyx(win, y, x); 27084c8945a0SNathan Whitehorn return y; 27094c8945a0SNathan Whitehorn } 27104c8945a0SNathan Whitehorn #endif 27114c8945a0SNathan Whitehorn 27124c8945a0SNathan Whitehorn #if !(defined(HAVE_GETCURX) && defined(HAVE_GETCURY)) 27134c8945a0SNathan Whitehorn int 27142a3e3873SBaptiste Daroussin dlg_getcurx(WINDOW *win) 27154c8945a0SNathan Whitehorn { 27164c8945a0SNathan Whitehorn int y, x; 27174c8945a0SNathan Whitehorn getyx(win, y, x); 27184c8945a0SNathan Whitehorn return x; 27194c8945a0SNathan Whitehorn } 27204c8945a0SNathan Whitehorn int 27212a3e3873SBaptiste Daroussin dlg_getcury(WINDOW *win) 27224c8945a0SNathan Whitehorn { 27234c8945a0SNathan Whitehorn int y, x; 27244c8945a0SNathan Whitehorn getyx(win, y, x); 27254c8945a0SNathan Whitehorn return y; 27264c8945a0SNathan Whitehorn } 27274c8945a0SNathan Whitehorn #endif 27284c8945a0SNathan Whitehorn 27294c8945a0SNathan Whitehorn #if !(defined(HAVE_GETMAXX) && defined(HAVE_GETMAXY)) 27304c8945a0SNathan Whitehorn int 27312a3e3873SBaptiste Daroussin dlg_getmaxx(WINDOW *win) 27324c8945a0SNathan Whitehorn { 27334c8945a0SNathan Whitehorn int y, x; 27344c8945a0SNathan Whitehorn getmaxyx(win, y, x); 27354c8945a0SNathan Whitehorn return x; 27364c8945a0SNathan Whitehorn } 27374c8945a0SNathan Whitehorn int 27382a3e3873SBaptiste Daroussin dlg_getmaxy(WINDOW *win) 27394c8945a0SNathan Whitehorn { 27404c8945a0SNathan Whitehorn int y, x; 27414c8945a0SNathan Whitehorn getmaxyx(win, y, x); 27424c8945a0SNathan Whitehorn return y; 27434c8945a0SNathan Whitehorn } 27444c8945a0SNathan Whitehorn #endif 27454c8945a0SNathan Whitehorn 27464c8945a0SNathan Whitehorn #if !(defined(HAVE_GETPARX) && defined(HAVE_GETPARY)) 27474c8945a0SNathan Whitehorn int 27482a3e3873SBaptiste Daroussin dlg_getparx(WINDOW *win) 27494c8945a0SNathan Whitehorn { 27504c8945a0SNathan Whitehorn int y, x; 27514c8945a0SNathan Whitehorn getparyx(win, y, x); 27524c8945a0SNathan Whitehorn return x; 27534c8945a0SNathan Whitehorn } 27544c8945a0SNathan Whitehorn int 27552a3e3873SBaptiste Daroussin dlg_getpary(WINDOW *win) 27564c8945a0SNathan Whitehorn { 27574c8945a0SNathan Whitehorn int y, x; 27584c8945a0SNathan Whitehorn getparyx(win, y, x); 27594c8945a0SNathan Whitehorn return y; 27604c8945a0SNathan Whitehorn } 27614c8945a0SNathan Whitehorn #endif 27622a3e3873SBaptiste Daroussin 27632a3e3873SBaptiste Daroussin #ifdef NEED_WGETPARENT 27642a3e3873SBaptiste Daroussin WINDOW * 27652a3e3873SBaptiste Daroussin dlg_wgetparent(WINDOW *win) 27662a3e3873SBaptiste Daroussin { 27672a3e3873SBaptiste Daroussin #undef wgetparent 27682a3e3873SBaptiste Daroussin WINDOW *result = 0; 27692a3e3873SBaptiste Daroussin DIALOG_WINDOWS *p; 27702a3e3873SBaptiste Daroussin 27712a3e3873SBaptiste Daroussin for (p = dialog_state.all_subwindows; p != 0; p = p->next) { 27722a3e3873SBaptiste Daroussin if (p->shadow == win) { 27732a3e3873SBaptiste Daroussin result = p->normal; 27742a3e3873SBaptiste Daroussin break; 27752a3e3873SBaptiste Daroussin } 27762a3e3873SBaptiste Daroussin } 27772a3e3873SBaptiste Daroussin return result; 27782a3e3873SBaptiste Daroussin } 27792a3e3873SBaptiste Daroussin #endif 2780