]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - gui.c
paraslash 0.7.3
[paraslash.git] / gui.c
diff --git a/gui.c b/gui.c
index 493bc3c9781d6cfac42b91878d52153f2243910c..66fb7870bd65868a750b5918747da59ad4681b6d 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. */
 
@@ -17,6 +13,7 @@
 #include "gui.lsg.h"
 #include "para.h"
 #include "gui.h"
+#include "lsu.h"
 #include "string.h"
 #include "ringbuffer.h"
 #include "fd.h"
@@ -195,7 +192,7 @@ static bool curses_active(void)
 }
 
 /* taken from mutt */
-static char *km_keyname(int c)
+static const char *km_keyname(int c)
 {
        static char buf[10];
 
@@ -434,7 +431,7 @@ static void rb_add_entry(int color, char *msg)
 
        if (strwidth(msg, &len) < 0)
                return;
-       new = para_malloc(sizeof(struct rb_entry));
+       new = alloc(sizeof(struct rb_entry));
        new->color = color;
        new->len = len;
        new->msg = msg;
@@ -612,19 +609,19 @@ static void clear_all_items(void)
        }
 }
 
-static void status_pre_select(struct sched *s, void *context)
+static void status_pre_monitor(struct sched *s, void *context)
 {
        struct status_task *st = context;
 
        if (st->fd >= 0)
-               para_fd_set(st->fd, &s->rfds, &s->max_fileno);
+               sched_monitor_readfd(st->fd, s);
        if (task_get_notification(st->task) < 0)
                return sched_min_delay(s);
        if (st->fd < 0)
                sched_request_barrier_or_min_delay(&st->next_exec, s);
 }
 
-static int status_post_select(struct sched *s, void *context)
+static int status_post_monitor(__a_unused struct sched *s, void *context)
 {
        struct status_task *st = context;
        size_t sz;
@@ -670,7 +667,7 @@ static int status_post_select(struct sched *s, void *context)
        }
        assert(st->loaded < st->bufsize);
        ret = read_nonblock(st->fd, st->buf + st->loaded,
-               st->bufsize - st->loaded, &s->rfds, &sz);
+               st->bufsize - st->loaded, &sz);
        st->loaded += sz;
        ret2 = for_each_stat_item(st->buf, st->loaded, update_item);
        if (ret < 0 || ret2 < 0) {
@@ -861,64 +858,23 @@ static void check_key_map_args_or_die(void)
 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 override 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);
-       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 (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);
        }
+       loglevel = OPT_UINT32_VAL(LOGLEVEL);
+       check_key_map_args_or_die();
+       theme_init(OPT_STRING_VAL(THEME), &theme);
 }
 
 /* Reread configuration, terminate on errors. */
@@ -936,15 +892,23 @@ static void reread_conf(void)
 }
 
 /* React to various signal-related events. */
-static int signal_post_select(struct sched *s, __a_unused void *context)
+static int signal_post_monitor(struct sched *s, __a_unused void *context)
 {
-       int ret = para_next_signal(&s->rfds);
+       int ret = para_next_signal();
 
        if (ret <= 0)
                return 0;
        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:
@@ -967,18 +931,18 @@ static enum exec_status exec_status(void)
        return EXEC_IDLE;
 }
 
-static void exec_pre_select(struct sched *s, void *context)
+static void exec_pre_monitor(struct sched *s, void *context)
 {
        struct exec_task *et = context;
        if (exec_fds[0] >= 0)
-               para_fd_set(exec_fds[0], &s->rfds, &s->max_fileno);
+               sched_monitor_readfd(exec_fds[0], s);
        if (exec_fds[1] >= 0)
-               para_fd_set(exec_fds[1], &s->rfds, &s->max_fileno);
+               sched_monitor_readfd(exec_fds[1], s);
        if (task_get_notification(et->task) < 0)
                sched_min_delay(s);
 }
 
-static int exec_post_select(struct sched *s, void *context)
+static int exec_post_monitor(__a_unused struct sched *s, void *context)
 {
        struct exec_task *ct = context;
        int i, ret;
@@ -999,7 +963,7 @@ static int exec_post_select(struct sched *s, void *context)
                        continue;
                ret = read_nonblock(exec_fds[i],
                        ct->command_buf[i] + ct->cbo[i],
-                       COMMAND_BUF_SIZE - 1 - ct->cbo[i], &s->rfds, &sz);
+                       COMMAND_BUF_SIZE - 1 - ct->cbo[i], &sz);
                ct->cbo[i] += sz;
                sz = ct->cbo[i];
                ct->cbo[i] = for_each_line(ct->flags[i], ct->command_buf[i],
@@ -1028,10 +992,10 @@ static int exec_post_select(struct sched *s, void *context)
        return 0;
 }
 
-static void input_pre_select(struct sched *s, __a_unused void *context)
+static void input_pre_monitor(struct sched *s, __a_unused void *context)
 {
        if (exec_status() != EXEC_XCMD)
-               para_fd_set(STDIN_FILENO, &s->rfds, &s->max_fileno);
+               sched_monitor_readfd(STDIN_FILENO, s);
        if (window_update_needed())
                sched_min_delay(s);
 }
@@ -1085,6 +1049,7 @@ static void handle_command(int c)
 {
        int i;
        const struct lls_opt_result *lor = OPT_RESULT(KEY_MAP);
+       const char *keyname = km_keyname(c);
 
        /* first check user-defined key bindings */
        FOR_EACH_KEY_MAP(i) {
@@ -1095,7 +1060,7 @@ static void handle_command(int c)
                        free(tmp);
                        return;
                }
-               if (strcmp(tmp, km_keyname(c))) {
+               if (strcmp(tmp, keyname)) {
                        free(tmp);
                        continue;
                }
@@ -1115,16 +1080,16 @@ static void handle_command(int c)
        }
        /* not found, check internal key bindings */
        for (i = 0; command_list[i].handler; i++) {
-               if (!strcmp(km_keyname(c), command_list[i].key)) {
+               if (!strcmp(keyname, command_list[i].key)) {
                        command_list[i].handler();
                        return;
                }
        }
        print_in_bar(COLOR_ERRMSG, "key '%s' is not bound, press ? for help",
-               km_keyname(c));
+               keyname);
 }
 
-static int input_post_select(__a_unused struct sched *s,
+static int input_post_monitor(__a_unused struct sched *s,
                __a_unused void *context)
 {
        int ret;
@@ -1150,14 +1115,8 @@ static int input_post_select(__a_unused struct sched *s,
        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_monitor() */
                return 0;
-       }
        if (exs == EXEC_IDLE)
                handle_command(ret);
        else if (exec_pid > 0)
@@ -1207,6 +1166,7 @@ static void com_cancel_scroll(void)
        }
        scroll_position = 0;
        redraw_bot_win();
+       print_in_bar(COLOR_MSG, " ");
 }
 
 static void com_page_down(void)
@@ -1308,6 +1268,12 @@ err_out:
        print_in_bar(COLOR_ERRMSG, "top of buffer is shown\n");
 }
 
+static void print_ll_msg(void)
+{
+       const char *sev[] = {SEVERITIES};
+       print_in_bar(COLOR_MSG, "new loglevel: %s\n", sev[loglevel]);
+}
+
 static void com_ll_decr(void)
 {
        if (loglevel <= LL_DEBUG) {
@@ -1316,7 +1282,7 @@ static void com_ll_decr(void)
                return;
        }
        loglevel--;
-       print_in_bar(COLOR_MSG, "loglevel set to %d\n", loglevel);
+       print_ll_msg();
 }
 
 static void com_ll_incr(void)
@@ -1327,7 +1293,7 @@ static void com_ll_incr(void)
                return;
        }
        loglevel++;
-       print_in_bar(COLOR_MSG, "loglevel set to %d\n", loglevel);
+       print_ll_msg();
 }
 
 static void com_reread_conf(void)
@@ -1432,26 +1398,26 @@ static int setup_tasks_and_schedule(void)
        struct status_task status_task = {.fd = -1};
        struct input_task input_task = {.task = NULL};
        struct signal_task *signal_task;
-       struct sched sched = {.default_timeout = {.tv_sec = 1}};
+       struct sched sched = {.default_timeout = 1000};
 
        exec_task.task = task_register(&(struct task_info) {
                .name = "exec",
-               .pre_select = exec_pre_select,
-               .post_select = exec_post_select,
+               .pre_monitor = exec_pre_monitor,
+               .post_monitor = exec_post_monitor,
                .context = &exec_task,
        }, &sched);
 
        status_task.task = task_register(&(struct task_info) {
                .name = "status",
-               .pre_select = status_pre_select,
-               .post_select = status_post_select,
+               .pre_monitor = status_pre_monitor,
+               .post_monitor = status_post_monitor,
                .context = &status_task,
        }, &sched);
 
        input_task.task = task_register(&(struct task_info) {
                .name = "input",
-               .pre_select = input_pre_select,
-               .post_select = input_post_select,
+               .pre_monitor = input_pre_monitor,
+               .post_monitor = input_post_monitor,
                .context = &input_task,
        }, &sched);
 
@@ -1460,10 +1426,11 @@ static int setup_tasks_and_schedule(void)
        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,
-               .post_select = signal_post_select,
+               .pre_monitor = signal_pre_monitor,
+               .post_monitor = signal_post_monitor,
                .context = signal_task,
        }, &sched);
        ret = schedule(&sched);