X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=gui.c;h=8ec009cc53506ba976d9c60f4c489935259d494e;hb=2b8250e7d8b4bb34727470ee208fc9b725371bec;hp=25e852dee462d3d394723bd26935f8cfbf6ecaa7;hpb=2bd6a294428d7acb1da1b0cf7f4ed569ad0e018a;p=paraslash.git diff --git a/gui.c b/gui.c index 25e852de..8ec009cc 100644 --- a/gui.c +++ b/gui.c @@ -34,8 +34,6 @@ static int signal_pipe; static struct gui_window { WINDOW *win; - size_t begx; - size_t begy; size_t cols; size_t lines; } top, bot, sb, in, sep; @@ -51,7 +49,6 @@ static struct ringbuffer *bot_win_rb; static unsigned scroll_position; -static bool curses_active; static pid_t cmd_pid; static int command_fds[2] = {-1, -1}; @@ -87,9 +84,6 @@ struct gui_command { static struct gui_theme theme; -static int _argc; -static char **_argv; - static void com_help(void); static void com_reread_conf(void); static void com_enlarge_top_win(void); @@ -209,6 +203,12 @@ static int find_cmd_byname(char *name) return -1; } +/* isendwin() returns false before initscr() was called */ +static bool curses_active(void) +{ + return top.win && !isendwin(); +} + /* taken from mutt */ static char *km_keyname(int c) { @@ -347,7 +347,7 @@ __printf_2_3 static void print_in_bar(int color, const char *fmt,...) char *msg; va_list ap; - if (!curses_active) + if (!curses_active()) return; wattron(in.win, COLOR_PAIR(color)); va_start(ap, fmt); @@ -383,7 +383,6 @@ static int first_visible_rbe(unsigned *lines) int rbe_lines; if (!rbe) return i - 1; -// fprintf(stderr, "found: %s\n", rbe->msg); rbe_lines = NUM_LINES(rbe->len); if (rbe_lines > bot.lines) return -1; @@ -467,7 +466,6 @@ static void rb_add_entry(int color, char *msg) new->len = len; new->msg = msg; old = ringbuffer_add(bot_win_rb, new); -// fprintf(stderr, "added: %s\n", new->msg); if (old) { free(old->msg); free(old); @@ -493,7 +491,7 @@ __printf_2_3 static void outputf(int color, const char* fmt,...) char *msg; va_list ap; - if (!curses_active) + if (!curses_active()) return; va_start(ap, fmt); xvasprintf(&msg, fmt, ap); @@ -506,7 +504,7 @@ static int add_output_line(char *line, void *data) { int color = *(int *)data? COLOR_ERRMSG : COLOR_OUTPUT; - if (!curses_active) + if (!curses_active()) return 1; rb_add_entry(color, para_strdup(line)); return 1; @@ -516,29 +514,22 @@ static int loglevel; static __printf_2_3 void curses_log(int ll, const char *fmt,...) { - int color; - char *msg; va_list ap; - unsigned bytes; - if (ll < loglevel || !curses_active) + if (ll < loglevel) return; - switch (ll) { - case LL_DEBUG: - case LL_INFO: - case LL_NOTICE: - color = COLOR_MSG; - break; - default: - color = COLOR_ERRMSG; - } va_start(ap, fmt); - bytes = xvasprintf(&msg, fmt, ap); + if (curses_active()) { + int color = ll <= LL_NOTICE? COLOR_MSG : COLOR_ERRMSG; + char *msg; + unsigned bytes = xvasprintf(&msg, fmt, ap); + if (bytes > 0 && msg[bytes - 1] == '\n') + msg[bytes - 1] = '\0'; /* cut trailing newline */ + rb_add_entry(color, msg); + wrefresh(bot.win); + } else if (cmd_pid <= 0) /* no external command running */ + vfprintf(stderr, fmt, ap); va_end(ap); - if (bytes > 0 && msg[bytes - 1] == '\n') - msg[bytes - 1] = '\0'; /* cut trailing newline */ - rb_add_entry(color, msg); - wrefresh(bot.win); } __printf_2_3 void (*para_log)(int, const char*, ...) = curses_log; @@ -552,42 +543,25 @@ static void setup_signal_handling(void) para_install_sighandler(SIGUSR1); } -/* kill every process in the process group and exit */ -__noreturn static void kill_pg_and_die(int ret) -{ - para_sigaction(SIGTERM, SIG_IGN); - kill(0, SIGTERM); - exit(ret); -} - static void shutdown_curses(void) { - if (!curses_active) - return; def_prog_mode(); - curses_active = false; endwin(); } -__noreturn static void finish(int ret) -{ - shutdown_curses(); - kill_pg_and_die(ret); -} - -/* - * exit curses and print given message to stdout/stderr - */ -__noreturn __printf_2_3 static void msg_n_exit(int ret, const char* fmt, ...) +/* disable curses, print a message, kill running processes and exit */ +__noreturn __printf_2_3 static void die(int exit_code, const char* fmt, ...) { va_list argp; - FILE *outfd = ret? stderr: stdout; shutdown_curses(); va_start(argp, fmt); - vfprintf(outfd, fmt, argp); + vfprintf(stderr, fmt, argp); va_end(argp); - kill_pg_and_die(ret); + /* kill every process in the process group and exit */ + para_sigaction(SIGTERM, SIG_IGN); + kill(0, SIGTERM); + exit(exit_code); } /* @@ -595,55 +569,39 @@ __noreturn __printf_2_3 static void msg_n_exit(int ret, const char* fmt, ...) */ static void init_wins(int top_lines) { - top.lines = top_lines; - top.cols = COLS; - top.begy = 0; - top.begx = 0; + int top_y = 0, bot_y = top_lines + 1, sb_y = LINES - 2, + in_y = LINES - 1, sep_y = top_lines; + top.lines = top_lines; bot.lines = LINES - top.lines - 3; - bot.cols = COLS; - bot.begy = top.lines + 1; - bot.begx = 0; - - sb.lines = 1; - sb.cols = COLS; - sb.begy = LINES - 2; - sb.begx = 0; - - in.lines = 1; - in.cols = COLS; - in.begy = LINES - 1; - in.begx = 0; + sb.lines = in.lines = sep.lines = 1; - sep.lines = 1; - sep.cols = COLS; - sep.begy = top.lines; - sep.begx = 0; + top.cols = bot.cols = sb.cols = in.cols = sep.cols = COLS; assume_default_colors(theme.default_fg, theme.default_bg); if (top.win) { wresize(top.win, top.lines, top.cols); - mvwin(top.win, top.begy, top.begx); + mvwin(top.win, top_y, 0); wresize(sb.win, sb.lines, sb.cols); - mvwin(sb.win, sb.begy, sb.begx); + mvwin(sb.win, sb_y, 0); wresize(sep.win, sep.lines, sep.cols); - mvwin(sep.win, sep.begy, sep.begx); + mvwin(sep.win, sep_y, 0); wresize(bot.win, bot.lines, bot.cols); - mvwin(bot.win, bot.begy, bot.begx); + mvwin(bot.win, bot_y, 0); wresize(in.win, in.lines, in.cols); - mvwin(in.win, in.begy, in.begx); + mvwin(in.win, in_y, 0); } else { - sep.win = newwin(sep.lines, sep.cols, sep.begy, sep.begx); - top.win = newwin(top.lines, top.cols, top.begy, top.begx); - bot.win = newwin(bot.lines, bot.cols, bot.begy, bot.begx); - sb.win = newwin(sb.lines, sb.cols, sb.begy, sb.begx); - in.win = newwin(in.lines, in.cols, in.begy, in.begx); + sep.win = newwin(sep.lines, sep.cols, sep_y, 0); + top.win = newwin(top.lines, top.cols, top_y, 0); + bot.win = newwin(bot.lines, bot.cols, bot_y, 0); + sb.win = newwin(sb.lines, sb.cols, sb_y, 0); + in.win = newwin(in.lines, in.cols, in_y, 0); if (!top.win || !bot.win || !sb.win || !in.win || !sep.win) - msg_n_exit(1, "Error: Cannot create curses windows\n"); + die(EXIT_FAILURE, "Error: Cannot create curses windows\n"); wclear(bot.win); wclear(sb.win); wclear(in.win); @@ -684,7 +642,7 @@ static void print_stat_item(int i) struct stat_item_data d = theme.data[i]; char *c = stat_content[i]; - if (!curses_active || !d.len || !c) + if (!curses_active() || !d.len || !c) return; tmp = make_message("%s%s%s", d.prefix, c, d.postfix); wmove(top.win, d.y * top.lines / 100, d.x * COLS / 100); @@ -763,7 +721,7 @@ static void print_all_items(void) { int i; - if (!curses_active) + if (!curses_active()) return; FOR_EACH_STATUS_ITEM(i) print_stat_item(i); @@ -782,7 +740,7 @@ static void clear_all_items(void) static void init_pair_or_die(short pair, short f, short b) { if (init_pair(pair, f, b) == ERR) - msg_n_exit(EXIT_FAILURE, "fatal: init_pair() failed\n"); + die(EXIT_FAILURE, "fatal: init_pair() failed\n"); } static void init_colors_or_die(void) @@ -790,9 +748,9 @@ static void init_colors_or_die(void) int i; if (!has_colors()) - msg_n_exit(EXIT_FAILURE, "fatal: No color term\n"); + die(EXIT_FAILURE, "fatal: No color term\n"); if (start_color() == ERR) - msg_n_exit(EXIT_FAILURE, "fatal: failed to start colors\n"); + die(EXIT_FAILURE, "fatal: failed to start colors\n"); FOR_EACH_STATUS_ITEM(i) if (theme.data[i].len) init_pair_or_die(i + 1, theme.data[i].fg, @@ -810,21 +768,22 @@ static void init_colors_or_die(void) /* (Re-)initialize the curses library. */ static void init_curses(void) { - curses_active = true; + if (curses_active()) + return; if (top.win && refresh() == ERR) /* refresh is really needed */ - msg_n_exit(EXIT_FAILURE, "refresh() failed\n"); + die(EXIT_FAILURE, "refresh() failed\n"); if (LINES < theme.lines_min || COLS < theme.cols_min) - msg_n_exit(EXIT_FAILURE, "Error: Terminal (%dx%d) too small" + die(EXIT_FAILURE, "Terminal (%dx%d) too small" " (need at least %dx%d)\n", COLS, LINES, theme.cols_min, theme.lines_min); curs_set(0); /* make cursor invisible, ignore errors */ nonl(); /* do not NL->CR/NL on output, always returns OK */ /* don't echo input */ if (noecho() == ERR) - msg_n_exit(EXIT_FAILURE, "fatal: noecho() failed\n"); + die(EXIT_FAILURE, "fatal: noecho() failed\n"); /* take input chars one at a time, no wait for \n */ if (cbreak() == ERR) - msg_n_exit(EXIT_FAILURE, "fatal: cbreak() failed\n"); + die(EXIT_FAILURE, "fatal: cbreak() failed\n"); init_colors_or_die(); clear(); /* ignore non-fatal errors */ init_wins(theme.top_lines_default); @@ -904,11 +863,10 @@ static void handle_signal(int sig) { switch (sig) { case SIGTERM: - msg_n_exit(EXIT_FAILURE, - "only the good die young (caught SIGTERM))\n"); + die(EXIT_FAILURE, "only the good die young (caught SIGTERM)\n"); return; case SIGWINCH: - if (curses_active) { + if (curses_active()) { shutdown_curses(); init_curses(); redraw_bot_win(); @@ -1265,7 +1223,6 @@ static void com_scroll_up(void) break; rbe_lines = NUM_LINES(rbe->len); lines += rbe_lines; -// fprintf(stderr, "msg: %s\n", rbe->msg); wattron(bot.win, COLOR_PAIR(rbe->color)); waddstr(bot.win, "\n"); waddstr(bot.win, rbe->msg); @@ -1321,7 +1278,6 @@ static void com_reread_conf(void) return; } PARA_INFO_LOG("rereading command line options and config file\n"); - gui_cmdline_parser_ext(_argc, _argv, &conf, ¶ms); /* * Despite .print_errors is set to 0, gengetopt will print to stderr * anyway, and exit on errors. So we have to shutdown curses first. @@ -1331,7 +1287,7 @@ static void com_reread_conf(void) init_curses(); PARA_NOTICE_LOG("config file reloaded\n"); if (check_key_map_args() < 0) - finish(EXIT_FAILURE); + die(EXIT_FAILURE, "invalid key map\n"); } static void com_help(void) @@ -1378,7 +1334,6 @@ static void com_shrink_top_win(void) return; } init_wins(top.lines - 1); - wclear(top.win); print_all_items(); print_in_bar(COLOR_MSG, "%s", "decreased top window"); } @@ -1390,7 +1345,6 @@ static void com_enlarge_top_win(void) return; } init_wins(top.lines + 1); - wclear(top.win); print_all_items(); print_in_bar(COLOR_MSG, "increased top window"); } @@ -1402,7 +1356,7 @@ static void com_version(void) __noreturn static void com_quit(void) { - finish(0); + die(EXIT_SUCCESS, "%s", ""); } static void com_refresh(void) @@ -1411,27 +1365,18 @@ static void com_refresh(void) init_curses(); } -static void change_theme(int next) -{ - if (next) - theme_next(&theme); - else - theme_prev(&theme); - com_refresh(); - PARA_NOTICE_LOG("new theme: %s\n", theme.name); -} - static void com_next_theme(void) { - change_theme(1); + theme_next(&theme); + com_refresh(); } static void com_prev_theme(void) { - change_theme(0); + theme_prev(&theme); + com_refresh(); } - static void handle_command(int c) { int i; @@ -1488,20 +1433,15 @@ int main(int argc, char *argv[]) int ret; char *cf; - _argc = argc; - _argv = argv; - gui_cmdline_parser(argc, argv, &conf); /* exits on errors */ loglevel = get_loglevel_by_name(conf.loglevel_arg); version_handle_flag("gui", conf.version_given); if (conf.help_given || conf.detailed_help_given) print_help_and_die(); cf = configfile_exists(); - if (!cf && conf.config_file_given) { - fprintf(stderr, "can not read config file %s\n", + if (!cf && conf.config_file_given) + die(EXIT_FAILURE, "can not read config file %s\n", conf.config_file_arg); - exit(EXIT_FAILURE); - } if (cf) { struct gui_cmdline_parser_params params = { .override = 0, @@ -1513,10 +1453,8 @@ int main(int argc, char *argv[]) gui_cmdline_parser_config_file(cf, &conf, ¶ms); loglevel = get_loglevel_by_name(conf.loglevel_arg); } - if (check_key_map_args() < 0) { - fprintf(stderr, "invalid key map\n"); - exit(EXIT_FAILURE); - } + if (check_key_map_args() < 0) + die(EXIT_FAILURE, "invalid key map\n"); theme_init(conf.theme_arg, &theme); setup_signal_handling(); bot_win_rb = ringbuffer_new(RINGBUFFER_SIZE);