14c8945a0SNathan Whitehorn /* 2*2a3e3873SBaptiste Daroussin * $Id: util.c,v 1.255 2013/05/23 22:58:28 tom Exp $ 34c8945a0SNathan Whitehorn * 44c8945a0SNathan Whitehorn * util.c -- miscellaneous utilities for dialog 54c8945a0SNathan Whitehorn * 6*2a3e3873SBaptiste Daroussin * Copyright 2000-2012,2013 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 30*2a3e3873SBaptiste Daroussin #ifdef HAVE_SETLOCALE 31*2a3e3873SBaptiste Daroussin #include <locale.h> 32*2a3e3873SBaptiste Daroussin #endif 33*2a3e3873SBaptiste Daroussin 34*2a3e3873SBaptiste Daroussin #ifdef NEED_WCHAR_H 35*2a3e3873SBaptiste Daroussin #include <wchar.h> 36*2a3e3873SBaptiste Daroussin #endif 37*2a3e3873SBaptiste 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 66*2a3e3873SBaptiste Daroussin #if !(defined(HAVE_WGETPARENT) && defined(HAVE_WINDOW__PARENT)) 67*2a3e3873SBaptiste Daroussin #define NEED_WGETPARENT 1 68*2a3e3873SBaptiste Daroussin #else 69*2a3e3873SBaptiste Daroussin #undef NEED_WGETPARENT 70*2a3e3873SBaptiste Daroussin #endif 71*2a3e3873SBaptiste 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. 96*2a3e3873SBaptiste 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"), 134*2a3e3873SBaptiste Daroussin DATA(A_REVERSE, GAUGE, gauge, "Dialog box gauge"), 135*2a3e3873SBaptiste Daroussin DATA(A_REVERSE, BORDER2, border2, "Dialog box border2"), 136*2a3e3873SBaptiste Daroussin DATA(A_REVERSE, INPUTBOX_BORDER2, inputbox_border2, "Input box border2"), 137*2a3e3873SBaptiste Daroussin DATA(A_REVERSE, SEARCHBOX_BORDER2, searchbox_border2, "Search box border2"), 138*2a3e3873SBaptiste Daroussin DATA(A_REVERSE, MENUBOX_BORDER2, menubox_border2, "Menu box border2") 1394c8945a0SNathan Whitehorn }; 1404c8945a0SNathan Whitehorn /* *INDENT-ON* */ 1414c8945a0SNathan Whitehorn 1424c8945a0SNathan Whitehorn /* 143*2a3e3873SBaptiste Daroussin * Maintain a list of subwindows so that we can delete them to cleanup. 144*2a3e3873SBaptiste Daroussin * More important, this provides a fallback when wgetparent() is not available. 145*2a3e3873SBaptiste Daroussin */ 146*2a3e3873SBaptiste Daroussin static void 147*2a3e3873SBaptiste Daroussin add_subwindow(WINDOW *parent, WINDOW *child) 148*2a3e3873SBaptiste Daroussin { 149*2a3e3873SBaptiste Daroussin DIALOG_WINDOWS *p = dlg_calloc(DIALOG_WINDOWS, 1); 150*2a3e3873SBaptiste Daroussin 151*2a3e3873SBaptiste Daroussin if (p != 0) { 152*2a3e3873SBaptiste Daroussin p->normal = parent; 153*2a3e3873SBaptiste Daroussin p->shadow = child; 154*2a3e3873SBaptiste Daroussin p->next = dialog_state.all_subwindows; 155*2a3e3873SBaptiste Daroussin dialog_state.all_subwindows = p; 156*2a3e3873SBaptiste Daroussin } 157*2a3e3873SBaptiste Daroussin } 158*2a3e3873SBaptiste Daroussin 159*2a3e3873SBaptiste Daroussin static void 160*2a3e3873SBaptiste Daroussin del_subwindows(WINDOW *parent) 161*2a3e3873SBaptiste Daroussin { 162*2a3e3873SBaptiste Daroussin DIALOG_WINDOWS *p = dialog_state.all_subwindows; 163*2a3e3873SBaptiste Daroussin DIALOG_WINDOWS *q = 0; 164*2a3e3873SBaptiste Daroussin DIALOG_WINDOWS *r; 165*2a3e3873SBaptiste Daroussin 166*2a3e3873SBaptiste Daroussin while (p != 0) { 167*2a3e3873SBaptiste Daroussin if (p->normal == parent) { 168*2a3e3873SBaptiste Daroussin delwin(p->shadow); 169*2a3e3873SBaptiste Daroussin r = p->next; 170*2a3e3873SBaptiste Daroussin if (q == 0) { 171*2a3e3873SBaptiste Daroussin dialog_state.all_subwindows = r; 172*2a3e3873SBaptiste Daroussin } else { 173*2a3e3873SBaptiste Daroussin q->next = r; 174*2a3e3873SBaptiste Daroussin } 175*2a3e3873SBaptiste Daroussin free(p); 176*2a3e3873SBaptiste Daroussin p = r; 177*2a3e3873SBaptiste Daroussin } else { 178*2a3e3873SBaptiste Daroussin q = p; 179*2a3e3873SBaptiste Daroussin p = p->next; 180*2a3e3873SBaptiste Daroussin } 181*2a3e3873SBaptiste Daroussin } 182*2a3e3873SBaptiste Daroussin } 183*2a3e3873SBaptiste Daroussin 184*2a3e3873SBaptiste 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*2a3e3873SBaptiste Daroussin (void) wattrset(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*2a3e3873SBaptiste Daroussin (void) wattrset(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 274*2a3e3873SBaptiste Daroussin #ifdef NCURSES_VERSION 275*2a3e3873SBaptiste Daroussin static int 276*2a3e3873SBaptiste Daroussin my_putc(int ch) 277*2a3e3873SBaptiste Daroussin { 278*2a3e3873SBaptiste Daroussin char buffer[2]; 279*2a3e3873SBaptiste Daroussin int fd = fileno(dialog_state.screen_output); 280*2a3e3873SBaptiste Daroussin 281*2a3e3873SBaptiste Daroussin buffer[0] = (char) ch; 282*2a3e3873SBaptiste Daroussin return (int) write(fd, buffer, (size_t) 1); 283*2a3e3873SBaptiste Daroussin } 284*2a3e3873SBaptiste Daroussin #endif 285*2a3e3873SBaptiste 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 302*2a3e3873SBaptiste Daroussin setlocale(LC_ALL, ""); 303*2a3e3873SBaptiste 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); 336*2a3e3873SBaptiste Daroussin } else { 3374c8945a0SNathan Whitehorn dlg_exiterr("cannot open tty-input"); 338*2a3e3873SBaptiste Daroussin } 339*2a3e3873SBaptiste Daroussin close(fd1); 3404c8945a0SNathan Whitehorn } else if (!isatty(fileno(stdin))) { 341*2a3e3873SBaptiste Daroussin if ((fd1 = open_terminal(&device, O_RDONLY)) >= 0) { 342*2a3e3873SBaptiste 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 } 349*2a3e3873SBaptiste Daroussin close(fd1); 350*2a3e3873SBaptiste 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 392*2a3e3873SBaptiste 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 /* 398*2a3e3873SBaptiste 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 */ 403*2a3e3873SBaptiste Daroussin (void) refresh(); 404*2a3e3873SBaptiste Daroussin (void) tputs(exit_ca_mode, 0, my_putc); 405*2a3e3873SBaptiste 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 { 5587a1c0d96SNathan Whitehorn chtype attrs = dlg_get_attrs(win); 5594c8945a0SNathan Whitehorn int pair; 5604c8945a0SNathan Whitehorn short fg, bg, background; 5614c8945a0SNathan Whitehorn 5624c8945a0SNathan Whitehorn if ((pair = PAIR_NUMBER(attrs)) != 0 5634c8945a0SNathan Whitehorn && pair_content((short) pair, &fg, &bg) != ERR) { 5644c8945a0SNathan Whitehorn background = bg; 5654c8945a0SNathan Whitehorn } else { 5664c8945a0SNathan Whitehorn background = COLOR_BLACK; 5674c8945a0SNathan Whitehorn } 5684c8945a0SNathan Whitehorn return dlg_color_pair(foreground, background); 5694c8945a0SNathan Whitehorn } 5704c8945a0SNathan Whitehorn #endif 5714c8945a0SNathan Whitehorn 5724c8945a0SNathan Whitehorn /* 5734c8945a0SNathan Whitehorn * End using dialog functions. 5744c8945a0SNathan Whitehorn */ 5754c8945a0SNathan Whitehorn void 5764c8945a0SNathan Whitehorn end_dialog(void) 5774c8945a0SNathan Whitehorn { 5784c8945a0SNathan Whitehorn if (dialog_state.screen_initialized) { 5794c8945a0SNathan Whitehorn dialog_state.screen_initialized = FALSE; 5804c8945a0SNathan Whitehorn mouse_close(); 5814c8945a0SNathan Whitehorn (void) endwin(); 5824c8945a0SNathan Whitehorn (void) fflush(stdout); 5834c8945a0SNathan Whitehorn } 5844c8945a0SNathan Whitehorn } 5854c8945a0SNathan Whitehorn 586682c9e0fSNathan Whitehorn #define ESCAPE_LEN 3 5874c8945a0SNathan Whitehorn #define isOurEscape(p) (((p)[0] == '\\') && ((p)[1] == 'Z') && ((p)[2] != 0)) 5884c8945a0SNathan Whitehorn 589*2a3e3873SBaptiste Daroussin int 590*2a3e3873SBaptiste Daroussin dlg_count_real_columns(const char *text) 591*2a3e3873SBaptiste Daroussin { 592*2a3e3873SBaptiste Daroussin int result = dlg_count_columns(text); 593*2a3e3873SBaptiste Daroussin if (result && dialog_vars.colors) { 594*2a3e3873SBaptiste Daroussin int hidden = 0; 595*2a3e3873SBaptiste Daroussin while (*text) { 596*2a3e3873SBaptiste Daroussin if (dialog_vars.colors && isOurEscape(text)) { 597*2a3e3873SBaptiste Daroussin hidden += ESCAPE_LEN; 598*2a3e3873SBaptiste Daroussin text += ESCAPE_LEN; 599*2a3e3873SBaptiste Daroussin } else { 600*2a3e3873SBaptiste Daroussin ++text; 601*2a3e3873SBaptiste Daroussin } 602*2a3e3873SBaptiste Daroussin } 603*2a3e3873SBaptiste Daroussin result -= hidden; 604*2a3e3873SBaptiste Daroussin } 605*2a3e3873SBaptiste Daroussin return result; 606*2a3e3873SBaptiste Daroussin } 607*2a3e3873SBaptiste Daroussin 6084c8945a0SNathan Whitehorn static int 6094c8945a0SNathan Whitehorn centered(int width, const char *string) 6104c8945a0SNathan Whitehorn { 611*2a3e3873SBaptiste Daroussin int need = dlg_count_real_columns(string); 6124c8945a0SNathan Whitehorn int left; 6134c8945a0SNathan Whitehorn 614*2a3e3873SBaptiste Daroussin left = (width - need) / 2 - 1; 6154c8945a0SNathan Whitehorn if (left < 0) 6164c8945a0SNathan Whitehorn left = 0; 6174c8945a0SNathan Whitehorn return left; 6184c8945a0SNathan Whitehorn } 6194c8945a0SNathan Whitehorn 6207a1c0d96SNathan Whitehorn #ifdef USE_WIDE_CURSES 6217a1c0d96SNathan Whitehorn static bool 6227a1c0d96SNathan Whitehorn is_combining(const char *txt, int *combined) 6237a1c0d96SNathan Whitehorn { 6247a1c0d96SNathan Whitehorn bool result = FALSE; 6257a1c0d96SNathan Whitehorn 6267a1c0d96SNathan Whitehorn if (*combined == 0) { 6277a1c0d96SNathan Whitehorn if (UCH(*txt) >= 128) { 6287a1c0d96SNathan Whitehorn wchar_t wch; 6297a1c0d96SNathan Whitehorn mbstate_t state; 6307a1c0d96SNathan Whitehorn size_t given = strlen(txt); 6317a1c0d96SNathan Whitehorn size_t len; 6327a1c0d96SNathan Whitehorn 6337a1c0d96SNathan Whitehorn memset(&state, 0, sizeof(state)); 6347a1c0d96SNathan Whitehorn len = mbrtowc(&wch, txt, given, &state); 6357a1c0d96SNathan Whitehorn if ((int) len > 0 && wcwidth(wch) == 0) { 6367a1c0d96SNathan Whitehorn *combined = (int) len - 1; 6377a1c0d96SNathan Whitehorn result = TRUE; 6387a1c0d96SNathan Whitehorn } 6397a1c0d96SNathan Whitehorn } 6407a1c0d96SNathan Whitehorn } else { 6417a1c0d96SNathan Whitehorn result = TRUE; 6427a1c0d96SNathan Whitehorn *combined -= 1; 6437a1c0d96SNathan Whitehorn } 6447a1c0d96SNathan Whitehorn return result; 6457a1c0d96SNathan Whitehorn } 6467a1c0d96SNathan Whitehorn #endif 6477a1c0d96SNathan Whitehorn 6484c8945a0SNathan Whitehorn /* 649*2a3e3873SBaptiste Daroussin * Print the name (tag) or text from a DIALOG_LISTITEM, highlighting the 650*2a3e3873SBaptiste Daroussin * first character if selected. 651*2a3e3873SBaptiste Daroussin */ 652*2a3e3873SBaptiste Daroussin void 653*2a3e3873SBaptiste Daroussin dlg_print_listitem(WINDOW *win, 654*2a3e3873SBaptiste Daroussin const char *text, 655*2a3e3873SBaptiste Daroussin int climit, 656*2a3e3873SBaptiste Daroussin bool first, 657*2a3e3873SBaptiste Daroussin int selected) 658*2a3e3873SBaptiste Daroussin { 659*2a3e3873SBaptiste Daroussin chtype attr = A_NORMAL; 660*2a3e3873SBaptiste Daroussin int limit; 661*2a3e3873SBaptiste Daroussin const int *cols; 662*2a3e3873SBaptiste Daroussin chtype attrs[4]; 663*2a3e3873SBaptiste Daroussin 664*2a3e3873SBaptiste Daroussin if (text == 0) 665*2a3e3873SBaptiste Daroussin text = ""; 666*2a3e3873SBaptiste Daroussin 667*2a3e3873SBaptiste Daroussin if (first) { 668*2a3e3873SBaptiste Daroussin const int *indx = dlg_index_wchars(text); 669*2a3e3873SBaptiste Daroussin attrs[3] = tag_key_selected_attr; 670*2a3e3873SBaptiste Daroussin attrs[2] = tag_key_attr; 671*2a3e3873SBaptiste Daroussin attrs[1] = tag_selected_attr; 672*2a3e3873SBaptiste Daroussin attrs[0] = tag_attr; 673*2a3e3873SBaptiste Daroussin 674*2a3e3873SBaptiste Daroussin (void) wattrset(win, selected ? attrs[3] : attrs[2]); 675*2a3e3873SBaptiste Daroussin (void) waddnstr(win, text, indx[1]); 676*2a3e3873SBaptiste Daroussin 677*2a3e3873SBaptiste Daroussin if ((int) strlen(text) > indx[1]) { 678*2a3e3873SBaptiste Daroussin limit = dlg_limit_columns(text, climit, 1); 679*2a3e3873SBaptiste Daroussin if (limit > 1) { 680*2a3e3873SBaptiste Daroussin (void) wattrset(win, selected ? attrs[1] : attrs[0]); 681*2a3e3873SBaptiste Daroussin (void) waddnstr(win, 682*2a3e3873SBaptiste Daroussin text + indx[1], 683*2a3e3873SBaptiste Daroussin indx[limit] - indx[1]); 684*2a3e3873SBaptiste Daroussin } 685*2a3e3873SBaptiste Daroussin } 686*2a3e3873SBaptiste Daroussin } else { 687*2a3e3873SBaptiste Daroussin attrs[1] = item_selected_attr; 688*2a3e3873SBaptiste Daroussin attrs[0] = item_attr; 689*2a3e3873SBaptiste Daroussin 690*2a3e3873SBaptiste Daroussin cols = dlg_index_columns(text); 691*2a3e3873SBaptiste Daroussin limit = dlg_limit_columns(text, climit, 0); 692*2a3e3873SBaptiste Daroussin 693*2a3e3873SBaptiste Daroussin if (limit > 0) { 694*2a3e3873SBaptiste Daroussin (void) wattrset(win, selected ? attrs[1] : attrs[0]); 695*2a3e3873SBaptiste Daroussin dlg_print_text(win, text, cols[limit], &attr); 696*2a3e3873SBaptiste Daroussin } 697*2a3e3873SBaptiste Daroussin } 698*2a3e3873SBaptiste Daroussin } 699*2a3e3873SBaptiste Daroussin 700*2a3e3873SBaptiste Daroussin /* 7014c8945a0SNathan Whitehorn * Print up to 'cols' columns from 'text', optionally rendering our escape 7024c8945a0SNathan Whitehorn * sequence for attributes and color. 7034c8945a0SNathan Whitehorn */ 7044c8945a0SNathan Whitehorn void 7054c8945a0SNathan Whitehorn dlg_print_text(WINDOW *win, const char *txt, int cols, chtype *attr) 7064c8945a0SNathan Whitehorn { 7074c8945a0SNathan Whitehorn int y_origin, x_origin; 7084c8945a0SNathan Whitehorn int y_before, x_before = 0; 7094c8945a0SNathan Whitehorn int y_after, x_after; 7104c8945a0SNathan Whitehorn int tabbed = 0; 7114c8945a0SNathan Whitehorn bool thisTab; 7124c8945a0SNathan Whitehorn bool ended = FALSE; 7134c8945a0SNathan Whitehorn chtype useattr; 7147a1c0d96SNathan Whitehorn #ifdef USE_WIDE_CURSES 7157a1c0d96SNathan Whitehorn int combined = 0; 7167a1c0d96SNathan Whitehorn #endif 7174c8945a0SNathan Whitehorn 7184c8945a0SNathan Whitehorn getyx(win, y_origin, x_origin); 7194c8945a0SNathan Whitehorn while (cols > 0 && (*txt != '\0')) { 7204c8945a0SNathan Whitehorn if (dialog_vars.colors) { 7214c8945a0SNathan Whitehorn while (isOurEscape(txt)) { 7224c8945a0SNathan Whitehorn int code; 7234c8945a0SNathan Whitehorn 7244c8945a0SNathan Whitehorn txt += 2; 7254c8945a0SNathan Whitehorn switch (code = CharOf(*txt)) { 7264c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 7274c8945a0SNathan Whitehorn case '0': 7284c8945a0SNathan Whitehorn case '1': 7294c8945a0SNathan Whitehorn case '2': 7304c8945a0SNathan Whitehorn case '3': 7314c8945a0SNathan Whitehorn case '4': 7324c8945a0SNathan Whitehorn case '5': 7334c8945a0SNathan Whitehorn case '6': 7344c8945a0SNathan Whitehorn case '7': 7354c8945a0SNathan Whitehorn *attr &= ~A_COLOR; 7364c8945a0SNathan Whitehorn *attr |= define_color(win, code - '0'); 7374c8945a0SNathan Whitehorn break; 7384c8945a0SNathan Whitehorn #endif 7394c8945a0SNathan Whitehorn case 'B': 7404c8945a0SNathan Whitehorn *attr &= ~A_BOLD; 7414c8945a0SNathan Whitehorn break; 7424c8945a0SNathan Whitehorn case 'b': 7434c8945a0SNathan Whitehorn *attr |= A_BOLD; 7444c8945a0SNathan Whitehorn break; 7454c8945a0SNathan Whitehorn case 'R': 7464c8945a0SNathan Whitehorn *attr &= ~A_REVERSE; 7474c8945a0SNathan Whitehorn break; 7484c8945a0SNathan Whitehorn case 'r': 7494c8945a0SNathan Whitehorn *attr |= A_REVERSE; 7504c8945a0SNathan Whitehorn break; 7514c8945a0SNathan Whitehorn case 'U': 7524c8945a0SNathan Whitehorn *attr &= ~A_UNDERLINE; 7534c8945a0SNathan Whitehorn break; 7544c8945a0SNathan Whitehorn case 'u': 7554c8945a0SNathan Whitehorn *attr |= A_UNDERLINE; 7564c8945a0SNathan Whitehorn break; 7574c8945a0SNathan Whitehorn case 'n': 7584c8945a0SNathan Whitehorn *attr = A_NORMAL; 7594c8945a0SNathan Whitehorn break; 7604c8945a0SNathan Whitehorn } 7614c8945a0SNathan Whitehorn ++txt; 7624c8945a0SNathan Whitehorn } 7634c8945a0SNathan Whitehorn } 7644c8945a0SNathan Whitehorn if (ended || *txt == '\n' || *txt == '\0') 7654c8945a0SNathan Whitehorn break; 7664c8945a0SNathan Whitehorn useattr = (*attr) & A_ATTRIBUTES; 7674c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 7684c8945a0SNathan Whitehorn /* 7694c8945a0SNathan Whitehorn * Prevent this from making text invisible when the foreground and 7704c8945a0SNathan Whitehorn * background colors happen to be the same, and there's no bold 7714c8945a0SNathan Whitehorn * attribute. 7724c8945a0SNathan Whitehorn */ 7734c8945a0SNathan Whitehorn if ((useattr & A_COLOR) != 0 && (useattr & A_BOLD) == 0) { 7744c8945a0SNathan Whitehorn short pair = (short) PAIR_NUMBER(useattr); 7754c8945a0SNathan Whitehorn short fg, bg; 7764c8945a0SNathan Whitehorn if (pair_content(pair, &fg, &bg) != ERR 7774c8945a0SNathan Whitehorn && fg == bg) { 7784c8945a0SNathan Whitehorn useattr &= ~A_COLOR; 7794c8945a0SNathan Whitehorn useattr |= dlg_color_pair(fg, ((bg == COLOR_BLACK) 7804c8945a0SNathan Whitehorn ? COLOR_WHITE 7814c8945a0SNathan Whitehorn : COLOR_BLACK)); 7824c8945a0SNathan Whitehorn } 7834c8945a0SNathan Whitehorn } 7844c8945a0SNathan Whitehorn #endif 7854c8945a0SNathan Whitehorn /* 7864c8945a0SNathan Whitehorn * Write the character, using curses to tell exactly how wide it 7874c8945a0SNathan Whitehorn * is. If it is a tab, discount that, since the caller thinks 7884c8945a0SNathan Whitehorn * tabs are nonprinting, and curses will expand tabs to one or 7894c8945a0SNathan Whitehorn * more blanks. 7904c8945a0SNathan Whitehorn */ 7914c8945a0SNathan Whitehorn thisTab = (CharOf(*txt) == TAB); 792*2a3e3873SBaptiste Daroussin if (thisTab) { 7934c8945a0SNathan Whitehorn getyx(win, y_before, x_before); 794*2a3e3873SBaptiste Daroussin (void) y_before; 795*2a3e3873SBaptiste Daroussin } 7964c8945a0SNathan Whitehorn (void) waddch(win, CharOf(*txt++) | useattr); 7974c8945a0SNathan Whitehorn getyx(win, y_after, x_after); 7984c8945a0SNathan Whitehorn if (thisTab && (y_after == y_origin)) 7994c8945a0SNathan Whitehorn tabbed += (x_after - x_before); 8007a1c0d96SNathan Whitehorn if ((y_after != y_origin) || 8017a1c0d96SNathan Whitehorn (x_after >= (cols + tabbed + x_origin) 8027a1c0d96SNathan Whitehorn #ifdef USE_WIDE_CURSES 8037a1c0d96SNathan Whitehorn && !is_combining(txt, &combined) 8047a1c0d96SNathan Whitehorn #endif 8057a1c0d96SNathan Whitehorn )) { 8064c8945a0SNathan Whitehorn ended = TRUE; 8074c8945a0SNathan Whitehorn } 8084c8945a0SNathan Whitehorn } 8094c8945a0SNathan Whitehorn } 8104c8945a0SNathan Whitehorn 8114c8945a0SNathan Whitehorn /* 8124c8945a0SNathan Whitehorn * Print one line of the prompt in the window within the limits of the 8134c8945a0SNathan Whitehorn * specified right margin. The line will end on a word boundary and a pointer 8144c8945a0SNathan Whitehorn * to the start of the next line is returned, or a NULL pointer if the end of 8154c8945a0SNathan Whitehorn * *prompt is reached. 8164c8945a0SNathan Whitehorn */ 8174c8945a0SNathan Whitehorn const char * 8184c8945a0SNathan Whitehorn dlg_print_line(WINDOW *win, 8194c8945a0SNathan Whitehorn chtype *attr, 8204c8945a0SNathan Whitehorn const char *prompt, 8214c8945a0SNathan Whitehorn int lm, int rm, int *x) 8224c8945a0SNathan Whitehorn { 823*2a3e3873SBaptiste Daroussin const char *wrap_ptr; 824*2a3e3873SBaptiste Daroussin const char *test_ptr; 825682c9e0fSNathan Whitehorn const char *hide_ptr = 0; 8264c8945a0SNathan Whitehorn const int *cols = dlg_index_columns(prompt); 8274c8945a0SNathan Whitehorn const int *indx = dlg_index_wchars(prompt); 8284c8945a0SNathan Whitehorn int wrap_inx = 0; 8294c8945a0SNathan Whitehorn int test_inx = 0; 8304c8945a0SNathan Whitehorn int cur_x = lm; 8314c8945a0SNathan Whitehorn int hidden = 0; 8324c8945a0SNathan Whitehorn int limit = dlg_count_wchars(prompt); 8334c8945a0SNathan Whitehorn int n; 8344c8945a0SNathan Whitehorn int tabbed = 0; 8354c8945a0SNathan Whitehorn 8364c8945a0SNathan Whitehorn *x = 1; 8374c8945a0SNathan Whitehorn 8384c8945a0SNathan Whitehorn /* 8394c8945a0SNathan Whitehorn * Set *test_ptr to the end of the line or the right margin (rm), whichever 8404c8945a0SNathan Whitehorn * is less, and set wrap_ptr to the end of the last word in the line. 8414c8945a0SNathan Whitehorn */ 8424c8945a0SNathan Whitehorn for (n = 0; n < limit; ++n) { 8434c8945a0SNathan Whitehorn test_ptr = prompt + indx[test_inx]; 8444c8945a0SNathan Whitehorn if (*test_ptr == '\n' || *test_ptr == '\0' || cur_x >= (rm + hidden)) 8454c8945a0SNathan Whitehorn break; 8464c8945a0SNathan Whitehorn if (*test_ptr == TAB && n == 0) { 8474c8945a0SNathan Whitehorn tabbed = 8; /* workaround for leading tabs */ 8484c8945a0SNathan Whitehorn } else if (*test_ptr == ' ' && n != 0 && prompt[indx[n - 1]] != ' ') { 8494c8945a0SNathan Whitehorn wrap_inx = n; 8504c8945a0SNathan Whitehorn *x = cur_x; 851*2a3e3873SBaptiste Daroussin } else if (dialog_vars.colors && isOurEscape(test_ptr)) { 852682c9e0fSNathan Whitehorn hide_ptr = test_ptr; 853682c9e0fSNathan Whitehorn hidden += ESCAPE_LEN; 854682c9e0fSNathan Whitehorn n += (ESCAPE_LEN - 1); 8554c8945a0SNathan Whitehorn } 8564c8945a0SNathan Whitehorn cur_x = lm + tabbed + cols[n + 1]; 8574c8945a0SNathan Whitehorn if (cur_x > (rm + hidden)) 8584c8945a0SNathan Whitehorn break; 8594c8945a0SNathan Whitehorn test_inx = n + 1; 8604c8945a0SNathan Whitehorn } 8614c8945a0SNathan Whitehorn 8624c8945a0SNathan Whitehorn /* 8634c8945a0SNathan Whitehorn * If the line doesn't reach the right margin in the middle of a word, then 8644c8945a0SNathan Whitehorn * we don't have to wrap it at the end of the previous word. 8654c8945a0SNathan Whitehorn */ 8664c8945a0SNathan Whitehorn test_ptr = prompt + indx[test_inx]; 8674c8945a0SNathan Whitehorn if (*test_ptr == '\n' || *test_ptr == ' ' || *test_ptr == '\0') { 8684c8945a0SNathan Whitehorn wrap_inx = test_inx; 8694c8945a0SNathan Whitehorn while (wrap_inx > 0 && prompt[indx[wrap_inx - 1]] == ' ') { 8704c8945a0SNathan Whitehorn wrap_inx--; 8714c8945a0SNathan Whitehorn } 8724c8945a0SNathan Whitehorn *x = lm + indx[wrap_inx]; 8734c8945a0SNathan Whitehorn } else if (*x == 1 && cur_x >= rm) { 8744c8945a0SNathan Whitehorn /* 8754c8945a0SNathan Whitehorn * If the line has no spaces, then wrap it anyway at the right margin 8764c8945a0SNathan Whitehorn */ 8774c8945a0SNathan Whitehorn *x = rm; 8784c8945a0SNathan Whitehorn wrap_inx = test_inx; 8794c8945a0SNathan Whitehorn } 8804c8945a0SNathan Whitehorn wrap_ptr = prompt + indx[wrap_inx]; 8817a1c0d96SNathan Whitehorn #ifdef USE_WIDE_CURSES 8827a1c0d96SNathan Whitehorn if (UCH(*wrap_ptr) >= 128) { 8837a1c0d96SNathan Whitehorn int combined = 0; 8847a1c0d96SNathan Whitehorn while (is_combining(wrap_ptr, &combined)) { 8857a1c0d96SNathan Whitehorn ++wrap_ptr; 8867a1c0d96SNathan Whitehorn } 8877a1c0d96SNathan Whitehorn } 8887a1c0d96SNathan Whitehorn #endif 8894c8945a0SNathan Whitehorn 8904c8945a0SNathan Whitehorn /* 891682c9e0fSNathan Whitehorn * If we found hidden text past the last point that we will display, 892682c9e0fSNathan Whitehorn * discount that from the displayed length. 893682c9e0fSNathan Whitehorn */ 894682c9e0fSNathan Whitehorn if ((hide_ptr != 0) && (hide_ptr >= wrap_ptr)) { 895682c9e0fSNathan Whitehorn hidden -= ESCAPE_LEN; 896682c9e0fSNathan Whitehorn test_ptr = wrap_ptr; 897682c9e0fSNathan Whitehorn while (test_ptr < wrap_ptr) { 898*2a3e3873SBaptiste Daroussin if (dialog_vars.colors && isOurEscape(test_ptr)) { 899682c9e0fSNathan Whitehorn hidden -= ESCAPE_LEN; 900682c9e0fSNathan Whitehorn test_ptr += ESCAPE_LEN; 901682c9e0fSNathan Whitehorn } else { 902682c9e0fSNathan Whitehorn ++test_ptr; 903682c9e0fSNathan Whitehorn } 904682c9e0fSNathan Whitehorn } 905682c9e0fSNathan Whitehorn } 906682c9e0fSNathan Whitehorn 907682c9e0fSNathan Whitehorn /* 9084c8945a0SNathan Whitehorn * Print the line if we have a window pointer. Otherwise this routine 9094c8945a0SNathan Whitehorn * is just being called for sizing the window. 9104c8945a0SNathan Whitehorn */ 9114c8945a0SNathan Whitehorn if (win) { 9124c8945a0SNathan Whitehorn dlg_print_text(win, prompt, (cols[wrap_inx] - hidden), attr); 9134c8945a0SNathan Whitehorn } 9144c8945a0SNathan Whitehorn 9154c8945a0SNathan Whitehorn /* *x tells the calling function how long the line was */ 9164c8945a0SNathan Whitehorn if (*x == 1) 9174c8945a0SNathan Whitehorn *x = rm; 9184c8945a0SNathan Whitehorn 919682c9e0fSNathan Whitehorn *x -= hidden; 920682c9e0fSNathan Whitehorn 9214c8945a0SNathan Whitehorn /* Find the start of the next line and return a pointer to it */ 9224c8945a0SNathan Whitehorn test_ptr = wrap_ptr; 9234c8945a0SNathan Whitehorn while (*test_ptr == ' ') 9244c8945a0SNathan Whitehorn test_ptr++; 9254c8945a0SNathan Whitehorn if (*test_ptr == '\n') 9264c8945a0SNathan Whitehorn test_ptr++; 9274c8945a0SNathan Whitehorn return (test_ptr); 9284c8945a0SNathan Whitehorn } 9294c8945a0SNathan Whitehorn 9304c8945a0SNathan Whitehorn static void 9314c8945a0SNathan Whitehorn justify_text(WINDOW *win, 9324c8945a0SNathan Whitehorn const char *prompt, 9334c8945a0SNathan Whitehorn int limit_y, 9344c8945a0SNathan Whitehorn int limit_x, 9354c8945a0SNathan Whitehorn int *high, int *wide) 9364c8945a0SNathan Whitehorn { 9374c8945a0SNathan Whitehorn chtype attr = A_NORMAL; 9384c8945a0SNathan Whitehorn int x = (2 * MARGIN); 9394c8945a0SNathan Whitehorn int y = MARGIN; 9404c8945a0SNathan Whitehorn int max_x = 2; 9414c8945a0SNathan Whitehorn int lm = (2 * MARGIN); /* left margin (box-border plus a space) */ 9424c8945a0SNathan Whitehorn int rm = limit_x; /* right margin */ 9434c8945a0SNathan Whitehorn int bm = limit_y; /* bottom margin */ 9444c8945a0SNathan Whitehorn int last_y = 0, last_x = 0; 9454c8945a0SNathan Whitehorn 9464c8945a0SNathan Whitehorn if (win) { 9474c8945a0SNathan Whitehorn rm -= (2 * MARGIN); 9484c8945a0SNathan Whitehorn bm -= (2 * MARGIN); 9494c8945a0SNathan Whitehorn } 9504c8945a0SNathan Whitehorn if (prompt == 0) 9514c8945a0SNathan Whitehorn prompt = ""; 9524c8945a0SNathan Whitehorn 9534c8945a0SNathan Whitehorn if (win != 0) 9544c8945a0SNathan Whitehorn getyx(win, last_y, last_x); 9554c8945a0SNathan Whitehorn while (y <= bm && *prompt) { 9564c8945a0SNathan Whitehorn x = lm; 9574c8945a0SNathan Whitehorn 9584c8945a0SNathan Whitehorn if (*prompt == '\n') { 9594c8945a0SNathan Whitehorn while (*prompt == '\n' && y < bm) { 9604c8945a0SNathan Whitehorn if (*(prompt + 1) != '\0') { 9614c8945a0SNathan Whitehorn ++y; 9624c8945a0SNathan Whitehorn if (win != 0) 9634c8945a0SNathan Whitehorn (void) wmove(win, y, lm); 9644c8945a0SNathan Whitehorn } 9654c8945a0SNathan Whitehorn prompt++; 9664c8945a0SNathan Whitehorn } 9674c8945a0SNathan Whitehorn } else if (win != 0) 9684c8945a0SNathan Whitehorn (void) wmove(win, y, lm); 9694c8945a0SNathan Whitehorn 9704c8945a0SNathan Whitehorn if (*prompt) { 9714c8945a0SNathan Whitehorn prompt = dlg_print_line(win, &attr, prompt, lm, rm, &x); 9724c8945a0SNathan Whitehorn if (win != 0) 9734c8945a0SNathan Whitehorn getyx(win, last_y, last_x); 9744c8945a0SNathan Whitehorn } 9754c8945a0SNathan Whitehorn if (*prompt) { 9764c8945a0SNathan Whitehorn ++y; 9774c8945a0SNathan Whitehorn if (win != 0) 9784c8945a0SNathan Whitehorn (void) wmove(win, y, lm); 9794c8945a0SNathan Whitehorn } 9804c8945a0SNathan Whitehorn max_x = MAX(max_x, x); 9814c8945a0SNathan Whitehorn } 9824c8945a0SNathan Whitehorn /* Move back to the last position after drawing prompt, for msgbox. */ 9834c8945a0SNathan Whitehorn if (win != 0) 9844c8945a0SNathan Whitehorn (void) wmove(win, last_y, last_x); 9854c8945a0SNathan Whitehorn 9864c8945a0SNathan Whitehorn /* Set the final height and width for the calling function */ 9874c8945a0SNathan Whitehorn if (high != 0) 9884c8945a0SNathan Whitehorn *high = y; 9894c8945a0SNathan Whitehorn if (wide != 0) 9904c8945a0SNathan Whitehorn *wide = max_x; 9914c8945a0SNathan Whitehorn } 9924c8945a0SNathan Whitehorn 9934c8945a0SNathan Whitehorn /* 9944c8945a0SNathan Whitehorn * Print a string of text in a window, automatically wrap around to the next 9954c8945a0SNathan Whitehorn * line if the string is too long to fit on one line. Note that the string may 9964c8945a0SNathan Whitehorn * contain embedded newlines. 9974c8945a0SNathan Whitehorn */ 9984c8945a0SNathan Whitehorn void 9994c8945a0SNathan Whitehorn dlg_print_autowrap(WINDOW *win, const char *prompt, int height, int width) 10004c8945a0SNathan Whitehorn { 10014c8945a0SNathan Whitehorn justify_text(win, prompt, 10024c8945a0SNathan Whitehorn height, 10034c8945a0SNathan Whitehorn width, 10044c8945a0SNathan Whitehorn (int *) 0, (int *) 0); 10054c8945a0SNathan Whitehorn } 10064c8945a0SNathan Whitehorn 10074c8945a0SNathan Whitehorn /* 10084c8945a0SNathan Whitehorn * Display the message in a scrollable window. Actually the way it works is 10094c8945a0SNathan Whitehorn * that we create a "tall" window of the proper width, let the text wrap within 10104c8945a0SNathan Whitehorn * that, and copy a slice of the result to the dialog. 10114c8945a0SNathan Whitehorn * 10124c8945a0SNathan Whitehorn * It works for ncurses. Other curses implementations show only blanks (Tru64) 10134c8945a0SNathan Whitehorn * or garbage (NetBSD). 10144c8945a0SNathan Whitehorn */ 10154c8945a0SNathan Whitehorn int 10164c8945a0SNathan Whitehorn dlg_print_scrolled(WINDOW *win, 10174c8945a0SNathan Whitehorn const char *prompt, 10184c8945a0SNathan Whitehorn int offset, 10194c8945a0SNathan Whitehorn int height, 10204c8945a0SNathan Whitehorn int width, 10214c8945a0SNathan Whitehorn int pauseopt) 10224c8945a0SNathan Whitehorn { 10234c8945a0SNathan Whitehorn int oldy, oldx; 10244c8945a0SNathan Whitehorn int last = 0; 10254c8945a0SNathan Whitehorn 10267a1c0d96SNathan Whitehorn (void) pauseopt; /* used only for ncurses */ 10277a1c0d96SNathan Whitehorn 10284c8945a0SNathan Whitehorn getyx(win, oldy, oldx); 10294c8945a0SNathan Whitehorn #ifdef NCURSES_VERSION 10304c8945a0SNathan Whitehorn if (pauseopt) { 10314c8945a0SNathan Whitehorn int wide = width - (2 * MARGIN); 10324c8945a0SNathan Whitehorn int high = LINES; 10334c8945a0SNathan Whitehorn int y, x; 10344c8945a0SNathan Whitehorn int len; 10354c8945a0SNathan Whitehorn int percent; 10364c8945a0SNathan Whitehorn WINDOW *dummy; 10374c8945a0SNathan Whitehorn char buffer[5]; 10384c8945a0SNathan Whitehorn 10394c8945a0SNathan Whitehorn #if defined(NCURSES_VERSION_PATCH) && NCURSES_VERSION_PATCH >= 20040417 10404c8945a0SNathan Whitehorn /* 10414c8945a0SNathan Whitehorn * If we're not limited by the screensize, allow text to possibly be 10424c8945a0SNathan Whitehorn * one character per line. 10434c8945a0SNathan Whitehorn */ 10444c8945a0SNathan Whitehorn if ((len = dlg_count_columns(prompt)) > high) 10454c8945a0SNathan Whitehorn high = len; 10464c8945a0SNathan Whitehorn #endif 10474c8945a0SNathan Whitehorn dummy = newwin(high, width, 0, 0); 1048682c9e0fSNathan Whitehorn if (dummy == 0) { 1049*2a3e3873SBaptiste Daroussin (void) wattrset(win, dialog_attr); 1050682c9e0fSNathan Whitehorn dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width); 1051682c9e0fSNathan Whitehorn last = 0; 1052682c9e0fSNathan Whitehorn } else { 10534c8945a0SNathan Whitehorn wbkgdset(dummy, dialog_attr | ' '); 1054*2a3e3873SBaptiste Daroussin (void) wattrset(dummy, dialog_attr); 10554c8945a0SNathan Whitehorn werase(dummy); 10564c8945a0SNathan Whitehorn dlg_print_autowrap(dummy, prompt, high, width); 10574c8945a0SNathan Whitehorn getyx(dummy, y, x); 1058*2a3e3873SBaptiste Daroussin (void) x; 10594c8945a0SNathan Whitehorn 10604c8945a0SNathan Whitehorn copywin(dummy, /* srcwin */ 10614c8945a0SNathan Whitehorn win, /* dstwin */ 10624c8945a0SNathan Whitehorn offset + MARGIN, /* sminrow */ 10634c8945a0SNathan Whitehorn MARGIN, /* smincol */ 10644c8945a0SNathan Whitehorn MARGIN, /* dminrow */ 10654c8945a0SNathan Whitehorn MARGIN, /* dmincol */ 10664c8945a0SNathan Whitehorn height, /* dmaxrow */ 10674c8945a0SNathan Whitehorn wide, /* dmaxcol */ 10684c8945a0SNathan Whitehorn FALSE); 10694c8945a0SNathan Whitehorn 10704c8945a0SNathan Whitehorn delwin(dummy); 10714c8945a0SNathan Whitehorn 10724c8945a0SNathan Whitehorn /* if the text is incomplete, or we have scrolled, show the percentage */ 10734c8945a0SNathan Whitehorn if (y > 0 && wide > 4) { 10744c8945a0SNathan Whitehorn percent = (int) ((height + offset) * 100.0 / y); 10754c8945a0SNathan Whitehorn if (percent < 0) 10764c8945a0SNathan Whitehorn percent = 0; 10774c8945a0SNathan Whitehorn if (percent > 100) 10784c8945a0SNathan Whitehorn percent = 100; 10794c8945a0SNathan Whitehorn if (offset != 0 || percent != 100) { 10804c8945a0SNathan Whitehorn (void) wattrset(win, position_indicator_attr); 10814c8945a0SNathan Whitehorn (void) wmove(win, MARGIN + height, wide - 4); 10824c8945a0SNathan Whitehorn (void) sprintf(buffer, "%d%%", percent); 10834c8945a0SNathan Whitehorn (void) waddstr(win, buffer); 10844c8945a0SNathan Whitehorn if ((len = (int) strlen(buffer)) < 4) { 1085*2a3e3873SBaptiste Daroussin (void) wattrset(win, border_attr); 10864c8945a0SNathan Whitehorn whline(win, dlg_boxchar(ACS_HLINE), 4 - len); 10874c8945a0SNathan Whitehorn } 10884c8945a0SNathan Whitehorn } 10894c8945a0SNathan Whitehorn } 10904c8945a0SNathan Whitehorn last = (y - height); 1091682c9e0fSNathan Whitehorn } 10924c8945a0SNathan Whitehorn } else 10934c8945a0SNathan Whitehorn #endif 10944c8945a0SNathan Whitehorn { 10954c8945a0SNathan Whitehorn (void) offset; 1096*2a3e3873SBaptiste Daroussin (void) wattrset(win, dialog_attr); 10974c8945a0SNathan Whitehorn dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width); 10984c8945a0SNathan Whitehorn last = 0; 10994c8945a0SNathan Whitehorn } 11004c8945a0SNathan Whitehorn wmove(win, oldy, oldx); 11014c8945a0SNathan Whitehorn return last; 11024c8945a0SNathan Whitehorn } 11034c8945a0SNathan Whitehorn 11044c8945a0SNathan Whitehorn int 11054c8945a0SNathan Whitehorn dlg_check_scrolled(int key, int last, int page, bool * show, int *offset) 11064c8945a0SNathan Whitehorn { 11074c8945a0SNathan Whitehorn int code = 0; 11084c8945a0SNathan Whitehorn 11094c8945a0SNathan Whitehorn *show = FALSE; 11104c8945a0SNathan Whitehorn 11114c8945a0SNathan Whitehorn switch (key) { 11124c8945a0SNathan Whitehorn case DLGK_PAGE_FIRST: 11134c8945a0SNathan Whitehorn if (*offset > 0) { 11144c8945a0SNathan Whitehorn *offset = 0; 11154c8945a0SNathan Whitehorn *show = TRUE; 11164c8945a0SNathan Whitehorn } 11174c8945a0SNathan Whitehorn break; 11184c8945a0SNathan Whitehorn case DLGK_PAGE_LAST: 11194c8945a0SNathan Whitehorn if (*offset < last) { 11204c8945a0SNathan Whitehorn *offset = last; 11214c8945a0SNathan Whitehorn *show = TRUE; 11224c8945a0SNathan Whitehorn } 11234c8945a0SNathan Whitehorn break; 11244c8945a0SNathan Whitehorn case DLGK_GRID_UP: 11254c8945a0SNathan Whitehorn if (*offset > 0) { 11264c8945a0SNathan Whitehorn --(*offset); 11274c8945a0SNathan Whitehorn *show = TRUE; 11284c8945a0SNathan Whitehorn } 11294c8945a0SNathan Whitehorn break; 11304c8945a0SNathan Whitehorn case DLGK_GRID_DOWN: 11314c8945a0SNathan Whitehorn if (*offset < last) { 11324c8945a0SNathan Whitehorn ++(*offset); 11334c8945a0SNathan Whitehorn *show = TRUE; 11344c8945a0SNathan Whitehorn } 11354c8945a0SNathan Whitehorn break; 11364c8945a0SNathan Whitehorn case DLGK_PAGE_PREV: 11374c8945a0SNathan Whitehorn if (*offset > 0) { 11384c8945a0SNathan Whitehorn *offset -= page; 11394c8945a0SNathan Whitehorn if (*offset < 0) 11404c8945a0SNathan Whitehorn *offset = 0; 11414c8945a0SNathan Whitehorn *show = TRUE; 11424c8945a0SNathan Whitehorn } 11434c8945a0SNathan Whitehorn break; 11444c8945a0SNathan Whitehorn case DLGK_PAGE_NEXT: 11454c8945a0SNathan Whitehorn if (*offset < last) { 11464c8945a0SNathan Whitehorn *offset += page; 11474c8945a0SNathan Whitehorn if (*offset > last) 11484c8945a0SNathan Whitehorn *offset = last; 11494c8945a0SNathan Whitehorn *show = TRUE; 11504c8945a0SNathan Whitehorn } 11514c8945a0SNathan Whitehorn break; 11524c8945a0SNathan Whitehorn default: 11534c8945a0SNathan Whitehorn code = -1; 11544c8945a0SNathan Whitehorn break; 11554c8945a0SNathan Whitehorn } 11564c8945a0SNathan Whitehorn return code; 11574c8945a0SNathan Whitehorn } 11584c8945a0SNathan Whitehorn 11594c8945a0SNathan Whitehorn /* 11604c8945a0SNathan Whitehorn * Calculate the window size for preformatted text. This will calculate box 11614c8945a0SNathan Whitehorn * dimensions that are at or close to the specified aspect ratio for the prompt 11624c8945a0SNathan Whitehorn * string with all spaces and newlines preserved and additional newlines added 11634c8945a0SNathan Whitehorn * as necessary. 11644c8945a0SNathan Whitehorn */ 11654c8945a0SNathan Whitehorn static void 11664c8945a0SNathan Whitehorn auto_size_preformatted(const char *prompt, int *height, int *width) 11674c8945a0SNathan Whitehorn { 11684c8945a0SNathan Whitehorn int high = 0, wide = 0; 11694c8945a0SNathan Whitehorn float car; /* Calculated Aspect Ratio */ 11704c8945a0SNathan Whitehorn float diff; 11714c8945a0SNathan Whitehorn int max_y = SLINES - 1; 11724c8945a0SNathan Whitehorn int max_x = SCOLS - 2; 11734c8945a0SNathan Whitehorn int max_width = max_x; 11744c8945a0SNathan Whitehorn int ar = dialog_state.aspect_ratio; 11754c8945a0SNathan Whitehorn 11764c8945a0SNathan Whitehorn /* Get the initial dimensions */ 11774c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide); 11784c8945a0SNathan Whitehorn car = (float) (wide / high); 11794c8945a0SNathan Whitehorn 11804c8945a0SNathan Whitehorn /* 11814c8945a0SNathan Whitehorn * If the aspect ratio is greater than it should be, then decrease the 11824c8945a0SNathan Whitehorn * width proportionately. 11834c8945a0SNathan Whitehorn */ 11844c8945a0SNathan Whitehorn if (car > ar) { 11854c8945a0SNathan Whitehorn diff = car / (float) ar; 11864c8945a0SNathan Whitehorn max_x = (int) ((float) wide / diff + 4); 11874c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide); 11884c8945a0SNathan Whitehorn car = (float) wide / (float) high; 11894c8945a0SNathan Whitehorn } 11904c8945a0SNathan Whitehorn 11914c8945a0SNathan Whitehorn /* 11924c8945a0SNathan Whitehorn * If the aspect ratio is too small after decreasing the width, then 11934c8945a0SNathan Whitehorn * incrementally increase the width until the aspect ratio is equal to or 11944c8945a0SNathan Whitehorn * greater than the specified aspect ratio. 11954c8945a0SNathan Whitehorn */ 11964c8945a0SNathan Whitehorn while (car < ar && max_x < max_width) { 11974c8945a0SNathan Whitehorn max_x += 4; 11984c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide); 11994c8945a0SNathan Whitehorn car = (float) (wide / high); 12004c8945a0SNathan Whitehorn } 12014c8945a0SNathan Whitehorn 12024c8945a0SNathan Whitehorn *height = high; 12034c8945a0SNathan Whitehorn *width = wide; 12044c8945a0SNathan Whitehorn } 12054c8945a0SNathan Whitehorn 12064c8945a0SNathan Whitehorn /* 12074c8945a0SNathan Whitehorn * Find the length of the longest "word" in the given string. By setting the 12084c8945a0SNathan Whitehorn * widget width at least this long, we can avoid splitting a word on the 12094c8945a0SNathan Whitehorn * margin. 12104c8945a0SNathan Whitehorn */ 12114c8945a0SNathan Whitehorn static int 12124c8945a0SNathan Whitehorn longest_word(const char *string) 12134c8945a0SNathan Whitehorn { 12144c8945a0SNathan Whitehorn int length, result = 0; 12154c8945a0SNathan Whitehorn 12164c8945a0SNathan Whitehorn while (*string != '\0') { 12174c8945a0SNathan Whitehorn length = 0; 12184c8945a0SNathan Whitehorn while (*string != '\0' && !isspace(UCH(*string))) { 12194c8945a0SNathan Whitehorn length++; 12204c8945a0SNathan Whitehorn string++; 12214c8945a0SNathan Whitehorn } 12224c8945a0SNathan Whitehorn result = MAX(result, length); 12234c8945a0SNathan Whitehorn if (*string != '\0') 12244c8945a0SNathan Whitehorn string++; 12254c8945a0SNathan Whitehorn } 12264c8945a0SNathan Whitehorn return result; 12274c8945a0SNathan Whitehorn } 12284c8945a0SNathan Whitehorn 12294c8945a0SNathan Whitehorn /* 12304c8945a0SNathan Whitehorn * if (height or width == -1) Maximize() 12314c8945a0SNathan Whitehorn * if (height or width == 0), justify and return actual limits. 12324c8945a0SNathan Whitehorn */ 12334c8945a0SNathan Whitehorn static void 12344c8945a0SNathan Whitehorn real_auto_size(const char *title, 12354c8945a0SNathan Whitehorn const char *prompt, 12364c8945a0SNathan Whitehorn int *height, int *width, 12374c8945a0SNathan Whitehorn int boxlines, int mincols) 12384c8945a0SNathan Whitehorn { 12394c8945a0SNathan Whitehorn int x = (dialog_vars.begin_set ? dialog_vars.begin_x : 2); 12404c8945a0SNathan Whitehorn int y = (dialog_vars.begin_set ? dialog_vars.begin_y : 1); 12414c8945a0SNathan Whitehorn int title_length = title ? dlg_count_columns(title) : 0; 12424c8945a0SNathan Whitehorn int nc = 4; 12434c8945a0SNathan Whitehorn int high; 12444c8945a0SNathan Whitehorn int wide; 12454c8945a0SNathan Whitehorn int save_high = *height; 12464c8945a0SNathan Whitehorn int save_wide = *width; 12474c8945a0SNathan Whitehorn 12484c8945a0SNathan Whitehorn if (prompt == 0) { 12494c8945a0SNathan Whitehorn if (*height == 0) 12504c8945a0SNathan Whitehorn *height = -1; 12514c8945a0SNathan Whitehorn if (*width == 0) 12524c8945a0SNathan Whitehorn *width = -1; 12534c8945a0SNathan Whitehorn } 12544c8945a0SNathan Whitehorn 12554c8945a0SNathan Whitehorn if (*height > 0) { 12564c8945a0SNathan Whitehorn high = *height; 12574c8945a0SNathan Whitehorn } else { 12584c8945a0SNathan Whitehorn high = SLINES - y; 12594c8945a0SNathan Whitehorn } 12604c8945a0SNathan Whitehorn 1261*2a3e3873SBaptiste Daroussin if (*width <= 0) { 1262*2a3e3873SBaptiste Daroussin if (prompt != 0) { 12634c8945a0SNathan Whitehorn wide = MAX(title_length, mincols); 12644c8945a0SNathan Whitehorn if (strchr(prompt, '\n') == 0) { 1265*2a3e3873SBaptiste Daroussin double val = (dialog_state.aspect_ratio * 1266*2a3e3873SBaptiste Daroussin dlg_count_real_columns(prompt)); 12674c8945a0SNathan Whitehorn double xxx = sqrt(val); 12684c8945a0SNathan Whitehorn int tmp = (int) xxx; 12694c8945a0SNathan Whitehorn wide = MAX(wide, tmp); 12704c8945a0SNathan Whitehorn wide = MAX(wide, longest_word(prompt)); 12714c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, high, wide, height, width); 12724c8945a0SNathan Whitehorn } else { 12734c8945a0SNathan Whitehorn auto_size_preformatted(prompt, height, width); 12744c8945a0SNathan Whitehorn } 12754c8945a0SNathan Whitehorn } else { 12764c8945a0SNathan Whitehorn wide = SCOLS - x; 12774c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, high, wide, height, width); 12784c8945a0SNathan Whitehorn } 1279*2a3e3873SBaptiste Daroussin } 12804c8945a0SNathan Whitehorn 12814c8945a0SNathan Whitehorn if (*width < title_length) { 12824c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, high, title_length, height, width); 12834c8945a0SNathan Whitehorn *width = title_length; 12844c8945a0SNathan Whitehorn } 12854c8945a0SNathan Whitehorn 12864c8945a0SNathan Whitehorn if (*width < mincols && save_wide == 0) 12874c8945a0SNathan Whitehorn *width = mincols; 12884c8945a0SNathan Whitehorn if (prompt != 0) { 12894c8945a0SNathan Whitehorn *width += nc; 12904c8945a0SNathan Whitehorn *height += boxlines + 2; 12914c8945a0SNathan Whitehorn } 12924c8945a0SNathan Whitehorn if (save_high > 0) 12934c8945a0SNathan Whitehorn *height = save_high; 12944c8945a0SNathan Whitehorn if (save_wide > 0) 12954c8945a0SNathan Whitehorn *width = save_wide; 12964c8945a0SNathan Whitehorn } 12974c8945a0SNathan Whitehorn 12984c8945a0SNathan Whitehorn /* End of real_auto_size() */ 12994c8945a0SNathan Whitehorn 13004c8945a0SNathan Whitehorn void 13014c8945a0SNathan Whitehorn dlg_auto_size(const char *title, 13024c8945a0SNathan Whitehorn const char *prompt, 13034c8945a0SNathan Whitehorn int *height, 13044c8945a0SNathan Whitehorn int *width, 13054c8945a0SNathan Whitehorn int boxlines, 13064c8945a0SNathan Whitehorn int mincols) 13074c8945a0SNathan Whitehorn { 13084c8945a0SNathan Whitehorn real_auto_size(title, prompt, height, width, boxlines, mincols); 13094c8945a0SNathan Whitehorn 13104c8945a0SNathan Whitehorn if (*width > SCOLS) { 13114c8945a0SNathan Whitehorn (*height)++; 13124c8945a0SNathan Whitehorn *width = SCOLS; 13134c8945a0SNathan Whitehorn } 13144c8945a0SNathan Whitehorn 13154c8945a0SNathan Whitehorn if (*height > SLINES) 13164c8945a0SNathan Whitehorn *height = SLINES; 13174c8945a0SNathan Whitehorn } 13184c8945a0SNathan Whitehorn 13194c8945a0SNathan Whitehorn /* 13204c8945a0SNathan Whitehorn * if (height or width == -1) Maximize() 13214c8945a0SNathan Whitehorn * if (height or width == 0) 13224c8945a0SNathan Whitehorn * height=MIN(SLINES, num.lines in fd+n); 13234c8945a0SNathan Whitehorn * width=MIN(SCOLS, MAX(longer line+n, mincols)); 13244c8945a0SNathan Whitehorn */ 13254c8945a0SNathan Whitehorn void 13264c8945a0SNathan Whitehorn dlg_auto_sizefile(const char *title, 13274c8945a0SNathan Whitehorn const char *file, 13284c8945a0SNathan Whitehorn int *height, 13294c8945a0SNathan Whitehorn int *width, 13304c8945a0SNathan Whitehorn int boxlines, 13314c8945a0SNathan Whitehorn int mincols) 13324c8945a0SNathan Whitehorn { 13334c8945a0SNathan Whitehorn int count = 0; 13344c8945a0SNathan Whitehorn int len = title ? dlg_count_columns(title) : 0; 13354c8945a0SNathan Whitehorn int nc = 4; 13364c8945a0SNathan Whitehorn int numlines = 2; 13374c8945a0SNathan Whitehorn long offset; 13384c8945a0SNathan Whitehorn int ch; 13394c8945a0SNathan Whitehorn FILE *fd; 13404c8945a0SNathan Whitehorn 13414c8945a0SNathan Whitehorn /* Open input file for reading */ 13424c8945a0SNathan Whitehorn if ((fd = fopen(file, "rb")) == NULL) 13434c8945a0SNathan Whitehorn dlg_exiterr("dlg_auto_sizefile: Cannot open input file %s", file); 13444c8945a0SNathan Whitehorn 13454c8945a0SNathan Whitehorn if ((*height == -1) || (*width == -1)) { 13464c8945a0SNathan Whitehorn *height = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0); 13474c8945a0SNathan Whitehorn *width = SCOLS - (dialog_vars.begin_set ? dialog_vars.begin_x : 0); 13484c8945a0SNathan Whitehorn } 13494c8945a0SNathan Whitehorn if ((*height != 0) && (*width != 0)) { 13504c8945a0SNathan Whitehorn (void) fclose(fd); 13514c8945a0SNathan Whitehorn if (*width > SCOLS) 13524c8945a0SNathan Whitehorn *width = SCOLS; 13534c8945a0SNathan Whitehorn if (*height > SLINES) 13544c8945a0SNathan Whitehorn *height = SLINES; 13554c8945a0SNathan Whitehorn return; 13564c8945a0SNathan Whitehorn } 13574c8945a0SNathan Whitehorn 13584c8945a0SNathan Whitehorn while (!feof(fd)) { 13594c8945a0SNathan Whitehorn offset = 0; 13604c8945a0SNathan Whitehorn while (((ch = getc(fd)) != '\n') && !feof(fd)) 13614c8945a0SNathan Whitehorn if ((ch == TAB) && (dialog_vars.tab_correct)) 13624c8945a0SNathan Whitehorn offset += dialog_state.tab_len - (offset % dialog_state.tab_len); 13634c8945a0SNathan Whitehorn else 13644c8945a0SNathan Whitehorn offset++; 13654c8945a0SNathan Whitehorn 13664c8945a0SNathan Whitehorn if (offset > len) 13677a1c0d96SNathan Whitehorn len = (int) offset; 13684c8945a0SNathan Whitehorn 13694c8945a0SNathan Whitehorn count++; 13704c8945a0SNathan Whitehorn } 13714c8945a0SNathan Whitehorn 13727a1c0d96SNathan Whitehorn /* now 'count' has the number of lines of fd and 'len' the max length */ 13734c8945a0SNathan Whitehorn 13744c8945a0SNathan Whitehorn *height = MIN(SLINES, count + numlines + boxlines); 13754c8945a0SNathan Whitehorn *width = MIN(SCOLS, MAX((len + nc), mincols)); 13764c8945a0SNathan Whitehorn /* here width and height can be maximized if > SCOLS|SLINES because 13774c8945a0SNathan Whitehorn textbox-like widgets don't put all <file> on the screen. 13784c8945a0SNathan Whitehorn Msgbox-like widget instead have to put all <text> correctly. */ 13794c8945a0SNathan Whitehorn 13804c8945a0SNathan Whitehorn (void) fclose(fd); 13814c8945a0SNathan Whitehorn } 13824c8945a0SNathan Whitehorn 1383682c9e0fSNathan Whitehorn static chtype 1384682c9e0fSNathan Whitehorn dlg_get_cell_attrs(WINDOW *win) 1385682c9e0fSNathan Whitehorn { 1386682c9e0fSNathan Whitehorn chtype result; 1387682c9e0fSNathan Whitehorn #ifdef USE_WIDE_CURSES 1388682c9e0fSNathan Whitehorn cchar_t wch; 1389682c9e0fSNathan Whitehorn wchar_t cc; 1390682c9e0fSNathan Whitehorn attr_t attrs; 1391682c9e0fSNathan Whitehorn short pair; 1392682c9e0fSNathan Whitehorn if (win_wch(win, &wch) == OK 1393682c9e0fSNathan Whitehorn && getcchar(&wch, &cc, &attrs, &pair, NULL) == OK) { 1394682c9e0fSNathan Whitehorn result = attrs; 1395682c9e0fSNathan Whitehorn } else { 1396682c9e0fSNathan Whitehorn result = 0; 1397682c9e0fSNathan Whitehorn } 1398682c9e0fSNathan Whitehorn #else 1399682c9e0fSNathan Whitehorn result = winch(win) & (A_ATTRIBUTES & ~A_COLOR); 1400682c9e0fSNathan Whitehorn #endif 1401682c9e0fSNathan Whitehorn return result; 1402682c9e0fSNathan Whitehorn } 1403682c9e0fSNathan Whitehorn 14044c8945a0SNathan Whitehorn /* 14054c8945a0SNathan Whitehorn * Draw a rectangular box with line drawing characters. 14064c8945a0SNathan Whitehorn * 14074c8945a0SNathan Whitehorn * borderchar is used to color the upper/left edges. 14084c8945a0SNathan Whitehorn * 14094c8945a0SNathan Whitehorn * boxchar is used to color the right/lower edges. It also is fill-color used 14104c8945a0SNathan Whitehorn * for the box contents. 14114c8945a0SNathan Whitehorn * 14124c8945a0SNathan Whitehorn * Normally, if you are drawing a scrollable box, use menubox_border_attr for 14134c8945a0SNathan Whitehorn * boxchar, and menubox_attr for borderchar since the scroll-arrows are drawn 14144c8945a0SNathan Whitehorn * with menubox_attr at the top, and menubox_border_attr at the bottom. That 14154c8945a0SNathan Whitehorn * also (given the default color choices) produces a recessed effect. 14164c8945a0SNathan Whitehorn * 14174c8945a0SNathan Whitehorn * If you want a raised effect (and are not going to use the scroll-arrows), 14184c8945a0SNathan Whitehorn * reverse this choice. 14194c8945a0SNathan Whitehorn */ 14204c8945a0SNathan Whitehorn void 1421*2a3e3873SBaptiste Daroussin dlg_draw_box2(WINDOW *win, int y, int x, int height, int width, 1422*2a3e3873SBaptiste Daroussin chtype boxchar, chtype borderchar, chtype borderchar2) 14234c8945a0SNathan Whitehorn { 14244c8945a0SNathan Whitehorn int i, j; 14257a1c0d96SNathan Whitehorn chtype save = dlg_get_attrs(win); 14264c8945a0SNathan Whitehorn 1427*2a3e3873SBaptiste Daroussin (void) wattrset(win, 0); 14284c8945a0SNathan Whitehorn for (i = 0; i < height; i++) { 14294c8945a0SNathan Whitehorn (void) wmove(win, y + i, x); 14304c8945a0SNathan Whitehorn for (j = 0; j < width; j++) 14314c8945a0SNathan Whitehorn if (!i && !j) 14324c8945a0SNathan Whitehorn (void) waddch(win, borderchar | dlg_boxchar(ACS_ULCORNER)); 14334c8945a0SNathan Whitehorn else if (i == height - 1 && !j) 14344c8945a0SNathan Whitehorn (void) waddch(win, borderchar | dlg_boxchar(ACS_LLCORNER)); 14354c8945a0SNathan Whitehorn else if (!i && j == width - 1) 1436*2a3e3873SBaptiste Daroussin (void) waddch(win, borderchar2 | dlg_boxchar(ACS_URCORNER)); 14374c8945a0SNathan Whitehorn else if (i == height - 1 && j == width - 1) 1438*2a3e3873SBaptiste Daroussin (void) waddch(win, borderchar2 | dlg_boxchar(ACS_LRCORNER)); 14394c8945a0SNathan Whitehorn else if (!i) 14404c8945a0SNathan Whitehorn (void) waddch(win, borderchar | dlg_boxchar(ACS_HLINE)); 14414c8945a0SNathan Whitehorn else if (i == height - 1) 1442*2a3e3873SBaptiste Daroussin (void) waddch(win, borderchar2 | dlg_boxchar(ACS_HLINE)); 14434c8945a0SNathan Whitehorn else if (!j) 14444c8945a0SNathan Whitehorn (void) waddch(win, borderchar | dlg_boxchar(ACS_VLINE)); 14454c8945a0SNathan Whitehorn else if (j == width - 1) 1446*2a3e3873SBaptiste Daroussin (void) waddch(win, borderchar2 | dlg_boxchar(ACS_VLINE)); 14474c8945a0SNathan Whitehorn else 14484c8945a0SNathan Whitehorn (void) waddch(win, boxchar | ' '); 14494c8945a0SNathan Whitehorn } 1450*2a3e3873SBaptiste Daroussin (void) wattrset(win, save); 1451*2a3e3873SBaptiste Daroussin } 1452*2a3e3873SBaptiste Daroussin 1453*2a3e3873SBaptiste Daroussin void 1454*2a3e3873SBaptiste Daroussin dlg_draw_box(WINDOW *win, int y, int x, int height, int width, 1455*2a3e3873SBaptiste Daroussin chtype boxchar, chtype borderchar) 1456*2a3e3873SBaptiste Daroussin { 1457*2a3e3873SBaptiste Daroussin dlg_draw_box2(win, y, x, height, width, boxchar, borderchar, boxchar); 14584c8945a0SNathan Whitehorn } 14594c8945a0SNathan Whitehorn 1460682c9e0fSNathan Whitehorn static DIALOG_WINDOWS * 1461682c9e0fSNathan Whitehorn find_window(WINDOW *win) 1462682c9e0fSNathan Whitehorn { 1463682c9e0fSNathan Whitehorn DIALOG_WINDOWS *result = 0; 1464682c9e0fSNathan Whitehorn DIALOG_WINDOWS *p; 1465682c9e0fSNathan Whitehorn 1466682c9e0fSNathan Whitehorn for (p = dialog_state.all_windows; p != 0; p = p->next) { 1467682c9e0fSNathan Whitehorn if (p->normal == win) { 1468682c9e0fSNathan Whitehorn result = p; 1469682c9e0fSNathan Whitehorn break; 1470682c9e0fSNathan Whitehorn } 1471682c9e0fSNathan Whitehorn } 1472682c9e0fSNathan Whitehorn return result; 1473682c9e0fSNathan Whitehorn } 1474682c9e0fSNathan Whitehorn 14754c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 14764c8945a0SNathan Whitehorn /* 1477682c9e0fSNathan Whitehorn * If we have wchgat(), use that for updating shadow attributes, to work with 1478682c9e0fSNathan Whitehorn * wide-character data. 1479682c9e0fSNathan Whitehorn */ 1480682c9e0fSNathan Whitehorn 1481682c9e0fSNathan Whitehorn /* 1482682c9e0fSNathan Whitehorn * Check if the given point is "in" the given window. If so, return the window 1483682c9e0fSNathan Whitehorn * pointer, otherwise null. 1484682c9e0fSNathan Whitehorn */ 1485682c9e0fSNathan Whitehorn static WINDOW * 1486682c9e0fSNathan Whitehorn in_window(WINDOW *win, int y, int x) 1487682c9e0fSNathan Whitehorn { 1488682c9e0fSNathan Whitehorn WINDOW *result = 0; 1489682c9e0fSNathan Whitehorn int y_base = getbegy(win); 1490682c9e0fSNathan Whitehorn int x_base = getbegx(win); 1491682c9e0fSNathan Whitehorn int y_last = getmaxy(win) + y_base; 1492682c9e0fSNathan Whitehorn int x_last = getmaxx(win) + x_base; 1493682c9e0fSNathan Whitehorn 1494682c9e0fSNathan Whitehorn if (y >= y_base && y <= y_last && x >= x_base && x <= x_last) 1495682c9e0fSNathan Whitehorn result = win; 1496682c9e0fSNathan Whitehorn return result; 1497682c9e0fSNathan Whitehorn } 1498682c9e0fSNathan Whitehorn 1499682c9e0fSNathan Whitehorn static WINDOW * 1500682c9e0fSNathan Whitehorn window_at_cell(DIALOG_WINDOWS * dw, int y, int x) 1501682c9e0fSNathan Whitehorn { 1502682c9e0fSNathan Whitehorn WINDOW *result = 0; 1503682c9e0fSNathan Whitehorn DIALOG_WINDOWS *p; 1504682c9e0fSNathan Whitehorn int y_want = y + getbegy(dw->shadow); 1505682c9e0fSNathan Whitehorn int x_want = x + getbegx(dw->shadow); 1506682c9e0fSNathan Whitehorn 1507682c9e0fSNathan Whitehorn for (p = dialog_state.all_windows; p != 0; p = p->next) { 1508682c9e0fSNathan Whitehorn if (dw->normal != p->normal 1509682c9e0fSNathan Whitehorn && dw->shadow != p->normal 1510682c9e0fSNathan Whitehorn && (result = in_window(p->normal, y_want, x_want)) != 0) { 1511682c9e0fSNathan Whitehorn break; 1512682c9e0fSNathan Whitehorn } 1513682c9e0fSNathan Whitehorn } 1514682c9e0fSNathan Whitehorn if (result == 0) { 1515682c9e0fSNathan Whitehorn result = stdscr; 1516682c9e0fSNathan Whitehorn } 1517682c9e0fSNathan Whitehorn return result; 1518682c9e0fSNathan Whitehorn } 1519682c9e0fSNathan Whitehorn 1520682c9e0fSNathan Whitehorn static bool 1521682c9e0fSNathan Whitehorn in_shadow(WINDOW *normal, WINDOW *shadow, int y, int x) 1522682c9e0fSNathan Whitehorn { 1523682c9e0fSNathan Whitehorn bool result = FALSE; 1524682c9e0fSNathan Whitehorn int ybase = getbegy(normal); 1525682c9e0fSNathan Whitehorn int ylast = getmaxy(normal) + ybase; 1526682c9e0fSNathan Whitehorn int xbase = getbegx(normal); 1527682c9e0fSNathan Whitehorn int xlast = getmaxx(normal) + xbase; 1528682c9e0fSNathan Whitehorn 1529682c9e0fSNathan Whitehorn y += getbegy(shadow); 1530682c9e0fSNathan Whitehorn x += getbegx(shadow); 1531682c9e0fSNathan Whitehorn 1532682c9e0fSNathan Whitehorn if (y >= ybase + SHADOW_ROWS 1533682c9e0fSNathan Whitehorn && y < ylast + SHADOW_ROWS 1534682c9e0fSNathan Whitehorn && x >= xlast 1535682c9e0fSNathan Whitehorn && x < xlast + SHADOW_COLS) { 1536682c9e0fSNathan Whitehorn /* in the right-side */ 1537682c9e0fSNathan Whitehorn result = TRUE; 1538682c9e0fSNathan Whitehorn } else if (y >= ylast 1539682c9e0fSNathan Whitehorn && y < ylast + SHADOW_ROWS 1540682c9e0fSNathan Whitehorn && x >= ybase + SHADOW_COLS 1541682c9e0fSNathan Whitehorn && x < ylast + SHADOW_COLS) { 1542682c9e0fSNathan Whitehorn /* check the bottom */ 1543682c9e0fSNathan Whitehorn result = TRUE; 1544682c9e0fSNathan Whitehorn } 1545682c9e0fSNathan Whitehorn 1546682c9e0fSNathan Whitehorn return result; 1547682c9e0fSNathan Whitehorn } 1548682c9e0fSNathan Whitehorn 1549682c9e0fSNathan Whitehorn /* 1550682c9e0fSNathan Whitehorn * When erasing a shadow, check each cell to make sure that it is not part of 1551682c9e0fSNathan Whitehorn * another box's shadow. This is a little complicated since most shadows are 1552682c9e0fSNathan Whitehorn * merged onto stdscr. 1553682c9e0fSNathan Whitehorn */ 1554682c9e0fSNathan Whitehorn static bool 1555682c9e0fSNathan Whitehorn last_shadow(DIALOG_WINDOWS * dw, int y, int x) 1556682c9e0fSNathan Whitehorn { 1557682c9e0fSNathan Whitehorn DIALOG_WINDOWS *p; 1558682c9e0fSNathan Whitehorn bool result = TRUE; 1559682c9e0fSNathan Whitehorn 1560682c9e0fSNathan Whitehorn for (p = dialog_state.all_windows; p != 0; p = p->next) { 1561682c9e0fSNathan Whitehorn if (p->normal != dw->normal 1562682c9e0fSNathan Whitehorn && in_shadow(p->normal, dw->shadow, y, x)) { 1563682c9e0fSNathan Whitehorn result = FALSE; 1564682c9e0fSNathan Whitehorn break; 1565682c9e0fSNathan Whitehorn } 1566682c9e0fSNathan Whitehorn } 1567682c9e0fSNathan Whitehorn return result; 1568682c9e0fSNathan Whitehorn } 1569682c9e0fSNathan Whitehorn 1570682c9e0fSNathan Whitehorn static void 1571682c9e0fSNathan Whitehorn repaint_cell(DIALOG_WINDOWS * dw, bool draw, int y, int x) 1572682c9e0fSNathan Whitehorn { 1573682c9e0fSNathan Whitehorn WINDOW *win = dw->shadow; 1574682c9e0fSNathan Whitehorn WINDOW *cellwin; 1575682c9e0fSNathan Whitehorn int y2, x2; 1576682c9e0fSNathan Whitehorn 1577682c9e0fSNathan Whitehorn if ((cellwin = window_at_cell(dw, y, x)) != 0 1578682c9e0fSNathan Whitehorn && (draw || last_shadow(dw, y, x)) 1579682c9e0fSNathan Whitehorn && (y2 = (y + getbegy(win) - getbegy(cellwin))) >= 0 1580682c9e0fSNathan Whitehorn && (x2 = (x + getbegx(win) - getbegx(cellwin))) >= 0 1581682c9e0fSNathan Whitehorn && wmove(cellwin, y2, x2) != ERR) { 1582682c9e0fSNathan Whitehorn chtype the_cell = dlg_get_attrs(cellwin); 1583682c9e0fSNathan Whitehorn chtype the_attr = (draw ? shadow_attr : the_cell); 1584682c9e0fSNathan Whitehorn 1585682c9e0fSNathan Whitehorn if (dlg_get_cell_attrs(cellwin) & A_ALTCHARSET) { 1586682c9e0fSNathan Whitehorn the_attr |= A_ALTCHARSET; 1587682c9e0fSNathan Whitehorn } 1588682c9e0fSNathan Whitehorn #if USE_WCHGAT 1589682c9e0fSNathan Whitehorn wchgat(cellwin, 1, 1590682c9e0fSNathan Whitehorn the_attr & (chtype) (~A_COLOR), 1591*2a3e3873SBaptiste Daroussin (short) PAIR_NUMBER(the_attr), 1592682c9e0fSNathan Whitehorn NULL); 1593682c9e0fSNathan Whitehorn #else 1594682c9e0fSNathan Whitehorn { 1595682c9e0fSNathan Whitehorn chtype the_char = ((winch(cellwin) & A_CHARTEXT) | the_attr); 1596682c9e0fSNathan Whitehorn (void) waddch(cellwin, the_char); 1597682c9e0fSNathan Whitehorn } 1598682c9e0fSNathan Whitehorn #endif 1599682c9e0fSNathan Whitehorn wnoutrefresh(cellwin); 1600682c9e0fSNathan Whitehorn } 1601682c9e0fSNathan Whitehorn } 1602682c9e0fSNathan Whitehorn 1603682c9e0fSNathan Whitehorn #define RepaintCell(dw, draw, y, x) repaint_cell(dw, draw, y, x) 1604682c9e0fSNathan Whitehorn 1605682c9e0fSNathan Whitehorn static void 1606682c9e0fSNathan Whitehorn repaint_shadow(DIALOG_WINDOWS * dw, bool draw, int y, int x, int height, int width) 1607682c9e0fSNathan Whitehorn { 1608682c9e0fSNathan Whitehorn int i, j; 1609682c9e0fSNathan Whitehorn 1610682c9e0fSNathan Whitehorn if (UseShadow(dw)) { 1611682c9e0fSNathan Whitehorn #if !USE_WCHGAT 1612682c9e0fSNathan Whitehorn chtype save = dlg_get_attrs(dw->shadow); 1613*2a3e3873SBaptiste Daroussin (void) wattrset(dw->shadow, draw ? shadow_attr : screen_attr); 1614682c9e0fSNathan Whitehorn #endif 1615682c9e0fSNathan Whitehorn for (i = 0; i < SHADOW_ROWS; ++i) { 1616682c9e0fSNathan Whitehorn for (j = 0; j < width; ++j) { 1617682c9e0fSNathan Whitehorn RepaintCell(dw, draw, i + y + height, j + x + SHADOW_COLS); 1618682c9e0fSNathan Whitehorn } 1619682c9e0fSNathan Whitehorn } 1620682c9e0fSNathan Whitehorn for (i = 0; i < height; i++) { 1621682c9e0fSNathan Whitehorn for (j = 0; j < SHADOW_COLS; ++j) { 1622682c9e0fSNathan Whitehorn RepaintCell(dw, draw, i + y + SHADOW_ROWS, j + x + width); 1623682c9e0fSNathan Whitehorn } 1624682c9e0fSNathan Whitehorn } 1625682c9e0fSNathan Whitehorn (void) wnoutrefresh(dw->shadow); 1626682c9e0fSNathan Whitehorn #if !USE_WCHGAT 1627*2a3e3873SBaptiste Daroussin (void) wattrset(dw->shadow, save); 1628682c9e0fSNathan Whitehorn #endif 1629682c9e0fSNathan Whitehorn } 1630682c9e0fSNathan Whitehorn } 1631682c9e0fSNathan Whitehorn 1632682c9e0fSNathan Whitehorn /* 16334c8945a0SNathan Whitehorn * Draw a shadow on the parent window corresponding to the right- and 16344c8945a0SNathan Whitehorn * bottom-edge of the child window, to give a 3-dimensional look. 16354c8945a0SNathan Whitehorn */ 16364c8945a0SNathan Whitehorn static void 1637682c9e0fSNathan Whitehorn draw_childs_shadow(DIALOG_WINDOWS * dw) 16384c8945a0SNathan Whitehorn { 1639682c9e0fSNathan Whitehorn if (UseShadow(dw)) { 1640682c9e0fSNathan Whitehorn repaint_shadow(dw, 1641682c9e0fSNathan Whitehorn TRUE, 1642682c9e0fSNathan Whitehorn getbegy(dw->normal) - getbegy(dw->shadow), 1643682c9e0fSNathan Whitehorn getbegx(dw->normal) - getbegx(dw->shadow), 1644682c9e0fSNathan Whitehorn getmaxy(dw->normal), 1645682c9e0fSNathan Whitehorn getmaxx(dw->normal)); 1646682c9e0fSNathan Whitehorn } 1647682c9e0fSNathan Whitehorn } 16484c8945a0SNathan Whitehorn 1649682c9e0fSNathan Whitehorn /* 1650682c9e0fSNathan Whitehorn * Erase a shadow on the parent window corresponding to the right- and 1651682c9e0fSNathan Whitehorn * bottom-edge of the child window. 1652682c9e0fSNathan Whitehorn */ 1653682c9e0fSNathan Whitehorn static void 1654682c9e0fSNathan Whitehorn erase_childs_shadow(DIALOG_WINDOWS * dw) 1655682c9e0fSNathan Whitehorn { 1656682c9e0fSNathan Whitehorn if (UseShadow(dw)) { 1657682c9e0fSNathan Whitehorn repaint_shadow(dw, 1658682c9e0fSNathan Whitehorn FALSE, 1659682c9e0fSNathan Whitehorn getbegy(dw->normal) - getbegy(dw->shadow), 1660682c9e0fSNathan Whitehorn getbegx(dw->normal) - getbegx(dw->shadow), 1661682c9e0fSNathan Whitehorn getmaxy(dw->normal), 1662682c9e0fSNathan Whitehorn getmaxx(dw->normal)); 16634c8945a0SNathan Whitehorn } 16644c8945a0SNathan Whitehorn } 16654c8945a0SNathan Whitehorn 16664c8945a0SNathan Whitehorn /* 16674c8945a0SNathan Whitehorn * Draw shadows along the right and bottom edge to give a more 3D look 1668682c9e0fSNathan Whitehorn * to the boxes. 16694c8945a0SNathan Whitehorn */ 16704c8945a0SNathan Whitehorn void 16714c8945a0SNathan Whitehorn dlg_draw_shadow(WINDOW *win, int y, int x, int height, int width) 16724c8945a0SNathan Whitehorn { 1673682c9e0fSNathan Whitehorn repaint_shadow(find_window(win), TRUE, y, x, height, width); 16744c8945a0SNathan Whitehorn } 16754c8945a0SNathan Whitehorn #endif /* HAVE_COLOR */ 16764c8945a0SNathan Whitehorn 16774c8945a0SNathan Whitehorn /* 16784c8945a0SNathan Whitehorn * Allow shell scripts to remap the exit codes so they can distinguish ESC 16794c8945a0SNathan Whitehorn * from ERROR. 16804c8945a0SNathan Whitehorn */ 16814c8945a0SNathan Whitehorn void 16824c8945a0SNathan Whitehorn dlg_exit(int code) 16834c8945a0SNathan Whitehorn { 16844c8945a0SNathan Whitehorn /* *INDENT-OFF* */ 16854c8945a0SNathan Whitehorn static const struct { 16864c8945a0SNathan Whitehorn int code; 16874c8945a0SNathan Whitehorn const char *name; 16884c8945a0SNathan Whitehorn } table[] = { 16894c8945a0SNathan Whitehorn { DLG_EXIT_CANCEL, "DIALOG_CANCEL" }, 16904c8945a0SNathan Whitehorn { DLG_EXIT_ERROR, "DIALOG_ERROR" }, 16914c8945a0SNathan Whitehorn { DLG_EXIT_ESC, "DIALOG_ESC" }, 16924c8945a0SNathan Whitehorn { DLG_EXIT_EXTRA, "DIALOG_EXTRA" }, 16934c8945a0SNathan Whitehorn { DLG_EXIT_HELP, "DIALOG_HELP" }, 16944c8945a0SNathan Whitehorn { DLG_EXIT_OK, "DIALOG_OK" }, 16954c8945a0SNathan Whitehorn { DLG_EXIT_ITEM_HELP, "DIALOG_ITEM_HELP" }, 16964c8945a0SNathan Whitehorn }; 16974c8945a0SNathan Whitehorn /* *INDENT-ON* */ 16984c8945a0SNathan Whitehorn 16994c8945a0SNathan Whitehorn unsigned n; 17004c8945a0SNathan Whitehorn char *name; 17014c8945a0SNathan Whitehorn char *temp; 17024c8945a0SNathan Whitehorn long value; 17034c8945a0SNathan Whitehorn bool overridden = FALSE; 17044c8945a0SNathan Whitehorn 17054c8945a0SNathan Whitehorn retry: 17064c8945a0SNathan Whitehorn for (n = 0; n < sizeof(table) / sizeof(table[0]); n++) { 17074c8945a0SNathan Whitehorn if (table[n].code == code) { 17084c8945a0SNathan Whitehorn if ((name = getenv(table[n].name)) != 0) { 17094c8945a0SNathan Whitehorn value = strtol(name, &temp, 0); 17104c8945a0SNathan Whitehorn if (temp != 0 && temp != name && *temp == '\0') { 17117a1c0d96SNathan Whitehorn code = (int) value; 17124c8945a0SNathan Whitehorn overridden = TRUE; 17134c8945a0SNathan Whitehorn } 17144c8945a0SNathan Whitehorn } 17154c8945a0SNathan Whitehorn break; 17164c8945a0SNathan Whitehorn } 17174c8945a0SNathan Whitehorn } 17184c8945a0SNathan Whitehorn 17194c8945a0SNathan Whitehorn /* 17204c8945a0SNathan Whitehorn * Prior to 2004/12/19, a widget using --item-help would exit with "OK" 17214c8945a0SNathan Whitehorn * if the help button were selected. Now we want to exit with "HELP", 17224c8945a0SNathan Whitehorn * but allow the environment variable to override. 17234c8945a0SNathan Whitehorn */ 17244c8945a0SNathan Whitehorn if (code == DLG_EXIT_ITEM_HELP && !overridden) { 17254c8945a0SNathan Whitehorn code = DLG_EXIT_HELP; 17264c8945a0SNathan Whitehorn goto retry; 17274c8945a0SNathan Whitehorn } 1728682c9e0fSNathan Whitehorn #ifdef HAVE_DLG_TRACE 1729682c9e0fSNathan Whitehorn dlg_trace((const char *) 0); /* close it */ 1730682c9e0fSNathan Whitehorn #endif 1731682c9e0fSNathan Whitehorn 17324c8945a0SNathan Whitehorn #ifdef NO_LEAKS 17334c8945a0SNathan Whitehorn _dlg_inputstr_leaks(); 17344c8945a0SNathan Whitehorn #if defined(NCURSES_VERSION) && defined(HAVE__NC_FREE_AND_EXIT) 17354c8945a0SNathan Whitehorn _nc_free_and_exit(code); 17364c8945a0SNathan Whitehorn #endif 17374c8945a0SNathan Whitehorn #endif 17384c8945a0SNathan Whitehorn 17394c8945a0SNathan Whitehorn if (dialog_state.input == stdin) { 17404c8945a0SNathan Whitehorn exit(code); 17414c8945a0SNathan Whitehorn } else { 17424c8945a0SNathan Whitehorn /* 17434c8945a0SNathan Whitehorn * Just in case of using --input-fd option, do not 17444c8945a0SNathan Whitehorn * call atexit functions of ncurses which may hang. 17454c8945a0SNathan Whitehorn */ 17464c8945a0SNathan Whitehorn if (dialog_state.input) { 17474c8945a0SNathan Whitehorn fclose(dialog_state.input); 17484c8945a0SNathan Whitehorn dialog_state.input = 0; 17494c8945a0SNathan Whitehorn } 17504c8945a0SNathan Whitehorn if (dialog_state.pipe_input) { 17514c8945a0SNathan Whitehorn if (dialog_state.pipe_input != stdin) { 17524c8945a0SNathan Whitehorn fclose(dialog_state.pipe_input); 17534c8945a0SNathan Whitehorn dialog_state.pipe_input = 0; 17544c8945a0SNathan Whitehorn } 17554c8945a0SNathan Whitehorn } 17564c8945a0SNathan Whitehorn _exit(code); 17574c8945a0SNathan Whitehorn } 17584c8945a0SNathan Whitehorn } 17594c8945a0SNathan Whitehorn 17604c8945a0SNathan Whitehorn /* quit program killing all tailbg */ 17614c8945a0SNathan Whitehorn void 17624c8945a0SNathan Whitehorn dlg_exiterr(const char *fmt,...) 17634c8945a0SNathan Whitehorn { 17644c8945a0SNathan Whitehorn int retval; 17654c8945a0SNathan Whitehorn va_list ap; 17664c8945a0SNathan Whitehorn 17674c8945a0SNathan Whitehorn end_dialog(); 17684c8945a0SNathan Whitehorn 17694c8945a0SNathan Whitehorn (void) fputc('\n', stderr); 17704c8945a0SNathan Whitehorn va_start(ap, fmt); 17714c8945a0SNathan Whitehorn (void) vfprintf(stderr, fmt, ap); 17724c8945a0SNathan Whitehorn va_end(ap); 17734c8945a0SNathan Whitehorn (void) fputc('\n', stderr); 17744c8945a0SNathan Whitehorn 17754c8945a0SNathan Whitehorn dlg_killall_bg(&retval); 17764c8945a0SNathan Whitehorn 17774c8945a0SNathan Whitehorn (void) fflush(stderr); 17784c8945a0SNathan Whitehorn (void) fflush(stdout); 17794c8945a0SNathan Whitehorn dlg_exit(DLG_EXIT_ERROR); 17804c8945a0SNathan Whitehorn } 17814c8945a0SNathan Whitehorn 17824c8945a0SNathan Whitehorn void 17834c8945a0SNathan Whitehorn dlg_beeping(void) 17844c8945a0SNathan Whitehorn { 17854c8945a0SNathan Whitehorn if (dialog_vars.beep_signal) { 17864c8945a0SNathan Whitehorn (void) beep(); 17874c8945a0SNathan Whitehorn dialog_vars.beep_signal = 0; 17884c8945a0SNathan Whitehorn } 17894c8945a0SNathan Whitehorn } 17904c8945a0SNathan Whitehorn 17914c8945a0SNathan Whitehorn void 17924c8945a0SNathan Whitehorn dlg_print_size(int height, int width) 17934c8945a0SNathan Whitehorn { 17944c8945a0SNathan Whitehorn if (dialog_vars.print_siz) 17954c8945a0SNathan Whitehorn fprintf(dialog_state.output, "Size: %d, %d\n", height, width); 17964c8945a0SNathan Whitehorn } 17974c8945a0SNathan Whitehorn 17984c8945a0SNathan Whitehorn void 17994c8945a0SNathan Whitehorn dlg_ctl_size(int height, int width) 18004c8945a0SNathan Whitehorn { 18014c8945a0SNathan Whitehorn if (dialog_vars.size_err) { 18024c8945a0SNathan Whitehorn if ((width > COLS) || (height > LINES)) { 18034c8945a0SNathan Whitehorn dlg_exiterr("Window too big. (height, width) = (%d, %d). Max allowed (%d, %d).", 18044c8945a0SNathan Whitehorn height, width, LINES, COLS); 18054c8945a0SNathan Whitehorn } 18064c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 18074c8945a0SNathan Whitehorn else if ((dialog_state.use_shadow) 18084c8945a0SNathan Whitehorn && ((width > SCOLS || height > SLINES))) { 18094c8945a0SNathan Whitehorn if ((width <= COLS) && (height <= LINES)) { 18104c8945a0SNathan Whitehorn /* try again, without shadows */ 18114c8945a0SNathan Whitehorn dialog_state.use_shadow = 0; 18124c8945a0SNathan Whitehorn } else { 18134c8945a0SNathan Whitehorn dlg_exiterr("Window+Shadow too big. (height, width) = (%d, %d). Max allowed (%d, %d).", 18144c8945a0SNathan Whitehorn height, width, SLINES, SCOLS); 18154c8945a0SNathan Whitehorn } 18164c8945a0SNathan Whitehorn } 18174c8945a0SNathan Whitehorn #endif 18184c8945a0SNathan Whitehorn } 18194c8945a0SNathan Whitehorn } 18204c8945a0SNathan Whitehorn 18214c8945a0SNathan Whitehorn /* 18224c8945a0SNathan Whitehorn * If the --tab-correct was not selected, convert tabs to single spaces. 18234c8945a0SNathan Whitehorn */ 18244c8945a0SNathan Whitehorn void 18254c8945a0SNathan Whitehorn dlg_tab_correct_str(char *prompt) 18264c8945a0SNathan Whitehorn { 18274c8945a0SNathan Whitehorn char *ptr; 18284c8945a0SNathan Whitehorn 18294c8945a0SNathan Whitehorn if (dialog_vars.tab_correct) { 18304c8945a0SNathan Whitehorn while ((ptr = strchr(prompt, TAB)) != NULL) { 18314c8945a0SNathan Whitehorn *ptr = ' '; 18324c8945a0SNathan Whitehorn prompt = ptr; 18334c8945a0SNathan Whitehorn } 18344c8945a0SNathan Whitehorn } 18354c8945a0SNathan Whitehorn } 18364c8945a0SNathan Whitehorn 18374c8945a0SNathan Whitehorn void 18384c8945a0SNathan Whitehorn dlg_calc_listh(int *height, int *list_height, int item_no) 18394c8945a0SNathan Whitehorn { 18404c8945a0SNathan Whitehorn /* calculate new height and list_height */ 18414c8945a0SNathan Whitehorn int rows = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0); 18424c8945a0SNathan Whitehorn if (rows - (*height) > 0) { 18434c8945a0SNathan Whitehorn if (rows - (*height) > item_no) 18444c8945a0SNathan Whitehorn *list_height = item_no; 18454c8945a0SNathan Whitehorn else 18464c8945a0SNathan Whitehorn *list_height = rows - (*height); 18474c8945a0SNathan Whitehorn } 18484c8945a0SNathan Whitehorn (*height) += (*list_height); 18494c8945a0SNathan Whitehorn } 18504c8945a0SNathan Whitehorn 18514c8945a0SNathan Whitehorn /* obsolete */ 18524c8945a0SNathan Whitehorn int 18534c8945a0SNathan Whitehorn dlg_calc_listw(int item_no, char **items, int group) 18544c8945a0SNathan Whitehorn { 18554c8945a0SNathan Whitehorn int n, i, len1 = 0, len2 = 0; 18564c8945a0SNathan Whitehorn for (i = 0; i < (item_no * group); i += group) { 18574c8945a0SNathan Whitehorn if ((n = dlg_count_columns(items[i])) > len1) 18584c8945a0SNathan Whitehorn len1 = n; 18594c8945a0SNathan Whitehorn if ((n = dlg_count_columns(items[i + 1])) > len2) 18604c8945a0SNathan Whitehorn len2 = n; 18614c8945a0SNathan Whitehorn } 18624c8945a0SNathan Whitehorn return len1 + len2; 18634c8945a0SNathan Whitehorn } 18644c8945a0SNathan Whitehorn 18654c8945a0SNathan Whitehorn int 18664c8945a0SNathan Whitehorn dlg_calc_list_width(int item_no, DIALOG_LISTITEM * items) 18674c8945a0SNathan Whitehorn { 18684c8945a0SNathan Whitehorn int n, i, len1 = 0, len2 = 0; 1869*2a3e3873SBaptiste Daroussin int bits = ((dialog_vars.no_tags ? 1 : 0) 1870*2a3e3873SBaptiste Daroussin + (dialog_vars.no_items ? 2 : 0)); 1871*2a3e3873SBaptiste Daroussin 18724c8945a0SNathan Whitehorn for (i = 0; i < item_no; ++i) { 1873*2a3e3873SBaptiste Daroussin switch (bits) { 1874*2a3e3873SBaptiste Daroussin case 0: 1875*2a3e3873SBaptiste Daroussin /* FALLTHRU */ 1876*2a3e3873SBaptiste Daroussin case 1: 18774c8945a0SNathan Whitehorn if ((n = dlg_count_columns(items[i].name)) > len1) 18784c8945a0SNathan Whitehorn len1 = n; 18794c8945a0SNathan Whitehorn if ((n = dlg_count_columns(items[i].text)) > len2) 18804c8945a0SNathan Whitehorn len2 = n; 1881*2a3e3873SBaptiste Daroussin break; 1882*2a3e3873SBaptiste Daroussin case 2: 1883*2a3e3873SBaptiste Daroussin /* FALLTHRU */ 1884*2a3e3873SBaptiste Daroussin case 3: 1885*2a3e3873SBaptiste Daroussin if ((n = dlg_count_columns(items[i].name)) > len1) 1886*2a3e3873SBaptiste Daroussin len1 = n; 1887*2a3e3873SBaptiste Daroussin break; 1888*2a3e3873SBaptiste Daroussin } 18894c8945a0SNathan Whitehorn } 18904c8945a0SNathan Whitehorn return len1 + len2; 18914c8945a0SNathan Whitehorn } 18924c8945a0SNathan Whitehorn 18934c8945a0SNathan Whitehorn char * 18944c8945a0SNathan Whitehorn dlg_strempty(void) 18954c8945a0SNathan Whitehorn { 18964c8945a0SNathan Whitehorn static char empty[] = ""; 18974c8945a0SNathan Whitehorn return empty; 18984c8945a0SNathan Whitehorn } 18994c8945a0SNathan Whitehorn 19004c8945a0SNathan Whitehorn char * 19014c8945a0SNathan Whitehorn dlg_strclone(const char *cprompt) 19024c8945a0SNathan Whitehorn { 19034c8945a0SNathan Whitehorn char *prompt = dlg_malloc(char, strlen(cprompt) + 1); 19044c8945a0SNathan Whitehorn assert_ptr(prompt, "dlg_strclone"); 19054c8945a0SNathan Whitehorn strcpy(prompt, cprompt); 19064c8945a0SNathan Whitehorn return prompt; 19074c8945a0SNathan Whitehorn } 19084c8945a0SNathan Whitehorn 19094c8945a0SNathan Whitehorn chtype 19104c8945a0SNathan Whitehorn dlg_asciibox(chtype ch) 19114c8945a0SNathan Whitehorn { 19124c8945a0SNathan Whitehorn chtype result = 0; 19134c8945a0SNathan Whitehorn 19144c8945a0SNathan Whitehorn if (ch == ACS_ULCORNER) 19154c8945a0SNathan Whitehorn result = '+'; 19164c8945a0SNathan Whitehorn else if (ch == ACS_LLCORNER) 19174c8945a0SNathan Whitehorn result = '+'; 19184c8945a0SNathan Whitehorn else if (ch == ACS_URCORNER) 19194c8945a0SNathan Whitehorn result = '+'; 19204c8945a0SNathan Whitehorn else if (ch == ACS_LRCORNER) 19214c8945a0SNathan Whitehorn result = '+'; 19224c8945a0SNathan Whitehorn else if (ch == ACS_HLINE) 19234c8945a0SNathan Whitehorn result = '-'; 19244c8945a0SNathan Whitehorn else if (ch == ACS_VLINE) 19254c8945a0SNathan Whitehorn result = '|'; 19264c8945a0SNathan Whitehorn else if (ch == ACS_LTEE) 19274c8945a0SNathan Whitehorn result = '+'; 19284c8945a0SNathan Whitehorn else if (ch == ACS_RTEE) 19294c8945a0SNathan Whitehorn result = '+'; 19304c8945a0SNathan Whitehorn else if (ch == ACS_UARROW) 19314c8945a0SNathan Whitehorn result = '^'; 19324c8945a0SNathan Whitehorn else if (ch == ACS_DARROW) 19334c8945a0SNathan Whitehorn result = 'v'; 19344c8945a0SNathan Whitehorn 19354c8945a0SNathan Whitehorn return result; 19364c8945a0SNathan Whitehorn } 19374c8945a0SNathan Whitehorn 19384c8945a0SNathan Whitehorn chtype 19394c8945a0SNathan Whitehorn dlg_boxchar(chtype ch) 19404c8945a0SNathan Whitehorn { 19414c8945a0SNathan Whitehorn chtype result = dlg_asciibox(ch); 19424c8945a0SNathan Whitehorn 19434c8945a0SNathan Whitehorn if (result != 0) { 19444c8945a0SNathan Whitehorn if (dialog_vars.ascii_lines) 19454c8945a0SNathan Whitehorn ch = result; 19464c8945a0SNathan Whitehorn else if (dialog_vars.no_lines) 19474c8945a0SNathan Whitehorn ch = ' '; 19484c8945a0SNathan Whitehorn } 19494c8945a0SNathan Whitehorn return ch; 19504c8945a0SNathan Whitehorn } 19514c8945a0SNathan Whitehorn 19524c8945a0SNathan Whitehorn int 19534c8945a0SNathan Whitehorn dlg_box_x_ordinate(int width) 19544c8945a0SNathan Whitehorn { 19554c8945a0SNathan Whitehorn int x; 19564c8945a0SNathan Whitehorn 19574c8945a0SNathan Whitehorn if (dialog_vars.begin_set == 1) { 19584c8945a0SNathan Whitehorn x = dialog_vars.begin_x; 19594c8945a0SNathan Whitehorn } else { 19604c8945a0SNathan Whitehorn /* center dialog box on screen unless --begin-set */ 19614c8945a0SNathan Whitehorn x = (SCOLS - width) / 2; 19624c8945a0SNathan Whitehorn } 19634c8945a0SNathan Whitehorn return x; 19644c8945a0SNathan Whitehorn } 19654c8945a0SNathan Whitehorn 19664c8945a0SNathan Whitehorn int 19674c8945a0SNathan Whitehorn dlg_box_y_ordinate(int height) 19684c8945a0SNathan Whitehorn { 19694c8945a0SNathan Whitehorn int y; 19704c8945a0SNathan Whitehorn 19714c8945a0SNathan Whitehorn if (dialog_vars.begin_set == 1) { 19724c8945a0SNathan Whitehorn y = dialog_vars.begin_y; 19734c8945a0SNathan Whitehorn } else { 19744c8945a0SNathan Whitehorn /* center dialog box on screen unless --begin-set */ 19754c8945a0SNathan Whitehorn y = (SLINES - height) / 2; 19764c8945a0SNathan Whitehorn } 19774c8945a0SNathan Whitehorn return y; 19784c8945a0SNathan Whitehorn } 19794c8945a0SNathan Whitehorn 19804c8945a0SNathan Whitehorn void 19814c8945a0SNathan Whitehorn dlg_draw_title(WINDOW *win, const char *title) 19824c8945a0SNathan Whitehorn { 19834c8945a0SNathan Whitehorn if (title != NULL) { 19844c8945a0SNathan Whitehorn chtype attr = A_NORMAL; 19857a1c0d96SNathan Whitehorn chtype save = dlg_get_attrs(win); 19864c8945a0SNathan Whitehorn int x = centered(getmaxx(win), title); 19874c8945a0SNathan Whitehorn 1988*2a3e3873SBaptiste Daroussin (void) wattrset(win, title_attr); 19894c8945a0SNathan Whitehorn wmove(win, 0, x); 19904c8945a0SNathan Whitehorn dlg_print_text(win, title, getmaxx(win) - x, &attr); 1991*2a3e3873SBaptiste Daroussin (void) wattrset(win, save); 19924c8945a0SNathan Whitehorn } 19934c8945a0SNathan Whitehorn } 19944c8945a0SNathan Whitehorn 19954c8945a0SNathan Whitehorn void 1996*2a3e3873SBaptiste Daroussin dlg_draw_bottom_box2(WINDOW *win, chtype on_left, chtype on_right, chtype on_inside) 19974c8945a0SNathan Whitehorn { 19984c8945a0SNathan Whitehorn int width = getmaxx(win); 19994c8945a0SNathan Whitehorn int height = getmaxy(win); 20004c8945a0SNathan Whitehorn int i; 20014c8945a0SNathan Whitehorn 2002*2a3e3873SBaptiste Daroussin (void) wattrset(win, on_left); 20034c8945a0SNathan Whitehorn (void) wmove(win, height - 3, 0); 20044c8945a0SNathan Whitehorn (void) waddch(win, dlg_boxchar(ACS_LTEE)); 20054c8945a0SNathan Whitehorn for (i = 0; i < width - 2; i++) 20064c8945a0SNathan Whitehorn (void) waddch(win, dlg_boxchar(ACS_HLINE)); 2007*2a3e3873SBaptiste Daroussin (void) wattrset(win, on_right); 20084c8945a0SNathan Whitehorn (void) waddch(win, dlg_boxchar(ACS_RTEE)); 2009*2a3e3873SBaptiste Daroussin (void) wattrset(win, on_inside); 20104c8945a0SNathan Whitehorn (void) wmove(win, height - 2, 1); 20114c8945a0SNathan Whitehorn for (i = 0; i < width - 2; i++) 20124c8945a0SNathan Whitehorn (void) waddch(win, ' '); 20134c8945a0SNathan Whitehorn } 20144c8945a0SNathan Whitehorn 2015*2a3e3873SBaptiste Daroussin void 2016*2a3e3873SBaptiste Daroussin dlg_draw_bottom_box(WINDOW *win) 2017*2a3e3873SBaptiste Daroussin { 2018*2a3e3873SBaptiste Daroussin dlg_draw_bottom_box2(win, border_attr, dialog_attr, dialog_attr); 2019*2a3e3873SBaptiste Daroussin } 2020*2a3e3873SBaptiste Daroussin 20214c8945a0SNathan Whitehorn /* 20224c8945a0SNathan Whitehorn * Remove a window, repainting everything else. This would be simpler if we 20234c8945a0SNathan Whitehorn * used the panel library, but that is not _always_ available. 20244c8945a0SNathan Whitehorn */ 20254c8945a0SNathan Whitehorn void 20264c8945a0SNathan Whitehorn dlg_del_window(WINDOW *win) 20274c8945a0SNathan Whitehorn { 20284c8945a0SNathan Whitehorn DIALOG_WINDOWS *p, *q, *r; 20294c8945a0SNathan Whitehorn 20304c8945a0SNathan Whitehorn /* 20314c8945a0SNathan Whitehorn * If --keep-window was set, do not delete/repaint the windows. 20324c8945a0SNathan Whitehorn */ 20334c8945a0SNathan Whitehorn if (dialog_vars.keep_window) 20344c8945a0SNathan Whitehorn return; 20354c8945a0SNathan Whitehorn 20364c8945a0SNathan Whitehorn /* Leave the main window untouched if there are no background windows. 20374c8945a0SNathan Whitehorn * We do this so the current window will not be cleared on exit, allowing 20384c8945a0SNathan Whitehorn * things like the infobox demo to run without flicker. 20394c8945a0SNathan Whitehorn */ 20404c8945a0SNathan Whitehorn if (dialog_state.getc_callbacks != 0) { 20414c8945a0SNathan Whitehorn touchwin(stdscr); 20424c8945a0SNathan Whitehorn wnoutrefresh(stdscr); 20434c8945a0SNathan Whitehorn } 20444c8945a0SNathan Whitehorn 20454c8945a0SNathan Whitehorn for (p = dialog_state.all_windows, q = r = 0; p != 0; r = p, p = p->next) { 20464c8945a0SNathan Whitehorn if (p->normal == win) { 20474c8945a0SNathan Whitehorn q = p; /* found a match - should be only one */ 20484c8945a0SNathan Whitehorn if (r == 0) { 20494c8945a0SNathan Whitehorn dialog_state.all_windows = p->next; 20504c8945a0SNathan Whitehorn } else { 20514c8945a0SNathan Whitehorn r->next = p->next; 20524c8945a0SNathan Whitehorn } 20534c8945a0SNathan Whitehorn } else { 20544c8945a0SNathan Whitehorn if (p->shadow != 0) { 20554c8945a0SNathan Whitehorn touchwin(p->shadow); 20564c8945a0SNathan Whitehorn wnoutrefresh(p->shadow); 20574c8945a0SNathan Whitehorn } 20584c8945a0SNathan Whitehorn touchwin(p->normal); 20594c8945a0SNathan Whitehorn wnoutrefresh(p->normal); 20604c8945a0SNathan Whitehorn } 20614c8945a0SNathan Whitehorn } 20624c8945a0SNathan Whitehorn 20634c8945a0SNathan Whitehorn if (q) { 2064682c9e0fSNathan Whitehorn if (dialog_state.all_windows != 0) 2065682c9e0fSNathan Whitehorn erase_childs_shadow(q); 2066*2a3e3873SBaptiste Daroussin del_subwindows(q->normal); 20674c8945a0SNathan Whitehorn dlg_unregister_window(q->normal); 2068*2a3e3873SBaptiste Daroussin delwin(q->normal); 20694c8945a0SNathan Whitehorn free(q); 20704c8945a0SNathan Whitehorn } 20714c8945a0SNathan Whitehorn doupdate(); 20724c8945a0SNathan Whitehorn } 20734c8945a0SNathan Whitehorn 20744c8945a0SNathan Whitehorn /* 20754c8945a0SNathan Whitehorn * Create a window, optionally with a shadow. 20764c8945a0SNathan Whitehorn */ 20774c8945a0SNathan Whitehorn WINDOW * 20784c8945a0SNathan Whitehorn dlg_new_window(int height, int width, int y, int x) 20794c8945a0SNathan Whitehorn { 2080682c9e0fSNathan Whitehorn return dlg_new_modal_window(stdscr, height, width, y, x); 20814c8945a0SNathan Whitehorn } 20824c8945a0SNathan Whitehorn 2083682c9e0fSNathan Whitehorn /* 2084682c9e0fSNathan Whitehorn * "Modal" windows differ from normal ones by having a shadow in a window 2085682c9e0fSNathan Whitehorn * separate from the standard screen. 2086682c9e0fSNathan Whitehorn */ 20874c8945a0SNathan Whitehorn WINDOW * 20884c8945a0SNathan Whitehorn dlg_new_modal_window(WINDOW *parent, int height, int width, int y, int x) 20894c8945a0SNathan Whitehorn { 20904c8945a0SNathan Whitehorn WINDOW *win; 20914c8945a0SNathan Whitehorn DIALOG_WINDOWS *p = dlg_calloc(DIALOG_WINDOWS, 1); 20924c8945a0SNathan Whitehorn 20934c8945a0SNathan Whitehorn (void) parent; 2094*2a3e3873SBaptiste Daroussin if (p == 0 2095*2a3e3873SBaptiste Daroussin || (win = newwin(height, width, y, x)) == 0) { 20964c8945a0SNathan Whitehorn dlg_exiterr("Can't make new window at (%d,%d), size (%d,%d).\n", 20974c8945a0SNathan Whitehorn y, x, height, width); 20984c8945a0SNathan Whitehorn } 20994c8945a0SNathan Whitehorn p->next = dialog_state.all_windows; 21004c8945a0SNathan Whitehorn p->normal = win; 21014c8945a0SNathan Whitehorn dialog_state.all_windows = p; 21024c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 21034c8945a0SNathan Whitehorn if (dialog_state.use_shadow) { 2104682c9e0fSNathan Whitehorn p->shadow = parent; 2105682c9e0fSNathan Whitehorn draw_childs_shadow(p); 21064c8945a0SNathan Whitehorn } 21074c8945a0SNathan Whitehorn #endif 21084c8945a0SNathan Whitehorn 21094c8945a0SNathan Whitehorn (void) keypad(win, TRUE); 21104c8945a0SNathan Whitehorn return win; 21114c8945a0SNathan Whitehorn } 21124c8945a0SNathan Whitehorn 21134c8945a0SNathan Whitehorn /* 21144c8945a0SNathan Whitehorn * Move/Resize a window, optionally with a shadow. 21154c8945a0SNathan Whitehorn */ 21164c8945a0SNathan Whitehorn #ifdef KEY_RESIZE 21174c8945a0SNathan Whitehorn void 21184c8945a0SNathan Whitehorn dlg_move_window(WINDOW *win, int height, int width, int y, int x) 21194c8945a0SNathan Whitehorn { 2120682c9e0fSNathan Whitehorn DIALOG_WINDOWS *p; 21214c8945a0SNathan Whitehorn 21224c8945a0SNathan Whitehorn if (win != 0) { 21234c8945a0SNathan Whitehorn dlg_ctl_size(height, width); 21244c8945a0SNathan Whitehorn 2125682c9e0fSNathan Whitehorn if ((p = find_window(win)) != 0) { 21264c8945a0SNathan Whitehorn (void) wresize(win, height, width); 21274c8945a0SNathan Whitehorn (void) mvwin(win, y, x); 21284c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 21294c8945a0SNathan Whitehorn if (p->shadow != 0) { 21304c8945a0SNathan Whitehorn if (dialog_state.use_shadow) { 21314c8945a0SNathan Whitehorn (void) mvwin(p->shadow, y + SHADOW_ROWS, x + SHADOW_COLS); 21324c8945a0SNathan Whitehorn } else { 21334c8945a0SNathan Whitehorn p->shadow = 0; 21344c8945a0SNathan Whitehorn } 21354c8945a0SNathan Whitehorn } 21364c8945a0SNathan Whitehorn #endif 21374c8945a0SNathan Whitehorn (void) refresh(); 21384c8945a0SNathan Whitehorn 21394c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 2140682c9e0fSNathan Whitehorn draw_childs_shadow(p); 21414c8945a0SNathan Whitehorn #endif 21424c8945a0SNathan Whitehorn } 21434c8945a0SNathan Whitehorn } 21444c8945a0SNathan Whitehorn } 21454c8945a0SNathan Whitehorn #endif /* KEY_RESIZE */ 21464c8945a0SNathan Whitehorn 21474c8945a0SNathan Whitehorn WINDOW * 21484c8945a0SNathan Whitehorn dlg_sub_window(WINDOW *parent, int height, int width, int y, int x) 21494c8945a0SNathan Whitehorn { 21504c8945a0SNathan Whitehorn WINDOW *win; 21514c8945a0SNathan Whitehorn 21524c8945a0SNathan Whitehorn if ((win = subwin(parent, height, width, y, x)) == 0) { 21534c8945a0SNathan Whitehorn dlg_exiterr("Can't make sub-window at (%d,%d), size (%d,%d).\n", 21544c8945a0SNathan Whitehorn y, x, height, width); 21554c8945a0SNathan Whitehorn } 21564c8945a0SNathan Whitehorn 2157*2a3e3873SBaptiste Daroussin add_subwindow(parent, win); 21584c8945a0SNathan Whitehorn (void) keypad(win, TRUE); 21594c8945a0SNathan Whitehorn return win; 21604c8945a0SNathan Whitehorn } 21614c8945a0SNathan Whitehorn 21624c8945a0SNathan Whitehorn /* obsolete */ 21634c8945a0SNathan Whitehorn int 21644c8945a0SNathan Whitehorn dlg_default_item(char **items, int llen) 21654c8945a0SNathan Whitehorn { 21664c8945a0SNathan Whitehorn int result = 0; 21674c8945a0SNathan Whitehorn 21684c8945a0SNathan Whitehorn if (dialog_vars.default_item != 0) { 21694c8945a0SNathan Whitehorn int count = 0; 21704c8945a0SNathan Whitehorn while (*items != 0) { 21714c8945a0SNathan Whitehorn if (!strcmp(dialog_vars.default_item, *items)) { 21724c8945a0SNathan Whitehorn result = count; 21734c8945a0SNathan Whitehorn break; 21744c8945a0SNathan Whitehorn } 21754c8945a0SNathan Whitehorn items += llen; 21764c8945a0SNathan Whitehorn count++; 21774c8945a0SNathan Whitehorn } 21784c8945a0SNathan Whitehorn } 21794c8945a0SNathan Whitehorn return result; 21804c8945a0SNathan Whitehorn } 21814c8945a0SNathan Whitehorn 21824c8945a0SNathan Whitehorn int 21834c8945a0SNathan Whitehorn dlg_default_listitem(DIALOG_LISTITEM * items) 21844c8945a0SNathan Whitehorn { 21854c8945a0SNathan Whitehorn int result = 0; 21864c8945a0SNathan Whitehorn 21874c8945a0SNathan Whitehorn if (dialog_vars.default_item != 0) { 21884c8945a0SNathan Whitehorn int count = 0; 21894c8945a0SNathan Whitehorn while (items->name != 0) { 21904c8945a0SNathan Whitehorn if (!strcmp(dialog_vars.default_item, items->name)) { 21914c8945a0SNathan Whitehorn result = count; 21924c8945a0SNathan Whitehorn break; 21934c8945a0SNathan Whitehorn } 21944c8945a0SNathan Whitehorn ++items; 21954c8945a0SNathan Whitehorn count++; 21964c8945a0SNathan Whitehorn } 21974c8945a0SNathan Whitehorn } 21984c8945a0SNathan Whitehorn return result; 21994c8945a0SNathan Whitehorn } 22004c8945a0SNathan Whitehorn 22014c8945a0SNathan Whitehorn /* 22024c8945a0SNathan Whitehorn * Draw the string for item_help 22034c8945a0SNathan Whitehorn */ 22044c8945a0SNathan Whitehorn void 22054c8945a0SNathan Whitehorn dlg_item_help(const char *txt) 22064c8945a0SNathan Whitehorn { 22074c8945a0SNathan Whitehorn if (USE_ITEM_HELP(txt)) { 22084c8945a0SNathan Whitehorn chtype attr = A_NORMAL; 22094c8945a0SNathan Whitehorn int y, x; 22104c8945a0SNathan Whitehorn 2211*2a3e3873SBaptiste Daroussin (void) wattrset(stdscr, itemhelp_attr); 22124c8945a0SNathan Whitehorn (void) wmove(stdscr, LINES - 1, 0); 22134c8945a0SNathan Whitehorn (void) wclrtoeol(stdscr); 22144c8945a0SNathan Whitehorn (void) addch(' '); 22154c8945a0SNathan Whitehorn dlg_print_text(stdscr, txt, COLS - 1, &attr); 22164c8945a0SNathan Whitehorn if (itemhelp_attr & A_COLOR) { 22174c8945a0SNathan Whitehorn /* fill the remainder of the line with the window's attributes */ 22184c8945a0SNathan Whitehorn getyx(stdscr, y, x); 2219*2a3e3873SBaptiste Daroussin (void) y; 22204c8945a0SNathan Whitehorn while (x < COLS) { 22214c8945a0SNathan Whitehorn (void) addch(' '); 22224c8945a0SNathan Whitehorn ++x; 22234c8945a0SNathan Whitehorn } 22244c8945a0SNathan Whitehorn } 22254c8945a0SNathan Whitehorn (void) wnoutrefresh(stdscr); 22264c8945a0SNathan Whitehorn } 22274c8945a0SNathan Whitehorn } 22284c8945a0SNathan Whitehorn 22294c8945a0SNathan Whitehorn #ifndef HAVE_STRCASECMP 22304c8945a0SNathan Whitehorn int 22314c8945a0SNathan Whitehorn dlg_strcmp(const char *a, const char *b) 22324c8945a0SNathan Whitehorn { 22334c8945a0SNathan Whitehorn int ac, bc, cmp; 22344c8945a0SNathan Whitehorn 22354c8945a0SNathan Whitehorn for (;;) { 22364c8945a0SNathan Whitehorn ac = UCH(*a++); 22374c8945a0SNathan Whitehorn bc = UCH(*b++); 22384c8945a0SNathan Whitehorn if (isalpha(ac) && islower(ac)) 22394c8945a0SNathan Whitehorn ac = _toupper(ac); 22404c8945a0SNathan Whitehorn if (isalpha(bc) && islower(bc)) 22414c8945a0SNathan Whitehorn bc = _toupper(bc); 22424c8945a0SNathan Whitehorn cmp = ac - bc; 22434c8945a0SNathan Whitehorn if (ac == 0 || bc == 0 || cmp != 0) 22444c8945a0SNathan Whitehorn break; 22454c8945a0SNathan Whitehorn } 22464c8945a0SNathan Whitehorn return cmp; 22474c8945a0SNathan Whitehorn } 22484c8945a0SNathan Whitehorn #endif 22494c8945a0SNathan Whitehorn 22504c8945a0SNathan Whitehorn /* 22514c8945a0SNathan Whitehorn * Returns true if 'dst' points to a blank which follows another blank which 22524c8945a0SNathan Whitehorn * is not a leading blank on a line. 22534c8945a0SNathan Whitehorn */ 22544c8945a0SNathan Whitehorn static bool 22554c8945a0SNathan Whitehorn trim_blank(char *base, char *dst) 22564c8945a0SNathan Whitehorn { 22574c8945a0SNathan Whitehorn int count = 0; 22584c8945a0SNathan Whitehorn 22594c8945a0SNathan Whitehorn while (dst-- != base) { 22604c8945a0SNathan Whitehorn if (*dst == '\n') { 22614c8945a0SNathan Whitehorn return FALSE; 22624c8945a0SNathan Whitehorn } else if (*dst != ' ') { 22634c8945a0SNathan Whitehorn return (count > 1); 22644c8945a0SNathan Whitehorn } else { 22654c8945a0SNathan Whitehorn count++; 22664c8945a0SNathan Whitehorn } 22674c8945a0SNathan Whitehorn } 22684c8945a0SNathan Whitehorn return FALSE; 22694c8945a0SNathan Whitehorn } 22704c8945a0SNathan Whitehorn 22714c8945a0SNathan Whitehorn /* 22724c8945a0SNathan Whitehorn * Change embedded "\n" substrings to '\n' characters and tabs to single 22734c8945a0SNathan Whitehorn * spaces. If there are no "\n"s, it will strip all extra spaces, for 22744c8945a0SNathan Whitehorn * justification. If it has "\n"'s, it will preserve extra spaces. If cr_wrap 22754c8945a0SNathan Whitehorn * is set, it will preserve '\n's. 22764c8945a0SNathan Whitehorn */ 22774c8945a0SNathan Whitehorn void 22784c8945a0SNathan Whitehorn dlg_trim_string(char *s) 22794c8945a0SNathan Whitehorn { 22804c8945a0SNathan Whitehorn char *base = s; 22814c8945a0SNathan Whitehorn char *p1; 22824c8945a0SNathan Whitehorn char *p = s; 2283682c9e0fSNathan Whitehorn int has_newlines = !dialog_vars.no_nl_expand && (strstr(s, "\\n") != 0); 22844c8945a0SNathan Whitehorn 22854c8945a0SNathan Whitehorn while (*p != '\0') { 22864c8945a0SNathan Whitehorn if (*p == TAB && !dialog_vars.nocollapse) 22874c8945a0SNathan Whitehorn *p = ' '; 22884c8945a0SNathan Whitehorn 22894c8945a0SNathan Whitehorn if (has_newlines) { /* If prompt contains "\n" strings */ 22904c8945a0SNathan Whitehorn if (*p == '\\' && *(p + 1) == 'n') { 22914c8945a0SNathan Whitehorn *s++ = '\n'; 22924c8945a0SNathan Whitehorn p += 2; 22934c8945a0SNathan Whitehorn p1 = p; 22944c8945a0SNathan Whitehorn /* 22954c8945a0SNathan Whitehorn * Handle end of lines intelligently. If '\n' follows "\n" 22964c8945a0SNathan Whitehorn * then ignore the '\n'. This eliminates the need to escape 22974c8945a0SNathan Whitehorn * the '\n' character (no need to use "\n\"). 22984c8945a0SNathan Whitehorn */ 22994c8945a0SNathan Whitehorn while (*p1 == ' ') 23004c8945a0SNathan Whitehorn p1++; 23014c8945a0SNathan Whitehorn if (*p1 == '\n') 23024c8945a0SNathan Whitehorn p = p1 + 1; 23034c8945a0SNathan Whitehorn } else if (*p == '\n') { 23044c8945a0SNathan Whitehorn if (dialog_vars.cr_wrap) 23054c8945a0SNathan Whitehorn *s++ = *p++; 23064c8945a0SNathan Whitehorn else { 23074c8945a0SNathan Whitehorn /* Replace the '\n' with a space if cr_wrap is not set */ 23084c8945a0SNathan Whitehorn if (!trim_blank(base, s)) 23094c8945a0SNathan Whitehorn *s++ = ' '; 23104c8945a0SNathan Whitehorn p++; 23114c8945a0SNathan Whitehorn } 23124c8945a0SNathan Whitehorn } else /* If *p != '\n' */ 23134c8945a0SNathan Whitehorn *s++ = *p++; 23144c8945a0SNathan Whitehorn } else if (dialog_vars.trim_whitespace) { 23154c8945a0SNathan Whitehorn if (*p == ' ') { 23164c8945a0SNathan Whitehorn if (*(s - 1) != ' ') { 23174c8945a0SNathan Whitehorn *s++ = ' '; 23184c8945a0SNathan Whitehorn p++; 23194c8945a0SNathan Whitehorn } else 23204c8945a0SNathan Whitehorn p++; 23214c8945a0SNathan Whitehorn } else if (*p == '\n') { 23224c8945a0SNathan Whitehorn if (dialog_vars.cr_wrap) 23234c8945a0SNathan Whitehorn *s++ = *p++; 23244c8945a0SNathan Whitehorn else if (*(s - 1) != ' ') { 23254c8945a0SNathan Whitehorn /* Strip '\n's if cr_wrap is not set. */ 23264c8945a0SNathan Whitehorn *s++ = ' '; 23274c8945a0SNathan Whitehorn p++; 23284c8945a0SNathan Whitehorn } else 23294c8945a0SNathan Whitehorn p++; 23304c8945a0SNathan Whitehorn } else 23314c8945a0SNathan Whitehorn *s++ = *p++; 23324c8945a0SNathan Whitehorn } else { /* If there are no "\n" strings */ 23334c8945a0SNathan Whitehorn if (*p == ' ' && !dialog_vars.nocollapse) { 23344c8945a0SNathan Whitehorn if (!trim_blank(base, s)) 23354c8945a0SNathan Whitehorn *s++ = *p; 23364c8945a0SNathan Whitehorn p++; 23374c8945a0SNathan Whitehorn } else 23384c8945a0SNathan Whitehorn *s++ = *p++; 23394c8945a0SNathan Whitehorn } 23404c8945a0SNathan Whitehorn } 23414c8945a0SNathan Whitehorn 23424c8945a0SNathan Whitehorn *s = '\0'; 23434c8945a0SNathan Whitehorn } 23444c8945a0SNathan Whitehorn 23454c8945a0SNathan Whitehorn void 23464c8945a0SNathan Whitehorn dlg_set_focus(WINDOW *parent, WINDOW *win) 23474c8945a0SNathan Whitehorn { 23484c8945a0SNathan Whitehorn if (win != 0) { 23494c8945a0SNathan Whitehorn (void) wmove(parent, 23504c8945a0SNathan Whitehorn getpary(win) + getcury(win), 23514c8945a0SNathan Whitehorn getparx(win) + getcurx(win)); 23524c8945a0SNathan Whitehorn (void) wnoutrefresh(win); 23534c8945a0SNathan Whitehorn (void) doupdate(); 23544c8945a0SNathan Whitehorn } 23554c8945a0SNathan Whitehorn } 23564c8945a0SNathan Whitehorn 23574c8945a0SNathan Whitehorn /* 23584c8945a0SNathan Whitehorn * Returns the nominal maximum buffer size. 23594c8945a0SNathan Whitehorn */ 23604c8945a0SNathan Whitehorn int 23614c8945a0SNathan Whitehorn dlg_max_input(int max_len) 23624c8945a0SNathan Whitehorn { 23634c8945a0SNathan Whitehorn if (dialog_vars.max_input != 0 && dialog_vars.max_input < MAX_LEN) 23644c8945a0SNathan Whitehorn max_len = dialog_vars.max_input; 23654c8945a0SNathan Whitehorn 23664c8945a0SNathan Whitehorn return max_len; 23674c8945a0SNathan Whitehorn } 23684c8945a0SNathan Whitehorn 23694c8945a0SNathan Whitehorn /* 23704c8945a0SNathan Whitehorn * Free storage used for the result buffer. 23714c8945a0SNathan Whitehorn */ 23724c8945a0SNathan Whitehorn void 23734c8945a0SNathan Whitehorn dlg_clr_result(void) 23744c8945a0SNathan Whitehorn { 23754c8945a0SNathan Whitehorn if (dialog_vars.input_length) { 23764c8945a0SNathan Whitehorn dialog_vars.input_length = 0; 23774c8945a0SNathan Whitehorn if (dialog_vars.input_result) 23784c8945a0SNathan Whitehorn free(dialog_vars.input_result); 23794c8945a0SNathan Whitehorn } 23804c8945a0SNathan Whitehorn dialog_vars.input_result = 0; 23814c8945a0SNathan Whitehorn } 23824c8945a0SNathan Whitehorn 23834c8945a0SNathan Whitehorn /* 23844c8945a0SNathan Whitehorn * Setup a fixed-buffer for the result. 23854c8945a0SNathan Whitehorn */ 23864c8945a0SNathan Whitehorn char * 23874c8945a0SNathan Whitehorn dlg_set_result(const char *string) 23884c8945a0SNathan Whitehorn { 23897a1c0d96SNathan Whitehorn unsigned need = string ? (unsigned) strlen(string) + 1 : 0; 23904c8945a0SNathan Whitehorn 23914c8945a0SNathan Whitehorn /* inputstr.c needs a fixed buffer */ 23924c8945a0SNathan Whitehorn if (need < MAX_LEN) 23934c8945a0SNathan Whitehorn need = MAX_LEN; 23944c8945a0SNathan Whitehorn 23954c8945a0SNathan Whitehorn /* 23964c8945a0SNathan Whitehorn * If the buffer is not big enough, allocate a new one. 23974c8945a0SNathan Whitehorn */ 23984c8945a0SNathan Whitehorn if (dialog_vars.input_length != 0 23994c8945a0SNathan Whitehorn || dialog_vars.input_result == 0 24004c8945a0SNathan Whitehorn || need > MAX_LEN) { 24014c8945a0SNathan Whitehorn 24024c8945a0SNathan Whitehorn dlg_clr_result(); 24034c8945a0SNathan Whitehorn 24044c8945a0SNathan Whitehorn dialog_vars.input_length = need; 24054c8945a0SNathan Whitehorn dialog_vars.input_result = dlg_malloc(char, need); 24064c8945a0SNathan Whitehorn assert_ptr(dialog_vars.input_result, "dlg_set_result"); 24074c8945a0SNathan Whitehorn } 24084c8945a0SNathan Whitehorn 24094c8945a0SNathan Whitehorn strcpy(dialog_vars.input_result, string ? string : ""); 24104c8945a0SNathan Whitehorn 24114c8945a0SNathan Whitehorn return dialog_vars.input_result; 24124c8945a0SNathan Whitehorn } 24134c8945a0SNathan Whitehorn 24144c8945a0SNathan Whitehorn /* 24154c8945a0SNathan Whitehorn * Accumulate results in dynamically allocated buffer. 24164c8945a0SNathan Whitehorn * If input_length is zero, it is a MAX_LEN buffer belonging to the caller. 24174c8945a0SNathan Whitehorn */ 24184c8945a0SNathan Whitehorn void 24194c8945a0SNathan Whitehorn dlg_add_result(const char *string) 24204c8945a0SNathan Whitehorn { 24214c8945a0SNathan Whitehorn unsigned have = (dialog_vars.input_result 24227a1c0d96SNathan Whitehorn ? (unsigned) strlen(dialog_vars.input_result) 24234c8945a0SNathan Whitehorn : 0); 24247a1c0d96SNathan Whitehorn unsigned want = (unsigned) strlen(string) + 1 + have; 24254c8945a0SNathan Whitehorn 24264c8945a0SNathan Whitehorn if ((want >= MAX_LEN) 24274c8945a0SNathan Whitehorn || (dialog_vars.input_length != 0) 24284c8945a0SNathan Whitehorn || (dialog_vars.input_result == 0)) { 24294c8945a0SNathan Whitehorn 24304c8945a0SNathan Whitehorn if (dialog_vars.input_length == 0 24314c8945a0SNathan Whitehorn || dialog_vars.input_result == 0) { 24324c8945a0SNathan Whitehorn 24337a1c0d96SNathan Whitehorn char *save_result = dialog_vars.input_result; 24344c8945a0SNathan Whitehorn 24354c8945a0SNathan Whitehorn dialog_vars.input_length = want * 2; 24364c8945a0SNathan Whitehorn dialog_vars.input_result = dlg_malloc(char, dialog_vars.input_length); 24374c8945a0SNathan Whitehorn assert_ptr(dialog_vars.input_result, "dlg_add_result malloc"); 24387a1c0d96SNathan Whitehorn dialog_vars.input_result[0] = '\0'; 24397a1c0d96SNathan Whitehorn if (save_result != 0) 24407a1c0d96SNathan Whitehorn strcpy(dialog_vars.input_result, save_result); 24414c8945a0SNathan Whitehorn } else if (want >= dialog_vars.input_length) { 24424c8945a0SNathan Whitehorn dialog_vars.input_length = want * 2; 24434c8945a0SNathan Whitehorn dialog_vars.input_result = dlg_realloc(char, 24444c8945a0SNathan Whitehorn dialog_vars.input_length, 24454c8945a0SNathan Whitehorn dialog_vars.input_result); 24464c8945a0SNathan Whitehorn assert_ptr(dialog_vars.input_result, "dlg_add_result realloc"); 24474c8945a0SNathan Whitehorn } 24484c8945a0SNathan Whitehorn } 24494c8945a0SNathan Whitehorn strcat(dialog_vars.input_result, string); 24504c8945a0SNathan Whitehorn } 24514c8945a0SNathan Whitehorn 24524c8945a0SNathan Whitehorn /* 24534c8945a0SNathan Whitehorn * These are characters that (aside from the quote-delimiter) will have to 24544c8945a0SNathan Whitehorn * be escaped in a single- or double-quoted string. 24554c8945a0SNathan Whitehorn */ 24564c8945a0SNathan Whitehorn #define FIX_SINGLE "\n\\" 24574c8945a0SNathan Whitehorn #define FIX_DOUBLE FIX_SINGLE "[]{}?*;`~#$^&()|<>" 24584c8945a0SNathan Whitehorn 24594c8945a0SNathan Whitehorn /* 24604c8945a0SNathan Whitehorn * Returns the quote-delimiter. 24614c8945a0SNathan Whitehorn */ 24624c8945a0SNathan Whitehorn static const char * 24634c8945a0SNathan Whitehorn quote_delimiter(void) 24644c8945a0SNathan Whitehorn { 24654c8945a0SNathan Whitehorn return dialog_vars.single_quoted ? "'" : "\""; 24664c8945a0SNathan Whitehorn } 24674c8945a0SNathan Whitehorn 24684c8945a0SNathan Whitehorn /* 24694c8945a0SNathan Whitehorn * Returns true if we should quote the given string. 24704c8945a0SNathan Whitehorn */ 24714c8945a0SNathan Whitehorn static bool 24724c8945a0SNathan Whitehorn must_quote(char *string) 24734c8945a0SNathan Whitehorn { 24744c8945a0SNathan Whitehorn bool code = FALSE; 24754c8945a0SNathan Whitehorn 24764c8945a0SNathan Whitehorn if (*string != '\0') { 24777a1c0d96SNathan Whitehorn size_t len = strlen(string); 24784c8945a0SNathan Whitehorn if (strcspn(string, quote_delimiter()) != len) 24794c8945a0SNathan Whitehorn code = TRUE; 24804c8945a0SNathan Whitehorn else if (strcspn(string, "\n\t ") != len) 24814c8945a0SNathan Whitehorn code = TRUE; 24824c8945a0SNathan Whitehorn else 24834c8945a0SNathan Whitehorn code = (strcspn(string, FIX_DOUBLE) != len); 24844c8945a0SNathan Whitehorn } else { 24854c8945a0SNathan Whitehorn code = TRUE; 24864c8945a0SNathan Whitehorn } 24874c8945a0SNathan Whitehorn 24884c8945a0SNathan Whitehorn return code; 24894c8945a0SNathan Whitehorn } 24904c8945a0SNathan Whitehorn 24914c8945a0SNathan Whitehorn /* 24924c8945a0SNathan Whitehorn * Add a quoted string to the result buffer. 24934c8945a0SNathan Whitehorn */ 24944c8945a0SNathan Whitehorn void 24954c8945a0SNathan Whitehorn dlg_add_quoted(char *string) 24964c8945a0SNathan Whitehorn { 24974c8945a0SNathan Whitehorn char temp[2]; 24984c8945a0SNathan Whitehorn const char *my_quote = quote_delimiter(); 24994c8945a0SNathan Whitehorn const char *must_fix = (dialog_vars.single_quoted 25004c8945a0SNathan Whitehorn ? FIX_SINGLE 25014c8945a0SNathan Whitehorn : FIX_DOUBLE); 25024c8945a0SNathan Whitehorn 2503*2a3e3873SBaptiste Daroussin if (must_quote(string)) { 25044c8945a0SNathan Whitehorn temp[1] = '\0'; 25054c8945a0SNathan Whitehorn dlg_add_result(my_quote); 25064c8945a0SNathan Whitehorn while (*string != '\0') { 25074c8945a0SNathan Whitehorn temp[0] = *string++; 25084c8945a0SNathan Whitehorn if (strchr(my_quote, *temp) || strchr(must_fix, *temp)) 25094c8945a0SNathan Whitehorn dlg_add_result("\\"); 25104c8945a0SNathan Whitehorn dlg_add_result(temp); 25114c8945a0SNathan Whitehorn } 25124c8945a0SNathan Whitehorn dlg_add_result(my_quote); 25134c8945a0SNathan Whitehorn } else { 25144c8945a0SNathan Whitehorn dlg_add_result(string); 25154c8945a0SNathan Whitehorn } 25164c8945a0SNathan Whitehorn } 25174c8945a0SNathan Whitehorn 25184c8945a0SNathan Whitehorn /* 25194c8945a0SNathan Whitehorn * When adding a result, make that depend on whether "--quoted" is used. 25204c8945a0SNathan Whitehorn */ 25214c8945a0SNathan Whitehorn void 25224c8945a0SNathan Whitehorn dlg_add_string(char *string) 25234c8945a0SNathan Whitehorn { 25244c8945a0SNathan Whitehorn if (dialog_vars.quoted) { 25254c8945a0SNathan Whitehorn dlg_add_quoted(string); 25264c8945a0SNathan Whitehorn } else { 25274c8945a0SNathan Whitehorn dlg_add_result(string); 25284c8945a0SNathan Whitehorn } 25294c8945a0SNathan Whitehorn } 25304c8945a0SNathan Whitehorn 25314c8945a0SNathan Whitehorn bool 25324c8945a0SNathan Whitehorn dlg_need_separator(void) 25334c8945a0SNathan Whitehorn { 25344c8945a0SNathan Whitehorn bool result = FALSE; 25354c8945a0SNathan Whitehorn 25364c8945a0SNathan Whitehorn if (dialog_vars.output_separator) { 25374c8945a0SNathan Whitehorn result = TRUE; 25384c8945a0SNathan Whitehorn } else if (dialog_vars.input_result && *(dialog_vars.input_result)) { 25394c8945a0SNathan Whitehorn result = TRUE; 25404c8945a0SNathan Whitehorn } 25414c8945a0SNathan Whitehorn return result; 25424c8945a0SNathan Whitehorn } 25434c8945a0SNathan Whitehorn 25444c8945a0SNathan Whitehorn void 25454c8945a0SNathan Whitehorn dlg_add_separator(void) 25464c8945a0SNathan Whitehorn { 25474c8945a0SNathan Whitehorn const char *separator = (dialog_vars.separate_output) ? "\n" : " "; 25484c8945a0SNathan Whitehorn 25494c8945a0SNathan Whitehorn if (dialog_vars.output_separator) 25504c8945a0SNathan Whitehorn separator = dialog_vars.output_separator; 25514c8945a0SNathan Whitehorn 25524c8945a0SNathan Whitehorn dlg_add_result(separator); 25534c8945a0SNathan Whitehorn } 25544c8945a0SNathan Whitehorn 25554c8945a0SNathan Whitehorn /* 25564c8945a0SNathan Whitehorn * Some widgets support only one value of a given variable - save/restore the 25574c8945a0SNathan Whitehorn * global dialog_vars so we can override it consistently. 25584c8945a0SNathan Whitehorn */ 25594c8945a0SNathan Whitehorn void 25604c8945a0SNathan Whitehorn dlg_save_vars(DIALOG_VARS * vars) 25614c8945a0SNathan Whitehorn { 25624c8945a0SNathan Whitehorn *vars = dialog_vars; 25634c8945a0SNathan Whitehorn } 25644c8945a0SNathan Whitehorn 25657a1c0d96SNathan Whitehorn /* 25667a1c0d96SNathan Whitehorn * Most of the data in DIALOG_VARS is normally set by command-line options. 25677a1c0d96SNathan Whitehorn * The input_result member is an exception; it is normally set by the dialog 25687a1c0d96SNathan Whitehorn * library to return result values. 25697a1c0d96SNathan Whitehorn */ 25704c8945a0SNathan Whitehorn void 25714c8945a0SNathan Whitehorn dlg_restore_vars(DIALOG_VARS * vars) 25724c8945a0SNathan Whitehorn { 25737a1c0d96SNathan Whitehorn char *save_result = dialog_vars.input_result; 25747a1c0d96SNathan Whitehorn unsigned save_length = dialog_vars.input_length; 25757a1c0d96SNathan Whitehorn 25764c8945a0SNathan Whitehorn dialog_vars = *vars; 25777a1c0d96SNathan Whitehorn dialog_vars.input_result = save_result; 25787a1c0d96SNathan Whitehorn dialog_vars.input_length = save_length; 25794c8945a0SNathan Whitehorn } 25804c8945a0SNathan Whitehorn 25814c8945a0SNathan Whitehorn /* 25824c8945a0SNathan Whitehorn * Called each time a widget is invoked which may do output, increment a count. 25834c8945a0SNathan Whitehorn */ 25844c8945a0SNathan Whitehorn void 25854c8945a0SNathan Whitehorn dlg_does_output(void) 25864c8945a0SNathan Whitehorn { 25874c8945a0SNathan Whitehorn dialog_state.output_count += 1; 25884c8945a0SNathan Whitehorn } 25894c8945a0SNathan Whitehorn 25904c8945a0SNathan Whitehorn /* 25914c8945a0SNathan Whitehorn * Compatibility for different versions of curses. 25924c8945a0SNathan Whitehorn */ 25934c8945a0SNathan Whitehorn #if !(defined(HAVE_GETBEGX) && defined(HAVE_GETBEGY)) 25944c8945a0SNathan Whitehorn int 2595*2a3e3873SBaptiste Daroussin dlg_getbegx(WINDOW *win) 25964c8945a0SNathan Whitehorn { 25974c8945a0SNathan Whitehorn int y, x; 25984c8945a0SNathan Whitehorn getbegyx(win, y, x); 25994c8945a0SNathan Whitehorn return x; 26004c8945a0SNathan Whitehorn } 26014c8945a0SNathan Whitehorn int 2602*2a3e3873SBaptiste Daroussin dlg_getbegy(WINDOW *win) 26034c8945a0SNathan Whitehorn { 26044c8945a0SNathan Whitehorn int y, x; 26054c8945a0SNathan Whitehorn getbegyx(win, y, x); 26064c8945a0SNathan Whitehorn return y; 26074c8945a0SNathan Whitehorn } 26084c8945a0SNathan Whitehorn #endif 26094c8945a0SNathan Whitehorn 26104c8945a0SNathan Whitehorn #if !(defined(HAVE_GETCURX) && defined(HAVE_GETCURY)) 26114c8945a0SNathan Whitehorn int 2612*2a3e3873SBaptiste Daroussin dlg_getcurx(WINDOW *win) 26134c8945a0SNathan Whitehorn { 26144c8945a0SNathan Whitehorn int y, x; 26154c8945a0SNathan Whitehorn getyx(win, y, x); 26164c8945a0SNathan Whitehorn return x; 26174c8945a0SNathan Whitehorn } 26184c8945a0SNathan Whitehorn int 2619*2a3e3873SBaptiste Daroussin dlg_getcury(WINDOW *win) 26204c8945a0SNathan Whitehorn { 26214c8945a0SNathan Whitehorn int y, x; 26224c8945a0SNathan Whitehorn getyx(win, y, x); 26234c8945a0SNathan Whitehorn return y; 26244c8945a0SNathan Whitehorn } 26254c8945a0SNathan Whitehorn #endif 26264c8945a0SNathan Whitehorn 26274c8945a0SNathan Whitehorn #if !(defined(HAVE_GETMAXX) && defined(HAVE_GETMAXY)) 26284c8945a0SNathan Whitehorn int 2629*2a3e3873SBaptiste Daroussin dlg_getmaxx(WINDOW *win) 26304c8945a0SNathan Whitehorn { 26314c8945a0SNathan Whitehorn int y, x; 26324c8945a0SNathan Whitehorn getmaxyx(win, y, x); 26334c8945a0SNathan Whitehorn return x; 26344c8945a0SNathan Whitehorn } 26354c8945a0SNathan Whitehorn int 2636*2a3e3873SBaptiste Daroussin dlg_getmaxy(WINDOW *win) 26374c8945a0SNathan Whitehorn { 26384c8945a0SNathan Whitehorn int y, x; 26394c8945a0SNathan Whitehorn getmaxyx(win, y, x); 26404c8945a0SNathan Whitehorn return y; 26414c8945a0SNathan Whitehorn } 26424c8945a0SNathan Whitehorn #endif 26434c8945a0SNathan Whitehorn 26444c8945a0SNathan Whitehorn #if !(defined(HAVE_GETPARX) && defined(HAVE_GETPARY)) 26454c8945a0SNathan Whitehorn int 2646*2a3e3873SBaptiste Daroussin dlg_getparx(WINDOW *win) 26474c8945a0SNathan Whitehorn { 26484c8945a0SNathan Whitehorn int y, x; 26494c8945a0SNathan Whitehorn getparyx(win, y, x); 26504c8945a0SNathan Whitehorn return x; 26514c8945a0SNathan Whitehorn } 26524c8945a0SNathan Whitehorn int 2653*2a3e3873SBaptiste Daroussin dlg_getpary(WINDOW *win) 26544c8945a0SNathan Whitehorn { 26554c8945a0SNathan Whitehorn int y, x; 26564c8945a0SNathan Whitehorn getparyx(win, y, x); 26574c8945a0SNathan Whitehorn return y; 26584c8945a0SNathan Whitehorn } 26594c8945a0SNathan Whitehorn #endif 2660*2a3e3873SBaptiste Daroussin 2661*2a3e3873SBaptiste Daroussin #ifdef NEED_WGETPARENT 2662*2a3e3873SBaptiste Daroussin WINDOW * 2663*2a3e3873SBaptiste Daroussin dlg_wgetparent(WINDOW *win) 2664*2a3e3873SBaptiste Daroussin { 2665*2a3e3873SBaptiste Daroussin #undef wgetparent 2666*2a3e3873SBaptiste Daroussin WINDOW *result = 0; 2667*2a3e3873SBaptiste Daroussin DIALOG_WINDOWS *p; 2668*2a3e3873SBaptiste Daroussin 2669*2a3e3873SBaptiste Daroussin for (p = dialog_state.all_subwindows; p != 0; p = p->next) { 2670*2a3e3873SBaptiste Daroussin if (p->shadow == win) { 2671*2a3e3873SBaptiste Daroussin result = p->normal; 2672*2a3e3873SBaptiste Daroussin break; 2673*2a3e3873SBaptiste Daroussin } 2674*2a3e3873SBaptiste Daroussin } 2675*2a3e3873SBaptiste Daroussin return result; 2676*2a3e3873SBaptiste Daroussin } 2677*2a3e3873SBaptiste Daroussin #endif 2678