static struct gui_window {
WINDOW *win;
- size_t begx;
- size_t begy;
size_t cols;
size_t lines;
} top, bot, sb, in, sep;
static unsigned scroll_position;
-static bool curses_active;
static pid_t cmd_pid;
static int command_fds[2] = {-1, -1};
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);
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)
{
char *msg;
va_list ap;
- if (!curses_active)
+ if (!curses_active())
return;
wattron(in.win, COLOR_PAIR(color));
va_start(ap, fmt);
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;
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);
char *msg;
va_list ap;
- if (!curses_active)
+ if (!curses_active())
return;
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
{
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;
static __printf_2_3 void curses_log(int ll, const char *fmt,...)
{
- int color;
- char *msg;
va_list ap;
- 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);
- 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);
- chop(msg);
- rb_add_entry(color, msg);
- wrefresh(bot.win);
}
__printf_2_3 void (*para_log)(int, const char*, ...) = curses_log;
static void shutdown_curses(void)
{
- if (!curses_active)
- return;
def_prog_mode();
- curses_active = false;
endwin();
}
*/
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) {
- mvwin(top.win, top.begy, top.begx);
wresize(top.win, top.lines, top.cols);
+ mvwin(top.win, top_y, 0);
- mvwin(sb.win, sb.begy, sb.begx);
wresize(sb.win, sb.lines, sb.cols);
+ mvwin(sb.win, sb_y, 0);
- mvwin(sep.win, sep.begy, sep.begx);
wresize(sep.win, sep.lines, sep.cols);
+ mvwin(sep.win, sep_y, 0);
- mvwin(bot.win, bot.begy, bot.begx);
wresize(bot.win, bot.lines, bot.cols);
+ mvwin(bot.win, bot_y, 0);
- mvwin(in.win, in.begy, in.begx);
wresize(in.win, in.lines, in.cols);
+ 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");
wclear(bot.win);
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);
{
int i;
- if (!curses_active)
+ if (!curses_active())
return;
FOR_EACH_STATUS_ITEM(i)
print_stat_item(i);
/* (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");
if (LINES < theme.lines_min || COLS < theme.cols_min)
"only the good die young (caught SIGTERM))\n");
return;
case SIGWINCH:
- if (curses_active) {
+ if (curses_active()) {
shutdown_curses();
init_curses();
redraw_bot_win();
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);
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.
return;
}
init_wins(top.lines - 1);
- wclear(top.win);
print_all_items();
print_in_bar(COLOR_MSG, "%s", "decreased top window");
}
return;
}
init_wins(top.lines + 1);
- wclear(top.win);
print_all_items();
print_in_bar(COLOR_MSG, "increased top window");
}
init_curses();
}
-static void change_theme(int next)
-{
- if (next)
- next_theme(&theme);
- else
- prev_theme(&theme);
- /* This seems to be needed twice, why? */
- com_refresh();
- 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;
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)
+ msg_n_exit(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,
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);
- }
- init_theme_or_die(conf.theme_arg, &theme);
+ if (check_key_map_args() < 0)
+ msg_n_exit(EXIT_FAILURE, "invalid key map\n");
+ theme_init(conf.theme_arg, &theme);
setup_signal_handling();
bot_win_rb = ringbuffer_new(RINGBUFFER_SIZE);
setlocale(LC_CTYPE, "");