--- dialog.c +++ dialog.c 2006-07-10 14:09:10.000000000 +0200 @@ -1295,7 +1295,6 @@ init_result(char *buffer) int main(int argc, char *argv[]) { - FILE *input = stdin; char temp[256]; bool esc_pressed = FALSE; int offset = 1; @@ -1321,6 +1320,7 @@ main(int argc, char *argv[]) unescape_argv(&argc, &argv); program = argv[0]; dialog_state.output = stderr; + dialog_state.input = stdin; /* * Look for the last --stdout, --stderr or --output-fd option, and use @@ -1339,7 +1339,7 @@ main(int argc, char *argv[]) break; case o_input_fd: if ((j = optionValue(argv, &offset)) < 0 - || (input = fdopen(j, "r")) == 0) + || (dialog_state.input = fdopen(j, "r")) == 0) dlg_exiterr("Cannot open input-fd\n"); break; case o_output_fd: @@ -1405,7 +1405,7 @@ main(int argc, char *argv[]) } #endif - init_dialog(input, dialog_state.output); + init_dialog(dialog_state.input, dialog_state.output); while (offset < argc && !esc_pressed) { init_result(my_buffer); --- dialog.h +++ dialog.h 2006-07-10 14:39:40.000000000 +0200 @@ -39,6 +39,23 @@ #include #include /* fork() etc. */ #include /* sqrt() */ +#include /* struct winsize */ + +#ifndef GCC_NORETURN +#if defined(__GNUC__) +#define GCC_NORETURN __attribute__((noreturn)) +#else +#define GCC_NORETURN /*nothing*/ +#endif +#endif + +#ifndef GCC_UNUSED +#if defined(__GNUC__) +#define GCC_UNUSED __attribute__((unused)) +#else +#define GCC_UNUSED /*nothing*/ +#endif +#endif #if defined(HAVE_NCURSESW_NCURSES_H) #include @@ -72,14 +89,6 @@ #define _(s) s #endif -#ifndef GCC_NORETURN -#define GCC_NORETURN /*nothing*/ -#endif - -#ifndef GCC_UNUSED -#define GCC_UNUSED /*nothing*/ -#endif - #ifndef HAVE_WGET_WCH #undef USE_WIDE_CURSES #endif @@ -348,6 +357,7 @@ typedef struct { DIALOG_CALLBACK *getc_redirect; DIALOG_WINDOWS *all_windows; FILE *output; /* option "--output-fd fd" */ + FILE *input; /* option "--input-fd fd" */ FILE *pipe_input; /* used for gauge widget */ FILE *screen_output; /* newterm(), etc. */ bool screen_initialized; @@ -359,6 +369,7 @@ typedef struct { int aspect_ratio; /* option "--aspect ratio" */ int output_count; /* # of widgets that may have done output */ int tab_len; /* option "--tab-len n" */ + struct winsize tty; /* window size */ } DIALOG_STATE; extern DIALOG_STATE dialog_state; @@ -554,6 +565,7 @@ extern void dlg_killall_bg(int *retval); /* util.c */ extern WINDOW * dlg_new_window(int /*height*/, int /*width*/, int /*y*/, int /*x*/); +extern void dlg_move_window(WINDOW * /*win*/, int /*height*/, int /*width*/, int /*y*/, int /*x*/); extern WINDOW * dlg_sub_window(WINDOW * /*win*/, int /*height*/, int /*width*/, int /*y*/, int /*x*/); extern char * dlg_set_result(const char * /*string*/); extern char * dlg_strclone(const char * /*cprompt*/); @@ -591,7 +603,7 @@ extern void dlg_trim_string(char * /*src extern void end_dialog(void); extern void init_dialog(FILE * /*input*/, FILE * /*output*/); -extern void dlg_exiterr(const char *, ...) +extern void dlg_exiterr(const char *, ...) GCC_NORETURN #if defined(__GNUC__) && !defined(printf) __attribute__((format(printf,1,2))) #endif --- dlg_colors.h +++ dlg_colors.h 2006-07-10 14:42:18.000000000 +0200 @@ -43,13 +43,13 @@ #define DLGC_FG_SHADOW COLOR_BLACK #define DLGC_BG_SHADOW COLOR_BLACK -#define DLGC_HL_SHADOW TRUE +#define DLGC_HL_SHADOW FALSE #define DLGC_FG_DIALOG COLOR_BLACK #define DLGC_BG_DIALOG COLOR_WHITE #define DLGC_HL_DIALOG FALSE -#define DLGC_FG_TITLE COLOR_BLUE +#define DLGC_FG_TITLE COLOR_YELLOW #define DLGC_BG_TITLE COLOR_WHITE #define DLGC_HL_TITLE TRUE @@ -93,7 +93,7 @@ #define DLGC_BG_SEARCHBOX COLOR_WHITE #define DLGC_HL_SEARCHBOX FALSE -#define DLGC_FG_SEARCHBOX_TITLE COLOR_BLUE +#define DLGC_FG_SEARCHBOX_TITLE COLOR_YELLOW #define DLGC_BG_SEARCHBOX_TITLE COLOR_WHITE #define DLGC_HL_SEARCHBOX_TITLE TRUE @@ -101,7 +101,7 @@ #define DLGC_BG_SEARCHBOX_BORDER COLOR_WHITE #define DLGC_HL_SEARCHBOX_BORDER TRUE -#define DLGC_FG_POSITION_INDICATOR COLOR_BLUE +#define DLGC_FG_POSITION_INDICATOR COLOR_YELLOW #define DLGC_BG_POSITION_INDICATOR COLOR_WHITE #define DLGC_HL_POSITION_INDICATOR TRUE @@ -121,7 +121,7 @@ #define DLGC_BG_ITEM_SELECTED COLOR_BLUE #define DLGC_HL_ITEM_SELECTED TRUE -#define DLGC_FG_TAG COLOR_BLUE +#define DLGC_FG_TAG COLOR_YELLOW #define DLGC_BG_TAG COLOR_WHITE #define DLGC_HL_TAG TRUE --- guage.c +++ guage.c 2006-07-10 16:10:33.000000000 +0200 @@ -229,6 +229,7 @@ dialog_gauge(const char *title, nodelay(stdscr, FALSE); #endif fclose(dialog_state.pipe_input); + dialog_state.pipe_input = (FILE*)0; curs_set(1); dlg_del_window(dialog); if (prompt != prompt_buf) --- msgbox.c +++ msgbox.c 2006-07-10 14:49:08.000000000 +0200 @@ -174,11 +174,9 @@ dialog_msgbox(const char *title, const c y = dlg_box_y_ordinate(height); #ifdef KEY_RESIZE - if (dialog != 0) { - (void) wresize(dialog, height, width); - (void) mvwin(dialog, y, x); - (void) refresh(); - } else + if (dialog != 0) + dlg_move_window(dialog, height, width, y, x); + else #endif { dialog = dlg_new_window(height, width, y, x); --- ui_getc.c +++ ui_getc.c 2006-07-10 16:01:22.000000000 +0200 @@ -374,6 +374,7 @@ dlg_killall_bg(int *retval) (void) signal(SIGHUP, finish_bg); (void) signal(SIGINT, finish_bg); (void) signal(SIGQUIT, finish_bg); + (void) signal(SIGSEGV, finish_bg); while (dialog_state.getc_callbacks != 0) { int fkey = 0; dlg_getc_callbacks(ERR, fkey, retval); --- util.c +++ util.c 2006-07-10 16:11:23.000000000 +0200 @@ -373,6 +373,7 @@ dlg_color_setup(void) if (has_colors()) { /* Terminal supports color? */ (void) start_color(); + use_default_colors(); #if defined(__NetBSD__) && defined(_CURSES_) #define C_ATTR(x,y) (((x) != 0 ? A_BOLD : 0) | COLOR_PAIR((y))) @@ -404,7 +405,22 @@ dlg_color_setup(void) | color); } #endif + } else { + dialog_state.use_colors = 0; + dialog_state.use_shadow = 0; } + + dialog_state.tty.ws_row = 0; + dialog_state.tty.ws_col = 0; + + if (isatty(STDOUT_FILENO)) + ioctl(STDOUT_FILENO, TIOCGWINSZ, &dialog_state.tty); + else if (isatty(STDIN_FILENO)) + ioctl(STDIN_FILENO, TIOCGWINSZ, &dialog_state.tty); + + if (dialog_state.tty.ws_row == 0 || dialog_state.tty.ws_col == 0) + dialog_state.use_shadow = 0; + } int @@ -1037,24 +1053,57 @@ dlg_draw_box(WINDOW *win, int y, int x, #ifdef HAVE_COLOR /* * Draw shadows along the right and bottom edge to give a more 3D look - * to the boxes +* to the overlying boxes like search boxes. */ void dlg_draw_shadow(WINDOW *win, int y, int x, int height, int width) { int i, j; + int col = dialog_state.tty.ws_col; + int row = dialog_state.tty.ws_row; + if (has_colors()) { /* Whether terminal supports color? */ wattrset(win, shadow_attr); for (i = y + height; i < y + height + SHADOW_ROWS; ++i) { if (wmove(win, i, x + SHADOW_COLS) != ERR) { - for (j = 0; j < width; ++j) - (void) waddch(win, CharOf(winch(win))); + if (height + i < row) + for (j = 0; j < width; ++j) + (void) waddch(win, CharOf(winch(win))); } } for (i = y + SHADOW_ROWS; i < y + height + SHADOW_ROWS; i++) { if (wmove(win, i, x + width) != ERR) { for (j = 0; j < SHADOW_COLS; ++j) + if (width + x + j < col && i < row) + (void) waddch(win, CharOf(winch(win))); + } + } + (void) wnoutrefresh(win); + } +} + +/* + * Draw shadows along the right and bottom side to give a more 3D look + * to the boxes + */ +static void +dlg_draw_shadow_box(WINDOW *win, int height, int width) +{ + int i, j; + int x = width - SHADOW_COLS, y = height - SHADOW_ROWS; + + if (has_colors()) { /* Whether terminal supports color? */ + wattrset(win, shadow_attr); + for (i = y; i < height; ++i) { + if (wmove(win, i, 0) != ERR) { + for (j = 0; j < width; j++) + (void) waddch(win, CharOf(winch(win))); + } + } + for (i = 0; i < y; i++) { + if (wmove(win, i, x) != ERR) { + for (j = 0; j < SHADOW_COLS; ++j) (void) waddch(win, CharOf(winch(win))); } } @@ -1120,7 +1169,20 @@ dlg_exit(int code) _nc_free_and_exit(code); #endif #endif - exit(code); + + if (dialog_state.input == stdin) + exit(code); + /* + * Just in case of using --input-fd option, do not + * call atexit functions of ncurses which may hang. + */ + if (dialog_state.input) + fclose(dialog_state.input); + if (dialog_state.pipe_input != stdin) + fclose(dialog_state.pipe_input); + dialog_state.input = (FILE*)0; + dialog_state.pipe_input = (FILE*)0; + _exit(code); } /* quit program killing all tailbg */ @@ -1170,8 +1232,11 @@ dlg_ctl_size(int height, int width) height, width, LINES, COLS); } #ifdef HAVE_COLOR - else if ((dialog_state.use_shadow) - && ((width > SCOLS || height > SLINES))) { + else if ((dialog_state.use_shadow) && ((width > SCOLS || height > SLINES))) { + if ((width <= COLS) && (height <= LINES)) { + dialog_state.use_shadow = 0; + return; + } dlg_exiterr("Window+Shadow too big. (height, width) = (%d, %d). Max allowed (%d, %d).", height, width, SLINES, SCOLS); } @@ -1370,7 +1435,7 @@ dlg_new_window(int height, int width, in if ((win = newwin(height, width, y + SHADOW_ROWS, x + SHADOW_COLS)) != 0) { - dlg_draw_shadow(win, -SHADOW_ROWS, -SHADOW_COLS, height, width); + dlg_draw_shadow_box(win, height, width); } p->shadow = win; } @@ -1387,6 +1452,46 @@ dlg_new_window(int height, int width, in return win; } +/* + * Move/Resize a window, optionally with a shadow. + */ +void +dlg_move_window(WINDOW *win, int height, int width, int y, int x) +{ + DIALOG_WINDOWS *p, *q; + WINDOW *shadow = NULL; + + if (!win) + return; + + dlg_ctl_size(height, width); + + for (p = dialog_state.all_windows; p != 0; p = q) { + q = p->next; + if (p->normal == win) { + (void) wresize(win, height, width); + (void) mvwin(win, y, x); +#ifdef HAVE_COLOR + if (p->shadow != 0) { + if (dialog_state.use_shadow) { + shadow = p->shadow; + (void) wresize(shadow, height, width); + (void) mvwin(shadow, y + SHADOW_ROWS, x + SHADOW_COLS); + } else { + delwin(p->shadow); + p->shadow = NULL; + } + } +#endif + break; + } + } + (void) refresh(); + + if (shadow) + dlg_draw_shadow_box(shadow, height, width); +} + WINDOW * dlg_sub_window(WINDOW *parent, int height, int width, int y, int x) { --- yesno.c +++ yesno.c 2006-07-10 14:09:14.000000000 +0200 @@ -72,11 +72,9 @@ dialog_yesno(const char *title, const ch y = dlg_box_y_ordinate(height); #ifdef KEY_RESIZE - if (dialog != 0) { - (void) wresize(dialog, height, width); - (void) mvwin(dialog, y, x); - (void) refresh(); - } else + if (dialog != 0) + dlg_move_window(dialog, height, width, y, x); + else #endif { dialog = dlg_new_window(height, width, y, x);