com_select(): Improve message.
[paraslash.git] / gui.c
diff --git a/gui.c b/gui.c
index 24f1c7276d9e551da6dc05a039a2171007e97c25..a4f1717c2a996568d2fe36cc3a010f165ff1bcd9 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -1,8 +1,4 @@
-/*
- * Copyright (C) 1998 Andre Noll <maan@tuebingen.mpg.de>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
+/* Copyright (C) 1998 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
 
 /** \file gui.c Curses-based interface for paraslash. */
 
 
 /** \file gui.c Curses-based interface for paraslash. */
 
@@ -17,6 +13,7 @@
 #include "gui.lsg.h"
 #include "para.h"
 #include "gui.h"
 #include "gui.lsg.h"
 #include "para.h"
 #include "gui.h"
+#include "lsu.h"
 #include "string.h"
 #include "ringbuffer.h"
 #include "fd.h"
 #include "string.h"
 #include "ringbuffer.h"
 #include "fd.h"
@@ -56,9 +53,7 @@ struct rb_entry {
 static struct ringbuffer *bot_win_rb;
 
 static unsigned scroll_position;
 static struct ringbuffer *bot_win_rb;
 
 static unsigned scroll_position;
-
 static pid_t exec_pid;
 static pid_t exec_pid;
-
 static int exec_fds[2] = {-1, -1};
 static int loglevel;
 
 static int exec_fds[2] = {-1, -1};
 static int loglevel;
 
@@ -253,7 +248,7 @@ static char *km_keyname(int c)
 }
 
 /* Print given number of spaces to curses window. */
 }
 
 /* Print given number of spaces to curses window. */
-static void add_spaces(WINDOWwin, unsigned int num)
+static void add_spaces(WINDOW *win, unsigned int num)
 {
        const char space[] = "                                ";
        const unsigned sz = sizeof(space) - 1; /* number of spaces */
 {
        const char space[] = "                                ";
        const unsigned sz = sizeof(space) - 1; /* number of spaces */
@@ -269,10 +264,10 @@ static void add_spaces(WINDOW* win, unsigned int num)
 }
 
 /*
 }
 
 /*
- * print aligned string to curses window. This function always prints
+ * Print aligned string to curses window. This function always prints
  * exactly len chars.
  */
  * exactly len chars.
  */
-static int align_str(WINDOWwin, const char *str, unsigned int len,
+static int align_str(WINDOW *win, const char *str, unsigned int len,
                unsigned int align)
 {
        int ret, num; /* of spaces */
                unsigned int align)
 {
        int ret, num; /* of spaces */
@@ -458,10 +453,8 @@ static void rb_add_entry(int color, char *msg)
        waddstr(bot.win, msg);
 }
 
        waddstr(bot.win, msg);
 }
 
-/*
- * print formated output to bot win and refresh
- */
-__printf_2_3 static void outputf(int color, const char* fmt,...)
+/* Print formatted output to bot win and refresh. */
+__printf_2_3 static void outputf(int color, const char *fmt,...)
 {
        char *msg;
        va_list ap;
 {
        char *msg;
        va_list ap;
@@ -504,8 +497,9 @@ static __printf_2_3 void curses_log(int ll, const char *fmt,...)
                vfprintf(stderr, fmt, ap);
        va_end(ap);
 }
                vfprintf(stderr, fmt, ap);
        va_end(ap);
 }
+
 /** The log function of para_gui, always set to curses_log(). */
 /** The log function of para_gui, always set to curses_log(). */
-__printf_2_3 void (*para_log)(int, const char*, ...) = curses_log;
+__printf_2_3 void (*para_log)(int, const char *, ...) = curses_log;
 
 /* Call endwin() to reset the terminal into non-visual mode. */
 static void shutdown_curses(void)
 
 /* Call endwin() to reset the terminal into non-visual mode. */
 static void shutdown_curses(void)
@@ -522,8 +516,8 @@ static void shutdown_curses(void)
        endwin();
 }
 
        endwin();
 }
 
-/* disable curses, print a message, kill running processes and exit */
-__noreturn __printf_2_3 static void die(int exit_code, const charfmt, ...)
+/* 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;
 
 {
        va_list argp;
 
@@ -546,9 +540,7 @@ __noreturn __printf_2_3 static void die(int exit_code, const char* fmt, ...)
        exit(exit_code);
 }
 
        exit(exit_code);
 }
 
-/*
- * Print stat item #i to curses window
- */
+/* Print stat item #i to curses window. */
 static void print_stat_item(int i)
 {
        char *tmp;
 static void print_stat_item(int i)
 {
        char *tmp;
@@ -574,19 +566,19 @@ static int update_item(int item_num, char *buf)
        if (buf && buf[0])
                goto dup;
        switch (item_num) {
        if (buf && buf[0])
                goto dup;
        switch (item_num) {
-       case SI_ARTIST:
+       case SI_artist:
                *c = para_strdup("(artist tag not set)");
                goto print;
                *c = para_strdup("(artist tag not set)");
                goto print;
-       case SI_TITLE:
+       case SI_title:
                *c = para_strdup("(title tag not set)");
                goto print;
                *c = para_strdup("(title tag not set)");
                goto print;
-       case SI_YEAR:
+       case SI_year:
                *c = para_strdup("????");
                goto print;
                *c = para_strdup("????");
                goto print;
-       case SI_ALBUM:
+       case SI_album:
                *c = para_strdup("(album tag not set)");
                goto print;
                *c = para_strdup("(album tag not set)");
                goto print;
-       case SI_COMMENT:
+       case SI_comment:
                *c = para_strdup("(comment tag not set)");
                goto print;
        }
                *c = para_strdup("(comment tag not set)");
                goto print;
        }
@@ -685,8 +677,8 @@ static int status_post_select(struct sched *s, void *context)
                close(st->fd);
                st->fd = -1;
                clear_all_items();
                close(st->fd);
                st->fd = -1;
                clear_all_items();
-               free(stat_content[SI_BASENAME]);
-               stat_content[SI_BASENAME] =
+               free(stat_content[SI_basename]);
+               stat_content[SI_basename] =
                        para_strdup("stat command terminated!?");
                print_all_items();
                return 0;
                        para_strdup("stat command terminated!?");
                print_all_items();
                return 0;
@@ -698,9 +690,7 @@ static int status_post_select(struct sched *s, void *context)
        return 0;
 }
 
        return 0;
 }
 
-/*
- * init all windows
- */
+/* Initialize all windows. */
 static void init_wins(int top_lines)
 {
        int top_y = 0, bot_y = top_lines + 1, sb_y = LINES - 2,
 static void init_wins(int top_lines)
 {
        int top_y = 0, bot_y = top_lines + 1, sb_y = LINES - 2,
@@ -868,67 +858,26 @@ static void check_key_map_args_or_die(void)
 static void parse_config_file_or_die(bool reload)
 {
        int ret;
 static void parse_config_file_or_die(bool reload)
 {
        int ret;
-       char *cf = NULL, *errctx = NULL;
-       void *map;
-       size_t sz;
-       int cf_argc;
-       char **cf_argv;
-       struct lls_parse_result *cf_lpr, *merged_lpr;
-
-       if (OPT_GIVEN(CONFIG_FILE))
-               cf = para_strdup(OPT_STRING_VAL(CONFIG_FILE));
-       else {
-               char *home = para_homedir();
-               cf = make_message("%s/.paraslash/gui.conf", home);
-               free(home);
-       }
-       ret = mmap_full_file(cf, O_RDONLY, &map, &sz, NULL);
-       if (ret < 0) {
-               if (ret != -E_EMPTY && ret != -ERRNO_TO_PARA_ERROR(ENOENT))
-                       goto free_cf;
-               if (ret == -ERRNO_TO_PARA_ERROR(ENOENT) && OPT_GIVEN(CONFIG_FILE))
-                       goto free_cf;
-               ret = 0;
-               lpr = cmdline_lpr;
-               goto success;
-       }
-       ret = lls(lls_convert_config(map, sz, NULL, &cf_argv, &errctx));
-       para_munmap(map, sz);
-       if (ret < 0)
-               goto free_cf;
-       cf_argc = ret;
-       ret = lls(lls_parse(cf_argc, cf_argv, CMD_PTR, &cf_lpr, &errctx));
-       lls_free_argv(cf_argv);
-       if (ret < 0)
-               goto free_cf;
-       if (reload) /* config file overrides command line */
-               ret = lls(lls_merge(cf_lpr, cmdline_lpr, CMD_PTR, &merged_lpr,
-                       &errctx));
-       else /* command line options overrride config file options */
-               ret = lls(lls_merge(cmdline_lpr, cf_lpr, CMD_PTR, &merged_lpr,
-                       &errctx));
-       lls_free_parse_result(cf_lpr, CMD_PTR);
-       if (ret < 0)
-               goto free_cf;
+       unsigned flags = MCF_DONT_FREE;
+
        if (lpr != cmdline_lpr)
                lls_free_parse_result(lpr, CMD_PTR);
        if (lpr != cmdline_lpr)
                lls_free_parse_result(lpr, CMD_PTR);
-       lpr = merged_lpr;
-success:
-       loglevel = OPT_UINT32_VAL(LOGLEVEL);
-       check_key_map_args_or_die();
-       theme_init(OPT_STRING_VAL(THEME), &theme);
-free_cf:
-       free(cf);
+       lpr = cmdline_lpr;
+       if (reload)
+               flags |= MCF_OVERRIDE;
+       ret = lsu_merge_config_file_options(OPT_STRING_VAL(CONFIG_FILE),
+               "gui.conf", &lpr, CMD_PTR, gui_suite, flags);
        if (ret < 0) {
        if (ret < 0) {
-               if (errctx)
-                       PARA_ERROR_LOG("%s\n", errctx);
-               free(errctx);
-               PARA_EMERG_LOG("%s\n", para_strerror(-ret));
+               PARA_EMERG_LOG("failed to parse config file: %s\n",
+                       para_strerror(-ret));
                exit(EXIT_FAILURE);
        }
                exit(EXIT_FAILURE);
        }
+       loglevel = OPT_UINT32_VAL(LOGLEVEL);
+       check_key_map_args_or_die();
+       theme_init(OPT_STRING_VAL(THEME), &theme);
 }
 
 }
 
-/* reread configuration, terminate on errors */
+/* Reread configuration, terminate on errors. */
 static void reread_conf(void)
 {
        /*
 static void reread_conf(void)
 {
        /*
@@ -942,9 +891,7 @@ static void reread_conf(void)
        print_in_bar(COLOR_MSG, "config file reloaded\n");
 }
 
        print_in_bar(COLOR_MSG, "config file reloaded\n");
 }
 
-/*
- * React to various signal-related events
- */
+/* React to various signal-related events. */
 static int signal_post_select(struct sched *s, __a_unused void *context)
 {
        int ret = para_next_signal(&s->rfds);
 static int signal_post_select(struct sched *s, __a_unused void *context)
 {
        int ret = para_next_signal(&s->rfds);
@@ -954,6 +901,14 @@ static int signal_post_select(struct sched *s, __a_unused void *context)
        switch (ret) {
        case SIGTERM:
                die(EXIT_FAILURE, "only the good die young (caught SIGTERM)\n");
        switch (ret) {
        case SIGTERM:
                die(EXIT_FAILURE, "only the good die young (caught SIGTERM)\n");
+       case SIGWINCH:
+               PARA_NOTICE_LOG("got SIGWINCH\n");
+               if (curses_active()) {
+                       shutdown_curses();
+                       init_curses();
+                       redraw_bot_win();
+               }
+               return 1;
        case SIGINT:
                return 1;
        case SIGUSR1:
        case SIGINT:
                return 1;
        case SIGUSR1:
@@ -1045,7 +1000,7 @@ static void input_pre_select(struct sched *s, __a_unused void *context)
                sched_min_delay(s);
 }
 
                sched_min_delay(s);
 }
 
-/* read from command pipe and print data to bot window */
+/* Read from command pipe and print data to bot window. */
 static void exec_and_display(const char *file_and_args)
 {
        int ret, fds[3] = {0, 1, 1};
 static void exec_and_display(const char *file_and_args)
 {
        int ret, fds[3] = {0, 1, 1};
@@ -1079,9 +1034,7 @@ static void exec_para(const char *args)
        free(file_and_args);
 }
 
        free(file_and_args);
 }
 
-/*
- * shutdown curses and stat pipe before executing external commands
- */
+/* Shutdown curses and stat pipe before executing external commands. */
 static void exec_external(char *file_and_args)
 {
        int fds[3] = {-1, -1, -1};
 static void exec_external(char *file_and_args)
 {
        int fds[3] = {-1, -1, -1};
@@ -1135,7 +1088,8 @@ static void handle_command(int c)
                km_keyname(c));
 }
 
                km_keyname(c));
 }
 
-static int input_post_select(__a_unused struct sched *s, __a_unused void *context)
+static int input_post_select(__a_unused struct sched *s,
+               __a_unused void *context)
 {
        int ret;
        enum exec_status exs = exec_status();
 {
        int ret;
        enum exec_status exs = exec_status();
@@ -1160,14 +1114,8 @@ static int input_post_select(__a_unused struct sched *s, __a_unused void *contex
        ret = wgetch(top.win);
        if (ret == ERR)
                return 0;
        ret = wgetch(top.win);
        if (ret == ERR)
                return 0;
-       if (ret == KEY_RESIZE) {
-               if (curses_active()) {
-                       shutdown_curses();
-                       init_curses();
-                       redraw_bot_win();
-               }
+       if (ret == KEY_RESIZE) /* already handled in signal_post_select() */
                return 0;
                return 0;
-       }
        if (exs == EXEC_IDLE)
                handle_command(ret);
        else if (exec_pid > 0)
        if (exs == EXEC_IDLE)
                handle_command(ret);
        else if (exec_pid > 0)
@@ -1470,6 +1418,7 @@ static int setup_tasks_and_schedule(void)
        para_install_sighandler(SIGTERM);
        para_install_sighandler(SIGCHLD);
        para_install_sighandler(SIGUSR1);
        para_install_sighandler(SIGTERM);
        para_install_sighandler(SIGCHLD);
        para_install_sighandler(SIGUSR1);
+       para_install_sighandler(SIGWINCH);
        signal_task->task = task_register(&(struct task_info) {
                .name = "signal",
                .pre_select = signal_pre_select,
        signal_task->task = task_register(&(struct task_info) {
                .name = "signal",
                .pre_select = signal_pre_select,