diff options
author | David Herrmann <dh.herrmann@googlemail.com> | 2012-10-19 16:40:34 +0200 |
---|---|---|
committer | David Herrmann <dh.herrmann@googlemail.com> | 2012-10-19 16:51:01 +0200 |
commit | d40b23d78916b8b8221ca94ec17408ae0aa6e77e (patch) | |
tree | ea3eb826e2699ba9355ac30638bfb4b3a990522f | |
parent | 78cf66f087ef72fc2e2d1ba3b248094b1d884cd3 (diff) |
conf: add option-copy callback
We allow options to specify "aftercheck" callbacks but do not call them
during a copy. Therefore, we need a way to copy side-effects. As we cannot
do that generically, we now allow each option to specify such a callback.
We use it for the "all_seats" and "argv" parameters in kmscon.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
-rw-r--r-- | src/conf.c | 15 | ||||
-rw-r--r-- | src/conf.h | 23 | ||||
-rw-r--r-- | src/kmscon_conf.c | 94 | ||||
-rw-r--r-- | src/wlt_main.c | 110 |
4 files changed, 155 insertions, 87 deletions
@@ -141,12 +141,17 @@ int conf_ctx_parse_ctx(struct conf_ctx *ctx, const struct conf_ctx *src) if (s->flags & CONF_LOCKED) d->flags |= CONF_LOCKED; - if (!d->type->copy) - continue; + if (d->type->copy) { + ret = d->type->copy(d, s); + if (ret) + return ret; + } - ret = d->type->copy(d, s); - if (ret) - return ret; + if (d->copy) { + ret = d->copy(d, s); + if (ret) + return ret; + } } return 0; @@ -160,58 +160,65 @@ struct conf_option { const struct conf_type *type; int (*aftercheck) (struct conf_option *opt, int argc, char **argv, int idx); + int (*copy) (struct conf_option *opt, const struct conf_option *src); void *mem; void *def; }; -#define CONF_OPTION(_flags, _short, _long, _type, _aftercheck, _mem, _def) \ - { _flags, _short, "no-" _long, _type, _aftercheck, _mem, _def } -#define CONF_OPTION_BOOL(_short, _long, _aftercheck, _mem, _def) \ +#define CONF_OPTION(_flags, _short, _long, _type, _aftercheck, _copy, _mem, _def) \ + { _flags, _short, "no-" _long, _type, _aftercheck, _copy, _mem, _def } +#define CONF_OPTION_BOOL(_short, _long, _aftercheck, _copy, _mem, _def) \ CONF_OPTION(0, \ _short, \ _long, \ &conf_bool, \ _aftercheck, \ + _copy, \ _mem, \ _def) -#define CONF_OPTION_INT(_short, _long, _aftercheck, _mem, _def) \ +#define CONF_OPTION_INT(_short, _long, _aftercheck, _copy, _mem, _def) \ CONF_OPTION(0, \ _short, \ _long, \ &conf_int, \ _aftercheck, \ + _copy, \ _mem, \ (void*)(unsigned long)_def) -#define CONF_OPTION_UINT(_short, _long, _aftercheck, _mem, _def) \ +#define CONF_OPTION_UINT(_short, _long, _aftercheck, _copy, _mem, _def) \ CONF_OPTION(0, \ _short, \ _long, \ &conf_uint, \ _aftercheck, \ + _copy, \ _mem, \ (void*)(unsigned long)_def) -#define CONF_OPTION_STRING(_short, _long, _aftercheck, _mem, _def) \ +#define CONF_OPTION_STRING(_short, _long, _aftercheck, _copy, _mem, _def) \ CONF_OPTION(0, \ _short, \ _long, \ &conf_string, \ _aftercheck, \ + _copy, \ _mem, \ _def) -#define CONF_OPTION_STRING_LIST(_short, _long, _aftercheck, _mem, _def) \ +#define CONF_OPTION_STRING_LIST(_short, _long, _aftercheck, _copy, _mem, _def) \ CONF_OPTION(0, \ _short, \ _long, \ &conf_string_list, \ _aftercheck, \ + _copy, \ _mem, \ _def) -#define CONF_OPTION_GRAB(_short, _long, _aftercheck, _mem, _def) \ +#define CONF_OPTION_GRAB(_short, _long, _aftercheck, _copy, _mem, _def) \ CONF_OPTION(0, \ _short, \ _long, \ &conf_grab, \ _aftercheck, \ + _copy, \ _mem, \ _def) diff --git a/src/kmscon_conf.c b/src/kmscon_conf.c index 3301cd9..484e12d 100644 --- a/src/kmscon_conf.c +++ b/src/kmscon_conf.c @@ -272,6 +272,23 @@ static int aftercheck_login(struct conf_option *opt, int argc, char **argv, return ret; } +static int copy_login(struct conf_option *opt, const struct conf_option *src) +{ + struct kmscon_conf_t *conf = KMSCON_CONF_FROM_FIELD(opt->mem, login); + struct kmscon_conf_t *s = KMSCON_CONF_FROM_FIELD(src->mem, login); + int ret; + char **t; + + ret = shl_dup_array(&t, s->argv); + if (ret) + return ret; + + free(conf->argv); + conf->argv = t; + + return 0; +} + static int aftercheck_seats(struct conf_option *opt, int argc, char **argv, int idx) { @@ -285,6 +302,15 @@ static int aftercheck_seats(struct conf_option *opt, int argc, char **argv, return 0; } +static int copy_seats(struct conf_option *opt, const struct conf_option *src) +{ + struct kmscon_conf_t *conf = KMSCON_CONF_FROM_FIELD(opt->mem, seats); + struct kmscon_conf_t *s = KMSCON_CONF_FROM_FIELD(src->mem, seats); + + conf->all_seats = s->all_seats; + return 0; +} + static char *def_seats[] = { "seat0", NULL }; static struct conf_grab def_grab_scroll_up = @@ -321,54 +347,54 @@ int kmscon_conf_new(struct conf_ctx **out, struct kmscon_conf_t *conf) struct conf_option options[] = { /* Global Options */ - CONF_OPTION_BOOL('h', "help", aftercheck_help, &conf->help, false), - CONF_OPTION_BOOL('v', "verbose", NULL, &conf->verbose, false), - CONF_OPTION_BOOL(0, "debug", aftercheck_debug, &conf->debug, false), - CONF_OPTION_BOOL(0, "silent", NULL, &conf->silent, false), + CONF_OPTION_BOOL('h', "help", aftercheck_help, NULL, &conf->help, false), + CONF_OPTION_BOOL('v', "verbose", NULL, NULL, &conf->verbose, false), + CONF_OPTION_BOOL(0, "debug", aftercheck_debug, NULL, &conf->debug, false), + CONF_OPTION_BOOL(0, "silent", NULL, NULL, &conf->silent, false), /* Seat Options */ - CONF_OPTION(0, 0, "vt", &conf_vt, NULL, &conf->vt, NULL), - CONF_OPTION_BOOL('s', "switchvt", NULL, &conf->switchvt, false), - CONF_OPTION_STRING_LIST(0, "seats", aftercheck_seats, &conf->seats, def_seats), + CONF_OPTION(0, 0, "vt", &conf_vt, NULL, NULL, &conf->vt, NULL), + CONF_OPTION_BOOL('s', "switchvt", NULL, NULL, &conf->switchvt, false), + CONF_OPTION_STRING_LIST(0, "seats", aftercheck_seats, copy_seats, &conf->seats, def_seats), /* Session Options */ - CONF_OPTION_UINT(0, "session-max", NULL, &conf->session_max, 50), + CONF_OPTION_UINT(0, "session-max", NULL, NULL, &conf->session_max, 50), /* Terminal Options */ - CONF_OPTION_BOOL('l', "login", aftercheck_login, &conf->login, false), - CONF_OPTION_STRING('t', "term", NULL, &conf->term, "xterm-256color"), - CONF_OPTION_STRING(0, "palette", NULL, &conf->palette, NULL), - CONF_OPTION_UINT(0, "sb-size", NULL, &conf->sb_size, 1000), + CONF_OPTION_BOOL('l', "login", aftercheck_login, copy_login, &conf->login, false), + CONF_OPTION_STRING('t', "term", NULL, NULL, &conf->term, "xterm-256color"), + CONF_OPTION_STRING(0, "palette", NULL, NULL, &conf->palette, NULL), + CONF_OPTION_UINT(0, "sb-size", NULL, NULL, &conf->sb_size, 1000), /* Input Options */ - CONF_OPTION_STRING(0, "xkb-layout", NULL, &conf->xkb_layout, "us"), - CONF_OPTION_STRING(0, "xkb-variant", NULL, &conf->xkb_variant, ""), - CONF_OPTION_STRING(0, "xkb-options", NULL, &conf->xkb_options, ""), - CONF_OPTION_UINT(0, "xkb-repeat-delay", NULL, &conf->xkb_repeat_delay, 250), - CONF_OPTION_UINT(0, "xkb-repeat-rate", NULL, &conf->xkb_repeat_rate, 50), + CONF_OPTION_STRING(0, "xkb-layout", NULL, NULL, &conf->xkb_layout, "us"), + CONF_OPTION_STRING(0, "xkb-variant", NULL, NULL, &conf->xkb_variant, ""), + CONF_OPTION_STRING(0, "xkb-options", NULL, NULL, &conf->xkb_options, ""), + CONF_OPTION_UINT(0, "xkb-repeat-delay", NULL, NULL, &conf->xkb_repeat_delay, 250), + CONF_OPTION_UINT(0, "xkb-repeat-rate", NULL, NULL, &conf->xkb_repeat_rate, 50), /* Grabs / Keyboard-Shortcuts */ - CONF_OPTION_GRAB(0, "grab-scroll-up", NULL, &conf->grab_scroll_up, &def_grab_scroll_up), - CONF_OPTION_GRAB(0, "grab-scroll-down", NULL, &conf->grab_scroll_down, &def_grab_scroll_down), - CONF_OPTION_GRAB(0, "grab-page-up", NULL, &conf->grab_page_up, &def_grab_page_up), - CONF_OPTION_GRAB(0, "grab-page-down", NULL, &conf->grab_page_down, &def_grab_page_down), - CONF_OPTION_GRAB(0, "grab-session-next", NULL, &conf->grab_session_next, &def_grab_session_next), - CONF_OPTION_GRAB(0, "grab-session-prev", NULL, &conf->grab_session_prev, &def_grab_session_prev), - CONF_OPTION_GRAB(0, "grab-session-close", NULL, &conf->grab_session_close, &def_grab_session_close), - CONF_OPTION_GRAB(0, "grab-terminal-new", NULL, &conf->grab_terminal_new, &def_grab_terminal_new), + CONF_OPTION_GRAB(0, "grab-scroll-up", NULL, NULL, &conf->grab_scroll_up, &def_grab_scroll_up), + CONF_OPTION_GRAB(0, "grab-scroll-down", NULL, NULL, &conf->grab_scroll_down, &def_grab_scroll_down), + CONF_OPTION_GRAB(0, "grab-page-up", NULL, NULL, &conf->grab_page_up, &def_grab_page_up), + CONF_OPTION_GRAB(0, "grab-page-down", NULL, NULL, &conf->grab_page_down, &def_grab_page_down), + CONF_OPTION_GRAB(0, "grab-session-next", NULL, NULL, &conf->grab_session_next, &def_grab_session_next), + CONF_OPTION_GRAB(0, "grab-session-prev", NULL, NULL, &conf->grab_session_prev, &def_grab_session_prev), + CONF_OPTION_GRAB(0, "grab-session-close", NULL, NULL, &conf->grab_session_close, &def_grab_session_close), + CONF_OPTION_GRAB(0, "grab-terminal-new", NULL, NULL, &conf->grab_terminal_new, &def_grab_terminal_new), /* Video Options */ - CONF_OPTION_BOOL(0, "fbdev", NULL, &conf->fbdev, false), - CONF_OPTION_BOOL(0, "dumb", NULL, &conf->dumb, false), - CONF_OPTION_UINT(0, "fps", NULL, &conf->fps, 50), - CONF_OPTION_STRING(0, "render-engine", NULL, &conf->render_engine, NULL), - CONF_OPTION_BOOL(0, "render-timing", NULL, &conf->render_timing, false), + CONF_OPTION_BOOL(0, "fbdev", NULL, NULL, &conf->fbdev, false), + CONF_OPTION_BOOL(0, "dumb", NULL, NULL, &conf->dumb, false), + CONF_OPTION_UINT(0, "fps", NULL, NULL, &conf->fps, 50), + CONF_OPTION_STRING(0, "render-engine", NULL, NULL, &conf->render_engine, NULL), + CONF_OPTION_BOOL(0, "render-timing", NULL, NULL, &conf->render_timing, false), /* Font Options */ - CONF_OPTION_STRING(0, "font-engine", NULL, &conf->font_engine, "pango"), - CONF_OPTION_UINT(0, "font-size", NULL, &conf->font_size, 12), - CONF_OPTION_STRING(0, "font-name", NULL, &conf->font_name, "monospace"), - CONF_OPTION_UINT(0, "font-dpi", NULL, &conf->font_ppi, 96), + CONF_OPTION_STRING(0, "font-engine", NULL, NULL, &conf->font_engine, "pango"), + CONF_OPTION_UINT(0, "font-size", NULL, NULL, &conf->font_size, 12), + CONF_OPTION_STRING(0, "font-name", NULL, NULL, &conf->font_name, "monospace"), + CONF_OPTION_UINT(0, "font-dpi", NULL, NULL, &conf->font_ppi, 96), }; ret = conf_ctx_new(&ctx, options, sizeof(options) / sizeof(*options), diff --git a/src/wlt_main.c b/src/wlt_main.c index 094383b..4bf4050 100644 --- a/src/wlt_main.c +++ b/src/wlt_main.c @@ -38,6 +38,7 @@ #include "conf.h" #include "eloop.h" #include "log.h" +#include "shl_dlist.h" #include "shl_misc.h" #include "text.h" #include "wlt_main.h" @@ -180,6 +181,8 @@ err_app: } struct wlt_conf_t wlt_conf; +#define WLT_CONF_FROM_FIELD(_mem, _name) \ + shl_offsetof((_mem), struct wlt_conf_t, _name) static void print_help() { @@ -274,9 +277,11 @@ static void print_help() static int aftercheck_debug(struct conf_option *opt, int argc, char **argv, int idx) { + struct wlt_conf_t *conf = WLT_CONF_FROM_FIELD(opt->mem, debug); + /* --debug implies --verbose */ - if (wlt_conf.debug) - wlt_conf.verbose = 1; + if (conf->debug) + conf->verbose = true; return 0; } @@ -284,10 +289,12 @@ static int aftercheck_debug(struct conf_option *opt, int argc, char **argv, static int aftercheck_help(struct conf_option *opt, int argc, char **argv, int idx) { + struct wlt_conf_t *conf = WLT_CONF_FROM_FIELD(opt->mem, help); + /* exit after printing --help information */ - if (wlt_conf.help) { + if (conf->help) { print_help(); - wlt_conf.exit = true; + conf->exit = true; } return 0; @@ -298,26 +305,44 @@ static char *def_argv[] = { NULL, "-i", NULL }; static int aftercheck_login(struct conf_option *opt, int argc, char **argv, int idx) { + struct wlt_conf_t *conf = WLT_CONF_FROM_FIELD(opt->mem, login); int ret; /* parse "--login [...] -- args" arguments */ - if (wlt_conf.login) { + if (conf->login) { if (idx >= argc) { fprintf(stderr, "Arguments for --login missing\n"); return -EFAULT; } - wlt_conf.argv = &argv[idx]; + conf->argv = &argv[idx]; ret = argc - idx; } else { def_argv[0] = getenv("SHELL") ? : _PATH_BSHELL; - wlt_conf.argv = def_argv; + conf->argv = def_argv; ret = 0; } return ret; } +static int copy_login(struct conf_option *opt, const struct conf_option *src) +{ + struct wlt_conf_t *conf = WLT_CONF_FROM_FIELD(opt->mem, login); + struct wlt_conf_t *s = WLT_CONF_FROM_FIELD(src->mem, login); + int ret; + char **t; + + ret = shl_dup_array(&t, s->argv); + if (ret) + return ret; + + free(conf->argv); + conf->argv = t; + + return 0; +} + static struct conf_grab def_grab_scroll_up = CONF_SINGLE_GRAB(SHL_SHIFT_MASK, XKB_KEY_Up); @@ -346,48 +371,52 @@ static struct conf_grab def_grab_paste = CONF_SINGLE_GRAB(SHL_LOGO_MASK, XKB_KEY_v); struct conf_option options[] = { - CONF_OPTION_BOOL('h', "help", aftercheck_help, &wlt_conf.help, false), - CONF_OPTION_BOOL('v', "verbose", NULL, &wlt_conf.verbose, false), - CONF_OPTION_BOOL(0, "debug", aftercheck_debug, &wlt_conf.debug, false), - CONF_OPTION_BOOL(0, "silent", NULL, &wlt_conf.silent, false), - - CONF_OPTION_BOOL('l', "login", aftercheck_login, &wlt_conf.login, false), - CONF_OPTION_STRING('t', "term", NULL, &wlt_conf.term, "xterm-256color"), - CONF_OPTION_STRING(0, "palette", NULL, &wlt_conf.palette, NULL), - CONF_OPTION_UINT(0, "sb-size", NULL, &wlt_conf.sb_size, 1000), - - CONF_OPTION_GRAB(0, "grab-scroll-up", NULL, &wlt_conf.grab_scroll_up, &def_grab_scroll_up), - CONF_OPTION_GRAB(0, "grab-scroll-down", NULL, &wlt_conf.grab_scroll_down, &def_grab_scroll_down), - CONF_OPTION_GRAB(0, "grab-page-up", NULL, &wlt_conf.grab_page_up, &def_grab_page_up), - CONF_OPTION_GRAB(0, "grab-page-down", NULL, &wlt_conf.grab_page_down, &def_grab_page_down), - CONF_OPTION_GRAB(0, "grab-fullscreen", NULL, &wlt_conf.grab_fullscreen, &def_grab_fullscreen), - CONF_OPTION_GRAB(0, "grab-zoom-in", NULL, &wlt_conf.grab_zoom_in, &def_grab_zoom_in), - CONF_OPTION_GRAB(0, "grab-zoom-out", NULL, &wlt_conf.grab_zoom_out, &def_grab_zoom_out), - CONF_OPTION_GRAB(0, "grab-copy", NULL, &wlt_conf.grab_copy, &def_grab_copy), - CONF_OPTION_GRAB(0, "grab-paste", NULL, &wlt_conf.grab_paste, &def_grab_paste), - - CONF_OPTION_STRING(0, "font-engine", NULL, &wlt_conf.font_engine, "pango"), - CONF_OPTION_UINT(0, "font-size", NULL, &wlt_conf.font_size, 12), - CONF_OPTION_STRING(0, "font-name", NULL, &wlt_conf.font_name, "monospace"), - CONF_OPTION_UINT(0, "font-dpi", NULL, &wlt_conf.font_ppi, 96), - - CONF_OPTION_UINT(0, "xkb-repeat-delay", NULL, &wlt_conf.xkb_repeat_delay, 250), - CONF_OPTION_UINT(0, "xkb-repeat-rate", NULL, &wlt_conf.xkb_repeat_rate, 50), + CONF_OPTION_BOOL('h', "help", aftercheck_help, NULL, &wlt_conf.help, false), + CONF_OPTION_BOOL('v', "verbose", NULL, NULL, &wlt_conf.verbose, false), + CONF_OPTION_BOOL(0, "debug", aftercheck_debug, NULL, &wlt_conf.debug, false), + CONF_OPTION_BOOL(0, "silent", NULL, NULL, &wlt_conf.silent, false), + + CONF_OPTION_BOOL('l', "login", aftercheck_login, copy_login, &wlt_conf.login, false), + CONF_OPTION_STRING('t', "term", NULL, NULL, &wlt_conf.term, "xterm-256color"), + CONF_OPTION_STRING(0, "palette", NULL, NULL, &wlt_conf.palette, NULL), + CONF_OPTION_UINT(0, "sb-size", NULL, NULL, &wlt_conf.sb_size, 1000), + + CONF_OPTION_GRAB(0, "grab-scroll-up", NULL, NULL, &wlt_conf.grab_scroll_up, &def_grab_scroll_up), + CONF_OPTION_GRAB(0, "grab-scroll-down", NULL, NULL, &wlt_conf.grab_scroll_down, &def_grab_scroll_down), + CONF_OPTION_GRAB(0, "grab-page-up", NULL, NULL, &wlt_conf.grab_page_up, &def_grab_page_up), + CONF_OPTION_GRAB(0, "grab-page-down", NULL, NULL, &wlt_conf.grab_page_down, &def_grab_page_down), + CONF_OPTION_GRAB(0, "grab-fullscreen", NULL, NULL, &wlt_conf.grab_fullscreen, &def_grab_fullscreen), + CONF_OPTION_GRAB(0, "grab-zoom-in", NULL, NULL, &wlt_conf.grab_zoom_in, &def_grab_zoom_in), + CONF_OPTION_GRAB(0, "grab-zoom-out", NULL, NULL, &wlt_conf.grab_zoom_out, &def_grab_zoom_out), + CONF_OPTION_GRAB(0, "grab-copy", NULL, NULL, &wlt_conf.grab_copy, &def_grab_copy), + CONF_OPTION_GRAB(0, "grab-paste", NULL, NULL, &wlt_conf.grab_paste, &def_grab_paste), + + CONF_OPTION_STRING(0, "font-engine", NULL, NULL, &wlt_conf.font_engine, "pango"), + CONF_OPTION_UINT(0, "font-size", NULL, NULL, &wlt_conf.font_size, 12), + CONF_OPTION_STRING(0, "font-name", NULL, NULL, &wlt_conf.font_name, "monospace"), + CONF_OPTION_UINT(0, "font-dpi", NULL, NULL, &wlt_conf.font_ppi, 96), + + CONF_OPTION_UINT(0, "xkb-repeat-delay", NULL, NULL, &wlt_conf.xkb_repeat_delay, 250), + CONF_OPTION_UINT(0, "xkb-repeat-rate", NULL, NULL, &wlt_conf.xkb_repeat_rate, 50), }; int main(int argc, char **argv) { int ret; struct wlt_app app; - size_t onum; + struct conf_ctx *conf; - onum = sizeof(options) / sizeof(*options); - ret = conf_parse_argv(options, onum, argc, argv); + ret = conf_ctx_new(&conf, options, sizeof(options) / sizeof(*options), + &wlt_conf); if (ret) goto err_out; + ret = conf_ctx_parse_argv(conf, argc, argv); + if (ret) + goto err_conf; + if (wlt_conf.exit) { - conf_free(options, onum); + conf_ctx_free(conf); return EXIT_SUCCESS; } @@ -410,15 +439,16 @@ int main(int argc, char **argv) destroy_app(&app); kmscon_font_unload_all(); - conf_free(options, onum); + conf_ctx_free(conf); log_info("exiting"); return EXIT_SUCCESS; err_unload: kmscon_font_unload_all(); +err_conf: + conf_ctx_free(conf); err_out: - conf_free(options, onum); log_err("cannot initialize wlterm, errno %d: %s", ret, strerror(-ret)); return -ret; } |