14c8945a0SNathan Whitehorn /* 2*a96ef450SBaptiste Daroussin * $Id: util.c,v 1.300 2021/01/17 22:10:56 tom Exp $ 34c8945a0SNathan Whitehorn * 44c8945a0SNathan Whitehorn * util.c -- miscellaneous utilities for dialog 54c8945a0SNathan Whitehorn * 6*a96ef450SBaptiste Daroussin * Copyright 2000-2020,2021 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> 29*a96ef450SBaptiste Daroussin #include <dlg_internals.h> 30*a96ef450SBaptiste Daroussin 31*a96ef450SBaptiste Daroussin #include <sys/time.h> 324c8945a0SNathan Whitehorn 332a3e3873SBaptiste Daroussin #ifdef HAVE_SETLOCALE 342a3e3873SBaptiste Daroussin #include <locale.h> 352a3e3873SBaptiste Daroussin #endif 362a3e3873SBaptiste Daroussin 372a3e3873SBaptiste Daroussin #ifdef NEED_WCHAR_H 382a3e3873SBaptiste Daroussin #include <wchar.h> 392a3e3873SBaptiste Daroussin #endif 402a3e3873SBaptiste Daroussin 41*a96ef450SBaptiste Daroussin #ifdef HAVE_SYS_PARAM_H 42*a96ef450SBaptiste Daroussin #include <sys/param.h> 43*a96ef450SBaptiste Daroussin #endif 44*a96ef450SBaptiste Daroussin 45*a96ef450SBaptiste Daroussin #if defined(NCURSES_VERSION) 46*a96ef450SBaptiste Daroussin #define CAN_KEEP_TITE 1 47*a96ef450SBaptiste Daroussin #elif defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 800000000) 48*a96ef450SBaptiste Daroussin #define CAN_KEEP_TITE 1 49*a96ef450SBaptiste Daroussin #else 50*a96ef450SBaptiste Daroussin #define CAN_KEEP_TITE 0 51*a96ef450SBaptiste Daroussin #endif 52*a96ef450SBaptiste Daroussin 53*a96ef450SBaptiste Daroussin #if CAN_KEEP_TITE 54*a96ef450SBaptiste Daroussin #if defined(NCURSES_VERSION) && defined(HAVE_NCURSESW_TERM_H) 554c8945a0SNathan Whitehorn #include <ncursesw/term.h> 56*a96ef450SBaptiste Daroussin #elif defined(NCURSES_VERSION) && defined(HAVE_NCURSES_TERM_H) 574c8945a0SNathan Whitehorn #include <ncurses/term.h> 584c8945a0SNathan Whitehorn #else 594c8945a0SNathan Whitehorn #include <term.h> 604c8945a0SNathan Whitehorn #endif 614c8945a0SNathan Whitehorn #endif 624c8945a0SNathan Whitehorn 63682c9e0fSNathan Whitehorn #if defined(HAVE_WCHGAT) 64682c9e0fSNathan Whitehorn # if defined(NCURSES_VERSION_PATCH) 65682c9e0fSNathan Whitehorn # if NCURSES_VERSION_PATCH >= 20060715 66682c9e0fSNathan Whitehorn # define USE_WCHGAT 1 67682c9e0fSNathan Whitehorn # else 68682c9e0fSNathan Whitehorn # define USE_WCHGAT 0 69682c9e0fSNathan Whitehorn # endif 70682c9e0fSNathan Whitehorn # else 71682c9e0fSNathan Whitehorn # define USE_WCHGAT 1 72682c9e0fSNathan Whitehorn # endif 73682c9e0fSNathan Whitehorn #else 74682c9e0fSNathan Whitehorn # define USE_WCHGAT 0 75682c9e0fSNathan Whitehorn #endif 76682c9e0fSNathan Whitehorn 774c8945a0SNathan Whitehorn /* globals */ 784c8945a0SNathan Whitehorn DIALOG_STATE dialog_state; 794c8945a0SNathan Whitehorn DIALOG_VARS dialog_vars; 804c8945a0SNathan Whitehorn 812a3e3873SBaptiste Daroussin #if !(defined(HAVE_WGETPARENT) && defined(HAVE_WINDOW__PARENT)) 822a3e3873SBaptiste Daroussin #define NEED_WGETPARENT 1 832a3e3873SBaptiste Daroussin #else 842a3e3873SBaptiste Daroussin #undef NEED_WGETPARENT 852a3e3873SBaptiste Daroussin #endif 862a3e3873SBaptiste Daroussin 874c8945a0SNathan Whitehorn #define concat(a,b) a##b 884c8945a0SNathan Whitehorn 894c8945a0SNathan Whitehorn #ifdef HAVE_RC_FILE 904c8945a0SNathan Whitehorn #define RC_DATA(name,comment) , #name "_color", comment " color" 914c8945a0SNathan Whitehorn #else 924c8945a0SNathan Whitehorn #define RC_DATA(name,comment) /*nothing */ 934c8945a0SNathan Whitehorn #endif 944c8945a0SNathan Whitehorn 954c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 964c8945a0SNathan Whitehorn #include <dlg_colors.h> 97*a96ef450SBaptiste Daroussin #ifdef HAVE_RC_FILE2 98*a96ef450SBaptiste Daroussin #define COLOR_DATA(upr) , \ 99*a96ef450SBaptiste Daroussin concat(DLGC_FG_,upr), \ 100*a96ef450SBaptiste Daroussin concat(DLGC_BG_,upr), \ 101*a96ef450SBaptiste Daroussin concat(DLGC_HL_,upr), \ 102*a96ef450SBaptiste Daroussin concat(DLGC_UL_,upr), \ 103*a96ef450SBaptiste Daroussin concat(DLGC_RV_,upr) 104*a96ef450SBaptiste Daroussin #else /* HAVE_RC_FILE2 */ 1054c8945a0SNathan Whitehorn #define COLOR_DATA(upr) , \ 1064c8945a0SNathan Whitehorn concat(DLGC_FG_,upr), \ 1074c8945a0SNathan Whitehorn concat(DLGC_BG_,upr), \ 1084c8945a0SNathan Whitehorn concat(DLGC_HL_,upr) 109*a96ef450SBaptiste Daroussin #endif /* HAVE_RC_FILE2 */ 110*a96ef450SBaptiste Daroussin #else /* HAVE_COLOR */ 1114c8945a0SNathan Whitehorn #define COLOR_DATA(upr) /*nothing */ 112*a96ef450SBaptiste Daroussin #endif /* HAVE_COLOR */ 1134c8945a0SNathan Whitehorn 114682c9e0fSNathan Whitehorn #define UseShadow(dw) ((dw) != 0 && (dw)->normal != 0 && (dw)->shadow != 0) 115682c9e0fSNathan Whitehorn 1164c8945a0SNathan Whitehorn /* 1174c8945a0SNathan Whitehorn * Table of color and attribute values, default is for mono display. 1182a3e3873SBaptiste Daroussin * The order matches the DIALOG_ATR() values. 1194c8945a0SNathan Whitehorn */ 120*a96ef450SBaptiste Daroussin #define DATA(atr,upr,lwr,cmt) { atr COLOR_DATA(upr) RC_DATA(lwr,cmt) } 1214c8945a0SNathan Whitehorn /* *INDENT-OFF* */ 1224c8945a0SNathan Whitehorn DIALOG_COLORS dlg_color_table[] = 1234c8945a0SNathan Whitehorn { 1244c8945a0SNathan Whitehorn DATA(A_NORMAL, SCREEN, screen, "Screen"), 1254c8945a0SNathan Whitehorn DATA(A_NORMAL, SHADOW, shadow, "Shadow"), 1264c8945a0SNathan Whitehorn DATA(A_REVERSE, DIALOG, dialog, "Dialog box"), 1274c8945a0SNathan Whitehorn DATA(A_REVERSE, TITLE, title, "Dialog box title"), 1284c8945a0SNathan Whitehorn DATA(A_REVERSE, BORDER, border, "Dialog box border"), 1294c8945a0SNathan Whitehorn DATA(A_BOLD, BUTTON_ACTIVE, button_active, "Active button"), 1304c8945a0SNathan Whitehorn DATA(A_DIM, BUTTON_INACTIVE, button_inactive, "Inactive button"), 1314c8945a0SNathan Whitehorn DATA(A_UNDERLINE, BUTTON_KEY_ACTIVE, button_key_active, "Active button key"), 1324c8945a0SNathan Whitehorn DATA(A_UNDERLINE, BUTTON_KEY_INACTIVE, button_key_inactive, "Inactive button key"), 1334c8945a0SNathan Whitehorn DATA(A_NORMAL, BUTTON_LABEL_ACTIVE, button_label_active, "Active button label"), 1344c8945a0SNathan Whitehorn DATA(A_NORMAL, BUTTON_LABEL_INACTIVE, button_label_inactive, "Inactive button label"), 1354c8945a0SNathan Whitehorn DATA(A_REVERSE, INPUTBOX, inputbox, "Input box"), 1364c8945a0SNathan Whitehorn DATA(A_REVERSE, INPUTBOX_BORDER, inputbox_border, "Input box border"), 1374c8945a0SNathan Whitehorn DATA(A_REVERSE, SEARCHBOX, searchbox, "Search box"), 1384c8945a0SNathan Whitehorn DATA(A_REVERSE, SEARCHBOX_TITLE, searchbox_title, "Search box title"), 1394c8945a0SNathan Whitehorn DATA(A_REVERSE, SEARCHBOX_BORDER, searchbox_border, "Search box border"), 1404c8945a0SNathan Whitehorn DATA(A_REVERSE, POSITION_INDICATOR, position_indicator, "File position indicator"), 1414c8945a0SNathan Whitehorn DATA(A_REVERSE, MENUBOX, menubox, "Menu box"), 1424c8945a0SNathan Whitehorn DATA(A_REVERSE, MENUBOX_BORDER, menubox_border, "Menu box border"), 1434c8945a0SNathan Whitehorn DATA(A_REVERSE, ITEM, item, "Item"), 1444c8945a0SNathan Whitehorn DATA(A_NORMAL, ITEM_SELECTED, item_selected, "Selected item"), 1454c8945a0SNathan Whitehorn DATA(A_REVERSE, TAG, tag, "Tag"), 1464c8945a0SNathan Whitehorn DATA(A_REVERSE, TAG_SELECTED, tag_selected, "Selected tag"), 1474c8945a0SNathan Whitehorn DATA(A_NORMAL, TAG_KEY, tag_key, "Tag key"), 1484c8945a0SNathan Whitehorn DATA(A_BOLD, TAG_KEY_SELECTED, tag_key_selected, "Selected tag key"), 1494c8945a0SNathan Whitehorn DATA(A_REVERSE, CHECK, check, "Check box"), 1504c8945a0SNathan Whitehorn DATA(A_REVERSE, CHECK_SELECTED, check_selected, "Selected check box"), 1514c8945a0SNathan Whitehorn DATA(A_REVERSE, UARROW, uarrow, "Up arrow"), 1524c8945a0SNathan Whitehorn DATA(A_REVERSE, DARROW, darrow, "Down arrow"), 1534c8945a0SNathan Whitehorn DATA(A_NORMAL, ITEMHELP, itemhelp, "Item help-text"), 1544c8945a0SNathan Whitehorn DATA(A_BOLD, FORM_ACTIVE_TEXT, form_active_text, "Active form text"), 1554c8945a0SNathan Whitehorn DATA(A_REVERSE, FORM_TEXT, form_text, "Form text"), 1567a1c0d96SNathan Whitehorn DATA(A_NORMAL, FORM_ITEM_READONLY, form_item_readonly, "Readonly form item"), 1572a3e3873SBaptiste Daroussin DATA(A_REVERSE, GAUGE, gauge, "Dialog box gauge"), 1582a3e3873SBaptiste Daroussin DATA(A_REVERSE, BORDER2, border2, "Dialog box border2"), 1592a3e3873SBaptiste Daroussin DATA(A_REVERSE, INPUTBOX_BORDER2, inputbox_border2, "Input box border2"), 1602a3e3873SBaptiste Daroussin DATA(A_REVERSE, SEARCHBOX_BORDER2, searchbox_border2, "Search box border2"), 1612a3e3873SBaptiste Daroussin DATA(A_REVERSE, MENUBOX_BORDER2, menubox_border2, "Menu box border2") 1624c8945a0SNathan Whitehorn }; 163*a96ef450SBaptiste Daroussin #undef DATA 1644c8945a0SNathan Whitehorn /* *INDENT-ON* */ 1654c8945a0SNathan Whitehorn 1664c8945a0SNathan Whitehorn /* 1672a3e3873SBaptiste Daroussin * Maintain a list of subwindows so that we can delete them to cleanup. 1682a3e3873SBaptiste Daroussin * More important, this provides a fallback when wgetparent() is not available. 1692a3e3873SBaptiste Daroussin */ 1702a3e3873SBaptiste Daroussin static void 1712a3e3873SBaptiste Daroussin add_subwindow(WINDOW *parent, WINDOW *child) 1722a3e3873SBaptiste Daroussin { 1732a3e3873SBaptiste Daroussin DIALOG_WINDOWS *p = dlg_calloc(DIALOG_WINDOWS, 1); 1742a3e3873SBaptiste Daroussin 1752a3e3873SBaptiste Daroussin if (p != 0) { 1762a3e3873SBaptiste Daroussin p->normal = parent; 1772a3e3873SBaptiste Daroussin p->shadow = child; 178*a96ef450SBaptiste Daroussin p->getc_timeout = WTIMEOUT_OFF; 1792a3e3873SBaptiste Daroussin p->next = dialog_state.all_subwindows; 1802a3e3873SBaptiste Daroussin dialog_state.all_subwindows = p; 1812a3e3873SBaptiste Daroussin } 1822a3e3873SBaptiste Daroussin } 1832a3e3873SBaptiste Daroussin 1842a3e3873SBaptiste Daroussin static void 1852a3e3873SBaptiste Daroussin del_subwindows(WINDOW *parent) 1862a3e3873SBaptiste Daroussin { 1872a3e3873SBaptiste Daroussin DIALOG_WINDOWS *p = dialog_state.all_subwindows; 1882a3e3873SBaptiste Daroussin DIALOG_WINDOWS *q = 0; 1892a3e3873SBaptiste Daroussin DIALOG_WINDOWS *r; 1902a3e3873SBaptiste Daroussin 1912a3e3873SBaptiste Daroussin while (p != 0) { 1922a3e3873SBaptiste Daroussin if (p->normal == parent) { 1932a3e3873SBaptiste Daroussin delwin(p->shadow); 1942a3e3873SBaptiste Daroussin r = p->next; 1952a3e3873SBaptiste Daroussin if (q == 0) { 1962a3e3873SBaptiste Daroussin dialog_state.all_subwindows = r; 1972a3e3873SBaptiste Daroussin } else { 1982a3e3873SBaptiste Daroussin q->next = r; 1992a3e3873SBaptiste Daroussin } 2002a3e3873SBaptiste Daroussin free(p); 2012a3e3873SBaptiste Daroussin p = r; 2022a3e3873SBaptiste Daroussin } else { 2032a3e3873SBaptiste Daroussin q = p; 2042a3e3873SBaptiste Daroussin p = p->next; 2052a3e3873SBaptiste Daroussin } 2062a3e3873SBaptiste Daroussin } 2072a3e3873SBaptiste Daroussin } 2082a3e3873SBaptiste Daroussin 2092a3e3873SBaptiste Daroussin /* 2104c8945a0SNathan Whitehorn * Display background title if it exists ... 2114c8945a0SNathan Whitehorn */ 2124c8945a0SNathan Whitehorn void 2134c8945a0SNathan Whitehorn dlg_put_backtitle(void) 2144c8945a0SNathan Whitehorn { 2154c8945a0SNathan Whitehorn 2164c8945a0SNathan Whitehorn if (dialog_vars.backtitle != NULL) { 2174c8945a0SNathan Whitehorn chtype attr = A_NORMAL; 2184c8945a0SNathan Whitehorn int backwidth = dlg_count_columns(dialog_vars.backtitle); 219*a96ef450SBaptiste Daroussin int i; 2204c8945a0SNathan Whitehorn 221f4f33ea0SBaptiste Daroussin dlg_attrset(stdscr, screen_attr); 2224c8945a0SNathan Whitehorn (void) wmove(stdscr, 0, 1); 2234c8945a0SNathan Whitehorn dlg_print_text(stdscr, dialog_vars.backtitle, COLS - 2, &attr); 2244c8945a0SNathan Whitehorn for (i = 0; i < COLS - backwidth; i++) 2254c8945a0SNathan Whitehorn (void) waddch(stdscr, ' '); 2264c8945a0SNathan Whitehorn (void) wmove(stdscr, 1, 1); 2274c8945a0SNathan Whitehorn for (i = 0; i < COLS - 2; i++) 2284c8945a0SNathan Whitehorn (void) waddch(stdscr, dlg_boxchar(ACS_HLINE)); 2294c8945a0SNathan Whitehorn } 2304c8945a0SNathan Whitehorn 2314c8945a0SNathan Whitehorn (void) wnoutrefresh(stdscr); 2324c8945a0SNathan Whitehorn } 2334c8945a0SNathan Whitehorn 2344c8945a0SNathan Whitehorn /* 2354c8945a0SNathan Whitehorn * Set window to attribute 'attr'. There are more efficient ways to do this, 2364c8945a0SNathan Whitehorn * but will not work on older/buggy ncurses versions. 2374c8945a0SNathan Whitehorn */ 2384c8945a0SNathan Whitehorn void 2394c8945a0SNathan Whitehorn dlg_attr_clear(WINDOW *win, int height, int width, chtype attr) 2404c8945a0SNathan Whitehorn { 2414c8945a0SNathan Whitehorn int i, j; 2424c8945a0SNathan Whitehorn 243f4f33ea0SBaptiste Daroussin dlg_attrset(win, attr); 2444c8945a0SNathan Whitehorn for (i = 0; i < height; i++) { 2454c8945a0SNathan Whitehorn (void) wmove(win, i, 0); 2464c8945a0SNathan Whitehorn for (j = 0; j < width; j++) 2474c8945a0SNathan Whitehorn (void) waddch(win, ' '); 2484c8945a0SNathan Whitehorn } 2494c8945a0SNathan Whitehorn (void) touchwin(win); 2504c8945a0SNathan Whitehorn } 2514c8945a0SNathan Whitehorn 2524c8945a0SNathan Whitehorn void 2534c8945a0SNathan Whitehorn dlg_clear(void) 2544c8945a0SNathan Whitehorn { 2554c8945a0SNathan Whitehorn dlg_attr_clear(stdscr, LINES, COLS, screen_attr); 2564c8945a0SNathan Whitehorn } 2574c8945a0SNathan Whitehorn 258*a96ef450SBaptiste Daroussin #ifdef KEY_RESIZE 259*a96ef450SBaptiste Daroussin void 260*a96ef450SBaptiste Daroussin _dlg_resize_cleanup(WINDOW *w) 261*a96ef450SBaptiste Daroussin { 262*a96ef450SBaptiste Daroussin dlg_clear(); 263*a96ef450SBaptiste Daroussin dlg_put_backtitle(); 264*a96ef450SBaptiste Daroussin dlg_del_window(w); 265*a96ef450SBaptiste Daroussin dlg_mouse_free_regions(); 266*a96ef450SBaptiste Daroussin } 267*a96ef450SBaptiste Daroussin #endif /* KEY_RESIZE */ 268*a96ef450SBaptiste Daroussin 2694c8945a0SNathan Whitehorn #define isprivate(s) ((s) != 0 && strstr(s, "\033[?") != 0) 2704c8945a0SNathan Whitehorn 2714c8945a0SNathan Whitehorn #define TTY_DEVICE "/dev/tty" 2724c8945a0SNathan Whitehorn 2734c8945a0SNathan Whitehorn /* 2744c8945a0SNathan Whitehorn * If $DIALOG_TTY exists, allow the program to try to open the terminal 2754c8945a0SNathan Whitehorn * directly when stdout is redirected. By default we require the "--stdout" 2764c8945a0SNathan Whitehorn * option to be given, but some scripts were written making use of the 2774c8945a0SNathan Whitehorn * behavior of dialog which tried opening the terminal anyway. 2784c8945a0SNathan Whitehorn */ 279*a96ef450SBaptiste Daroussin #define dialog_tty() (dlg_getenv_num("DIALOG_TTY", (int *)0) > 0) 2804c8945a0SNathan Whitehorn 2814c8945a0SNathan Whitehorn /* 2824c8945a0SNathan Whitehorn * Open the terminal directly. If one of stdin, stdout or stderr really points 2834c8945a0SNathan Whitehorn * to a tty, use it. Otherwise give up and open /dev/tty. 2844c8945a0SNathan Whitehorn */ 2854c8945a0SNathan Whitehorn static int 2864c8945a0SNathan Whitehorn open_terminal(char **result, int mode) 2874c8945a0SNathan Whitehorn { 2884c8945a0SNathan Whitehorn const char *device = TTY_DEVICE; 2894c8945a0SNathan Whitehorn if (!isatty(fileno(stderr)) 2904c8945a0SNathan Whitehorn || (device = ttyname(fileno(stderr))) == 0) { 2914c8945a0SNathan Whitehorn if (!isatty(fileno(stdout)) 2924c8945a0SNathan Whitehorn || (device = ttyname(fileno(stdout))) == 0) { 2934c8945a0SNathan Whitehorn if (!isatty(fileno(stdin)) 2944c8945a0SNathan Whitehorn || (device = ttyname(fileno(stdin))) == 0) { 2954c8945a0SNathan Whitehorn device = TTY_DEVICE; 2964c8945a0SNathan Whitehorn } 2974c8945a0SNathan Whitehorn } 2984c8945a0SNathan Whitehorn } 2994c8945a0SNathan Whitehorn *result = dlg_strclone(device); 3004c8945a0SNathan Whitehorn return open(device, mode); 3014c8945a0SNathan Whitehorn } 3024c8945a0SNathan Whitehorn 303*a96ef450SBaptiste Daroussin #if CAN_KEEP_TITE 3042a3e3873SBaptiste Daroussin static int 3052a3e3873SBaptiste Daroussin my_putc(int ch) 3062a3e3873SBaptiste Daroussin { 3072a3e3873SBaptiste Daroussin char buffer[2]; 3082a3e3873SBaptiste Daroussin int fd = fileno(dialog_state.screen_output); 3092a3e3873SBaptiste Daroussin 3102a3e3873SBaptiste Daroussin buffer[0] = (char) ch; 3112a3e3873SBaptiste Daroussin return (int) write(fd, buffer, (size_t) 1); 3122a3e3873SBaptiste Daroussin } 3132a3e3873SBaptiste Daroussin #endif 3142a3e3873SBaptiste Daroussin 3154c8945a0SNathan Whitehorn /* 3164c8945a0SNathan Whitehorn * Do some initialization for dialog. 3174c8945a0SNathan Whitehorn * 3184c8945a0SNathan Whitehorn * 'input' is the real tty input of dialog. Usually it is stdin, but if 3194c8945a0SNathan Whitehorn * --input-fd option is used, it may be anything. 3204c8945a0SNathan Whitehorn * 3214c8945a0SNathan Whitehorn * 'output' is where dialog will send its result. Usually it is stderr, but 3224c8945a0SNathan Whitehorn * if --stdout or --output-fd is used, it may be anything. We are concerned 3234c8945a0SNathan Whitehorn * mainly with the case where it happens to be the same as stdout. 3244c8945a0SNathan Whitehorn */ 3254c8945a0SNathan Whitehorn void 3264c8945a0SNathan Whitehorn init_dialog(FILE *input, FILE *output) 3274c8945a0SNathan Whitehorn { 3284c8945a0SNathan Whitehorn int fd1, fd2; 3294c8945a0SNathan Whitehorn char *device = 0; 3304c8945a0SNathan Whitehorn 3312a3e3873SBaptiste Daroussin setlocale(LC_ALL, ""); 3322a3e3873SBaptiste Daroussin 3334c8945a0SNathan Whitehorn dialog_state.output = output; 334*a96ef450SBaptiste Daroussin if (dialog_state.tab_len == 0) 3354c8945a0SNathan Whitehorn dialog_state.tab_len = TAB_LEN; 336*a96ef450SBaptiste Daroussin if (dialog_state.aspect_ratio == 0) 3374c8945a0SNathan Whitehorn dialog_state.aspect_ratio = DEFAULT_ASPECT_RATIO; 3384c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 3394c8945a0SNathan Whitehorn dialog_state.use_colors = USE_COLORS; /* use colors by default? */ 3404c8945a0SNathan Whitehorn dialog_state.use_shadow = USE_SHADOW; /* shadow dialog boxes by default? */ 3414c8945a0SNathan Whitehorn #endif 3424c8945a0SNathan Whitehorn 3434c8945a0SNathan Whitehorn #ifdef HAVE_RC_FILE 3444c8945a0SNathan Whitehorn if (dlg_parse_rc() == -1) /* Read the configuration file */ 3454c8945a0SNathan Whitehorn dlg_exiterr("init_dialog: dlg_parse_rc"); 3464c8945a0SNathan Whitehorn #endif 3474c8945a0SNathan Whitehorn 3484c8945a0SNathan Whitehorn /* 3494c8945a0SNathan Whitehorn * Some widgets (such as gauge) may read from the standard input. Pipes 3504c8945a0SNathan Whitehorn * only connect stdout/stdin, so there is not much choice. But reading a 3514c8945a0SNathan Whitehorn * pipe would get in the way of curses' normal reading stdin for getch. 3524c8945a0SNathan Whitehorn * 3534c8945a0SNathan Whitehorn * As in the --stdout (see below), reopening the terminal does not always 3544c8945a0SNathan Whitehorn * work properly. dialog provides a --pipe-fd option for this purpose. We 3554c8945a0SNathan Whitehorn * test that case first (differing fileno's for input/stdin). If the 3564c8945a0SNathan Whitehorn * fileno's are equal, but we're not reading from a tty, see if we can open 3574c8945a0SNathan Whitehorn * /dev/tty. 3584c8945a0SNathan Whitehorn */ 3594c8945a0SNathan Whitehorn dialog_state.pipe_input = stdin; 3604c8945a0SNathan Whitehorn if (fileno(input) != fileno(stdin)) { 36119718649SNathan Whitehorn if ((fd1 = dup(fileno(input))) >= 0 3624c8945a0SNathan Whitehorn && (fd2 = dup(fileno(stdin))) >= 0) { 3634c8945a0SNathan Whitehorn (void) dup2(fileno(input), fileno(stdin)); 3644c8945a0SNathan Whitehorn dialog_state.pipe_input = fdopen(fd2, "r"); 3654c8945a0SNathan Whitehorn if (fileno(stdin) != 0) /* some functions may read fd #0 */ 3664c8945a0SNathan Whitehorn (void) dup2(fileno(stdin), 0); 3672a3e3873SBaptiste Daroussin } else { 3684c8945a0SNathan Whitehorn dlg_exiterr("cannot open tty-input"); 3692a3e3873SBaptiste Daroussin } 3702a3e3873SBaptiste Daroussin close(fd1); 3714c8945a0SNathan Whitehorn } else if (!isatty(fileno(stdin))) { 3722a3e3873SBaptiste Daroussin if ((fd1 = open_terminal(&device, O_RDONLY)) >= 0) { 3732a3e3873SBaptiste Daroussin if ((fd2 = dup(fileno(stdin))) >= 0) { 3744c8945a0SNathan Whitehorn dialog_state.pipe_input = fdopen(fd2, "r"); 3754c8945a0SNathan Whitehorn if (freopen(device, "r", stdin) == 0) 3764c8945a0SNathan Whitehorn dlg_exiterr("cannot open tty-input"); 3774c8945a0SNathan Whitehorn if (fileno(stdin) != 0) /* some functions may read fd #0 */ 3784c8945a0SNathan Whitehorn (void) dup2(fileno(stdin), 0); 3794c8945a0SNathan Whitehorn } 3802a3e3873SBaptiste Daroussin close(fd1); 3812a3e3873SBaptiste Daroussin } 3824c8945a0SNathan Whitehorn free(device); 3834c8945a0SNathan Whitehorn } 3844c8945a0SNathan Whitehorn 3854c8945a0SNathan Whitehorn /* 3864c8945a0SNathan Whitehorn * If stdout is not a tty and dialog is called with the --stdout option, we 3874c8945a0SNathan Whitehorn * have to provide for a way to write to the screen. 3884c8945a0SNathan Whitehorn * 3894c8945a0SNathan Whitehorn * The curses library normally writes its output to stdout, leaving stderr 3904c8945a0SNathan Whitehorn * free for scripting. Scripts are simpler when stdout is redirected. The 3914c8945a0SNathan Whitehorn * newterm function is useful; it allows us to specify where the output 3924c8945a0SNathan Whitehorn * goes. Reopening the terminal is not portable since several 3934c8945a0SNathan Whitehorn * configurations do not allow this to work properly: 3944c8945a0SNathan Whitehorn * 3954c8945a0SNathan Whitehorn * a) some getty implementations (and possibly broken tty drivers, e.g., on 3964c8945a0SNathan Whitehorn * HPUX 10 and 11) cause stdin to act as if it is still in cooked mode 3974c8945a0SNathan Whitehorn * even though results from ioctl's state that it is successfully 3984c8945a0SNathan Whitehorn * altered to raw mode. Broken is the proper term. 3994c8945a0SNathan Whitehorn * 4004c8945a0SNathan Whitehorn * b) the user may not have permissions on the device, e.g., if one su's 4014c8945a0SNathan Whitehorn * from the login user to another non-privileged user. 4024c8945a0SNathan Whitehorn */ 4034c8945a0SNathan Whitehorn if (!isatty(fileno(stdout)) 4044c8945a0SNathan Whitehorn && (fileno(stdout) == fileno(output) || dialog_tty())) { 4054c8945a0SNathan Whitehorn if ((fd1 = open_terminal(&device, O_WRONLY)) >= 0 4064c8945a0SNathan Whitehorn && (dialog_state.screen_output = fdopen(fd1, "w")) != 0) { 4074c8945a0SNathan Whitehorn if (newterm(NULL, dialog_state.screen_output, stdin) == 0) { 4084c8945a0SNathan Whitehorn dlg_exiterr("cannot initialize curses"); 4094c8945a0SNathan Whitehorn } 4104c8945a0SNathan Whitehorn free(device); 4114c8945a0SNathan Whitehorn } else { 4124c8945a0SNathan Whitehorn dlg_exiterr("cannot open tty-output"); 4134c8945a0SNathan Whitehorn } 4144c8945a0SNathan Whitehorn } else { 4154c8945a0SNathan Whitehorn dialog_state.screen_output = stdout; 4164c8945a0SNathan Whitehorn (void) initscr(); 4174c8945a0SNathan Whitehorn } 418*a96ef450SBaptiste Daroussin dlg_keep_tite(dialog_state.screen_output); 4194c8945a0SNathan Whitehorn #ifdef HAVE_FLUSHINP 4204c8945a0SNathan Whitehorn (void) flushinp(); 4214c8945a0SNathan Whitehorn #endif 4224c8945a0SNathan Whitehorn (void) keypad(stdscr, TRUE); 4234c8945a0SNathan Whitehorn (void) cbreak(); 4244c8945a0SNathan Whitehorn (void) noecho(); 4257a1c0d96SNathan Whitehorn 4267a1c0d96SNathan Whitehorn if (!dialog_state.no_mouse) { 4274c8945a0SNathan Whitehorn mouse_open(); 4287a1c0d96SNathan Whitehorn } 4297a1c0d96SNathan Whitehorn 4304c8945a0SNathan Whitehorn dialog_state.screen_initialized = TRUE; 4314c8945a0SNathan Whitehorn 4324c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 4334c8945a0SNathan Whitehorn if (dialog_state.use_colors || dialog_state.use_shadow) 4344c8945a0SNathan Whitehorn dlg_color_setup(); /* Set up colors */ 4354c8945a0SNathan Whitehorn #endif 4364c8945a0SNathan Whitehorn 4374c8945a0SNathan Whitehorn /* Set screen to screen attribute */ 4384c8945a0SNathan Whitehorn dlg_clear(); 4394c8945a0SNathan Whitehorn } 4404c8945a0SNathan Whitehorn 441*a96ef450SBaptiste Daroussin void 442*a96ef450SBaptiste Daroussin dlg_keep_tite(FILE *output) 443*a96ef450SBaptiste Daroussin { 444*a96ef450SBaptiste Daroussin if (!dialog_vars.keep_tite) { 445*a96ef450SBaptiste Daroussin #if CAN_KEEP_TITE 446*a96ef450SBaptiste Daroussin /* 447*a96ef450SBaptiste Daroussin * Cancel xterm's alternate-screen mode. 448*a96ef450SBaptiste Daroussin */ 449*a96ef450SBaptiste Daroussin if ((fileno(output) != fileno(stdout) 450*a96ef450SBaptiste Daroussin || isatty(fileno(output))) 451*a96ef450SBaptiste Daroussin && key_mouse != 0 /* xterm and kindred */ 452*a96ef450SBaptiste Daroussin && isprivate(enter_ca_mode) 453*a96ef450SBaptiste Daroussin && isprivate(exit_ca_mode)) { 454*a96ef450SBaptiste Daroussin FILE *save = dialog_state.screen_output; 455*a96ef450SBaptiste Daroussin 456*a96ef450SBaptiste Daroussin /* 457*a96ef450SBaptiste Daroussin * initscr() or newterm() already wrote enter_ca_mode as a side 458*a96ef450SBaptiste Daroussin * effect of initializing the screen. It would be nice to not even 459*a96ef450SBaptiste Daroussin * do that, but we do not really have access to the correct copy of 460*a96ef450SBaptiste Daroussin * the terminfo description until those functions have been 461*a96ef450SBaptiste Daroussin * invoked. 462*a96ef450SBaptiste Daroussin */ 463*a96ef450SBaptiste Daroussin (void) refresh(); 464*a96ef450SBaptiste Daroussin dialog_state.screen_output = output; 465*a96ef450SBaptiste Daroussin (void) tputs(exit_ca_mode, 0, my_putc); 466*a96ef450SBaptiste Daroussin (void) tputs(clear_screen, 0, my_putc); 467*a96ef450SBaptiste Daroussin dialog_state.screen_output = save; 468*a96ef450SBaptiste Daroussin 469*a96ef450SBaptiste Daroussin /* 470*a96ef450SBaptiste Daroussin * Prevent ncurses from switching "back" to the normal screen when 471*a96ef450SBaptiste Daroussin * exiting from dialog. That would move the cursor to the original 472*a96ef450SBaptiste Daroussin * location saved in xterm. Normally curses sets the cursor 473*a96ef450SBaptiste Daroussin * position to the first line after the display, but the alternate 474*a96ef450SBaptiste Daroussin * screen switching is done after that point. 475*a96ef450SBaptiste Daroussin * 476*a96ef450SBaptiste Daroussin * Cancelling the strings altogether also works around the buggy 477*a96ef450SBaptiste Daroussin * implementation of alternate-screen in rxvt, etc., which clear 478*a96ef450SBaptiste Daroussin * more of the display than they should. 479*a96ef450SBaptiste Daroussin */ 480*a96ef450SBaptiste Daroussin enter_ca_mode = 0; 481*a96ef450SBaptiste Daroussin exit_ca_mode = 0; 482*a96ef450SBaptiste Daroussin } 483*a96ef450SBaptiste Daroussin #else 484*a96ef450SBaptiste Daroussin /* 485*a96ef450SBaptiste Daroussin * For other implementations, there are no useful answers: 486*a96ef450SBaptiste Daroussin * + SVr4 curses "could" support a similar approach, but the clue about 487*a96ef450SBaptiste Daroussin * xterm is absent from its terminal database. 488*a96ef450SBaptiste Daroussin * + PDCurses does not provide terminfo. 489*a96ef450SBaptiste Daroussin */ 490*a96ef450SBaptiste Daroussin (void) output; 491*a96ef450SBaptiste Daroussin #endif 492*a96ef450SBaptiste Daroussin } 493*a96ef450SBaptiste Daroussin } 494*a96ef450SBaptiste Daroussin 4954c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 4964c8945a0SNathan Whitehorn static int defined_colors = 1; /* pair-0 is reserved */ 4974c8945a0SNathan Whitehorn /* 4984c8945a0SNathan Whitehorn * Setup for color display 4994c8945a0SNathan Whitehorn */ 5004c8945a0SNathan Whitehorn void 5014c8945a0SNathan Whitehorn dlg_color_setup(void) 5024c8945a0SNathan Whitehorn { 503*a96ef450SBaptiste Daroussin if (has_colors()) { /* Terminal supports color? */ 5044c8945a0SNathan Whitehorn unsigned i; 5054c8945a0SNathan Whitehorn 5064c8945a0SNathan Whitehorn (void) start_color(); 5074c8945a0SNathan Whitehorn 5084c8945a0SNathan Whitehorn #if defined(HAVE_USE_DEFAULT_COLORS) 5094c8945a0SNathan Whitehorn use_default_colors(); 5104c8945a0SNathan Whitehorn #endif 5114c8945a0SNathan Whitehorn 5124c8945a0SNathan Whitehorn #if defined(__NetBSD__) && defined(_CURSES_) 5134c8945a0SNathan Whitehorn #define C_ATTR(x,y) (((x) != 0 ? A_BOLD : 0) | COLOR_PAIR((y))) 5144c8945a0SNathan Whitehorn /* work around bug in NetBSD curses */ 5154c8945a0SNathan Whitehorn for (i = 0; i < sizeof(dlg_color_table) / 5164c8945a0SNathan Whitehorn sizeof(dlg_color_table[0]); i++) { 5174c8945a0SNathan Whitehorn 5184c8945a0SNathan Whitehorn /* Initialize color pairs */ 5194c8945a0SNathan Whitehorn (void) init_pair(i + 1, 5204c8945a0SNathan Whitehorn dlg_color_table[i].fg, 5214c8945a0SNathan Whitehorn dlg_color_table[i].bg); 5224c8945a0SNathan Whitehorn 5234c8945a0SNathan Whitehorn /* Setup color attributes */ 5244c8945a0SNathan Whitehorn dlg_color_table[i].atr = C_ATTR(dlg_color_table[i].hilite, i + 1); 5254c8945a0SNathan Whitehorn } 5264c8945a0SNathan Whitehorn defined_colors = i + 1; 5274c8945a0SNathan Whitehorn #else 5284c8945a0SNathan Whitehorn for (i = 0; i < sizeof(dlg_color_table) / 5294c8945a0SNathan Whitehorn sizeof(dlg_color_table[0]); i++) { 5304c8945a0SNathan Whitehorn 5314c8945a0SNathan Whitehorn /* Initialize color pairs */ 532*a96ef450SBaptiste Daroussin chtype atr = dlg_color_pair(dlg_color_table[i].fg, 5334c8945a0SNathan Whitehorn dlg_color_table[i].bg); 5344c8945a0SNathan Whitehorn 535*a96ef450SBaptiste Daroussin atr |= (dlg_color_table[i].hilite ? A_BOLD : 0); 536*a96ef450SBaptiste Daroussin #ifdef HAVE_RC_FILE2 537*a96ef450SBaptiste Daroussin atr |= (dlg_color_table[i].ul ? A_UNDERLINE : 0); 538*a96ef450SBaptiste Daroussin atr |= (dlg_color_table[i].rv ? A_REVERSE : 0); 539*a96ef450SBaptiste Daroussin #endif /* HAVE_RC_FILE2 */ 540*a96ef450SBaptiste Daroussin 541*a96ef450SBaptiste Daroussin dlg_color_table[i].atr = atr; 5424c8945a0SNathan Whitehorn } 5434c8945a0SNathan Whitehorn #endif 5444c8945a0SNathan Whitehorn } else { 5454c8945a0SNathan Whitehorn dialog_state.use_colors = FALSE; 5464c8945a0SNathan Whitehorn dialog_state.use_shadow = FALSE; 5474c8945a0SNathan Whitehorn } 5484c8945a0SNathan Whitehorn } 5494c8945a0SNathan Whitehorn 5504c8945a0SNathan Whitehorn int 5514c8945a0SNathan Whitehorn dlg_color_count(void) 5524c8945a0SNathan Whitehorn { 553*a96ef450SBaptiste Daroussin return TableSize(dlg_color_table); 5544c8945a0SNathan Whitehorn } 5554c8945a0SNathan Whitehorn 5564c8945a0SNathan Whitehorn /* 5577a1c0d96SNathan Whitehorn * Wrapper for getattrs(), or the more cumbersome X/Open wattr_get(). 5587a1c0d96SNathan Whitehorn */ 5597a1c0d96SNathan Whitehorn chtype 5607a1c0d96SNathan Whitehorn dlg_get_attrs(WINDOW *win) 5617a1c0d96SNathan Whitehorn { 5627a1c0d96SNathan Whitehorn chtype result; 5637a1c0d96SNathan Whitehorn #ifdef HAVE_GETATTRS 564682c9e0fSNathan Whitehorn result = (chtype) getattrs(win); 5657a1c0d96SNathan Whitehorn #else 5667a1c0d96SNathan Whitehorn attr_t my_result; 5677a1c0d96SNathan Whitehorn short my_pair; 5687a1c0d96SNathan Whitehorn wattr_get(win, &my_result, &my_pair, NULL); 5697a1c0d96SNathan Whitehorn result = my_result; 5707a1c0d96SNathan Whitehorn #endif 5717a1c0d96SNathan Whitehorn return result; 5727a1c0d96SNathan Whitehorn } 5737a1c0d96SNathan Whitehorn 5747a1c0d96SNathan Whitehorn /* 5754c8945a0SNathan Whitehorn * Reuse color pairs (they are limited), returning a COLOR_PAIR() value if we 5764c8945a0SNathan Whitehorn * have (or can) define a pair with the given color as foreground on the 5774c8945a0SNathan Whitehorn * window's defined background. 5784c8945a0SNathan Whitehorn */ 5794c8945a0SNathan Whitehorn chtype 5804c8945a0SNathan Whitehorn dlg_color_pair(int foreground, int background) 5814c8945a0SNathan Whitehorn { 5824c8945a0SNathan Whitehorn chtype result = 0; 5834c8945a0SNathan Whitehorn int pair; 5844c8945a0SNathan Whitehorn short fg, bg; 5854c8945a0SNathan Whitehorn bool found = FALSE; 5864c8945a0SNathan Whitehorn 5874c8945a0SNathan Whitehorn for (pair = 1; pair < defined_colors; ++pair) { 5884c8945a0SNathan Whitehorn if (pair_content((short) pair, &fg, &bg) != ERR 5894c8945a0SNathan Whitehorn && fg == foreground 5904c8945a0SNathan Whitehorn && bg == background) { 5914c8945a0SNathan Whitehorn result = (chtype) COLOR_PAIR(pair); 5924c8945a0SNathan Whitehorn found = TRUE; 5934c8945a0SNathan Whitehorn break; 5944c8945a0SNathan Whitehorn } 5954c8945a0SNathan Whitehorn } 5964c8945a0SNathan Whitehorn if (!found && (defined_colors + 1) < COLOR_PAIRS) { 5974c8945a0SNathan Whitehorn pair = defined_colors++; 5984c8945a0SNathan Whitehorn (void) init_pair((short) pair, (short) foreground, (short) background); 5994c8945a0SNathan Whitehorn result = (chtype) COLOR_PAIR(pair); 6004c8945a0SNathan Whitehorn } 6014c8945a0SNathan Whitehorn return result; 6024c8945a0SNathan Whitehorn } 6034c8945a0SNathan Whitehorn 6044c8945a0SNathan Whitehorn /* 6054c8945a0SNathan Whitehorn * Reuse color pairs (they are limited), returning a COLOR_PAIR() value if we 6064c8945a0SNathan Whitehorn * have (or can) define a pair with the given color as foreground on the 6074c8945a0SNathan Whitehorn * window's defined background. 6084c8945a0SNathan Whitehorn */ 6094c8945a0SNathan Whitehorn static chtype 6104c8945a0SNathan Whitehorn define_color(WINDOW *win, int foreground) 6114c8945a0SNathan Whitehorn { 6124c8945a0SNathan Whitehorn short fg, bg, background; 613f4f33ea0SBaptiste Daroussin if (dialog_state.text_only) { 614f4f33ea0SBaptiste Daroussin background = COLOR_BLACK; 615f4f33ea0SBaptiste Daroussin } else { 616f4f33ea0SBaptiste Daroussin chtype attrs = dlg_get_attrs(win); 617*a96ef450SBaptiste Daroussin int pair; 6184c8945a0SNathan Whitehorn 6194c8945a0SNathan Whitehorn if ((pair = PAIR_NUMBER(attrs)) != 0 6204c8945a0SNathan Whitehorn && pair_content((short) pair, &fg, &bg) != ERR) { 6214c8945a0SNathan Whitehorn background = bg; 6224c8945a0SNathan Whitehorn } else { 6234c8945a0SNathan Whitehorn background = COLOR_BLACK; 6244c8945a0SNathan Whitehorn } 625f4f33ea0SBaptiste Daroussin } 6264c8945a0SNathan Whitehorn return dlg_color_pair(foreground, background); 6274c8945a0SNathan Whitehorn } 6284c8945a0SNathan Whitehorn #endif 6294c8945a0SNathan Whitehorn 6304c8945a0SNathan Whitehorn /* 6314c8945a0SNathan Whitehorn * End using dialog functions. 6324c8945a0SNathan Whitehorn */ 6334c8945a0SNathan Whitehorn void 6344c8945a0SNathan Whitehorn end_dialog(void) 6354c8945a0SNathan Whitehorn { 6364c8945a0SNathan Whitehorn if (dialog_state.screen_initialized) { 6374c8945a0SNathan Whitehorn dialog_state.screen_initialized = FALSE; 638*a96ef450SBaptiste Daroussin if (dialog_vars.erase_on_exit) { 639*a96ef450SBaptiste Daroussin /* 640*a96ef450SBaptiste Daroussin * Clear the screen to the native background color, and leave the 641*a96ef450SBaptiste Daroussin * terminal cursor at the lower-left corner of the screen. 642*a96ef450SBaptiste Daroussin */ 643*a96ef450SBaptiste Daroussin werase(stdscr); 644*a96ef450SBaptiste Daroussin wrefresh(stdscr); 645*a96ef450SBaptiste Daroussin } 6464c8945a0SNathan Whitehorn mouse_close(); 6474c8945a0SNathan Whitehorn (void) endwin(); 6484c8945a0SNathan Whitehorn (void) fflush(stdout); 6494c8945a0SNathan Whitehorn } 6504c8945a0SNathan Whitehorn } 6514c8945a0SNathan Whitehorn 652682c9e0fSNathan Whitehorn #define ESCAPE_LEN 3 6534c8945a0SNathan Whitehorn #define isOurEscape(p) (((p)[0] == '\\') && ((p)[1] == 'Z') && ((p)[2] != 0)) 6544c8945a0SNathan Whitehorn 6552a3e3873SBaptiste Daroussin int 6562a3e3873SBaptiste Daroussin dlg_count_real_columns(const char *text) 6572a3e3873SBaptiste Daroussin { 658febdb468SDevin Teske int result = 0; 659febdb468SDevin Teske if (*text) { 660febdb468SDevin Teske result = dlg_count_columns(text); 6612a3e3873SBaptiste Daroussin if (result && dialog_vars.colors) { 6622a3e3873SBaptiste Daroussin int hidden = 0; 6632a3e3873SBaptiste Daroussin while (*text) { 6642a3e3873SBaptiste Daroussin if (dialog_vars.colors && isOurEscape(text)) { 6652a3e3873SBaptiste Daroussin hidden += ESCAPE_LEN; 6662a3e3873SBaptiste Daroussin text += ESCAPE_LEN; 6672a3e3873SBaptiste Daroussin } else { 6682a3e3873SBaptiste Daroussin ++text; 6692a3e3873SBaptiste Daroussin } 6702a3e3873SBaptiste Daroussin } 6712a3e3873SBaptiste Daroussin result -= hidden; 6722a3e3873SBaptiste Daroussin } 673febdb468SDevin Teske } 6742a3e3873SBaptiste Daroussin return result; 6752a3e3873SBaptiste Daroussin } 6762a3e3873SBaptiste Daroussin 6774c8945a0SNathan Whitehorn static int 6784c8945a0SNathan Whitehorn centered(int width, const char *string) 6794c8945a0SNathan Whitehorn { 6802a3e3873SBaptiste Daroussin int need = dlg_count_real_columns(string); 6814c8945a0SNathan Whitehorn int left; 6824c8945a0SNathan Whitehorn 6832a3e3873SBaptiste Daroussin left = (width - need) / 2 - 1; 6844c8945a0SNathan Whitehorn if (left < 0) 6854c8945a0SNathan Whitehorn left = 0; 6864c8945a0SNathan Whitehorn return left; 6874c8945a0SNathan Whitehorn } 6884c8945a0SNathan Whitehorn 6897a1c0d96SNathan Whitehorn #ifdef USE_WIDE_CURSES 6907a1c0d96SNathan Whitehorn static bool 6917a1c0d96SNathan Whitehorn is_combining(const char *txt, int *combined) 6927a1c0d96SNathan Whitehorn { 6937a1c0d96SNathan Whitehorn bool result = FALSE; 6947a1c0d96SNathan Whitehorn 6957a1c0d96SNathan Whitehorn if (*combined == 0) { 6967a1c0d96SNathan Whitehorn if (UCH(*txt) >= 128) { 6977a1c0d96SNathan Whitehorn wchar_t wch; 6987a1c0d96SNathan Whitehorn mbstate_t state; 6997a1c0d96SNathan Whitehorn size_t given = strlen(txt); 7007a1c0d96SNathan Whitehorn size_t len; 7017a1c0d96SNathan Whitehorn 7027a1c0d96SNathan Whitehorn memset(&state, 0, sizeof(state)); 7037a1c0d96SNathan Whitehorn len = mbrtowc(&wch, txt, given, &state); 7047a1c0d96SNathan Whitehorn if ((int) len > 0 && wcwidth(wch) == 0) { 7057a1c0d96SNathan Whitehorn *combined = (int) len - 1; 7067a1c0d96SNathan Whitehorn result = TRUE; 7077a1c0d96SNathan Whitehorn } 7087a1c0d96SNathan Whitehorn } 7097a1c0d96SNathan Whitehorn } else { 7107a1c0d96SNathan Whitehorn result = TRUE; 7117a1c0d96SNathan Whitehorn *combined -= 1; 7127a1c0d96SNathan Whitehorn } 7137a1c0d96SNathan Whitehorn return result; 7147a1c0d96SNathan Whitehorn } 7157a1c0d96SNathan Whitehorn #endif 7167a1c0d96SNathan Whitehorn 7174c8945a0SNathan Whitehorn /* 7182a3e3873SBaptiste Daroussin * Print the name (tag) or text from a DIALOG_LISTITEM, highlighting the 7192a3e3873SBaptiste Daroussin * first character if selected. 7202a3e3873SBaptiste Daroussin */ 7212a3e3873SBaptiste Daroussin void 7222a3e3873SBaptiste Daroussin dlg_print_listitem(WINDOW *win, 7232a3e3873SBaptiste Daroussin const char *text, 7242a3e3873SBaptiste Daroussin int climit, 7252a3e3873SBaptiste Daroussin bool first, 7262a3e3873SBaptiste Daroussin int selected) 7272a3e3873SBaptiste Daroussin { 7282a3e3873SBaptiste Daroussin chtype attr = A_NORMAL; 7292a3e3873SBaptiste Daroussin int limit; 7302a3e3873SBaptiste Daroussin chtype attrs[4]; 7312a3e3873SBaptiste Daroussin 7322a3e3873SBaptiste Daroussin if (text == 0) 7332a3e3873SBaptiste Daroussin text = ""; 7342a3e3873SBaptiste Daroussin 735*a96ef450SBaptiste Daroussin if (first && !dialog_vars.no_hot_list) { 7362a3e3873SBaptiste Daroussin const int *indx = dlg_index_wchars(text); 7372a3e3873SBaptiste Daroussin attrs[3] = tag_key_selected_attr; 7382a3e3873SBaptiste Daroussin attrs[2] = tag_key_attr; 7392a3e3873SBaptiste Daroussin attrs[1] = tag_selected_attr; 7402a3e3873SBaptiste Daroussin attrs[0] = tag_attr; 7412a3e3873SBaptiste Daroussin 742f4f33ea0SBaptiste Daroussin dlg_attrset(win, selected ? attrs[3] : attrs[2]); 743*a96ef450SBaptiste Daroussin if (*text != '\0') { 7442a3e3873SBaptiste Daroussin (void) waddnstr(win, text, indx[1]); 7452a3e3873SBaptiste Daroussin 7462a3e3873SBaptiste Daroussin if ((int) strlen(text) > indx[1]) { 7472a3e3873SBaptiste Daroussin limit = dlg_limit_columns(text, climit, 1); 7482a3e3873SBaptiste Daroussin if (limit > 1) { 749f4f33ea0SBaptiste Daroussin dlg_attrset(win, selected ? attrs[1] : attrs[0]); 7502a3e3873SBaptiste Daroussin (void) waddnstr(win, 7512a3e3873SBaptiste Daroussin text + indx[1], 7522a3e3873SBaptiste Daroussin indx[limit] - indx[1]); 7532a3e3873SBaptiste Daroussin } 7542a3e3873SBaptiste Daroussin } 755*a96ef450SBaptiste Daroussin } 7562a3e3873SBaptiste Daroussin } else { 757*a96ef450SBaptiste Daroussin const int *cols; 758*a96ef450SBaptiste Daroussin 7592a3e3873SBaptiste Daroussin attrs[1] = item_selected_attr; 7602a3e3873SBaptiste Daroussin attrs[0] = item_attr; 7612a3e3873SBaptiste Daroussin 7622a3e3873SBaptiste Daroussin cols = dlg_index_columns(text); 7632a3e3873SBaptiste Daroussin limit = dlg_limit_columns(text, climit, 0); 7642a3e3873SBaptiste Daroussin 7652a3e3873SBaptiste Daroussin if (limit > 0) { 766f4f33ea0SBaptiste Daroussin dlg_attrset(win, selected ? attrs[1] : attrs[0]); 7672a3e3873SBaptiste Daroussin dlg_print_text(win, text, cols[limit], &attr); 7682a3e3873SBaptiste Daroussin } 7692a3e3873SBaptiste Daroussin } 7702a3e3873SBaptiste Daroussin } 7712a3e3873SBaptiste Daroussin 7722a3e3873SBaptiste Daroussin /* 7734c8945a0SNathan Whitehorn * Print up to 'cols' columns from 'text', optionally rendering our escape 7744c8945a0SNathan Whitehorn * sequence for attributes and color. 7754c8945a0SNathan Whitehorn */ 7764c8945a0SNathan Whitehorn void 7774c8945a0SNathan Whitehorn dlg_print_text(WINDOW *win, const char *txt, int cols, chtype *attr) 7784c8945a0SNathan Whitehorn { 7794c8945a0SNathan Whitehorn int y_origin, x_origin; 7804c8945a0SNathan Whitehorn int y_before, x_before = 0; 7814c8945a0SNathan Whitehorn int y_after, x_after; 7824c8945a0SNathan Whitehorn int tabbed = 0; 7834c8945a0SNathan Whitehorn bool ended = FALSE; 7847a1c0d96SNathan Whitehorn #ifdef USE_WIDE_CURSES 7857a1c0d96SNathan Whitehorn int combined = 0; 7867a1c0d96SNathan Whitehorn #endif 7874c8945a0SNathan Whitehorn 788f4f33ea0SBaptiste Daroussin if (dialog_state.text_only) { 789f4f33ea0SBaptiste Daroussin y_origin = y_after = 0; 790f4f33ea0SBaptiste Daroussin x_origin = x_after = 0; 791f4f33ea0SBaptiste Daroussin } else { 792*a96ef450SBaptiste Daroussin y_after = 0; 793*a96ef450SBaptiste Daroussin x_after = 0; 7944c8945a0SNathan Whitehorn getyx(win, y_origin, x_origin); 795f4f33ea0SBaptiste Daroussin } 7964c8945a0SNathan Whitehorn while (cols > 0 && (*txt != '\0')) { 797*a96ef450SBaptiste Daroussin bool thisTab; 798*a96ef450SBaptiste Daroussin chtype useattr; 799*a96ef450SBaptiste Daroussin 8004c8945a0SNathan Whitehorn if (dialog_vars.colors) { 8014c8945a0SNathan Whitehorn while (isOurEscape(txt)) { 8024c8945a0SNathan Whitehorn int code; 8034c8945a0SNathan Whitehorn 8044c8945a0SNathan Whitehorn txt += 2; 8054c8945a0SNathan Whitehorn switch (code = CharOf(*txt)) { 8064c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 8074c8945a0SNathan Whitehorn case '0': 8084c8945a0SNathan Whitehorn case '1': 8094c8945a0SNathan Whitehorn case '2': 8104c8945a0SNathan Whitehorn case '3': 8114c8945a0SNathan Whitehorn case '4': 8124c8945a0SNathan Whitehorn case '5': 8134c8945a0SNathan Whitehorn case '6': 8144c8945a0SNathan Whitehorn case '7': 8154c8945a0SNathan Whitehorn *attr &= ~A_COLOR; 8164c8945a0SNathan Whitehorn *attr |= define_color(win, code - '0'); 8174c8945a0SNathan Whitehorn break; 8184c8945a0SNathan Whitehorn #endif 8194c8945a0SNathan Whitehorn case 'B': 8204c8945a0SNathan Whitehorn *attr &= ~A_BOLD; 8214c8945a0SNathan Whitehorn break; 8224c8945a0SNathan Whitehorn case 'b': 8234c8945a0SNathan Whitehorn *attr |= A_BOLD; 8244c8945a0SNathan Whitehorn break; 8254c8945a0SNathan Whitehorn case 'R': 8264c8945a0SNathan Whitehorn *attr &= ~A_REVERSE; 8274c8945a0SNathan Whitehorn break; 8284c8945a0SNathan Whitehorn case 'r': 8294c8945a0SNathan Whitehorn *attr |= A_REVERSE; 8304c8945a0SNathan Whitehorn break; 8314c8945a0SNathan Whitehorn case 'U': 8324c8945a0SNathan Whitehorn *attr &= ~A_UNDERLINE; 8334c8945a0SNathan Whitehorn break; 8344c8945a0SNathan Whitehorn case 'u': 8354c8945a0SNathan Whitehorn *attr |= A_UNDERLINE; 8364c8945a0SNathan Whitehorn break; 8374c8945a0SNathan Whitehorn case 'n': 8384c8945a0SNathan Whitehorn *attr = A_NORMAL; 8394c8945a0SNathan Whitehorn break; 840*a96ef450SBaptiste Daroussin default: 841*a96ef450SBaptiste Daroussin break; 8424c8945a0SNathan Whitehorn } 8434c8945a0SNathan Whitehorn ++txt; 8444c8945a0SNathan Whitehorn } 8454c8945a0SNathan Whitehorn } 8464c8945a0SNathan Whitehorn if (ended || *txt == '\n' || *txt == '\0') 8474c8945a0SNathan Whitehorn break; 8484c8945a0SNathan Whitehorn useattr = (*attr) & A_ATTRIBUTES; 8494c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 8504c8945a0SNathan Whitehorn /* 8514c8945a0SNathan Whitehorn * Prevent this from making text invisible when the foreground and 8524c8945a0SNathan Whitehorn * background colors happen to be the same, and there's no bold 8534c8945a0SNathan Whitehorn * attribute. 8544c8945a0SNathan Whitehorn */ 8554c8945a0SNathan Whitehorn if ((useattr & A_COLOR) != 0 && (useattr & A_BOLD) == 0) { 8564c8945a0SNathan Whitehorn short pair = (short) PAIR_NUMBER(useattr); 8574c8945a0SNathan Whitehorn short fg, bg; 8584c8945a0SNathan Whitehorn if (pair_content(pair, &fg, &bg) != ERR 8594c8945a0SNathan Whitehorn && fg == bg) { 8604c8945a0SNathan Whitehorn useattr &= ~A_COLOR; 8614c8945a0SNathan Whitehorn useattr |= dlg_color_pair(fg, ((bg == COLOR_BLACK) 8624c8945a0SNathan Whitehorn ? COLOR_WHITE 8634c8945a0SNathan Whitehorn : COLOR_BLACK)); 8644c8945a0SNathan Whitehorn } 8654c8945a0SNathan Whitehorn } 8664c8945a0SNathan Whitehorn #endif 8674c8945a0SNathan Whitehorn /* 8684c8945a0SNathan Whitehorn * Write the character, using curses to tell exactly how wide it 8694c8945a0SNathan Whitehorn * is. If it is a tab, discount that, since the caller thinks 8704c8945a0SNathan Whitehorn * tabs are nonprinting, and curses will expand tabs to one or 8714c8945a0SNathan Whitehorn * more blanks. 8724c8945a0SNathan Whitehorn */ 8734c8945a0SNathan Whitehorn thisTab = (CharOf(*txt) == TAB); 874f4f33ea0SBaptiste Daroussin if (dialog_state.text_only) { 875f4f33ea0SBaptiste Daroussin x_before = x_after; 876f4f33ea0SBaptiste Daroussin } else { 8772a3e3873SBaptiste Daroussin if (thisTab) { 8784c8945a0SNathan Whitehorn getyx(win, y_before, x_before); 8792a3e3873SBaptiste Daroussin (void) y_before; 8802a3e3873SBaptiste Daroussin } 881f4f33ea0SBaptiste Daroussin } 882f4f33ea0SBaptiste Daroussin if (dialog_state.text_only) { 883f4f33ea0SBaptiste Daroussin int ch = CharOf(*txt++); 884f4f33ea0SBaptiste Daroussin if (thisTab) { 885f4f33ea0SBaptiste Daroussin while ((x_after++) % 8) { 886f4f33ea0SBaptiste Daroussin fputc(' ', dialog_state.output); 887f4f33ea0SBaptiste Daroussin } 888f4f33ea0SBaptiste Daroussin } else { 889f4f33ea0SBaptiste Daroussin fputc(ch, dialog_state.output); 890f4f33ea0SBaptiste Daroussin x_after++; /* FIXME: handle meta per locale */ 891f4f33ea0SBaptiste Daroussin } 892f4f33ea0SBaptiste Daroussin } else { 8934c8945a0SNathan Whitehorn (void) waddch(win, CharOf(*txt++) | useattr); 8944c8945a0SNathan Whitehorn getyx(win, y_after, x_after); 895f4f33ea0SBaptiste Daroussin } 8964c8945a0SNathan Whitehorn if (thisTab && (y_after == y_origin)) 8974c8945a0SNathan Whitehorn tabbed += (x_after - x_before); 8987a1c0d96SNathan Whitehorn if ((y_after != y_origin) || 8997a1c0d96SNathan Whitehorn (x_after >= (cols + tabbed + x_origin) 9007a1c0d96SNathan Whitehorn #ifdef USE_WIDE_CURSES 9017a1c0d96SNathan Whitehorn && !is_combining(txt, &combined) 9027a1c0d96SNathan Whitehorn #endif 9037a1c0d96SNathan Whitehorn )) { 9044c8945a0SNathan Whitehorn ended = TRUE; 9054c8945a0SNathan Whitehorn } 9064c8945a0SNathan Whitehorn } 907f4f33ea0SBaptiste Daroussin if (dialog_state.text_only) { 908f4f33ea0SBaptiste Daroussin fputc('\n', dialog_state.output); 909f4f33ea0SBaptiste Daroussin } 9104c8945a0SNathan Whitehorn } 9114c8945a0SNathan Whitehorn 9124c8945a0SNathan Whitehorn /* 9134c8945a0SNathan Whitehorn * Print one line of the prompt in the window within the limits of the 9144c8945a0SNathan Whitehorn * specified right margin. The line will end on a word boundary and a pointer 9154c8945a0SNathan Whitehorn * to the start of the next line is returned, or a NULL pointer if the end of 9164c8945a0SNathan Whitehorn * *prompt is reached. 9174c8945a0SNathan Whitehorn */ 9184c8945a0SNathan Whitehorn const char * 9194c8945a0SNathan Whitehorn dlg_print_line(WINDOW *win, 9204c8945a0SNathan Whitehorn chtype *attr, 9214c8945a0SNathan Whitehorn const char *prompt, 9224c8945a0SNathan Whitehorn int lm, int rm, int *x) 9234c8945a0SNathan Whitehorn { 9242a3e3873SBaptiste Daroussin const char *wrap_ptr; 9252a3e3873SBaptiste Daroussin const char *test_ptr; 926682c9e0fSNathan Whitehorn const char *hide_ptr = 0; 9274c8945a0SNathan Whitehorn const int *cols = dlg_index_columns(prompt); 9284c8945a0SNathan Whitehorn const int *indx = dlg_index_wchars(prompt); 9294c8945a0SNathan Whitehorn int wrap_inx = 0; 9304c8945a0SNathan Whitehorn int test_inx = 0; 9314c8945a0SNathan Whitehorn int cur_x = lm; 9324c8945a0SNathan Whitehorn int hidden = 0; 9334c8945a0SNathan Whitehorn int limit = dlg_count_wchars(prompt); 9344c8945a0SNathan Whitehorn int n; 9354c8945a0SNathan Whitehorn int tabbed = 0; 9364c8945a0SNathan Whitehorn 9374c8945a0SNathan Whitehorn *x = 1; 9384c8945a0SNathan Whitehorn 9394c8945a0SNathan Whitehorn /* 9404c8945a0SNathan Whitehorn * Set *test_ptr to the end of the line or the right margin (rm), whichever 9414c8945a0SNathan Whitehorn * is less, and set wrap_ptr to the end of the last word in the line. 9424c8945a0SNathan Whitehorn */ 9434c8945a0SNathan Whitehorn for (n = 0; n < limit; ++n) { 944f4f33ea0SBaptiste Daroussin int ch = *(test_ptr = prompt + indx[test_inx]); 945f4f33ea0SBaptiste Daroussin if (ch == '\n' || ch == '\0' || cur_x >= (rm + hidden)) 9464c8945a0SNathan Whitehorn break; 947f4f33ea0SBaptiste Daroussin if (ch == TAB && n == 0) { 9484c8945a0SNathan Whitehorn tabbed = 8; /* workaround for leading tabs */ 949f4f33ea0SBaptiste Daroussin } else if (isblank(UCH(ch)) 950f4f33ea0SBaptiste Daroussin && n != 0 951f4f33ea0SBaptiste Daroussin && !isblank(UCH(prompt[indx[n - 1]]))) { 9524c8945a0SNathan Whitehorn wrap_inx = n; 9534c8945a0SNathan Whitehorn *x = cur_x; 9542a3e3873SBaptiste Daroussin } else if (dialog_vars.colors && isOurEscape(test_ptr)) { 955682c9e0fSNathan Whitehorn hide_ptr = test_ptr; 956682c9e0fSNathan Whitehorn hidden += ESCAPE_LEN; 957682c9e0fSNathan Whitehorn n += (ESCAPE_LEN - 1); 9584c8945a0SNathan Whitehorn } 9594c8945a0SNathan Whitehorn cur_x = lm + tabbed + cols[n + 1]; 9604c8945a0SNathan Whitehorn if (cur_x > (rm + hidden)) 9614c8945a0SNathan Whitehorn break; 9624c8945a0SNathan Whitehorn test_inx = n + 1; 9634c8945a0SNathan Whitehorn } 9644c8945a0SNathan Whitehorn 9654c8945a0SNathan Whitehorn /* 9664c8945a0SNathan Whitehorn * If the line doesn't reach the right margin in the middle of a word, then 9674c8945a0SNathan Whitehorn * we don't have to wrap it at the end of the previous word. 9684c8945a0SNathan Whitehorn */ 9694c8945a0SNathan Whitehorn test_ptr = prompt + indx[test_inx]; 970f4f33ea0SBaptiste Daroussin if (*test_ptr == '\n' || isblank(UCH(*test_ptr)) || *test_ptr == '\0') { 9714c8945a0SNathan Whitehorn wrap_inx = test_inx; 972f4f33ea0SBaptiste Daroussin while (wrap_inx > 0 && isblank(UCH(prompt[indx[wrap_inx - 1]]))) { 9734c8945a0SNathan Whitehorn wrap_inx--; 9744c8945a0SNathan Whitehorn } 9754c8945a0SNathan Whitehorn *x = lm + indx[wrap_inx]; 9764c8945a0SNathan Whitehorn } else if (*x == 1 && cur_x >= rm) { 9774c8945a0SNathan Whitehorn /* 9784c8945a0SNathan Whitehorn * If the line has no spaces, then wrap it anyway at the right margin 9794c8945a0SNathan Whitehorn */ 9804c8945a0SNathan Whitehorn *x = rm; 9814c8945a0SNathan Whitehorn wrap_inx = test_inx; 9824c8945a0SNathan Whitehorn } 9834c8945a0SNathan Whitehorn wrap_ptr = prompt + indx[wrap_inx]; 9847a1c0d96SNathan Whitehorn #ifdef USE_WIDE_CURSES 9857a1c0d96SNathan Whitehorn if (UCH(*wrap_ptr) >= 128) { 9867a1c0d96SNathan Whitehorn int combined = 0; 9877a1c0d96SNathan Whitehorn while (is_combining(wrap_ptr, &combined)) { 9887a1c0d96SNathan Whitehorn ++wrap_ptr; 9897a1c0d96SNathan Whitehorn } 9907a1c0d96SNathan Whitehorn } 9917a1c0d96SNathan Whitehorn #endif 9924c8945a0SNathan Whitehorn 9934c8945a0SNathan Whitehorn /* 994682c9e0fSNathan Whitehorn * If we found hidden text past the last point that we will display, 995682c9e0fSNathan Whitehorn * discount that from the displayed length. 996682c9e0fSNathan Whitehorn */ 997682c9e0fSNathan Whitehorn if ((hide_ptr != 0) && (hide_ptr >= wrap_ptr)) { 998682c9e0fSNathan Whitehorn hidden -= ESCAPE_LEN; 999682c9e0fSNathan Whitehorn test_ptr = wrap_ptr; 1000682c9e0fSNathan Whitehorn while (test_ptr < wrap_ptr) { 10012a3e3873SBaptiste Daroussin if (dialog_vars.colors && isOurEscape(test_ptr)) { 1002682c9e0fSNathan Whitehorn hidden -= ESCAPE_LEN; 1003682c9e0fSNathan Whitehorn test_ptr += ESCAPE_LEN; 1004682c9e0fSNathan Whitehorn } else { 1005682c9e0fSNathan Whitehorn ++test_ptr; 1006682c9e0fSNathan Whitehorn } 1007682c9e0fSNathan Whitehorn } 1008682c9e0fSNathan Whitehorn } 1009682c9e0fSNathan Whitehorn 1010682c9e0fSNathan Whitehorn /* 10114c8945a0SNathan Whitehorn * Print the line if we have a window pointer. Otherwise this routine 10124c8945a0SNathan Whitehorn * is just being called for sizing the window. 10134c8945a0SNathan Whitehorn */ 1014f4f33ea0SBaptiste Daroussin if (dialog_state.text_only || win) { 10154c8945a0SNathan Whitehorn dlg_print_text(win, prompt, (cols[wrap_inx] - hidden), attr); 10164c8945a0SNathan Whitehorn } 10174c8945a0SNathan Whitehorn 10184c8945a0SNathan Whitehorn /* *x tells the calling function how long the line was */ 1019f4f33ea0SBaptiste Daroussin if (*x == 1) { 10204c8945a0SNathan Whitehorn *x = rm; 1021f4f33ea0SBaptiste Daroussin } 10224c8945a0SNathan Whitehorn 1023682c9e0fSNathan Whitehorn *x -= hidden; 1024682c9e0fSNathan Whitehorn 10254c8945a0SNathan Whitehorn /* Find the start of the next line and return a pointer to it */ 10264c8945a0SNathan Whitehorn test_ptr = wrap_ptr; 1027f4f33ea0SBaptiste Daroussin while (isblank(UCH(*test_ptr))) 10284c8945a0SNathan Whitehorn test_ptr++; 10294c8945a0SNathan Whitehorn if (*test_ptr == '\n') 10304c8945a0SNathan Whitehorn test_ptr++; 1031febdb468SDevin Teske dlg_finish_string(prompt); 10324c8945a0SNathan Whitehorn return (test_ptr); 10334c8945a0SNathan Whitehorn } 10344c8945a0SNathan Whitehorn 10354c8945a0SNathan Whitehorn static void 10364c8945a0SNathan Whitehorn justify_text(WINDOW *win, 10374c8945a0SNathan Whitehorn const char *prompt, 10384c8945a0SNathan Whitehorn int limit_y, 10394c8945a0SNathan Whitehorn int limit_x, 10404c8945a0SNathan Whitehorn int *high, int *wide) 10414c8945a0SNathan Whitehorn { 10424c8945a0SNathan Whitehorn chtype attr = A_NORMAL; 1043*a96ef450SBaptiste Daroussin int x; 10444c8945a0SNathan Whitehorn int y = MARGIN; 10454c8945a0SNathan Whitehorn int max_x = 2; 10464c8945a0SNathan Whitehorn int lm = (2 * MARGIN); /* left margin (box-border plus a space) */ 10474c8945a0SNathan Whitehorn int rm = limit_x; /* right margin */ 10484c8945a0SNathan Whitehorn int bm = limit_y; /* bottom margin */ 10494c8945a0SNathan Whitehorn int last_y = 0, last_x = 0; 10504c8945a0SNathan Whitehorn 1051f4f33ea0SBaptiste Daroussin dialog_state.text_height = 0; 1052f4f33ea0SBaptiste Daroussin dialog_state.text_width = 0; 1053f4f33ea0SBaptiste Daroussin if (dialog_state.text_only || win) { 10544c8945a0SNathan Whitehorn rm -= (2 * MARGIN); 10554c8945a0SNathan Whitehorn bm -= (2 * MARGIN); 10564c8945a0SNathan Whitehorn } 10574c8945a0SNathan Whitehorn if (prompt == 0) 10584c8945a0SNathan Whitehorn prompt = ""; 10594c8945a0SNathan Whitehorn 10604c8945a0SNathan Whitehorn if (win != 0) 10614c8945a0SNathan Whitehorn getyx(win, last_y, last_x); 10624c8945a0SNathan Whitehorn while (y <= bm && *prompt) { 10634c8945a0SNathan Whitehorn x = lm; 10644c8945a0SNathan Whitehorn 10654c8945a0SNathan Whitehorn if (*prompt == '\n') { 10664c8945a0SNathan Whitehorn while (*prompt == '\n' && y < bm) { 10674c8945a0SNathan Whitehorn if (*(prompt + 1) != '\0') { 10684c8945a0SNathan Whitehorn ++y; 10694c8945a0SNathan Whitehorn if (win != 0) 10704c8945a0SNathan Whitehorn (void) wmove(win, y, lm); 10714c8945a0SNathan Whitehorn } 10724c8945a0SNathan Whitehorn prompt++; 10734c8945a0SNathan Whitehorn } 10744c8945a0SNathan Whitehorn } else if (win != 0) 10754c8945a0SNathan Whitehorn (void) wmove(win, y, lm); 10764c8945a0SNathan Whitehorn 10774c8945a0SNathan Whitehorn if (*prompt) { 10784c8945a0SNathan Whitehorn prompt = dlg_print_line(win, &attr, prompt, lm, rm, &x); 10794c8945a0SNathan Whitehorn if (win != 0) 10804c8945a0SNathan Whitehorn getyx(win, last_y, last_x); 10814c8945a0SNathan Whitehorn } 10824c8945a0SNathan Whitehorn if (*prompt) { 10834c8945a0SNathan Whitehorn ++y; 10844c8945a0SNathan Whitehorn if (win != 0) 10854c8945a0SNathan Whitehorn (void) wmove(win, y, lm); 10864c8945a0SNathan Whitehorn } 10874c8945a0SNathan Whitehorn max_x = MAX(max_x, x); 10884c8945a0SNathan Whitehorn } 10894c8945a0SNathan Whitehorn /* Move back to the last position after drawing prompt, for msgbox. */ 10904c8945a0SNathan Whitehorn if (win != 0) 10914c8945a0SNathan Whitehorn (void) wmove(win, last_y, last_x); 10924c8945a0SNathan Whitehorn 10934c8945a0SNathan Whitehorn /* Set the final height and width for the calling function */ 10944c8945a0SNathan Whitehorn if (high != 0) 10954c8945a0SNathan Whitehorn *high = y; 10964c8945a0SNathan Whitehorn if (wide != 0) 10974c8945a0SNathan Whitehorn *wide = max_x; 10984c8945a0SNathan Whitehorn } 10994c8945a0SNathan Whitehorn 11004c8945a0SNathan Whitehorn /* 11014c8945a0SNathan Whitehorn * Print a string of text in a window, automatically wrap around to the next 11024c8945a0SNathan Whitehorn * line if the string is too long to fit on one line. Note that the string may 11034c8945a0SNathan Whitehorn * contain embedded newlines. 11044c8945a0SNathan Whitehorn */ 11054c8945a0SNathan Whitehorn void 11064c8945a0SNathan Whitehorn dlg_print_autowrap(WINDOW *win, const char *prompt, int height, int width) 11074c8945a0SNathan Whitehorn { 11084c8945a0SNathan Whitehorn justify_text(win, prompt, 11094c8945a0SNathan Whitehorn height, 11104c8945a0SNathan Whitehorn width, 11114c8945a0SNathan Whitehorn (int *) 0, (int *) 0); 11124c8945a0SNathan Whitehorn } 11134c8945a0SNathan Whitehorn 11144c8945a0SNathan Whitehorn /* 11154c8945a0SNathan Whitehorn * Display the message in a scrollable window. Actually the way it works is 11164c8945a0SNathan Whitehorn * that we create a "tall" window of the proper width, let the text wrap within 11174c8945a0SNathan Whitehorn * that, and copy a slice of the result to the dialog. 11184c8945a0SNathan Whitehorn * 11194c8945a0SNathan Whitehorn * It works for ncurses. Other curses implementations show only blanks (Tru64) 11204c8945a0SNathan Whitehorn * or garbage (NetBSD). 11214c8945a0SNathan Whitehorn */ 11224c8945a0SNathan Whitehorn int 11234c8945a0SNathan Whitehorn dlg_print_scrolled(WINDOW *win, 11244c8945a0SNathan Whitehorn const char *prompt, 11254c8945a0SNathan Whitehorn int offset, 11264c8945a0SNathan Whitehorn int height, 11274c8945a0SNathan Whitehorn int width, 11284c8945a0SNathan Whitehorn int pauseopt) 11294c8945a0SNathan Whitehorn { 11304c8945a0SNathan Whitehorn int oldy, oldx; 11314c8945a0SNathan Whitehorn int last = 0; 11324c8945a0SNathan Whitehorn 11337a1c0d96SNathan Whitehorn (void) pauseopt; /* used only for ncurses */ 11347a1c0d96SNathan Whitehorn 11354c8945a0SNathan Whitehorn getyx(win, oldy, oldx); 11364c8945a0SNathan Whitehorn #ifdef NCURSES_VERSION 11374c8945a0SNathan Whitehorn if (pauseopt) { 11384c8945a0SNathan Whitehorn int wide = width - (2 * MARGIN); 11394c8945a0SNathan Whitehorn int high = LINES; 11404c8945a0SNathan Whitehorn int len; 11414c8945a0SNathan Whitehorn WINDOW *dummy; 11424c8945a0SNathan Whitehorn 11434c8945a0SNathan Whitehorn #if defined(NCURSES_VERSION_PATCH) && NCURSES_VERSION_PATCH >= 20040417 11444c8945a0SNathan Whitehorn /* 11454c8945a0SNathan Whitehorn * If we're not limited by the screensize, allow text to possibly be 11464c8945a0SNathan Whitehorn * one character per line. 11474c8945a0SNathan Whitehorn */ 11484c8945a0SNathan Whitehorn if ((len = dlg_count_columns(prompt)) > high) 11494c8945a0SNathan Whitehorn high = len; 11504c8945a0SNathan Whitehorn #endif 11514c8945a0SNathan Whitehorn dummy = newwin(high, width, 0, 0); 1152682c9e0fSNathan Whitehorn if (dummy == 0) { 1153f4f33ea0SBaptiste Daroussin dlg_attrset(win, dialog_attr); 1154682c9e0fSNathan Whitehorn dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width); 1155682c9e0fSNathan Whitehorn last = 0; 1156682c9e0fSNathan Whitehorn } else { 1157*a96ef450SBaptiste Daroussin int y, x; 1158*a96ef450SBaptiste Daroussin 11594c8945a0SNathan Whitehorn wbkgdset(dummy, dialog_attr | ' '); 1160f4f33ea0SBaptiste Daroussin dlg_attrset(dummy, dialog_attr); 11614c8945a0SNathan Whitehorn werase(dummy); 11624c8945a0SNathan Whitehorn dlg_print_autowrap(dummy, prompt, high, width); 11634c8945a0SNathan Whitehorn getyx(dummy, y, x); 11642a3e3873SBaptiste Daroussin (void) x; 11654c8945a0SNathan Whitehorn 11664c8945a0SNathan Whitehorn copywin(dummy, /* srcwin */ 11674c8945a0SNathan Whitehorn win, /* dstwin */ 11684c8945a0SNathan Whitehorn offset + MARGIN, /* sminrow */ 11694c8945a0SNathan Whitehorn MARGIN, /* smincol */ 11704c8945a0SNathan Whitehorn MARGIN, /* dminrow */ 11714c8945a0SNathan Whitehorn MARGIN, /* dmincol */ 11724c8945a0SNathan Whitehorn height, /* dmaxrow */ 11734c8945a0SNathan Whitehorn wide, /* dmaxcol */ 11744c8945a0SNathan Whitehorn FALSE); 11754c8945a0SNathan Whitehorn 11764c8945a0SNathan Whitehorn delwin(dummy); 11774c8945a0SNathan Whitehorn 11784c8945a0SNathan Whitehorn /* if the text is incomplete, or we have scrolled, show the percentage */ 11794c8945a0SNathan Whitehorn if (y > 0 && wide > 4) { 1180*a96ef450SBaptiste Daroussin int percent = (int) ((height + offset) * 100.0 / y); 1181*a96ef450SBaptiste Daroussin 11824c8945a0SNathan Whitehorn if (percent < 0) 11834c8945a0SNathan Whitehorn percent = 0; 11844c8945a0SNathan Whitehorn if (percent > 100) 11854c8945a0SNathan Whitehorn percent = 100; 1186*a96ef450SBaptiste Daroussin 11874c8945a0SNathan Whitehorn if (offset != 0 || percent != 100) { 1188*a96ef450SBaptiste Daroussin char buffer[5]; 1189*a96ef450SBaptiste Daroussin 1190f4f33ea0SBaptiste Daroussin dlg_attrset(win, position_indicator_attr); 11914c8945a0SNathan Whitehorn (void) wmove(win, MARGIN + height, wide - 4); 11924c8945a0SNathan Whitehorn (void) sprintf(buffer, "%d%%", percent); 11934c8945a0SNathan Whitehorn (void) waddstr(win, buffer); 11944c8945a0SNathan Whitehorn if ((len = (int) strlen(buffer)) < 4) { 1195f4f33ea0SBaptiste Daroussin dlg_attrset(win, border_attr); 11964c8945a0SNathan Whitehorn whline(win, dlg_boxchar(ACS_HLINE), 4 - len); 11974c8945a0SNathan Whitehorn } 11984c8945a0SNathan Whitehorn } 11994c8945a0SNathan Whitehorn } 12004c8945a0SNathan Whitehorn last = (y - height); 1201682c9e0fSNathan Whitehorn } 12024c8945a0SNathan Whitehorn } else 12034c8945a0SNathan Whitehorn #endif 12044c8945a0SNathan Whitehorn { 12054c8945a0SNathan Whitehorn (void) offset; 1206f4f33ea0SBaptiste Daroussin dlg_attrset(win, dialog_attr); 12074c8945a0SNathan Whitehorn dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width); 12084c8945a0SNathan Whitehorn last = 0; 12094c8945a0SNathan Whitehorn } 12104c8945a0SNathan Whitehorn wmove(win, oldy, oldx); 12114c8945a0SNathan Whitehorn return last; 12124c8945a0SNathan Whitehorn } 12134c8945a0SNathan Whitehorn 12144c8945a0SNathan Whitehorn int 12154c8945a0SNathan Whitehorn dlg_check_scrolled(int key, int last, int page, bool * show, int *offset) 12164c8945a0SNathan Whitehorn { 12174c8945a0SNathan Whitehorn int code = 0; 12184c8945a0SNathan Whitehorn 12194c8945a0SNathan Whitehorn *show = FALSE; 12204c8945a0SNathan Whitehorn 12214c8945a0SNathan Whitehorn switch (key) { 12224c8945a0SNathan Whitehorn case DLGK_PAGE_FIRST: 12234c8945a0SNathan Whitehorn if (*offset > 0) { 12244c8945a0SNathan Whitehorn *offset = 0; 12254c8945a0SNathan Whitehorn *show = TRUE; 12264c8945a0SNathan Whitehorn } 12274c8945a0SNathan Whitehorn break; 12284c8945a0SNathan Whitehorn case DLGK_PAGE_LAST: 12294c8945a0SNathan Whitehorn if (*offset < last) { 12304c8945a0SNathan Whitehorn *offset = last; 12314c8945a0SNathan Whitehorn *show = TRUE; 12324c8945a0SNathan Whitehorn } 12334c8945a0SNathan Whitehorn break; 12344c8945a0SNathan Whitehorn case DLGK_GRID_UP: 12354c8945a0SNathan Whitehorn if (*offset > 0) { 12364c8945a0SNathan Whitehorn --(*offset); 12374c8945a0SNathan Whitehorn *show = TRUE; 12384c8945a0SNathan Whitehorn } 12394c8945a0SNathan Whitehorn break; 12404c8945a0SNathan Whitehorn case DLGK_GRID_DOWN: 12414c8945a0SNathan Whitehorn if (*offset < last) { 12424c8945a0SNathan Whitehorn ++(*offset); 12434c8945a0SNathan Whitehorn *show = TRUE; 12444c8945a0SNathan Whitehorn } 12454c8945a0SNathan Whitehorn break; 12464c8945a0SNathan Whitehorn case DLGK_PAGE_PREV: 12474c8945a0SNathan Whitehorn if (*offset > 0) { 12484c8945a0SNathan Whitehorn *offset -= page; 12494c8945a0SNathan Whitehorn if (*offset < 0) 12504c8945a0SNathan Whitehorn *offset = 0; 12514c8945a0SNathan Whitehorn *show = TRUE; 12524c8945a0SNathan Whitehorn } 12534c8945a0SNathan Whitehorn break; 12544c8945a0SNathan Whitehorn case DLGK_PAGE_NEXT: 12554c8945a0SNathan Whitehorn if (*offset < last) { 12564c8945a0SNathan Whitehorn *offset += page; 12574c8945a0SNathan Whitehorn if (*offset > last) 12584c8945a0SNathan Whitehorn *offset = last; 12594c8945a0SNathan Whitehorn *show = TRUE; 12604c8945a0SNathan Whitehorn } 12614c8945a0SNathan Whitehorn break; 12624c8945a0SNathan Whitehorn default: 12634c8945a0SNathan Whitehorn code = -1; 12644c8945a0SNathan Whitehorn break; 12654c8945a0SNathan Whitehorn } 12664c8945a0SNathan Whitehorn return code; 12674c8945a0SNathan Whitehorn } 12684c8945a0SNathan Whitehorn 12694c8945a0SNathan Whitehorn /* 12704c8945a0SNathan Whitehorn * Calculate the window size for preformatted text. This will calculate box 12714c8945a0SNathan Whitehorn * dimensions that are at or close to the specified aspect ratio for the prompt 12724c8945a0SNathan Whitehorn * string with all spaces and newlines preserved and additional newlines added 12734c8945a0SNathan Whitehorn * as necessary. 12744c8945a0SNathan Whitehorn */ 12754c8945a0SNathan Whitehorn static void 12764c8945a0SNathan Whitehorn auto_size_preformatted(const char *prompt, int *height, int *width) 12774c8945a0SNathan Whitehorn { 12784c8945a0SNathan Whitehorn int high = 0, wide = 0; 12794c8945a0SNathan Whitehorn float car; /* Calculated Aspect Ratio */ 12804c8945a0SNathan Whitehorn int max_y = SLINES - 1; 12814c8945a0SNathan Whitehorn int max_x = SCOLS - 2; 12824c8945a0SNathan Whitehorn int max_width = max_x; 12834c8945a0SNathan Whitehorn int ar = dialog_state.aspect_ratio; 12844c8945a0SNathan Whitehorn 12854c8945a0SNathan Whitehorn /* Get the initial dimensions */ 12864c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide); 12874c8945a0SNathan Whitehorn car = (float) (wide / high); 12884c8945a0SNathan Whitehorn 12894c8945a0SNathan Whitehorn /* 12904c8945a0SNathan Whitehorn * If the aspect ratio is greater than it should be, then decrease the 12914c8945a0SNathan Whitehorn * width proportionately. 12924c8945a0SNathan Whitehorn */ 12934c8945a0SNathan Whitehorn if (car > ar) { 1294*a96ef450SBaptiste Daroussin float diff = car / (float) ar; 12954c8945a0SNathan Whitehorn max_x = (int) ((float) wide / diff + 4); 12964c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide); 12974c8945a0SNathan Whitehorn car = (float) wide / (float) high; 12984c8945a0SNathan Whitehorn } 12994c8945a0SNathan Whitehorn 13004c8945a0SNathan Whitehorn /* 13014c8945a0SNathan Whitehorn * If the aspect ratio is too small after decreasing the width, then 13024c8945a0SNathan Whitehorn * incrementally increase the width until the aspect ratio is equal to or 13034c8945a0SNathan Whitehorn * greater than the specified aspect ratio. 13044c8945a0SNathan Whitehorn */ 13054c8945a0SNathan Whitehorn while (car < ar && max_x < max_width) { 13064c8945a0SNathan Whitehorn max_x += 4; 13074c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide); 13084c8945a0SNathan Whitehorn car = (float) (wide / high); 13094c8945a0SNathan Whitehorn } 13104c8945a0SNathan Whitehorn 13114c8945a0SNathan Whitehorn *height = high; 13124c8945a0SNathan Whitehorn *width = wide; 13134c8945a0SNathan Whitehorn } 13144c8945a0SNathan Whitehorn 13154c8945a0SNathan Whitehorn /* 13164c8945a0SNathan Whitehorn * Find the length of the longest "word" in the given string. By setting the 13174c8945a0SNathan Whitehorn * widget width at least this long, we can avoid splitting a word on the 13184c8945a0SNathan Whitehorn * margin. 13194c8945a0SNathan Whitehorn */ 13204c8945a0SNathan Whitehorn static int 13214c8945a0SNathan Whitehorn longest_word(const char *string) 13224c8945a0SNathan Whitehorn { 1323*a96ef450SBaptiste Daroussin int result = 0; 13244c8945a0SNathan Whitehorn 13254c8945a0SNathan Whitehorn while (*string != '\0') { 1326*a96ef450SBaptiste Daroussin int length = 0; 13274c8945a0SNathan Whitehorn while (*string != '\0' && !isspace(UCH(*string))) { 13284c8945a0SNathan Whitehorn length++; 13294c8945a0SNathan Whitehorn string++; 13304c8945a0SNathan Whitehorn } 13314c8945a0SNathan Whitehorn result = MAX(result, length); 13324c8945a0SNathan Whitehorn if (*string != '\0') 13334c8945a0SNathan Whitehorn string++; 13344c8945a0SNathan Whitehorn } 13354c8945a0SNathan Whitehorn return result; 13364c8945a0SNathan Whitehorn } 13374c8945a0SNathan Whitehorn 13384c8945a0SNathan Whitehorn /* 13394c8945a0SNathan Whitehorn * if (height or width == -1) Maximize() 13404c8945a0SNathan Whitehorn * if (height or width == 0), justify and return actual limits. 13414c8945a0SNathan Whitehorn */ 13424c8945a0SNathan Whitehorn static void 13434c8945a0SNathan Whitehorn real_auto_size(const char *title, 13444c8945a0SNathan Whitehorn const char *prompt, 13454c8945a0SNathan Whitehorn int *height, int *width, 13464c8945a0SNathan Whitehorn int boxlines, int mincols) 13474c8945a0SNathan Whitehorn { 13484c8945a0SNathan Whitehorn int x = (dialog_vars.begin_set ? dialog_vars.begin_x : 2); 13494c8945a0SNathan Whitehorn int y = (dialog_vars.begin_set ? dialog_vars.begin_y : 1); 13504c8945a0SNathan Whitehorn int title_length = title ? dlg_count_columns(title) : 0; 13514c8945a0SNathan Whitehorn int high; 13524c8945a0SNathan Whitehorn int save_high = *height; 13534c8945a0SNathan Whitehorn int save_wide = *width; 1354f4f33ea0SBaptiste Daroussin int max_high; 1355f4f33ea0SBaptiste Daroussin int max_wide; 13564c8945a0SNathan Whitehorn 13574c8945a0SNathan Whitehorn if (prompt == 0) { 13584c8945a0SNathan Whitehorn if (*height == 0) 13594c8945a0SNathan Whitehorn *height = -1; 13604c8945a0SNathan Whitehorn if (*width == 0) 13614c8945a0SNathan Whitehorn *width = -1; 13624c8945a0SNathan Whitehorn } 13634c8945a0SNathan Whitehorn 1364f4f33ea0SBaptiste Daroussin max_high = (*height < 0); 1365f4f33ea0SBaptiste Daroussin max_wide = (*width < 0); 1366f4f33ea0SBaptiste Daroussin 13674c8945a0SNathan Whitehorn if (*height > 0) { 13684c8945a0SNathan Whitehorn high = *height; 13694c8945a0SNathan Whitehorn } else { 13704c8945a0SNathan Whitehorn high = SLINES - y; 13714c8945a0SNathan Whitehorn } 13724c8945a0SNathan Whitehorn 13732a3e3873SBaptiste Daroussin if (*width <= 0) { 1374*a96ef450SBaptiste Daroussin int wide; 1375*a96ef450SBaptiste Daroussin 13762a3e3873SBaptiste Daroussin if (prompt != 0) { 13774c8945a0SNathan Whitehorn wide = MAX(title_length, mincols); 13784c8945a0SNathan Whitehorn if (strchr(prompt, '\n') == 0) { 13792a3e3873SBaptiste Daroussin double val = (dialog_state.aspect_ratio * 13802a3e3873SBaptiste Daroussin dlg_count_real_columns(prompt)); 13814c8945a0SNathan Whitehorn double xxx = sqrt(val); 13824c8945a0SNathan Whitehorn int tmp = (int) xxx; 13834c8945a0SNathan Whitehorn wide = MAX(wide, tmp); 13844c8945a0SNathan Whitehorn wide = MAX(wide, longest_word(prompt)); 13854c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, high, wide, height, width); 13864c8945a0SNathan Whitehorn } else { 13874c8945a0SNathan Whitehorn auto_size_preformatted(prompt, height, width); 13884c8945a0SNathan Whitehorn } 13894c8945a0SNathan Whitehorn } else { 13904c8945a0SNathan Whitehorn wide = SCOLS - x; 13914c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, high, wide, height, width); 13924c8945a0SNathan Whitehorn } 13932a3e3873SBaptiste Daroussin } 13944c8945a0SNathan Whitehorn 13954c8945a0SNathan Whitehorn if (*width < title_length) { 13964c8945a0SNathan Whitehorn justify_text((WINDOW *) 0, prompt, high, title_length, height, width); 13974c8945a0SNathan Whitehorn *width = title_length; 13984c8945a0SNathan Whitehorn } 13994c8945a0SNathan Whitehorn 1400f4f33ea0SBaptiste Daroussin dialog_state.text_height = *height; 1401f4f33ea0SBaptiste Daroussin dialog_state.text_width = *width; 1402f4f33ea0SBaptiste Daroussin 14034c8945a0SNathan Whitehorn if (*width < mincols && save_wide == 0) 14044c8945a0SNathan Whitehorn *width = mincols; 14054c8945a0SNathan Whitehorn if (prompt != 0) { 1406f4f33ea0SBaptiste Daroussin *width += ((2 * MARGIN) + SHADOW_COLS); 1407f4f33ea0SBaptiste Daroussin *height += boxlines + (2 * MARGIN); 14084c8945a0SNathan Whitehorn } 1409f4f33ea0SBaptiste Daroussin 14104c8945a0SNathan Whitehorn if (save_high > 0) 14114c8945a0SNathan Whitehorn *height = save_high; 14124c8945a0SNathan Whitehorn if (save_wide > 0) 14134c8945a0SNathan Whitehorn *width = save_wide; 1414f4f33ea0SBaptiste Daroussin 1415f4f33ea0SBaptiste Daroussin if (max_high) 1416f4f33ea0SBaptiste Daroussin *height = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0); 1417f4f33ea0SBaptiste Daroussin if (max_wide) 1418f4f33ea0SBaptiste Daroussin *width = SCOLS - (dialog_vars.begin_set ? dialog_vars.begin_x : 0); 14194c8945a0SNathan Whitehorn } 14204c8945a0SNathan Whitehorn 14214c8945a0SNathan Whitehorn /* End of real_auto_size() */ 14224c8945a0SNathan Whitehorn 14234c8945a0SNathan Whitehorn void 14244c8945a0SNathan Whitehorn dlg_auto_size(const char *title, 14254c8945a0SNathan Whitehorn const char *prompt, 14264c8945a0SNathan Whitehorn int *height, 14274c8945a0SNathan Whitehorn int *width, 14284c8945a0SNathan Whitehorn int boxlines, 14294c8945a0SNathan Whitehorn int mincols) 14304c8945a0SNathan Whitehorn { 1431f4f33ea0SBaptiste Daroussin DLG_TRACE(("# dlg_auto_size(%d,%d) limits %d,%d\n", 1432f4f33ea0SBaptiste Daroussin *height, *width, 1433f4f33ea0SBaptiste Daroussin boxlines, mincols)); 1434f4f33ea0SBaptiste Daroussin 14354c8945a0SNathan Whitehorn real_auto_size(title, prompt, height, width, boxlines, mincols); 14364c8945a0SNathan Whitehorn 14374c8945a0SNathan Whitehorn if (*width > SCOLS) { 14384c8945a0SNathan Whitehorn (*height)++; 14394c8945a0SNathan Whitehorn *width = SCOLS; 14404c8945a0SNathan Whitehorn } 14414c8945a0SNathan Whitehorn 1442f4f33ea0SBaptiste Daroussin if (*height > SLINES) { 14434c8945a0SNathan Whitehorn *height = SLINES; 14444c8945a0SNathan Whitehorn } 1445f4f33ea0SBaptiste Daroussin DLG_TRACE(("# ...dlg_auto_size(%d,%d) also %d,%d\n", 1446f4f33ea0SBaptiste Daroussin *height, *width, 1447f4f33ea0SBaptiste Daroussin dialog_state.text_height, dialog_state.text_width)); 1448f4f33ea0SBaptiste Daroussin } 14494c8945a0SNathan Whitehorn 14504c8945a0SNathan Whitehorn /* 14514c8945a0SNathan Whitehorn * if (height or width == -1) Maximize() 14524c8945a0SNathan Whitehorn * if (height or width == 0) 14534c8945a0SNathan Whitehorn * height=MIN(SLINES, num.lines in fd+n); 14544c8945a0SNathan Whitehorn * width=MIN(SCOLS, MAX(longer line+n, mincols)); 14554c8945a0SNathan Whitehorn */ 14564c8945a0SNathan Whitehorn void 14574c8945a0SNathan Whitehorn dlg_auto_sizefile(const char *title, 14584c8945a0SNathan Whitehorn const char *file, 14594c8945a0SNathan Whitehorn int *height, 14604c8945a0SNathan Whitehorn int *width, 14614c8945a0SNathan Whitehorn int boxlines, 14624c8945a0SNathan Whitehorn int mincols) 14634c8945a0SNathan Whitehorn { 14644c8945a0SNathan Whitehorn int count = 0; 14654c8945a0SNathan Whitehorn int len = title ? dlg_count_columns(title) : 0; 14664c8945a0SNathan Whitehorn int nc = 4; 14674c8945a0SNathan Whitehorn int numlines = 2; 14684c8945a0SNathan Whitehorn FILE *fd; 14694c8945a0SNathan Whitehorn 14704c8945a0SNathan Whitehorn /* Open input file for reading */ 14714c8945a0SNathan Whitehorn if ((fd = fopen(file, "rb")) == NULL) 14724c8945a0SNathan Whitehorn dlg_exiterr("dlg_auto_sizefile: Cannot open input file %s", file); 14734c8945a0SNathan Whitehorn 14744c8945a0SNathan Whitehorn if ((*height == -1) || (*width == -1)) { 14754c8945a0SNathan Whitehorn *height = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0); 14764c8945a0SNathan Whitehorn *width = SCOLS - (dialog_vars.begin_set ? dialog_vars.begin_x : 0); 14774c8945a0SNathan Whitehorn } 14784c8945a0SNathan Whitehorn if ((*height != 0) && (*width != 0)) { 14794c8945a0SNathan Whitehorn (void) fclose(fd); 14804c8945a0SNathan Whitehorn if (*width > SCOLS) 14814c8945a0SNathan Whitehorn *width = SCOLS; 14824c8945a0SNathan Whitehorn if (*height > SLINES) 14834c8945a0SNathan Whitehorn *height = SLINES; 14844c8945a0SNathan Whitehorn return; 14854c8945a0SNathan Whitehorn } 14864c8945a0SNathan Whitehorn 14874c8945a0SNathan Whitehorn while (!feof(fd)) { 1488*a96ef450SBaptiste Daroussin int ch; 1489*a96ef450SBaptiste Daroussin long offset; 1490*a96ef450SBaptiste Daroussin 1491f4f33ea0SBaptiste Daroussin if (ferror(fd)) 1492f4f33ea0SBaptiste Daroussin break; 1493*a96ef450SBaptiste Daroussin 14944c8945a0SNathan Whitehorn offset = 0; 1495f4f33ea0SBaptiste Daroussin while (((ch = getc(fd)) != '\n') && !feof(fd)) { 1496f4f33ea0SBaptiste Daroussin if ((ch == TAB) && (dialog_vars.tab_correct)) { 14974c8945a0SNathan Whitehorn offset += dialog_state.tab_len - (offset % dialog_state.tab_len); 1498f4f33ea0SBaptiste Daroussin } else { 14994c8945a0SNathan Whitehorn offset++; 1500f4f33ea0SBaptiste Daroussin } 1501f4f33ea0SBaptiste Daroussin } 15024c8945a0SNathan Whitehorn 15034c8945a0SNathan Whitehorn if (offset > len) 15047a1c0d96SNathan Whitehorn len = (int) offset; 15054c8945a0SNathan Whitehorn 15064c8945a0SNathan Whitehorn count++; 15074c8945a0SNathan Whitehorn } 15084c8945a0SNathan Whitehorn 15097a1c0d96SNathan Whitehorn /* now 'count' has the number of lines of fd and 'len' the max length */ 15104c8945a0SNathan Whitehorn 15114c8945a0SNathan Whitehorn *height = MIN(SLINES, count + numlines + boxlines); 15124c8945a0SNathan Whitehorn *width = MIN(SCOLS, MAX((len + nc), mincols)); 15134c8945a0SNathan Whitehorn /* here width and height can be maximized if > SCOLS|SLINES because 15144c8945a0SNathan Whitehorn textbox-like widgets don't put all <file> on the screen. 15154c8945a0SNathan Whitehorn Msgbox-like widget instead have to put all <text> correctly. */ 15164c8945a0SNathan Whitehorn 15174c8945a0SNathan Whitehorn (void) fclose(fd); 15184c8945a0SNathan Whitehorn } 15194c8945a0SNathan Whitehorn 15204c8945a0SNathan Whitehorn /* 15214c8945a0SNathan Whitehorn * Draw a rectangular box with line drawing characters. 15224c8945a0SNathan Whitehorn * 15234c8945a0SNathan Whitehorn * borderchar is used to color the upper/left edges. 15244c8945a0SNathan Whitehorn * 15254c8945a0SNathan Whitehorn * boxchar is used to color the right/lower edges. It also is fill-color used 15264c8945a0SNathan Whitehorn * for the box contents. 15274c8945a0SNathan Whitehorn * 15284c8945a0SNathan Whitehorn * Normally, if you are drawing a scrollable box, use menubox_border_attr for 15294c8945a0SNathan Whitehorn * boxchar, and menubox_attr for borderchar since the scroll-arrows are drawn 15304c8945a0SNathan Whitehorn * with menubox_attr at the top, and menubox_border_attr at the bottom. That 15314c8945a0SNathan Whitehorn * also (given the default color choices) produces a recessed effect. 15324c8945a0SNathan Whitehorn * 15334c8945a0SNathan Whitehorn * If you want a raised effect (and are not going to use the scroll-arrows), 15344c8945a0SNathan Whitehorn * reverse this choice. 15354c8945a0SNathan Whitehorn */ 15364c8945a0SNathan Whitehorn void 15372a3e3873SBaptiste Daroussin dlg_draw_box2(WINDOW *win, int y, int x, int height, int width, 15382a3e3873SBaptiste Daroussin chtype boxchar, chtype borderchar, chtype borderchar2) 15394c8945a0SNathan Whitehorn { 15404c8945a0SNathan Whitehorn int i, j; 15417a1c0d96SNathan Whitehorn chtype save = dlg_get_attrs(win); 15424c8945a0SNathan Whitehorn 1543f4f33ea0SBaptiste Daroussin dlg_attrset(win, 0); 15444c8945a0SNathan Whitehorn for (i = 0; i < height; i++) { 15454c8945a0SNathan Whitehorn (void) wmove(win, y + i, x); 15464c8945a0SNathan Whitehorn for (j = 0; j < width; j++) 15474c8945a0SNathan Whitehorn if (!i && !j) 15484c8945a0SNathan Whitehorn (void) waddch(win, borderchar | dlg_boxchar(ACS_ULCORNER)); 15494c8945a0SNathan Whitehorn else if (i == height - 1 && !j) 15504c8945a0SNathan Whitehorn (void) waddch(win, borderchar | dlg_boxchar(ACS_LLCORNER)); 15514c8945a0SNathan Whitehorn else if (!i && j == width - 1) 15522a3e3873SBaptiste Daroussin (void) waddch(win, borderchar2 | dlg_boxchar(ACS_URCORNER)); 15534c8945a0SNathan Whitehorn else if (i == height - 1 && j == width - 1) 15542a3e3873SBaptiste Daroussin (void) waddch(win, borderchar2 | dlg_boxchar(ACS_LRCORNER)); 15554c8945a0SNathan Whitehorn else if (!i) 15564c8945a0SNathan Whitehorn (void) waddch(win, borderchar | dlg_boxchar(ACS_HLINE)); 15574c8945a0SNathan Whitehorn else if (i == height - 1) 15582a3e3873SBaptiste Daroussin (void) waddch(win, borderchar2 | dlg_boxchar(ACS_HLINE)); 15594c8945a0SNathan Whitehorn else if (!j) 15604c8945a0SNathan Whitehorn (void) waddch(win, borderchar | dlg_boxchar(ACS_VLINE)); 15614c8945a0SNathan Whitehorn else if (j == width - 1) 15622a3e3873SBaptiste Daroussin (void) waddch(win, borderchar2 | dlg_boxchar(ACS_VLINE)); 15634c8945a0SNathan Whitehorn else 15644c8945a0SNathan Whitehorn (void) waddch(win, boxchar | ' '); 15654c8945a0SNathan Whitehorn } 1566f4f33ea0SBaptiste Daroussin dlg_attrset(win, save); 15672a3e3873SBaptiste Daroussin } 15682a3e3873SBaptiste Daroussin 15692a3e3873SBaptiste Daroussin void 15702a3e3873SBaptiste Daroussin dlg_draw_box(WINDOW *win, int y, int x, int height, int width, 15712a3e3873SBaptiste Daroussin chtype boxchar, chtype borderchar) 15722a3e3873SBaptiste Daroussin { 15732a3e3873SBaptiste Daroussin dlg_draw_box2(win, y, x, height, width, boxchar, borderchar, boxchar); 15744c8945a0SNathan Whitehorn } 15754c8945a0SNathan Whitehorn 1576*a96ef450SBaptiste Daroussin /* 1577*a96ef450SBaptiste Daroussin * Search the given 'list' for the given window 'win'. Typically 'win' is an 1578*a96ef450SBaptiste Daroussin * input-window, i.e., a window where we might use wgetch. 1579*a96ef450SBaptiste Daroussin * 1580*a96ef450SBaptiste Daroussin * The all-windows list has normal- and shadow-windows. Since we never use the 1581*a96ef450SBaptiste Daroussin * shadow as an input window, normally we just look for the normal-window. 1582*a96ef450SBaptiste Daroussin * 1583*a96ef450SBaptiste Daroussin * However, the all-subwindows list stores parent/child windows rather than 1584*a96ef450SBaptiste Daroussin * normal/shadow windows. When searching that list, we look for the child 1585*a96ef450SBaptiste Daroussin * window (in the .shadow field). 1586*a96ef450SBaptiste Daroussin */ 1587682c9e0fSNathan Whitehorn static DIALOG_WINDOWS * 1588*a96ef450SBaptiste Daroussin find_window(DIALOG_WINDOWS * list, WINDOW *win, bool normal) 1589682c9e0fSNathan Whitehorn { 1590682c9e0fSNathan Whitehorn DIALOG_WINDOWS *result = 0; 1591682c9e0fSNathan Whitehorn DIALOG_WINDOWS *p; 1592682c9e0fSNathan Whitehorn 1593*a96ef450SBaptiste Daroussin for (p = list; p != 0; p = p->next) { 1594*a96ef450SBaptiste Daroussin WINDOW *check = normal ? p->normal : p->shadow; 1595*a96ef450SBaptiste Daroussin if (check == win) { 1596682c9e0fSNathan Whitehorn result = p; 1597682c9e0fSNathan Whitehorn break; 1598682c9e0fSNathan Whitehorn } 1599682c9e0fSNathan Whitehorn } 1600682c9e0fSNathan Whitehorn return result; 1601682c9e0fSNathan Whitehorn } 1602682c9e0fSNathan Whitehorn 1603*a96ef450SBaptiste Daroussin #define SearchTopWindows(win) find_window(dialog_state.all_windows, win, TRUE) 1604*a96ef450SBaptiste Daroussin #define SearchSubWindows(win) find_window(dialog_state.all_subwindows, win, FALSE) 1605*a96ef450SBaptiste Daroussin 1606*a96ef450SBaptiste Daroussin /* 1607*a96ef450SBaptiste Daroussin * Check for the existence of a window, e.g., when used for input or updating 1608*a96ef450SBaptiste Daroussin * the display. This is used in dlg_getc() and related functions, to guard 1609*a96ef450SBaptiste Daroussin * against an asynchronous window-deletion that might invalidate the input 1610*a96ef450SBaptiste Daroussin * window used in dlg_getc(). 1611*a96ef450SBaptiste Daroussin */ 1612*a96ef450SBaptiste Daroussin DIALOG_WINDOWS * 1613*a96ef450SBaptiste Daroussin _dlg_find_window(WINDOW *win) 1614*a96ef450SBaptiste Daroussin { 1615*a96ef450SBaptiste Daroussin DIALOG_WINDOWS *result = 0; 1616*a96ef450SBaptiste Daroussin 1617*a96ef450SBaptiste Daroussin if ((result = SearchTopWindows(win)) == NULL) 1618*a96ef450SBaptiste Daroussin result = SearchSubWindows(win); 1619*a96ef450SBaptiste Daroussin return result; 1620*a96ef450SBaptiste Daroussin } 1621*a96ef450SBaptiste Daroussin 16224c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 16234c8945a0SNathan Whitehorn /* 1624682c9e0fSNathan Whitehorn * If we have wchgat(), use that for updating shadow attributes, to work with 1625682c9e0fSNathan Whitehorn * wide-character data. 1626682c9e0fSNathan Whitehorn */ 1627682c9e0fSNathan Whitehorn 1628682c9e0fSNathan Whitehorn /* 1629682c9e0fSNathan Whitehorn * Check if the given point is "in" the given window. If so, return the window 1630682c9e0fSNathan Whitehorn * pointer, otherwise null. 1631682c9e0fSNathan Whitehorn */ 1632682c9e0fSNathan Whitehorn static WINDOW * 1633682c9e0fSNathan Whitehorn in_window(WINDOW *win, int y, int x) 1634682c9e0fSNathan Whitehorn { 1635682c9e0fSNathan Whitehorn WINDOW *result = 0; 1636682c9e0fSNathan Whitehorn int y_base = getbegy(win); 1637682c9e0fSNathan Whitehorn int x_base = getbegx(win); 1638682c9e0fSNathan Whitehorn int y_last = getmaxy(win) + y_base; 1639682c9e0fSNathan Whitehorn int x_last = getmaxx(win) + x_base; 1640682c9e0fSNathan Whitehorn 1641682c9e0fSNathan Whitehorn if (y >= y_base && y <= y_last && x >= x_base && x <= x_last) 1642682c9e0fSNathan Whitehorn result = win; 1643682c9e0fSNathan Whitehorn return result; 1644682c9e0fSNathan Whitehorn } 1645682c9e0fSNathan Whitehorn 1646682c9e0fSNathan Whitehorn static WINDOW * 1647682c9e0fSNathan Whitehorn window_at_cell(DIALOG_WINDOWS * dw, int y, int x) 1648682c9e0fSNathan Whitehorn { 1649682c9e0fSNathan Whitehorn WINDOW *result = 0; 1650682c9e0fSNathan Whitehorn DIALOG_WINDOWS *p; 1651682c9e0fSNathan Whitehorn int y_want = y + getbegy(dw->shadow); 1652682c9e0fSNathan Whitehorn int x_want = x + getbegx(dw->shadow); 1653682c9e0fSNathan Whitehorn 1654682c9e0fSNathan Whitehorn for (p = dialog_state.all_windows; p != 0; p = p->next) { 1655682c9e0fSNathan Whitehorn if (dw->normal != p->normal 1656682c9e0fSNathan Whitehorn && dw->shadow != p->normal 1657682c9e0fSNathan Whitehorn && (result = in_window(p->normal, y_want, x_want)) != 0) { 1658682c9e0fSNathan Whitehorn break; 1659682c9e0fSNathan Whitehorn } 1660682c9e0fSNathan Whitehorn } 1661682c9e0fSNathan Whitehorn if (result == 0) { 1662682c9e0fSNathan Whitehorn result = stdscr; 1663682c9e0fSNathan Whitehorn } 1664682c9e0fSNathan Whitehorn return result; 1665682c9e0fSNathan Whitehorn } 1666682c9e0fSNathan Whitehorn 1667682c9e0fSNathan Whitehorn static bool 1668682c9e0fSNathan Whitehorn in_shadow(WINDOW *normal, WINDOW *shadow, int y, int x) 1669682c9e0fSNathan Whitehorn { 1670682c9e0fSNathan Whitehorn bool result = FALSE; 1671682c9e0fSNathan Whitehorn int ybase = getbegy(normal); 1672682c9e0fSNathan Whitehorn int ylast = getmaxy(normal) + ybase; 1673682c9e0fSNathan Whitehorn int xbase = getbegx(normal); 1674682c9e0fSNathan Whitehorn int xlast = getmaxx(normal) + xbase; 1675682c9e0fSNathan Whitehorn 1676682c9e0fSNathan Whitehorn y += getbegy(shadow); 1677682c9e0fSNathan Whitehorn x += getbegx(shadow); 1678682c9e0fSNathan Whitehorn 1679682c9e0fSNathan Whitehorn if (y >= ybase + SHADOW_ROWS 1680682c9e0fSNathan Whitehorn && y < ylast + SHADOW_ROWS 1681682c9e0fSNathan Whitehorn && x >= xlast 1682682c9e0fSNathan Whitehorn && x < xlast + SHADOW_COLS) { 1683682c9e0fSNathan Whitehorn /* in the right-side */ 1684682c9e0fSNathan Whitehorn result = TRUE; 1685682c9e0fSNathan Whitehorn } else if (y >= ylast 1686682c9e0fSNathan Whitehorn && y < ylast + SHADOW_ROWS 1687682c9e0fSNathan Whitehorn && x >= ybase + SHADOW_COLS 1688682c9e0fSNathan Whitehorn && x < ylast + SHADOW_COLS) { 1689682c9e0fSNathan Whitehorn /* check the bottom */ 1690682c9e0fSNathan Whitehorn result = TRUE; 1691682c9e0fSNathan Whitehorn } 1692682c9e0fSNathan Whitehorn 1693682c9e0fSNathan Whitehorn return result; 1694682c9e0fSNathan Whitehorn } 1695682c9e0fSNathan Whitehorn 1696682c9e0fSNathan Whitehorn /* 1697682c9e0fSNathan Whitehorn * When erasing a shadow, check each cell to make sure that it is not part of 1698682c9e0fSNathan Whitehorn * another box's shadow. This is a little complicated since most shadows are 1699682c9e0fSNathan Whitehorn * merged onto stdscr. 1700682c9e0fSNathan Whitehorn */ 1701682c9e0fSNathan Whitehorn static bool 1702682c9e0fSNathan Whitehorn last_shadow(DIALOG_WINDOWS * dw, int y, int x) 1703682c9e0fSNathan Whitehorn { 1704682c9e0fSNathan Whitehorn DIALOG_WINDOWS *p; 1705682c9e0fSNathan Whitehorn bool result = TRUE; 1706682c9e0fSNathan Whitehorn 1707682c9e0fSNathan Whitehorn for (p = dialog_state.all_windows; p != 0; p = p->next) { 1708682c9e0fSNathan Whitehorn if (p->normal != dw->normal 1709682c9e0fSNathan Whitehorn && in_shadow(p->normal, dw->shadow, y, x)) { 1710682c9e0fSNathan Whitehorn result = FALSE; 1711682c9e0fSNathan Whitehorn break; 1712682c9e0fSNathan Whitehorn } 1713682c9e0fSNathan Whitehorn } 1714682c9e0fSNathan Whitehorn return result; 1715682c9e0fSNathan Whitehorn } 1716682c9e0fSNathan Whitehorn 1717682c9e0fSNathan Whitehorn static void 1718682c9e0fSNathan Whitehorn repaint_cell(DIALOG_WINDOWS * dw, bool draw, int y, int x) 1719682c9e0fSNathan Whitehorn { 1720682c9e0fSNathan Whitehorn WINDOW *win = dw->shadow; 1721682c9e0fSNathan Whitehorn WINDOW *cellwin; 1722682c9e0fSNathan Whitehorn int y2, x2; 1723682c9e0fSNathan Whitehorn 1724682c9e0fSNathan Whitehorn if ((cellwin = window_at_cell(dw, y, x)) != 0 1725682c9e0fSNathan Whitehorn && (draw || last_shadow(dw, y, x)) 1726682c9e0fSNathan Whitehorn && (y2 = (y + getbegy(win) - getbegy(cellwin))) >= 0 1727682c9e0fSNathan Whitehorn && (x2 = (x + getbegx(win) - getbegx(cellwin))) >= 0 1728682c9e0fSNathan Whitehorn && wmove(cellwin, y2, x2) != ERR) { 1729682c9e0fSNathan Whitehorn chtype the_cell = dlg_get_attrs(cellwin); 1730682c9e0fSNathan Whitehorn chtype the_attr = (draw ? shadow_attr : the_cell); 1731682c9e0fSNathan Whitehorn 1732f4f33ea0SBaptiste Daroussin if (winch(cellwin) & A_ALTCHARSET) { 1733682c9e0fSNathan Whitehorn the_attr |= A_ALTCHARSET; 1734682c9e0fSNathan Whitehorn } 1735682c9e0fSNathan Whitehorn #if USE_WCHGAT 1736682c9e0fSNathan Whitehorn wchgat(cellwin, 1, 1737682c9e0fSNathan Whitehorn the_attr & (chtype) (~A_COLOR), 17382a3e3873SBaptiste Daroussin (short) PAIR_NUMBER(the_attr), 1739682c9e0fSNathan Whitehorn NULL); 1740682c9e0fSNathan Whitehorn #else 1741682c9e0fSNathan Whitehorn { 1742682c9e0fSNathan Whitehorn chtype the_char = ((winch(cellwin) & A_CHARTEXT) | the_attr); 1743682c9e0fSNathan Whitehorn (void) waddch(cellwin, the_char); 1744682c9e0fSNathan Whitehorn } 1745682c9e0fSNathan Whitehorn #endif 1746682c9e0fSNathan Whitehorn wnoutrefresh(cellwin); 1747682c9e0fSNathan Whitehorn } 1748682c9e0fSNathan Whitehorn } 1749682c9e0fSNathan Whitehorn 1750682c9e0fSNathan Whitehorn #define RepaintCell(dw, draw, y, x) repaint_cell(dw, draw, y, x) 1751682c9e0fSNathan Whitehorn 1752682c9e0fSNathan Whitehorn static void 1753682c9e0fSNathan Whitehorn repaint_shadow(DIALOG_WINDOWS * dw, bool draw, int y, int x, int height, int width) 1754682c9e0fSNathan Whitehorn { 1755*a96ef450SBaptiste Daroussin if (UseShadow(dw)) { 1756682c9e0fSNathan Whitehorn int i, j; 1757682c9e0fSNathan Whitehorn 1758682c9e0fSNathan Whitehorn #if !USE_WCHGAT 1759682c9e0fSNathan Whitehorn chtype save = dlg_get_attrs(dw->shadow); 1760f4f33ea0SBaptiste Daroussin dlg_attrset(dw->shadow, draw ? shadow_attr : screen_attr); 1761682c9e0fSNathan Whitehorn #endif 1762682c9e0fSNathan Whitehorn for (i = 0; i < SHADOW_ROWS; ++i) { 1763682c9e0fSNathan Whitehorn for (j = 0; j < width; ++j) { 1764682c9e0fSNathan Whitehorn RepaintCell(dw, draw, i + y + height, j + x + SHADOW_COLS); 1765682c9e0fSNathan Whitehorn } 1766682c9e0fSNathan Whitehorn } 1767682c9e0fSNathan Whitehorn for (i = 0; i < height; i++) { 1768682c9e0fSNathan Whitehorn for (j = 0; j < SHADOW_COLS; ++j) { 1769682c9e0fSNathan Whitehorn RepaintCell(dw, draw, i + y + SHADOW_ROWS, j + x + width); 1770682c9e0fSNathan Whitehorn } 1771682c9e0fSNathan Whitehorn } 1772682c9e0fSNathan Whitehorn (void) wnoutrefresh(dw->shadow); 1773682c9e0fSNathan Whitehorn #if !USE_WCHGAT 1774f4f33ea0SBaptiste Daroussin dlg_attrset(dw->shadow, save); 1775682c9e0fSNathan Whitehorn #endif 1776682c9e0fSNathan Whitehorn } 1777682c9e0fSNathan Whitehorn } 1778682c9e0fSNathan Whitehorn 1779682c9e0fSNathan Whitehorn /* 17804c8945a0SNathan Whitehorn * Draw a shadow on the parent window corresponding to the right- and 17814c8945a0SNathan Whitehorn * bottom-edge of the child window, to give a 3-dimensional look. 17824c8945a0SNathan Whitehorn */ 17834c8945a0SNathan Whitehorn static void 1784682c9e0fSNathan Whitehorn draw_childs_shadow(DIALOG_WINDOWS * dw) 17854c8945a0SNathan Whitehorn { 1786682c9e0fSNathan Whitehorn if (UseShadow(dw)) { 1787682c9e0fSNathan Whitehorn repaint_shadow(dw, 1788682c9e0fSNathan Whitehorn TRUE, 1789682c9e0fSNathan Whitehorn getbegy(dw->normal) - getbegy(dw->shadow), 1790682c9e0fSNathan Whitehorn getbegx(dw->normal) - getbegx(dw->shadow), 1791682c9e0fSNathan Whitehorn getmaxy(dw->normal), 1792682c9e0fSNathan Whitehorn getmaxx(dw->normal)); 1793682c9e0fSNathan Whitehorn } 1794682c9e0fSNathan Whitehorn } 17954c8945a0SNathan Whitehorn 1796682c9e0fSNathan Whitehorn /* 1797682c9e0fSNathan Whitehorn * Erase a shadow on the parent window corresponding to the right- and 1798682c9e0fSNathan Whitehorn * bottom-edge of the child window. 1799682c9e0fSNathan Whitehorn */ 1800682c9e0fSNathan Whitehorn static void 1801682c9e0fSNathan Whitehorn erase_childs_shadow(DIALOG_WINDOWS * dw) 1802682c9e0fSNathan Whitehorn { 1803682c9e0fSNathan Whitehorn if (UseShadow(dw)) { 1804682c9e0fSNathan Whitehorn repaint_shadow(dw, 1805682c9e0fSNathan Whitehorn FALSE, 1806682c9e0fSNathan Whitehorn getbegy(dw->normal) - getbegy(dw->shadow), 1807682c9e0fSNathan Whitehorn getbegx(dw->normal) - getbegx(dw->shadow), 1808682c9e0fSNathan Whitehorn getmaxy(dw->normal), 1809682c9e0fSNathan Whitehorn getmaxx(dw->normal)); 18104c8945a0SNathan Whitehorn } 18114c8945a0SNathan Whitehorn } 18124c8945a0SNathan Whitehorn 18134c8945a0SNathan Whitehorn /* 18144c8945a0SNathan Whitehorn * Draw shadows along the right and bottom edge to give a more 3D look 1815682c9e0fSNathan Whitehorn * to the boxes. 18164c8945a0SNathan Whitehorn */ 18174c8945a0SNathan Whitehorn void 18184c8945a0SNathan Whitehorn dlg_draw_shadow(WINDOW *win, int y, int x, int height, int width) 18194c8945a0SNathan Whitehorn { 1820*a96ef450SBaptiste Daroussin repaint_shadow(SearchTopWindows(win), TRUE, y, x, height, width); 18214c8945a0SNathan Whitehorn } 18224c8945a0SNathan Whitehorn #endif /* HAVE_COLOR */ 18234c8945a0SNathan Whitehorn 18244c8945a0SNathan Whitehorn /* 18254c8945a0SNathan Whitehorn * Allow shell scripts to remap the exit codes so they can distinguish ESC 18264c8945a0SNathan Whitehorn * from ERROR. 18274c8945a0SNathan Whitehorn */ 18284c8945a0SNathan Whitehorn void 18294c8945a0SNathan Whitehorn dlg_exit(int code) 18304c8945a0SNathan Whitehorn { 18314c8945a0SNathan Whitehorn /* *INDENT-OFF* */ 18324c8945a0SNathan Whitehorn static const struct { 18334c8945a0SNathan Whitehorn int code; 18344c8945a0SNathan Whitehorn const char *name; 18354c8945a0SNathan Whitehorn } table[] = { 18364c8945a0SNathan Whitehorn { DLG_EXIT_CANCEL, "DIALOG_CANCEL" }, 18374c8945a0SNathan Whitehorn { DLG_EXIT_ERROR, "DIALOG_ERROR" }, 18384c8945a0SNathan Whitehorn { DLG_EXIT_ESC, "DIALOG_ESC" }, 18394c8945a0SNathan Whitehorn { DLG_EXIT_EXTRA, "DIALOG_EXTRA" }, 18404c8945a0SNathan Whitehorn { DLG_EXIT_HELP, "DIALOG_HELP" }, 18414c8945a0SNathan Whitehorn { DLG_EXIT_OK, "DIALOG_OK" }, 18424c8945a0SNathan Whitehorn { DLG_EXIT_ITEM_HELP, "DIALOG_ITEM_HELP" }, 1843*a96ef450SBaptiste Daroussin { DLG_EXIT_TIMEOUT, "DIALOG_TIMEOUT" }, 18444c8945a0SNathan Whitehorn }; 18454c8945a0SNathan Whitehorn /* *INDENT-ON* */ 18464c8945a0SNathan Whitehorn 18474c8945a0SNathan Whitehorn unsigned n; 18484c8945a0SNathan Whitehorn bool overridden = FALSE; 18494c8945a0SNathan Whitehorn 18504c8945a0SNathan Whitehorn retry: 1851*a96ef450SBaptiste Daroussin for (n = 0; n < TableSize(table); n++) { 18524c8945a0SNathan Whitehorn if (table[n].code == code) { 1853*a96ef450SBaptiste Daroussin if (dlg_getenv_num(table[n].name, &code)) { 18544c8945a0SNathan Whitehorn overridden = TRUE; 18554c8945a0SNathan Whitehorn } 18564c8945a0SNathan Whitehorn break; 18574c8945a0SNathan Whitehorn } 18584c8945a0SNathan Whitehorn } 18594c8945a0SNathan Whitehorn 18604c8945a0SNathan Whitehorn /* 18614c8945a0SNathan Whitehorn * Prior to 2004/12/19, a widget using --item-help would exit with "OK" 18624c8945a0SNathan Whitehorn * if the help button were selected. Now we want to exit with "HELP", 18634c8945a0SNathan Whitehorn * but allow the environment variable to override. 18644c8945a0SNathan Whitehorn */ 18654c8945a0SNathan Whitehorn if (code == DLG_EXIT_ITEM_HELP && !overridden) { 18664c8945a0SNathan Whitehorn code = DLG_EXIT_HELP; 18674c8945a0SNathan Whitehorn goto retry; 18684c8945a0SNathan Whitehorn } 1869682c9e0fSNathan Whitehorn #ifdef HAVE_DLG_TRACE 1870682c9e0fSNathan Whitehorn dlg_trace((const char *) 0); /* close it */ 1871682c9e0fSNathan Whitehorn #endif 1872682c9e0fSNathan Whitehorn 18734c8945a0SNathan Whitehorn #ifdef NO_LEAKS 18744c8945a0SNathan Whitehorn _dlg_inputstr_leaks(); 1875*a96ef450SBaptiste Daroussin #if defined(NCURSES_VERSION) && (defined(HAVE_CURSES_EXIT) || defined(HAVE__NC_FREE_AND_EXIT)) 1876*a96ef450SBaptiste Daroussin curses_exit(code); 18774c8945a0SNathan Whitehorn #endif 18784c8945a0SNathan Whitehorn #endif 18794c8945a0SNathan Whitehorn 18804c8945a0SNathan Whitehorn if (dialog_state.input == stdin) { 18814c8945a0SNathan Whitehorn exit(code); 18824c8945a0SNathan Whitehorn } else { 18834c8945a0SNathan Whitehorn /* 18844c8945a0SNathan Whitehorn * Just in case of using --input-fd option, do not 18854c8945a0SNathan Whitehorn * call atexit functions of ncurses which may hang. 18864c8945a0SNathan Whitehorn */ 18874c8945a0SNathan Whitehorn if (dialog_state.input) { 18884c8945a0SNathan Whitehorn fclose(dialog_state.input); 18894c8945a0SNathan Whitehorn dialog_state.input = 0; 18904c8945a0SNathan Whitehorn } 18914c8945a0SNathan Whitehorn if (dialog_state.pipe_input) { 18924c8945a0SNathan Whitehorn if (dialog_state.pipe_input != stdin) { 18934c8945a0SNathan Whitehorn fclose(dialog_state.pipe_input); 18944c8945a0SNathan Whitehorn dialog_state.pipe_input = 0; 18954c8945a0SNathan Whitehorn } 18964c8945a0SNathan Whitehorn } 18974c8945a0SNathan Whitehorn _exit(code); 18984c8945a0SNathan Whitehorn } 18994c8945a0SNathan Whitehorn } 19004c8945a0SNathan Whitehorn 1901*a96ef450SBaptiste Daroussin #define DATA(name) { DLG_EXIT_ ## name, #name } 1902*a96ef450SBaptiste Daroussin /* *INDENT-OFF* */ 1903*a96ef450SBaptiste Daroussin static struct { 1904*a96ef450SBaptiste Daroussin int code; 1905*a96ef450SBaptiste Daroussin const char *name; 1906*a96ef450SBaptiste Daroussin } exit_codenames[] = { 1907*a96ef450SBaptiste Daroussin DATA(ESC), 1908*a96ef450SBaptiste Daroussin DATA(UNKNOWN), 1909*a96ef450SBaptiste Daroussin DATA(ERROR), 1910*a96ef450SBaptiste Daroussin DATA(OK), 1911*a96ef450SBaptiste Daroussin DATA(CANCEL), 1912*a96ef450SBaptiste Daroussin DATA(HELP), 1913*a96ef450SBaptiste Daroussin DATA(EXTRA), 1914*a96ef450SBaptiste Daroussin DATA(ITEM_HELP), 1915*a96ef450SBaptiste Daroussin }; 1916*a96ef450SBaptiste Daroussin #undef DATA 1917*a96ef450SBaptiste Daroussin /* *INDENT-ON* */ 1918*a96ef450SBaptiste Daroussin 1919*a96ef450SBaptiste Daroussin const char * 1920*a96ef450SBaptiste Daroussin dlg_exitcode2s(int code) 1921*a96ef450SBaptiste Daroussin { 1922*a96ef450SBaptiste Daroussin const char *result = "?"; 1923*a96ef450SBaptiste Daroussin size_t n; 1924*a96ef450SBaptiste Daroussin 1925*a96ef450SBaptiste Daroussin for (n = 0; n < TableSize(exit_codenames); ++n) { 1926*a96ef450SBaptiste Daroussin if (exit_codenames[n].code == code) { 1927*a96ef450SBaptiste Daroussin result = exit_codenames[n].name; 1928*a96ef450SBaptiste Daroussin break; 1929*a96ef450SBaptiste Daroussin } 1930*a96ef450SBaptiste Daroussin } 1931*a96ef450SBaptiste Daroussin return result; 1932*a96ef450SBaptiste Daroussin } 1933*a96ef450SBaptiste Daroussin 1934*a96ef450SBaptiste Daroussin int 1935*a96ef450SBaptiste Daroussin dlg_exitname2n(const char *name) 1936*a96ef450SBaptiste Daroussin { 1937*a96ef450SBaptiste Daroussin int result = DLG_EXIT_UNKNOWN; 1938*a96ef450SBaptiste Daroussin size_t n; 1939*a96ef450SBaptiste Daroussin 1940*a96ef450SBaptiste Daroussin for (n = 0; n < TableSize(exit_codenames); ++n) { 1941*a96ef450SBaptiste Daroussin if (!dlg_strcmp(exit_codenames[n].name, name)) { 1942*a96ef450SBaptiste Daroussin result = exit_codenames[n].code; 1943*a96ef450SBaptiste Daroussin break; 1944*a96ef450SBaptiste Daroussin } 1945*a96ef450SBaptiste Daroussin } 1946*a96ef450SBaptiste Daroussin return result; 1947*a96ef450SBaptiste Daroussin } 1948*a96ef450SBaptiste Daroussin 19494c8945a0SNathan Whitehorn /* quit program killing all tailbg */ 19504c8945a0SNathan Whitehorn void 19514c8945a0SNathan Whitehorn dlg_exiterr(const char *fmt, ...) 19524c8945a0SNathan Whitehorn { 19534c8945a0SNathan Whitehorn int retval; 19544c8945a0SNathan Whitehorn va_list ap; 19554c8945a0SNathan Whitehorn 19564c8945a0SNathan Whitehorn end_dialog(); 19574c8945a0SNathan Whitehorn 19584c8945a0SNathan Whitehorn (void) fputc('\n', stderr); 19594c8945a0SNathan Whitehorn va_start(ap, fmt); 19604c8945a0SNathan Whitehorn (void) vfprintf(stderr, fmt, ap); 19614c8945a0SNathan Whitehorn va_end(ap); 19624c8945a0SNathan Whitehorn (void) fputc('\n', stderr); 19634c8945a0SNathan Whitehorn 1964*a96ef450SBaptiste Daroussin #ifdef HAVE_DLG_TRACE 1965*a96ef450SBaptiste Daroussin va_start(ap, fmt); 1966*a96ef450SBaptiste Daroussin dlg_trace_msg("## Error: "); 1967*a96ef450SBaptiste Daroussin dlg_trace_va_msg(fmt, ap); 1968*a96ef450SBaptiste Daroussin va_end(ap); 1969*a96ef450SBaptiste Daroussin #endif 1970*a96ef450SBaptiste Daroussin 19714c8945a0SNathan Whitehorn dlg_killall_bg(&retval); 19724c8945a0SNathan Whitehorn 19734c8945a0SNathan Whitehorn (void) fflush(stderr); 19744c8945a0SNathan Whitehorn (void) fflush(stdout); 1975*a96ef450SBaptiste Daroussin dlg_exit(strcmp(fmt, "timeout") == 0 ? DLG_EXIT_TIMEOUT : DLG_EXIT_ERROR); 1976*a96ef450SBaptiste Daroussin } 1977*a96ef450SBaptiste Daroussin 1978*a96ef450SBaptiste Daroussin /* 1979*a96ef450SBaptiste Daroussin * Get a string from the environment, rejecting those which are entirely blank. 1980*a96ef450SBaptiste Daroussin */ 1981*a96ef450SBaptiste Daroussin char * 1982*a96ef450SBaptiste Daroussin dlg_getenv_str(const char *name) 1983*a96ef450SBaptiste Daroussin { 1984*a96ef450SBaptiste Daroussin char *result = getenv(name); 1985*a96ef450SBaptiste Daroussin if (result != NULL) { 1986*a96ef450SBaptiste Daroussin while (*result != '\0' && isspace(UCH(*result))) 1987*a96ef450SBaptiste Daroussin ++result; 1988*a96ef450SBaptiste Daroussin if (*result == '\0') 1989*a96ef450SBaptiste Daroussin result = NULL; 1990*a96ef450SBaptiste Daroussin } 1991*a96ef450SBaptiste Daroussin return result; 1992*a96ef450SBaptiste Daroussin } 1993*a96ef450SBaptiste Daroussin 1994*a96ef450SBaptiste Daroussin /* 1995*a96ef450SBaptiste Daroussin * Get a number from the environment: 1996*a96ef450SBaptiste Daroussin * + If the caller provides a pointer in the second parameter, return 1997*a96ef450SBaptiste Daroussin * success/failure for the function return, and the actual value via the 1998*a96ef450SBaptiste Daroussin * pointer. Use this for decoding arbitrary numbers, e.g., negative or zero. 1999*a96ef450SBaptiste Daroussin * + If the caller does not provide a pointer, return the decoded value for 2000*a96ef450SBaptiste Daroussin * the function-return. Use this when only values greater than zero are 2001*a96ef450SBaptiste Daroussin * useful. 2002*a96ef450SBaptiste Daroussin */ 2003*a96ef450SBaptiste Daroussin int 2004*a96ef450SBaptiste Daroussin dlg_getenv_num(const char *name, int *value) 2005*a96ef450SBaptiste Daroussin { 2006*a96ef450SBaptiste Daroussin int result = 0; 2007*a96ef450SBaptiste Daroussin char *data = getenv(name); 2008*a96ef450SBaptiste Daroussin if (data != NULL) { 2009*a96ef450SBaptiste Daroussin char *temp = NULL; 2010*a96ef450SBaptiste Daroussin long check = strtol(data, &temp, 0); 2011*a96ef450SBaptiste Daroussin if (temp != 0 && temp != data && *temp == '\0') { 2012*a96ef450SBaptiste Daroussin result = (int) check; 2013*a96ef450SBaptiste Daroussin if (value != NULL) { 2014*a96ef450SBaptiste Daroussin *value = result; 2015*a96ef450SBaptiste Daroussin result = 1; 2016*a96ef450SBaptiste Daroussin } 2017*a96ef450SBaptiste Daroussin } 2018*a96ef450SBaptiste Daroussin } 2019*a96ef450SBaptiste Daroussin return result; 20204c8945a0SNathan Whitehorn } 20214c8945a0SNathan Whitehorn 20224c8945a0SNathan Whitehorn void 20234c8945a0SNathan Whitehorn dlg_beeping(void) 20244c8945a0SNathan Whitehorn { 20254c8945a0SNathan Whitehorn if (dialog_vars.beep_signal) { 20264c8945a0SNathan Whitehorn (void) beep(); 20274c8945a0SNathan Whitehorn dialog_vars.beep_signal = 0; 20284c8945a0SNathan Whitehorn } 20294c8945a0SNathan Whitehorn } 20304c8945a0SNathan Whitehorn 20314c8945a0SNathan Whitehorn void 20324c8945a0SNathan Whitehorn dlg_print_size(int height, int width) 20334c8945a0SNathan Whitehorn { 2034f4f33ea0SBaptiste Daroussin if (dialog_vars.print_siz) { 20354c8945a0SNathan Whitehorn fprintf(dialog_state.output, "Size: %d, %d\n", height, width); 2036f4f33ea0SBaptiste Daroussin DLG_TRACE(("# print size: %dx%d\n", height, width)); 2037f4f33ea0SBaptiste Daroussin } 20384c8945a0SNathan Whitehorn } 20394c8945a0SNathan Whitehorn 20404c8945a0SNathan Whitehorn void 20414c8945a0SNathan Whitehorn dlg_ctl_size(int height, int width) 20424c8945a0SNathan Whitehorn { 20434c8945a0SNathan Whitehorn if (dialog_vars.size_err) { 20444c8945a0SNathan Whitehorn if ((width > COLS) || (height > LINES)) { 20454c8945a0SNathan Whitehorn dlg_exiterr("Window too big. (height, width) = (%d, %d). Max allowed (%d, %d).", 20464c8945a0SNathan Whitehorn height, width, LINES, COLS); 20474c8945a0SNathan Whitehorn } 20484c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 20494c8945a0SNathan Whitehorn else if ((dialog_state.use_shadow) 20504c8945a0SNathan Whitehorn && ((width > SCOLS || height > SLINES))) { 20514c8945a0SNathan Whitehorn if ((width <= COLS) && (height <= LINES)) { 20524c8945a0SNathan Whitehorn /* try again, without shadows */ 20534c8945a0SNathan Whitehorn dialog_state.use_shadow = 0; 20544c8945a0SNathan Whitehorn } else { 20554c8945a0SNathan Whitehorn dlg_exiterr("Window+Shadow too big. (height, width) = (%d, %d). Max allowed (%d, %d).", 20564c8945a0SNathan Whitehorn height, width, SLINES, SCOLS); 20574c8945a0SNathan Whitehorn } 20584c8945a0SNathan Whitehorn } 20594c8945a0SNathan Whitehorn #endif 20604c8945a0SNathan Whitehorn } 20614c8945a0SNathan Whitehorn } 20624c8945a0SNathan Whitehorn 20634c8945a0SNathan Whitehorn /* 20644c8945a0SNathan Whitehorn * If the --tab-correct was not selected, convert tabs to single spaces. 20654c8945a0SNathan Whitehorn */ 20664c8945a0SNathan Whitehorn void 20674c8945a0SNathan Whitehorn dlg_tab_correct_str(char *prompt) 20684c8945a0SNathan Whitehorn { 20694c8945a0SNathan Whitehorn char *ptr; 20704c8945a0SNathan Whitehorn 20714c8945a0SNathan Whitehorn if (dialog_vars.tab_correct) { 20724c8945a0SNathan Whitehorn while ((ptr = strchr(prompt, TAB)) != NULL) { 20734c8945a0SNathan Whitehorn *ptr = ' '; 20744c8945a0SNathan Whitehorn prompt = ptr; 20754c8945a0SNathan Whitehorn } 20764c8945a0SNathan Whitehorn } 20774c8945a0SNathan Whitehorn } 20784c8945a0SNathan Whitehorn 20794c8945a0SNathan Whitehorn void 20804c8945a0SNathan Whitehorn dlg_calc_listh(int *height, int *list_height, int item_no) 20814c8945a0SNathan Whitehorn { 20824c8945a0SNathan Whitehorn /* calculate new height and list_height */ 20834c8945a0SNathan Whitehorn int rows = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0); 20844c8945a0SNathan Whitehorn if (rows - (*height) > 0) { 20854c8945a0SNathan Whitehorn if (rows - (*height) > item_no) 20864c8945a0SNathan Whitehorn *list_height = item_no; 20874c8945a0SNathan Whitehorn else 20884c8945a0SNathan Whitehorn *list_height = rows - (*height); 20894c8945a0SNathan Whitehorn } 20904c8945a0SNathan Whitehorn (*height) += (*list_height); 20914c8945a0SNathan Whitehorn } 20924c8945a0SNathan Whitehorn 20934c8945a0SNathan Whitehorn /* obsolete */ 20944c8945a0SNathan Whitehorn int 20954c8945a0SNathan Whitehorn dlg_calc_listw(int item_no, char **items, int group) 20964c8945a0SNathan Whitehorn { 2097*a96ef450SBaptiste Daroussin int i, len1 = 0, len2 = 0; 2098*a96ef450SBaptiste Daroussin 20994c8945a0SNathan Whitehorn for (i = 0; i < (item_no * group); i += group) { 2100*a96ef450SBaptiste Daroussin int n; 2101*a96ef450SBaptiste Daroussin 21024c8945a0SNathan Whitehorn if ((n = dlg_count_columns(items[i])) > len1) 21034c8945a0SNathan Whitehorn len1 = n; 21044c8945a0SNathan Whitehorn if ((n = dlg_count_columns(items[i + 1])) > len2) 21054c8945a0SNathan Whitehorn len2 = n; 21064c8945a0SNathan Whitehorn } 21074c8945a0SNathan Whitehorn return len1 + len2; 21084c8945a0SNathan Whitehorn } 21094c8945a0SNathan Whitehorn 21104c8945a0SNathan Whitehorn int 21114c8945a0SNathan Whitehorn dlg_calc_list_width(int item_no, DIALOG_LISTITEM * items) 21124c8945a0SNathan Whitehorn { 21134c8945a0SNathan Whitehorn int n, i, len1 = 0, len2 = 0; 21142a3e3873SBaptiste Daroussin int bits = ((dialog_vars.no_tags ? 1 : 0) 21152a3e3873SBaptiste Daroussin + (dialog_vars.no_items ? 2 : 0)); 21162a3e3873SBaptiste Daroussin 21174c8945a0SNathan Whitehorn for (i = 0; i < item_no; ++i) { 21182a3e3873SBaptiste Daroussin switch (bits) { 21192a3e3873SBaptiste Daroussin case 0: 21202a3e3873SBaptiste Daroussin /* FALLTHRU */ 21212a3e3873SBaptiste Daroussin case 1: 21224c8945a0SNathan Whitehorn if ((n = dlg_count_columns(items[i].name)) > len1) 21234c8945a0SNathan Whitehorn len1 = n; 21244c8945a0SNathan Whitehorn if ((n = dlg_count_columns(items[i].text)) > len2) 21254c8945a0SNathan Whitehorn len2 = n; 21262a3e3873SBaptiste Daroussin break; 21272a3e3873SBaptiste Daroussin case 2: 21282a3e3873SBaptiste Daroussin /* FALLTHRU */ 21292a3e3873SBaptiste Daroussin case 3: 21302a3e3873SBaptiste Daroussin if ((n = dlg_count_columns(items[i].name)) > len1) 21312a3e3873SBaptiste Daroussin len1 = n; 21322a3e3873SBaptiste Daroussin break; 21332a3e3873SBaptiste Daroussin } 21344c8945a0SNathan Whitehorn } 21354c8945a0SNathan Whitehorn return len1 + len2; 21364c8945a0SNathan Whitehorn } 21374c8945a0SNathan Whitehorn 21384c8945a0SNathan Whitehorn char * 21394c8945a0SNathan Whitehorn dlg_strempty(void) 21404c8945a0SNathan Whitehorn { 21414c8945a0SNathan Whitehorn static char empty[] = ""; 21424c8945a0SNathan Whitehorn return empty; 21434c8945a0SNathan Whitehorn } 21444c8945a0SNathan Whitehorn 21454c8945a0SNathan Whitehorn char * 21464c8945a0SNathan Whitehorn dlg_strclone(const char *cprompt) 21474c8945a0SNathan Whitehorn { 2148f4f33ea0SBaptiste Daroussin char *prompt = 0; 2149f4f33ea0SBaptiste Daroussin if (cprompt != 0) { 2150f4f33ea0SBaptiste Daroussin prompt = dlg_malloc(char, strlen(cprompt) + 1); 21514c8945a0SNathan Whitehorn assert_ptr(prompt, "dlg_strclone"); 21524c8945a0SNathan Whitehorn strcpy(prompt, cprompt); 2153f4f33ea0SBaptiste Daroussin } 21544c8945a0SNathan Whitehorn return prompt; 21554c8945a0SNathan Whitehorn } 21564c8945a0SNathan Whitehorn 21574c8945a0SNathan Whitehorn chtype 21584c8945a0SNathan Whitehorn dlg_asciibox(chtype ch) 21594c8945a0SNathan Whitehorn { 21604c8945a0SNathan Whitehorn chtype result = 0; 21614c8945a0SNathan Whitehorn 21624c8945a0SNathan Whitehorn if (ch == ACS_ULCORNER) 21634c8945a0SNathan Whitehorn result = '+'; 21644c8945a0SNathan Whitehorn else if (ch == ACS_LLCORNER) 21654c8945a0SNathan Whitehorn result = '+'; 21664c8945a0SNathan Whitehorn else if (ch == ACS_URCORNER) 21674c8945a0SNathan Whitehorn result = '+'; 21684c8945a0SNathan Whitehorn else if (ch == ACS_LRCORNER) 21694c8945a0SNathan Whitehorn result = '+'; 21704c8945a0SNathan Whitehorn else if (ch == ACS_HLINE) 21714c8945a0SNathan Whitehorn result = '-'; 21724c8945a0SNathan Whitehorn else if (ch == ACS_VLINE) 21734c8945a0SNathan Whitehorn result = '|'; 21744c8945a0SNathan Whitehorn else if (ch == ACS_LTEE) 21754c8945a0SNathan Whitehorn result = '+'; 21764c8945a0SNathan Whitehorn else if (ch == ACS_RTEE) 21774c8945a0SNathan Whitehorn result = '+'; 21784c8945a0SNathan Whitehorn else if (ch == ACS_UARROW) 21794c8945a0SNathan Whitehorn result = '^'; 21804c8945a0SNathan Whitehorn else if (ch == ACS_DARROW) 21814c8945a0SNathan Whitehorn result = 'v'; 21824c8945a0SNathan Whitehorn 21834c8945a0SNathan Whitehorn return result; 21844c8945a0SNathan Whitehorn } 21854c8945a0SNathan Whitehorn 21864c8945a0SNathan Whitehorn chtype 21874c8945a0SNathan Whitehorn dlg_boxchar(chtype ch) 21884c8945a0SNathan Whitehorn { 21894c8945a0SNathan Whitehorn chtype result = dlg_asciibox(ch); 21904c8945a0SNathan Whitehorn 21914c8945a0SNathan Whitehorn if (result != 0) { 21924c8945a0SNathan Whitehorn if (dialog_vars.ascii_lines) 21934c8945a0SNathan Whitehorn ch = result; 21944c8945a0SNathan Whitehorn else if (dialog_vars.no_lines) 21954c8945a0SNathan Whitehorn ch = ' '; 21964c8945a0SNathan Whitehorn } 21974c8945a0SNathan Whitehorn return ch; 21984c8945a0SNathan Whitehorn } 21994c8945a0SNathan Whitehorn 22004c8945a0SNathan Whitehorn int 22014c8945a0SNathan Whitehorn dlg_box_x_ordinate(int width) 22024c8945a0SNathan Whitehorn { 22034c8945a0SNathan Whitehorn int x; 22044c8945a0SNathan Whitehorn 22054c8945a0SNathan Whitehorn if (dialog_vars.begin_set == 1) { 22064c8945a0SNathan Whitehorn x = dialog_vars.begin_x; 22074c8945a0SNathan Whitehorn } else { 22084c8945a0SNathan Whitehorn /* center dialog box on screen unless --begin-set */ 22094c8945a0SNathan Whitehorn x = (SCOLS - width) / 2; 22104c8945a0SNathan Whitehorn } 22114c8945a0SNathan Whitehorn return x; 22124c8945a0SNathan Whitehorn } 22134c8945a0SNathan Whitehorn 22144c8945a0SNathan Whitehorn int 22154c8945a0SNathan Whitehorn dlg_box_y_ordinate(int height) 22164c8945a0SNathan Whitehorn { 22174c8945a0SNathan Whitehorn int y; 22184c8945a0SNathan Whitehorn 22194c8945a0SNathan Whitehorn if (dialog_vars.begin_set == 1) { 22204c8945a0SNathan Whitehorn y = dialog_vars.begin_y; 22214c8945a0SNathan Whitehorn } else { 22224c8945a0SNathan Whitehorn /* center dialog box on screen unless --begin-set */ 22234c8945a0SNathan Whitehorn y = (SLINES - height) / 2; 22244c8945a0SNathan Whitehorn } 22254c8945a0SNathan Whitehorn return y; 22264c8945a0SNathan Whitehorn } 22274c8945a0SNathan Whitehorn 22284c8945a0SNathan Whitehorn void 22294c8945a0SNathan Whitehorn dlg_draw_title(WINDOW *win, const char *title) 22304c8945a0SNathan Whitehorn { 22314c8945a0SNathan Whitehorn if (title != NULL) { 22324c8945a0SNathan Whitehorn chtype attr = A_NORMAL; 22337a1c0d96SNathan Whitehorn chtype save = dlg_get_attrs(win); 22344c8945a0SNathan Whitehorn int x = centered(getmaxx(win), title); 22354c8945a0SNathan Whitehorn 2236f4f33ea0SBaptiste Daroussin dlg_attrset(win, title_attr); 22374c8945a0SNathan Whitehorn wmove(win, 0, x); 22384c8945a0SNathan Whitehorn dlg_print_text(win, title, getmaxx(win) - x, &attr); 2239f4f33ea0SBaptiste Daroussin dlg_attrset(win, save); 2240febdb468SDevin Teske dlg_finish_string(title); 22414c8945a0SNathan Whitehorn } 22424c8945a0SNathan Whitehorn } 22434c8945a0SNathan Whitehorn 22444c8945a0SNathan Whitehorn void 22452a3e3873SBaptiste Daroussin dlg_draw_bottom_box2(WINDOW *win, chtype on_left, chtype on_right, chtype on_inside) 22464c8945a0SNathan Whitehorn { 22474c8945a0SNathan Whitehorn int width = getmaxx(win); 22484c8945a0SNathan Whitehorn int height = getmaxy(win); 22494c8945a0SNathan Whitehorn int i; 22504c8945a0SNathan Whitehorn 2251f4f33ea0SBaptiste Daroussin dlg_attrset(win, on_left); 22524c8945a0SNathan Whitehorn (void) wmove(win, height - 3, 0); 22534c8945a0SNathan Whitehorn (void) waddch(win, dlg_boxchar(ACS_LTEE)); 22544c8945a0SNathan Whitehorn for (i = 0; i < width - 2; i++) 22554c8945a0SNathan Whitehorn (void) waddch(win, dlg_boxchar(ACS_HLINE)); 2256f4f33ea0SBaptiste Daroussin dlg_attrset(win, on_right); 22574c8945a0SNathan Whitehorn (void) waddch(win, dlg_boxchar(ACS_RTEE)); 2258f4f33ea0SBaptiste Daroussin dlg_attrset(win, on_inside); 22594c8945a0SNathan Whitehorn (void) wmove(win, height - 2, 1); 22604c8945a0SNathan Whitehorn for (i = 0; i < width - 2; i++) 22614c8945a0SNathan Whitehorn (void) waddch(win, ' '); 22624c8945a0SNathan Whitehorn } 22634c8945a0SNathan Whitehorn 22642a3e3873SBaptiste Daroussin void 22652a3e3873SBaptiste Daroussin dlg_draw_bottom_box(WINDOW *win) 22662a3e3873SBaptiste Daroussin { 22672a3e3873SBaptiste Daroussin dlg_draw_bottom_box2(win, border_attr, dialog_attr, dialog_attr); 22682a3e3873SBaptiste Daroussin } 22692a3e3873SBaptiste Daroussin 22704c8945a0SNathan Whitehorn /* 22714c8945a0SNathan Whitehorn * Remove a window, repainting everything else. This would be simpler if we 22724c8945a0SNathan Whitehorn * used the panel library, but that is not _always_ available. 22734c8945a0SNathan Whitehorn */ 22744c8945a0SNathan Whitehorn void 22754c8945a0SNathan Whitehorn dlg_del_window(WINDOW *win) 22764c8945a0SNathan Whitehorn { 22774c8945a0SNathan Whitehorn DIALOG_WINDOWS *p, *q, *r; 22784c8945a0SNathan Whitehorn 22794c8945a0SNathan Whitehorn /* 22804c8945a0SNathan Whitehorn * If --keep-window was set, do not delete/repaint the windows. 22814c8945a0SNathan Whitehorn */ 22824c8945a0SNathan Whitehorn if (dialog_vars.keep_window) 22834c8945a0SNathan Whitehorn return; 22844c8945a0SNathan Whitehorn 22854c8945a0SNathan Whitehorn /* Leave the main window untouched if there are no background windows. 22864c8945a0SNathan Whitehorn * We do this so the current window will not be cleared on exit, allowing 22874c8945a0SNathan Whitehorn * things like the infobox demo to run without flicker. 22884c8945a0SNathan Whitehorn */ 22894c8945a0SNathan Whitehorn if (dialog_state.getc_callbacks != 0) { 22904c8945a0SNathan Whitehorn touchwin(stdscr); 22914c8945a0SNathan Whitehorn wnoutrefresh(stdscr); 22924c8945a0SNathan Whitehorn } 22934c8945a0SNathan Whitehorn 22944c8945a0SNathan Whitehorn for (p = dialog_state.all_windows, q = r = 0; p != 0; r = p, p = p->next) { 22954c8945a0SNathan Whitehorn if (p->normal == win) { 22964c8945a0SNathan Whitehorn q = p; /* found a match - should be only one */ 22974c8945a0SNathan Whitehorn if (r == 0) { 22984c8945a0SNathan Whitehorn dialog_state.all_windows = p->next; 22994c8945a0SNathan Whitehorn } else { 23004c8945a0SNathan Whitehorn r->next = p->next; 23014c8945a0SNathan Whitehorn } 23024c8945a0SNathan Whitehorn } else { 23034c8945a0SNathan Whitehorn if (p->shadow != 0) { 23044c8945a0SNathan Whitehorn touchwin(p->shadow); 23054c8945a0SNathan Whitehorn wnoutrefresh(p->shadow); 23064c8945a0SNathan Whitehorn } 23074c8945a0SNathan Whitehorn touchwin(p->normal); 23084c8945a0SNathan Whitehorn wnoutrefresh(p->normal); 23094c8945a0SNathan Whitehorn } 23104c8945a0SNathan Whitehorn } 23114c8945a0SNathan Whitehorn 23124c8945a0SNathan Whitehorn if (q) { 2313682c9e0fSNathan Whitehorn if (dialog_state.all_windows != 0) 2314682c9e0fSNathan Whitehorn erase_childs_shadow(q); 23152a3e3873SBaptiste Daroussin del_subwindows(q->normal); 23164c8945a0SNathan Whitehorn dlg_unregister_window(q->normal); 23172a3e3873SBaptiste Daroussin delwin(q->normal); 23184c8945a0SNathan Whitehorn free(q); 23194c8945a0SNathan Whitehorn } 23204c8945a0SNathan Whitehorn doupdate(); 23214c8945a0SNathan Whitehorn } 23224c8945a0SNathan Whitehorn 23234c8945a0SNathan Whitehorn /* 23244c8945a0SNathan Whitehorn * Create a window, optionally with a shadow. 23254c8945a0SNathan Whitehorn */ 23264c8945a0SNathan Whitehorn WINDOW * 23274c8945a0SNathan Whitehorn dlg_new_window(int height, int width, int y, int x) 23284c8945a0SNathan Whitehorn { 2329682c9e0fSNathan Whitehorn return dlg_new_modal_window(stdscr, height, width, y, x); 23304c8945a0SNathan Whitehorn } 23314c8945a0SNathan Whitehorn 2332682c9e0fSNathan Whitehorn /* 2333682c9e0fSNathan Whitehorn * "Modal" windows differ from normal ones by having a shadow in a window 2334682c9e0fSNathan Whitehorn * separate from the standard screen. 2335682c9e0fSNathan Whitehorn */ 23364c8945a0SNathan Whitehorn WINDOW * 23374c8945a0SNathan Whitehorn dlg_new_modal_window(WINDOW *parent, int height, int width, int y, int x) 23384c8945a0SNathan Whitehorn { 23394c8945a0SNathan Whitehorn WINDOW *win; 23404c8945a0SNathan Whitehorn DIALOG_WINDOWS *p = dlg_calloc(DIALOG_WINDOWS, 1); 23414c8945a0SNathan Whitehorn 23424c8945a0SNathan Whitehorn (void) parent; 23432a3e3873SBaptiste Daroussin if (p == 0 23442a3e3873SBaptiste Daroussin || (win = newwin(height, width, y, x)) == 0) { 23454c8945a0SNathan Whitehorn dlg_exiterr("Can't make new window at (%d,%d), size (%d,%d).\n", 23464c8945a0SNathan Whitehorn y, x, height, width); 23474c8945a0SNathan Whitehorn } 23484c8945a0SNathan Whitehorn p->next = dialog_state.all_windows; 23494c8945a0SNathan Whitehorn p->normal = win; 2350*a96ef450SBaptiste Daroussin p->getc_timeout = WTIMEOUT_OFF; 23514c8945a0SNathan Whitehorn dialog_state.all_windows = p; 23524c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 23534c8945a0SNathan Whitehorn if (dialog_state.use_shadow) { 2354682c9e0fSNathan Whitehorn p->shadow = parent; 2355682c9e0fSNathan Whitehorn draw_childs_shadow(p); 23564c8945a0SNathan Whitehorn } 23574c8945a0SNathan Whitehorn #endif 23584c8945a0SNathan Whitehorn 23594c8945a0SNathan Whitehorn (void) keypad(win, TRUE); 23604c8945a0SNathan Whitehorn return win; 23614c8945a0SNathan Whitehorn } 23624c8945a0SNathan Whitehorn 23634c8945a0SNathan Whitehorn /* 2364*a96ef450SBaptiste Daroussin * dlg_getc() uses the return-value to determine how to handle an ERR return 2365*a96ef450SBaptiste Daroussin * from a non-blocking read: 2366*a96ef450SBaptiste Daroussin * a) if greater than zero, there was an expired timeout (blocking for a short 2367*a96ef450SBaptiste Daroussin * time), or 2368*a96ef450SBaptiste Daroussin * b) if zero, it was a non-blocking read, or 2369*a96ef450SBaptiste Daroussin * c) if negative, an error occurred on a blocking read. 2370*a96ef450SBaptiste Daroussin */ 2371*a96ef450SBaptiste Daroussin int 2372*a96ef450SBaptiste Daroussin dlg_set_timeout(WINDOW *win, bool will_getc) 2373*a96ef450SBaptiste Daroussin { 2374*a96ef450SBaptiste Daroussin DIALOG_WINDOWS *p; 2375*a96ef450SBaptiste Daroussin int result = 0; 2376*a96ef450SBaptiste Daroussin 2377*a96ef450SBaptiste Daroussin if ((p = SearchTopWindows(win)) != NULL) { 2378*a96ef450SBaptiste Daroussin int interval = (dialog_vars.timeout_secs * 1000); 2379*a96ef450SBaptiste Daroussin 2380*a96ef450SBaptiste Daroussin if (will_getc || dialog_vars.pause_secs) { 2381*a96ef450SBaptiste Daroussin interval = WTIMEOUT_VAL; 2382*a96ef450SBaptiste Daroussin } else { 2383*a96ef450SBaptiste Daroussin result = interval; 2384*a96ef450SBaptiste Daroussin if (interval <= 0) { 2385*a96ef450SBaptiste Daroussin interval = WTIMEOUT_OFF; 2386*a96ef450SBaptiste Daroussin } 2387*a96ef450SBaptiste Daroussin } 2388*a96ef450SBaptiste Daroussin wtimeout(win, interval); 2389*a96ef450SBaptiste Daroussin p->getc_timeout = interval; 2390*a96ef450SBaptiste Daroussin } 2391*a96ef450SBaptiste Daroussin return result; 2392*a96ef450SBaptiste Daroussin } 2393*a96ef450SBaptiste Daroussin 2394*a96ef450SBaptiste Daroussin void 2395*a96ef450SBaptiste Daroussin dlg_reset_timeout(WINDOW *win) 2396*a96ef450SBaptiste Daroussin { 2397*a96ef450SBaptiste Daroussin DIALOG_WINDOWS *p; 2398*a96ef450SBaptiste Daroussin 2399*a96ef450SBaptiste Daroussin if ((p = SearchTopWindows(win)) != NULL) { 2400*a96ef450SBaptiste Daroussin wtimeout(win, p->getc_timeout); 2401*a96ef450SBaptiste Daroussin } else { 2402*a96ef450SBaptiste Daroussin wtimeout(win, WTIMEOUT_OFF); 2403*a96ef450SBaptiste Daroussin } 2404*a96ef450SBaptiste Daroussin } 2405*a96ef450SBaptiste Daroussin 2406*a96ef450SBaptiste Daroussin /* 24074c8945a0SNathan Whitehorn * Move/Resize a window, optionally with a shadow. 24084c8945a0SNathan Whitehorn */ 24094c8945a0SNathan Whitehorn #ifdef KEY_RESIZE 24104c8945a0SNathan Whitehorn void 24114c8945a0SNathan Whitehorn dlg_move_window(WINDOW *win, int height, int width, int y, int x) 24124c8945a0SNathan Whitehorn { 2413*a96ef450SBaptiste Daroussin if (win != 0) { 2414682c9e0fSNathan Whitehorn DIALOG_WINDOWS *p; 24154c8945a0SNathan Whitehorn 24164c8945a0SNathan Whitehorn dlg_ctl_size(height, width); 24174c8945a0SNathan Whitehorn 2418*a96ef450SBaptiste Daroussin if ((p = SearchTopWindows(win)) != 0) { 24194c8945a0SNathan Whitehorn (void) wresize(win, height, width); 24204c8945a0SNathan Whitehorn (void) mvwin(win, y, x); 24214c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 24224c8945a0SNathan Whitehorn if (p->shadow != 0) { 24234c8945a0SNathan Whitehorn if (dialog_state.use_shadow) { 24244c8945a0SNathan Whitehorn (void) mvwin(p->shadow, y + SHADOW_ROWS, x + SHADOW_COLS); 24254c8945a0SNathan Whitehorn } else { 24264c8945a0SNathan Whitehorn p->shadow = 0; 24274c8945a0SNathan Whitehorn } 24284c8945a0SNathan Whitehorn } 24294c8945a0SNathan Whitehorn #endif 24304c8945a0SNathan Whitehorn (void) refresh(); 24314c8945a0SNathan Whitehorn 24324c8945a0SNathan Whitehorn #ifdef HAVE_COLOR 2433682c9e0fSNathan Whitehorn draw_childs_shadow(p); 24344c8945a0SNathan Whitehorn #endif 24354c8945a0SNathan Whitehorn } 24364c8945a0SNathan Whitehorn } 24374c8945a0SNathan Whitehorn } 2438f4f33ea0SBaptiste Daroussin 2439f4f33ea0SBaptiste Daroussin /* 2440f4f33ea0SBaptiste Daroussin * Having just received a KEY_RESIZE, wait a short time to ignore followup 2441f4f33ea0SBaptiste Daroussin * KEY_RESIZE events. 2442f4f33ea0SBaptiste Daroussin */ 2443f4f33ea0SBaptiste Daroussin void 2444f4f33ea0SBaptiste Daroussin dlg_will_resize(WINDOW *win) 2445f4f33ea0SBaptiste Daroussin { 2446*a96ef450SBaptiste Daroussin int n, base; 2447f4f33ea0SBaptiste Daroussin int caught = 0; 2448f4f33ea0SBaptiste Daroussin 2449*a96ef450SBaptiste Daroussin dialog_state.had_resize = TRUE; 2450f4f33ea0SBaptiste Daroussin dlg_trace_win(win); 2451*a96ef450SBaptiste Daroussin wtimeout(win, WTIMEOUT_VAL * 5); 2452*a96ef450SBaptiste Daroussin 2453f4f33ea0SBaptiste Daroussin for (n = base = 0; n < base + 10; ++n) { 2454*a96ef450SBaptiste Daroussin int ch; 2455*a96ef450SBaptiste Daroussin 2456f4f33ea0SBaptiste Daroussin if ((ch = wgetch(win)) != ERR) { 2457f4f33ea0SBaptiste Daroussin if (ch == KEY_RESIZE) { 2458f4f33ea0SBaptiste Daroussin base = n; 2459f4f33ea0SBaptiste Daroussin ++caught; 2460*a96ef450SBaptiste Daroussin } else if (ch != ERR) { 2461f4f33ea0SBaptiste Daroussin ungetch(ch); 2462f4f33ea0SBaptiste Daroussin break; 2463f4f33ea0SBaptiste Daroussin } 2464f4f33ea0SBaptiste Daroussin } 2465f4f33ea0SBaptiste Daroussin } 2466*a96ef450SBaptiste Daroussin dlg_reset_timeout(win); 2467*a96ef450SBaptiste Daroussin DLG_TRACE(("# caught %d KEY_RESIZE key%s\n", 2468f4f33ea0SBaptiste Daroussin 1 + caught, 2469*a96ef450SBaptiste Daroussin caught == 1 ? "" : "s")); 2470f4f33ea0SBaptiste Daroussin } 24714c8945a0SNathan Whitehorn #endif /* KEY_RESIZE */ 24724c8945a0SNathan Whitehorn 24734c8945a0SNathan Whitehorn WINDOW * 2474*a96ef450SBaptiste Daroussin dlg_der_window(WINDOW *parent, int height, int width, int y, int x) 2475*a96ef450SBaptiste Daroussin { 2476*a96ef450SBaptiste Daroussin WINDOW *win; 2477*a96ef450SBaptiste Daroussin 2478*a96ef450SBaptiste Daroussin /* existing uses of derwin are (almost) guaranteed to succeed, and the 2479*a96ef450SBaptiste Daroussin * caller has to allow for failure. 2480*a96ef450SBaptiste Daroussin */ 2481*a96ef450SBaptiste Daroussin if ((win = derwin(parent, height, width, y, x)) != 0) { 2482*a96ef450SBaptiste Daroussin add_subwindow(parent, win); 2483*a96ef450SBaptiste Daroussin (void) keypad(win, TRUE); 2484*a96ef450SBaptiste Daroussin } 2485*a96ef450SBaptiste Daroussin return win; 2486*a96ef450SBaptiste Daroussin } 2487*a96ef450SBaptiste Daroussin 2488*a96ef450SBaptiste Daroussin WINDOW * 24894c8945a0SNathan Whitehorn dlg_sub_window(WINDOW *parent, int height, int width, int y, int x) 24904c8945a0SNathan Whitehorn { 24914c8945a0SNathan Whitehorn WINDOW *win; 24924c8945a0SNathan Whitehorn 24934c8945a0SNathan Whitehorn if ((win = subwin(parent, height, width, y, x)) == 0) { 24944c8945a0SNathan Whitehorn dlg_exiterr("Can't make sub-window at (%d,%d), size (%d,%d).\n", 24954c8945a0SNathan Whitehorn y, x, height, width); 24964c8945a0SNathan Whitehorn } 24974c8945a0SNathan Whitehorn 24982a3e3873SBaptiste Daroussin add_subwindow(parent, win); 24994c8945a0SNathan Whitehorn (void) keypad(win, TRUE); 25004c8945a0SNathan Whitehorn return win; 25014c8945a0SNathan Whitehorn } 25024c8945a0SNathan Whitehorn 25034c8945a0SNathan Whitehorn /* obsolete */ 25044c8945a0SNathan Whitehorn int 25054c8945a0SNathan Whitehorn dlg_default_item(char **items, int llen) 25064c8945a0SNathan Whitehorn { 25074c8945a0SNathan Whitehorn int result = 0; 25084c8945a0SNathan Whitehorn 25094c8945a0SNathan Whitehorn if (dialog_vars.default_item != 0) { 25104c8945a0SNathan Whitehorn int count = 0; 25114c8945a0SNathan Whitehorn while (*items != 0) { 25124c8945a0SNathan Whitehorn if (!strcmp(dialog_vars.default_item, *items)) { 25134c8945a0SNathan Whitehorn result = count; 25144c8945a0SNathan Whitehorn break; 25154c8945a0SNathan Whitehorn } 25164c8945a0SNathan Whitehorn items += llen; 25174c8945a0SNathan Whitehorn count++; 25184c8945a0SNathan Whitehorn } 25194c8945a0SNathan Whitehorn } 25204c8945a0SNathan Whitehorn return result; 25214c8945a0SNathan Whitehorn } 25224c8945a0SNathan Whitehorn 25234c8945a0SNathan Whitehorn int 25244c8945a0SNathan Whitehorn dlg_default_listitem(DIALOG_LISTITEM * items) 25254c8945a0SNathan Whitehorn { 25264c8945a0SNathan Whitehorn int result = 0; 25274c8945a0SNathan Whitehorn 25284c8945a0SNathan Whitehorn if (dialog_vars.default_item != 0) { 25294c8945a0SNathan Whitehorn int count = 0; 25304c8945a0SNathan Whitehorn while (items->name != 0) { 25314c8945a0SNathan Whitehorn if (!strcmp(dialog_vars.default_item, items->name)) { 25324c8945a0SNathan Whitehorn result = count; 25334c8945a0SNathan Whitehorn break; 25344c8945a0SNathan Whitehorn } 25354c8945a0SNathan Whitehorn ++items; 25364c8945a0SNathan Whitehorn count++; 25374c8945a0SNathan Whitehorn } 25384c8945a0SNathan Whitehorn } 25394c8945a0SNathan Whitehorn return result; 25404c8945a0SNathan Whitehorn } 25414c8945a0SNathan Whitehorn 25424c8945a0SNathan Whitehorn /* 25434c8945a0SNathan Whitehorn * Draw the string for item_help 25444c8945a0SNathan Whitehorn */ 25454c8945a0SNathan Whitehorn void 25464c8945a0SNathan Whitehorn dlg_item_help(const char *txt) 25474c8945a0SNathan Whitehorn { 25484c8945a0SNathan Whitehorn if (USE_ITEM_HELP(txt)) { 25494c8945a0SNathan Whitehorn chtype attr = A_NORMAL; 25504c8945a0SNathan Whitehorn 2551f4f33ea0SBaptiste Daroussin dlg_attrset(stdscr, itemhelp_attr); 25524c8945a0SNathan Whitehorn (void) wmove(stdscr, LINES - 1, 0); 25534c8945a0SNathan Whitehorn (void) wclrtoeol(stdscr); 25544c8945a0SNathan Whitehorn (void) addch(' '); 25554c8945a0SNathan Whitehorn dlg_print_text(stdscr, txt, COLS - 1, &attr); 2556*a96ef450SBaptiste Daroussin 25574c8945a0SNathan Whitehorn if (itemhelp_attr & A_COLOR) { 2558*a96ef450SBaptiste Daroussin int y, x; 25594c8945a0SNathan Whitehorn /* fill the remainder of the line with the window's attributes */ 25604c8945a0SNathan Whitehorn getyx(stdscr, y, x); 25612a3e3873SBaptiste Daroussin (void) y; 25624c8945a0SNathan Whitehorn while (x < COLS) { 25634c8945a0SNathan Whitehorn (void) addch(' '); 25644c8945a0SNathan Whitehorn ++x; 25654c8945a0SNathan Whitehorn } 25664c8945a0SNathan Whitehorn } 25674c8945a0SNathan Whitehorn (void) wnoutrefresh(stdscr); 25684c8945a0SNathan Whitehorn } 25694c8945a0SNathan Whitehorn } 25704c8945a0SNathan Whitehorn 25714c8945a0SNathan Whitehorn #ifndef HAVE_STRCASECMP 25724c8945a0SNathan Whitehorn int 25734c8945a0SNathan Whitehorn dlg_strcmp(const char *a, const char *b) 25744c8945a0SNathan Whitehorn { 25754c8945a0SNathan Whitehorn int ac, bc, cmp; 25764c8945a0SNathan Whitehorn 25774c8945a0SNathan Whitehorn for (;;) { 25784c8945a0SNathan Whitehorn ac = UCH(*a++); 25794c8945a0SNathan Whitehorn bc = UCH(*b++); 25804c8945a0SNathan Whitehorn if (isalpha(ac) && islower(ac)) 25814c8945a0SNathan Whitehorn ac = _toupper(ac); 25824c8945a0SNathan Whitehorn if (isalpha(bc) && islower(bc)) 25834c8945a0SNathan Whitehorn bc = _toupper(bc); 25844c8945a0SNathan Whitehorn cmp = ac - bc; 25854c8945a0SNathan Whitehorn if (ac == 0 || bc == 0 || cmp != 0) 25864c8945a0SNathan Whitehorn break; 25874c8945a0SNathan Whitehorn } 25884c8945a0SNathan Whitehorn return cmp; 25894c8945a0SNathan Whitehorn } 25904c8945a0SNathan Whitehorn #endif 25914c8945a0SNathan Whitehorn 25924c8945a0SNathan Whitehorn /* 25934c8945a0SNathan Whitehorn * Returns true if 'dst' points to a blank which follows another blank which 25944c8945a0SNathan Whitehorn * is not a leading blank on a line. 25954c8945a0SNathan Whitehorn */ 25964c8945a0SNathan Whitehorn static bool 25974c8945a0SNathan Whitehorn trim_blank(char *base, char *dst) 25984c8945a0SNathan Whitehorn { 2599*a96ef450SBaptiste Daroussin int count = !!isblank(UCH(*dst)); 26004c8945a0SNathan Whitehorn 26014c8945a0SNathan Whitehorn while (dst-- != base) { 26024c8945a0SNathan Whitehorn if (*dst == '\n') { 2603f4f33ea0SBaptiste Daroussin break; 2604f4f33ea0SBaptiste Daroussin } else if (isblank(UCH(*dst))) { 26054c8945a0SNathan Whitehorn count++; 2606f4f33ea0SBaptiste Daroussin } else { 2607f4f33ea0SBaptiste Daroussin break; 26084c8945a0SNathan Whitehorn } 26094c8945a0SNathan Whitehorn } 2610f4f33ea0SBaptiste Daroussin return (count > 1); 26114c8945a0SNathan Whitehorn } 26124c8945a0SNathan Whitehorn 26134c8945a0SNathan Whitehorn /* 26144c8945a0SNathan Whitehorn * Change embedded "\n" substrings to '\n' characters and tabs to single 26154c8945a0SNathan Whitehorn * spaces. If there are no "\n"s, it will strip all extra spaces, for 26164c8945a0SNathan Whitehorn * justification. If it has "\n"'s, it will preserve extra spaces. If cr_wrap 26174c8945a0SNathan Whitehorn * is set, it will preserve '\n's. 26184c8945a0SNathan Whitehorn */ 26194c8945a0SNathan Whitehorn void 26204c8945a0SNathan Whitehorn dlg_trim_string(char *s) 26214c8945a0SNathan Whitehorn { 26224c8945a0SNathan Whitehorn char *base = s; 26234c8945a0SNathan Whitehorn char *p1; 26244c8945a0SNathan Whitehorn char *p = s; 2625682c9e0fSNathan Whitehorn int has_newlines = !dialog_vars.no_nl_expand && (strstr(s, "\\n") != 0); 26264c8945a0SNathan Whitehorn 26274c8945a0SNathan Whitehorn while (*p != '\0') { 26284c8945a0SNathan Whitehorn if (*p == TAB && !dialog_vars.nocollapse) 26294c8945a0SNathan Whitehorn *p = ' '; 26304c8945a0SNathan Whitehorn 26314c8945a0SNathan Whitehorn if (has_newlines) { /* If prompt contains "\n" strings */ 26324c8945a0SNathan Whitehorn if (*p == '\\' && *(p + 1) == 'n') { 26334c8945a0SNathan Whitehorn *s++ = '\n'; 26344c8945a0SNathan Whitehorn p += 2; 26354c8945a0SNathan Whitehorn p1 = p; 26364c8945a0SNathan Whitehorn /* 26374c8945a0SNathan Whitehorn * Handle end of lines intelligently. If '\n' follows "\n" 26384c8945a0SNathan Whitehorn * then ignore the '\n'. This eliminates the need to escape 26394c8945a0SNathan Whitehorn * the '\n' character (no need to use "\n\"). 26404c8945a0SNathan Whitehorn */ 2641f4f33ea0SBaptiste Daroussin while (isblank(UCH(*p1))) 26424c8945a0SNathan Whitehorn p1++; 26434c8945a0SNathan Whitehorn if (*p1 == '\n') 26444c8945a0SNathan Whitehorn p = p1 + 1; 26454c8945a0SNathan Whitehorn } else if (*p == '\n') { 26464c8945a0SNathan Whitehorn if (dialog_vars.cr_wrap) 26474c8945a0SNathan Whitehorn *s++ = *p++; 26484c8945a0SNathan Whitehorn else { 26494c8945a0SNathan Whitehorn /* Replace the '\n' with a space if cr_wrap is not set */ 2650f4f33ea0SBaptiste Daroussin if (!trim_blank(base, p)) 26514c8945a0SNathan Whitehorn *s++ = ' '; 26524c8945a0SNathan Whitehorn p++; 26534c8945a0SNathan Whitehorn } 26544c8945a0SNathan Whitehorn } else /* If *p != '\n' */ 26554c8945a0SNathan Whitehorn *s++ = *p++; 26564c8945a0SNathan Whitehorn } else if (dialog_vars.trim_whitespace) { 2657f4f33ea0SBaptiste Daroussin if (isblank(UCH(*p))) { 2658f4f33ea0SBaptiste Daroussin if (!isblank(UCH(*(s - 1)))) { 26594c8945a0SNathan Whitehorn *s++ = ' '; 26604c8945a0SNathan Whitehorn p++; 26614c8945a0SNathan Whitehorn } else 26624c8945a0SNathan Whitehorn p++; 26634c8945a0SNathan Whitehorn } else if (*p == '\n') { 26644c8945a0SNathan Whitehorn if (dialog_vars.cr_wrap) 26654c8945a0SNathan Whitehorn *s++ = *p++; 2666f4f33ea0SBaptiste Daroussin else if (!isblank(UCH(*(s - 1)))) { 26674c8945a0SNathan Whitehorn /* Strip '\n's if cr_wrap is not set. */ 26684c8945a0SNathan Whitehorn *s++ = ' '; 26694c8945a0SNathan Whitehorn p++; 26704c8945a0SNathan Whitehorn } else 26714c8945a0SNathan Whitehorn p++; 26724c8945a0SNathan Whitehorn } else 26734c8945a0SNathan Whitehorn *s++ = *p++; 26744c8945a0SNathan Whitehorn } else { /* If there are no "\n" strings */ 2675f4f33ea0SBaptiste Daroussin if (isblank(UCH(*p)) && !dialog_vars.nocollapse) { 2676f4f33ea0SBaptiste Daroussin if (!trim_blank(base, p)) 26774c8945a0SNathan Whitehorn *s++ = *p; 26784c8945a0SNathan Whitehorn p++; 26794c8945a0SNathan Whitehorn } else 26804c8945a0SNathan Whitehorn *s++ = *p++; 26814c8945a0SNathan Whitehorn } 26824c8945a0SNathan Whitehorn } 26834c8945a0SNathan Whitehorn 26844c8945a0SNathan Whitehorn *s = '\0'; 26854c8945a0SNathan Whitehorn } 26864c8945a0SNathan Whitehorn 26874c8945a0SNathan Whitehorn void 26884c8945a0SNathan Whitehorn dlg_set_focus(WINDOW *parent, WINDOW *win) 26894c8945a0SNathan Whitehorn { 26904c8945a0SNathan Whitehorn if (win != 0) { 26914c8945a0SNathan Whitehorn (void) wmove(parent, 26924c8945a0SNathan Whitehorn getpary(win) + getcury(win), 26934c8945a0SNathan Whitehorn getparx(win) + getcurx(win)); 26944c8945a0SNathan Whitehorn (void) wnoutrefresh(win); 26954c8945a0SNathan Whitehorn (void) doupdate(); 26964c8945a0SNathan Whitehorn } 26974c8945a0SNathan Whitehorn } 26984c8945a0SNathan Whitehorn 26994c8945a0SNathan Whitehorn /* 27004c8945a0SNathan Whitehorn * Returns the nominal maximum buffer size. 27014c8945a0SNathan Whitehorn */ 27024c8945a0SNathan Whitehorn int 27034c8945a0SNathan Whitehorn dlg_max_input(int max_len) 27044c8945a0SNathan Whitehorn { 27054c8945a0SNathan Whitehorn if (dialog_vars.max_input != 0 && dialog_vars.max_input < MAX_LEN) 27064c8945a0SNathan Whitehorn max_len = dialog_vars.max_input; 27074c8945a0SNathan Whitehorn 27084c8945a0SNathan Whitehorn return max_len; 27094c8945a0SNathan Whitehorn } 27104c8945a0SNathan Whitehorn 27114c8945a0SNathan Whitehorn /* 27124c8945a0SNathan Whitehorn * Free storage used for the result buffer. 27134c8945a0SNathan Whitehorn */ 27144c8945a0SNathan Whitehorn void 27154c8945a0SNathan Whitehorn dlg_clr_result(void) 27164c8945a0SNathan Whitehorn { 27174c8945a0SNathan Whitehorn if (dialog_vars.input_length) { 27184c8945a0SNathan Whitehorn dialog_vars.input_length = 0; 27194c8945a0SNathan Whitehorn if (dialog_vars.input_result) 27204c8945a0SNathan Whitehorn free(dialog_vars.input_result); 27214c8945a0SNathan Whitehorn } 27224c8945a0SNathan Whitehorn dialog_vars.input_result = 0; 27234c8945a0SNathan Whitehorn } 27244c8945a0SNathan Whitehorn 27254c8945a0SNathan Whitehorn /* 27264c8945a0SNathan Whitehorn * Setup a fixed-buffer for the result. 27274c8945a0SNathan Whitehorn */ 27284c8945a0SNathan Whitehorn char * 27294c8945a0SNathan Whitehorn dlg_set_result(const char *string) 27304c8945a0SNathan Whitehorn { 27317a1c0d96SNathan Whitehorn unsigned need = string ? (unsigned) strlen(string) + 1 : 0; 27324c8945a0SNathan Whitehorn 27334c8945a0SNathan Whitehorn /* inputstr.c needs a fixed buffer */ 27344c8945a0SNathan Whitehorn if (need < MAX_LEN) 27354c8945a0SNathan Whitehorn need = MAX_LEN; 27364c8945a0SNathan Whitehorn 27374c8945a0SNathan Whitehorn /* 27384c8945a0SNathan Whitehorn * If the buffer is not big enough, allocate a new one. 27394c8945a0SNathan Whitehorn */ 27404c8945a0SNathan Whitehorn if (dialog_vars.input_length != 0 27414c8945a0SNathan Whitehorn || dialog_vars.input_result == 0 27424c8945a0SNathan Whitehorn || need > MAX_LEN) { 27434c8945a0SNathan Whitehorn 27444c8945a0SNathan Whitehorn dlg_clr_result(); 27454c8945a0SNathan Whitehorn 27464c8945a0SNathan Whitehorn dialog_vars.input_length = need; 27474c8945a0SNathan Whitehorn dialog_vars.input_result = dlg_malloc(char, need); 27484c8945a0SNathan Whitehorn assert_ptr(dialog_vars.input_result, "dlg_set_result"); 27494c8945a0SNathan Whitehorn } 27504c8945a0SNathan Whitehorn 27514c8945a0SNathan Whitehorn strcpy(dialog_vars.input_result, string ? string : ""); 27524c8945a0SNathan Whitehorn 27534c8945a0SNathan Whitehorn return dialog_vars.input_result; 27544c8945a0SNathan Whitehorn } 27554c8945a0SNathan Whitehorn 27564c8945a0SNathan Whitehorn /* 27574c8945a0SNathan Whitehorn * Accumulate results in dynamically allocated buffer. 27584c8945a0SNathan Whitehorn * If input_length is zero, it is a MAX_LEN buffer belonging to the caller. 27594c8945a0SNathan Whitehorn */ 27604c8945a0SNathan Whitehorn void 27614c8945a0SNathan Whitehorn dlg_add_result(const char *string) 27624c8945a0SNathan Whitehorn { 27634c8945a0SNathan Whitehorn unsigned have = (dialog_vars.input_result 27647a1c0d96SNathan Whitehorn ? (unsigned) strlen(dialog_vars.input_result) 27654c8945a0SNathan Whitehorn : 0); 27667a1c0d96SNathan Whitehorn unsigned want = (unsigned) strlen(string) + 1 + have; 27674c8945a0SNathan Whitehorn 27684c8945a0SNathan Whitehorn if ((want >= MAX_LEN) 27694c8945a0SNathan Whitehorn || (dialog_vars.input_length != 0) 27704c8945a0SNathan Whitehorn || (dialog_vars.input_result == 0)) { 27714c8945a0SNathan Whitehorn 27724c8945a0SNathan Whitehorn if (dialog_vars.input_length == 0 27734c8945a0SNathan Whitehorn || dialog_vars.input_result == 0) { 27744c8945a0SNathan Whitehorn 27757a1c0d96SNathan Whitehorn char *save_result = dialog_vars.input_result; 27764c8945a0SNathan Whitehorn 27774c8945a0SNathan Whitehorn dialog_vars.input_length = want * 2; 27784c8945a0SNathan Whitehorn dialog_vars.input_result = dlg_malloc(char, dialog_vars.input_length); 27794c8945a0SNathan Whitehorn assert_ptr(dialog_vars.input_result, "dlg_add_result malloc"); 27807a1c0d96SNathan Whitehorn dialog_vars.input_result[0] = '\0'; 27817a1c0d96SNathan Whitehorn if (save_result != 0) 27827a1c0d96SNathan Whitehorn strcpy(dialog_vars.input_result, save_result); 27834c8945a0SNathan Whitehorn } else if (want >= dialog_vars.input_length) { 27844c8945a0SNathan Whitehorn dialog_vars.input_length = want * 2; 27854c8945a0SNathan Whitehorn dialog_vars.input_result = dlg_realloc(char, 27864c8945a0SNathan Whitehorn dialog_vars.input_length, 27874c8945a0SNathan Whitehorn dialog_vars.input_result); 27884c8945a0SNathan Whitehorn assert_ptr(dialog_vars.input_result, "dlg_add_result realloc"); 27894c8945a0SNathan Whitehorn } 27904c8945a0SNathan Whitehorn } 27914c8945a0SNathan Whitehorn strcat(dialog_vars.input_result, string); 27924c8945a0SNathan Whitehorn } 27934c8945a0SNathan Whitehorn 27944c8945a0SNathan Whitehorn /* 27954c8945a0SNathan Whitehorn * These are characters that (aside from the quote-delimiter) will have to 27964c8945a0SNathan Whitehorn * be escaped in a single- or double-quoted string. 27974c8945a0SNathan Whitehorn */ 27984c8945a0SNathan Whitehorn #define FIX_SINGLE "\n\\" 27994c8945a0SNathan Whitehorn #define FIX_DOUBLE FIX_SINGLE "[]{}?*;`~#$^&()|<>" 28004c8945a0SNathan Whitehorn 28014c8945a0SNathan Whitehorn /* 28024c8945a0SNathan Whitehorn * Returns the quote-delimiter. 28034c8945a0SNathan Whitehorn */ 28044c8945a0SNathan Whitehorn static const char * 28054c8945a0SNathan Whitehorn quote_delimiter(void) 28064c8945a0SNathan Whitehorn { 28074c8945a0SNathan Whitehorn return dialog_vars.single_quoted ? "'" : "\""; 28084c8945a0SNathan Whitehorn } 28094c8945a0SNathan Whitehorn 28104c8945a0SNathan Whitehorn /* 28114c8945a0SNathan Whitehorn * Returns true if we should quote the given string. 28124c8945a0SNathan Whitehorn */ 28134c8945a0SNathan Whitehorn static bool 28144c8945a0SNathan Whitehorn must_quote(char *string) 28154c8945a0SNathan Whitehorn { 28164c8945a0SNathan Whitehorn bool code = FALSE; 28174c8945a0SNathan Whitehorn 28184c8945a0SNathan Whitehorn if (*string != '\0') { 28197a1c0d96SNathan Whitehorn size_t len = strlen(string); 28204c8945a0SNathan Whitehorn if (strcspn(string, quote_delimiter()) != len) 28214c8945a0SNathan Whitehorn code = TRUE; 28224c8945a0SNathan Whitehorn else if (strcspn(string, "\n\t ") != len) 28234c8945a0SNathan Whitehorn code = TRUE; 28244c8945a0SNathan Whitehorn else 28254c8945a0SNathan Whitehorn code = (strcspn(string, FIX_DOUBLE) != len); 28264c8945a0SNathan Whitehorn } else { 28274c8945a0SNathan Whitehorn code = TRUE; 28284c8945a0SNathan Whitehorn } 28294c8945a0SNathan Whitehorn 28304c8945a0SNathan Whitehorn return code; 28314c8945a0SNathan Whitehorn } 28324c8945a0SNathan Whitehorn 28334c8945a0SNathan Whitehorn /* 28344c8945a0SNathan Whitehorn * Add a quoted string to the result buffer. 28354c8945a0SNathan Whitehorn */ 28364c8945a0SNathan Whitehorn void 28374c8945a0SNathan Whitehorn dlg_add_quoted(char *string) 28384c8945a0SNathan Whitehorn { 28394c8945a0SNathan Whitehorn char temp[2]; 28404c8945a0SNathan Whitehorn const char *my_quote = quote_delimiter(); 28414c8945a0SNathan Whitehorn const char *must_fix = (dialog_vars.single_quoted 28424c8945a0SNathan Whitehorn ? FIX_SINGLE 28434c8945a0SNathan Whitehorn : FIX_DOUBLE); 28444c8945a0SNathan Whitehorn 28452a3e3873SBaptiste Daroussin if (must_quote(string)) { 28464c8945a0SNathan Whitehorn temp[1] = '\0'; 28474c8945a0SNathan Whitehorn dlg_add_result(my_quote); 28484c8945a0SNathan Whitehorn while (*string != '\0') { 28494c8945a0SNathan Whitehorn temp[0] = *string++; 2850f4f33ea0SBaptiste Daroussin if ((strchr) (my_quote, *temp) || (strchr) (must_fix, *temp)) 28514c8945a0SNathan Whitehorn dlg_add_result("\\"); 28524c8945a0SNathan Whitehorn dlg_add_result(temp); 28534c8945a0SNathan Whitehorn } 28544c8945a0SNathan Whitehorn dlg_add_result(my_quote); 28554c8945a0SNathan Whitehorn } else { 28564c8945a0SNathan Whitehorn dlg_add_result(string); 28574c8945a0SNathan Whitehorn } 28584c8945a0SNathan Whitehorn } 28594c8945a0SNathan Whitehorn 28604c8945a0SNathan Whitehorn /* 28614c8945a0SNathan Whitehorn * When adding a result, make that depend on whether "--quoted" is used. 28624c8945a0SNathan Whitehorn */ 28634c8945a0SNathan Whitehorn void 28644c8945a0SNathan Whitehorn dlg_add_string(char *string) 28654c8945a0SNathan Whitehorn { 28664c8945a0SNathan Whitehorn if (dialog_vars.quoted) { 28674c8945a0SNathan Whitehorn dlg_add_quoted(string); 28684c8945a0SNathan Whitehorn } else { 28694c8945a0SNathan Whitehorn dlg_add_result(string); 28704c8945a0SNathan Whitehorn } 28714c8945a0SNathan Whitehorn } 28724c8945a0SNathan Whitehorn 28734c8945a0SNathan Whitehorn bool 28744c8945a0SNathan Whitehorn dlg_need_separator(void) 28754c8945a0SNathan Whitehorn { 28764c8945a0SNathan Whitehorn bool result = FALSE; 28774c8945a0SNathan Whitehorn 28784c8945a0SNathan Whitehorn if (dialog_vars.output_separator) { 28794c8945a0SNathan Whitehorn result = TRUE; 28804c8945a0SNathan Whitehorn } else if (dialog_vars.input_result && *(dialog_vars.input_result)) { 28814c8945a0SNathan Whitehorn result = TRUE; 28824c8945a0SNathan Whitehorn } 28834c8945a0SNathan Whitehorn return result; 28844c8945a0SNathan Whitehorn } 28854c8945a0SNathan Whitehorn 28864c8945a0SNathan Whitehorn void 28874c8945a0SNathan Whitehorn dlg_add_separator(void) 28884c8945a0SNathan Whitehorn { 28894c8945a0SNathan Whitehorn const char *separator = (dialog_vars.separate_output) ? "\n" : " "; 28904c8945a0SNathan Whitehorn 28914c8945a0SNathan Whitehorn if (dialog_vars.output_separator) 28924c8945a0SNathan Whitehorn separator = dialog_vars.output_separator; 28934c8945a0SNathan Whitehorn 28944c8945a0SNathan Whitehorn dlg_add_result(separator); 28954c8945a0SNathan Whitehorn } 28964c8945a0SNathan Whitehorn 2897febdb468SDevin Teske #define HELP_PREFIX "HELP " 2898febdb468SDevin Teske 2899febdb468SDevin Teske void 2900febdb468SDevin Teske dlg_add_help_listitem(int *result, char **tag, DIALOG_LISTITEM * item) 2901febdb468SDevin Teske { 2902febdb468SDevin Teske dlg_add_result(HELP_PREFIX); 2903febdb468SDevin Teske if (USE_ITEM_HELP(item->help)) { 2904febdb468SDevin Teske *tag = dialog_vars.help_tags ? item->name : item->help; 2905febdb468SDevin Teske *result = DLG_EXIT_ITEM_HELP; 2906febdb468SDevin Teske } else { 2907febdb468SDevin Teske *tag = item->name; 2908febdb468SDevin Teske } 2909febdb468SDevin Teske } 2910febdb468SDevin Teske 2911febdb468SDevin Teske void 2912febdb468SDevin Teske dlg_add_help_formitem(int *result, char **tag, DIALOG_FORMITEM * item) 2913febdb468SDevin Teske { 2914febdb468SDevin Teske dlg_add_result(HELP_PREFIX); 2915febdb468SDevin Teske if (USE_ITEM_HELP(item->help)) { 2916febdb468SDevin Teske *tag = dialog_vars.help_tags ? item->name : item->help; 2917febdb468SDevin Teske *result = DLG_EXIT_ITEM_HELP; 2918febdb468SDevin Teske } else { 2919febdb468SDevin Teske *tag = item->name; 2920febdb468SDevin Teske } 2921febdb468SDevin Teske } 2922febdb468SDevin Teske 29234c8945a0SNathan Whitehorn /* 29244c8945a0SNathan Whitehorn * Some widgets support only one value of a given variable - save/restore the 29254c8945a0SNathan Whitehorn * global dialog_vars so we can override it consistently. 29264c8945a0SNathan Whitehorn */ 29274c8945a0SNathan Whitehorn void 29284c8945a0SNathan Whitehorn dlg_save_vars(DIALOG_VARS * vars) 29294c8945a0SNathan Whitehorn { 29304c8945a0SNathan Whitehorn *vars = dialog_vars; 29314c8945a0SNathan Whitehorn } 29324c8945a0SNathan Whitehorn 29337a1c0d96SNathan Whitehorn /* 29347a1c0d96SNathan Whitehorn * Most of the data in DIALOG_VARS is normally set by command-line options. 29357a1c0d96SNathan Whitehorn * The input_result member is an exception; it is normally set by the dialog 29367a1c0d96SNathan Whitehorn * library to return result values. 29377a1c0d96SNathan Whitehorn */ 29384c8945a0SNathan Whitehorn void 29394c8945a0SNathan Whitehorn dlg_restore_vars(DIALOG_VARS * vars) 29404c8945a0SNathan Whitehorn { 29417a1c0d96SNathan Whitehorn char *save_result = dialog_vars.input_result; 29427a1c0d96SNathan Whitehorn unsigned save_length = dialog_vars.input_length; 29437a1c0d96SNathan Whitehorn 29444c8945a0SNathan Whitehorn dialog_vars = *vars; 29457a1c0d96SNathan Whitehorn dialog_vars.input_result = save_result; 29467a1c0d96SNathan Whitehorn dialog_vars.input_length = save_length; 29474c8945a0SNathan Whitehorn } 29484c8945a0SNathan Whitehorn 29494c8945a0SNathan Whitehorn /* 29504c8945a0SNathan Whitehorn * Called each time a widget is invoked which may do output, increment a count. 29514c8945a0SNathan Whitehorn */ 29524c8945a0SNathan Whitehorn void 29534c8945a0SNathan Whitehorn dlg_does_output(void) 29544c8945a0SNathan Whitehorn { 29554c8945a0SNathan Whitehorn dialog_state.output_count += 1; 29564c8945a0SNathan Whitehorn } 29574c8945a0SNathan Whitehorn 29584c8945a0SNathan Whitehorn /* 29594c8945a0SNathan Whitehorn * Compatibility for different versions of curses. 29604c8945a0SNathan Whitehorn */ 29614c8945a0SNathan Whitehorn #if !(defined(HAVE_GETBEGX) && defined(HAVE_GETBEGY)) 29624c8945a0SNathan Whitehorn int 29632a3e3873SBaptiste Daroussin dlg_getbegx(WINDOW *win) 29644c8945a0SNathan Whitehorn { 29654c8945a0SNathan Whitehorn int y, x; 29664c8945a0SNathan Whitehorn getbegyx(win, y, x); 29674c8945a0SNathan Whitehorn return x; 29684c8945a0SNathan Whitehorn } 29694c8945a0SNathan Whitehorn int 29702a3e3873SBaptiste Daroussin dlg_getbegy(WINDOW *win) 29714c8945a0SNathan Whitehorn { 29724c8945a0SNathan Whitehorn int y, x; 29734c8945a0SNathan Whitehorn getbegyx(win, y, x); 29744c8945a0SNathan Whitehorn return y; 29754c8945a0SNathan Whitehorn } 29764c8945a0SNathan Whitehorn #endif 29774c8945a0SNathan Whitehorn 29784c8945a0SNathan Whitehorn #if !(defined(HAVE_GETCURX) && defined(HAVE_GETCURY)) 29794c8945a0SNathan Whitehorn int 29802a3e3873SBaptiste Daroussin dlg_getcurx(WINDOW *win) 29814c8945a0SNathan Whitehorn { 29824c8945a0SNathan Whitehorn int y, x; 29834c8945a0SNathan Whitehorn getyx(win, y, x); 29844c8945a0SNathan Whitehorn return x; 29854c8945a0SNathan Whitehorn } 29864c8945a0SNathan Whitehorn int 29872a3e3873SBaptiste Daroussin dlg_getcury(WINDOW *win) 29884c8945a0SNathan Whitehorn { 29894c8945a0SNathan Whitehorn int y, x; 29904c8945a0SNathan Whitehorn getyx(win, y, x); 29914c8945a0SNathan Whitehorn return y; 29924c8945a0SNathan Whitehorn } 29934c8945a0SNathan Whitehorn #endif 29944c8945a0SNathan Whitehorn 29954c8945a0SNathan Whitehorn #if !(defined(HAVE_GETMAXX) && defined(HAVE_GETMAXY)) 29964c8945a0SNathan Whitehorn int 29972a3e3873SBaptiste Daroussin dlg_getmaxx(WINDOW *win) 29984c8945a0SNathan Whitehorn { 29994c8945a0SNathan Whitehorn int y, x; 30004c8945a0SNathan Whitehorn getmaxyx(win, y, x); 30014c8945a0SNathan Whitehorn return x; 30024c8945a0SNathan Whitehorn } 30034c8945a0SNathan Whitehorn int 30042a3e3873SBaptiste Daroussin dlg_getmaxy(WINDOW *win) 30054c8945a0SNathan Whitehorn { 30064c8945a0SNathan Whitehorn int y, x; 30074c8945a0SNathan Whitehorn getmaxyx(win, y, x); 30084c8945a0SNathan Whitehorn return y; 30094c8945a0SNathan Whitehorn } 30104c8945a0SNathan Whitehorn #endif 30114c8945a0SNathan Whitehorn 30124c8945a0SNathan Whitehorn #if !(defined(HAVE_GETPARX) && defined(HAVE_GETPARY)) 30134c8945a0SNathan Whitehorn int 30142a3e3873SBaptiste Daroussin dlg_getparx(WINDOW *win) 30154c8945a0SNathan Whitehorn { 30164c8945a0SNathan Whitehorn int y, x; 30174c8945a0SNathan Whitehorn getparyx(win, y, x); 30184c8945a0SNathan Whitehorn return x; 30194c8945a0SNathan Whitehorn } 30204c8945a0SNathan Whitehorn int 30212a3e3873SBaptiste Daroussin dlg_getpary(WINDOW *win) 30224c8945a0SNathan Whitehorn { 30234c8945a0SNathan Whitehorn int y, x; 30244c8945a0SNathan Whitehorn getparyx(win, y, x); 30254c8945a0SNathan Whitehorn return y; 30264c8945a0SNathan Whitehorn } 30274c8945a0SNathan Whitehorn #endif 30282a3e3873SBaptiste Daroussin 30292a3e3873SBaptiste Daroussin #ifdef NEED_WGETPARENT 30302a3e3873SBaptiste Daroussin WINDOW * 30312a3e3873SBaptiste Daroussin dlg_wgetparent(WINDOW *win) 30322a3e3873SBaptiste Daroussin { 30332a3e3873SBaptiste Daroussin #undef wgetparent 30342a3e3873SBaptiste Daroussin WINDOW *result = 0; 30352a3e3873SBaptiste Daroussin DIALOG_WINDOWS *p; 30362a3e3873SBaptiste Daroussin 30372a3e3873SBaptiste Daroussin for (p = dialog_state.all_subwindows; p != 0; p = p->next) { 30382a3e3873SBaptiste Daroussin if (p->shadow == win) { 30392a3e3873SBaptiste Daroussin result = p->normal; 30402a3e3873SBaptiste Daroussin break; 30412a3e3873SBaptiste Daroussin } 30422a3e3873SBaptiste Daroussin } 30432a3e3873SBaptiste Daroussin return result; 30442a3e3873SBaptiste Daroussin } 30452a3e3873SBaptiste Daroussin #endif 3046