From 79ef4f950575a7e6943dd1a75ccc2e90520cdeee Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Mon, 1 Oct 2012 11:23:21 +0200 Subject: [PATCH] Move grab-parsing into conf.c We really need to clean this up and allow parsing of grabs in conf.c again. xkbcommon is now mandatory so we can fix all the input layers to use it. Signed-off-by: David Herrmann --- src/conf.c | 87 +++++++++++++++++++++++++++++ src/conf.h | 18 ++++++ src/main.c | 118 +++------------------------------------- src/main.h | 10 ++-- src/shl_misc.h | 38 ++++++++++++- src/tsm_vte.c | 2 +- src/tsm_vte.h | 10 ++-- src/uterm.h | 15 ++--- src/uterm_input_plain.c | 13 ++--- src/uterm_input_uxkb.c | 26 +-------- src/uterm_vt.c | 2 +- src/wlt_toolkit.c | 28 +--------- 12 files changed, 174 insertions(+), 193 deletions(-) diff --git a/src/conf.c b/src/conf.c index c69026a..87cac59 100644 --- a/src/conf.c +++ b/src/conf.c @@ -36,8 +36,10 @@ #include #include #include +#include #include "conf.h" #include "log.h" +#include "shl_misc.h" #define LOG_SUBSYSTEM "config" @@ -147,6 +149,84 @@ void conf_default_string_list(struct conf_option *opt) *(void**)opt->mem = opt->def; } +int conf_parse_grab(struct conf_option *opt, bool on, const char *arg) +{ + char *buf, *tmp, *start; + struct conf_grab grab, *gnew; + + memset(&grab, 0, sizeof(grab)); + + buf = strdup(arg); + if (!buf) + return -ENOMEM; + tmp = buf; + +next_mod: + if (*tmp == '<') { + start = tmp; + while (*tmp && *tmp != '>') + ++tmp; + + if (*tmp != '>') { + log_error("missing '>' in grab '%s' near '%s'", + arg, start); + goto err_free; + } + + *tmp++ = 0; + ++start; + if (!strcasecmp(start, "shift")) { + grab.mods |= SHL_SHIFT_MASK; + } else if (!strcasecmp(start, "lock")) { + grab.mods |= SHL_LOCK_MASK; + } else if (!strcasecmp(start, "control") || + !strcasecmp(start, "ctrl")) { + grab.mods |= SHL_CONTROL_MASK; + } else if (!strcasecmp(start, "alt")) { + grab.mods |= SHL_ALT_MASK; + } else if (!strcasecmp(start, "logo")) { + grab.mods |= SHL_LOGO_MASK; + } else { + log_error("invalid modifier '%s' in grab '%s'", + start, arg); + goto err_free; + } + + goto next_mod; + } + + if (!*tmp) { + log_error("missing key in grab '%s'", arg); + goto err_free; + } + + grab.keysym = xkb_keysym_from_name(tmp); + if (!grab.keysym) { + log_error("invalid key '%s' in grab '%s'", tmp, arg); + goto err_free; + } + + gnew = malloc(sizeof(*gnew)); + if (!gnew) + goto err_free; + memcpy(gnew, &grab, sizeof(*gnew)); + + opt->type->free(opt); + *(void**)opt->mem = gnew; + free(buf); + + return 0; + +err_free: + free(buf); + return -EFAULT; +} + +void conf_default_grab(struct conf_option *opt) +{ + *(void**)opt->mem = opt->def; +} + const struct conf_type conf_bool = { .flags = 0, .parse = conf_parse_bool, @@ -182,6 +262,13 @@ const struct conf_type conf_string_list = { .set_default = conf_default_string_list, }; +const struct conf_type conf_grab = { + .flags = CONF_HAS_ARG, + .parse = conf_parse_grab, + .free = conf_free_value, + .set_default = conf_default_grab, +}; + /* free all memory that we allocated and reset to initial state */ void conf_free(struct conf_option *opts, size_t len) { diff --git a/src/conf.h b/src/conf.h index 8643d36..3499ddf 100644 --- a/src/conf.h +++ b/src/conf.h @@ -36,6 +36,13 @@ #include #include +/* parsed types */ + +struct conf_grab { + unsigned int mods; + uint32_t keysym; +}; + /* configuration parser */ struct conf_type; @@ -108,6 +115,14 @@ struct conf_option { _aftercheck, \ _mem, \ _def) +#define CONF_OPTION_GRAB(_short, _long, _aftercheck, _mem, _def) \ + CONF_OPTION(0, \ + _short, \ + _long, \ + &conf_grab, \ + _aftercheck, \ + _mem, \ + _def) void conf_free_value(struct conf_option *opt); int conf_parse_bool(struct conf_option *opt, bool on, const char *arg); @@ -120,12 +135,15 @@ int conf_parse_string(struct conf_option *opt, bool on, const char *arg); void conf_default_string(struct conf_option *opt); int conf_parse_string_list(struct conf_option *opt, bool on, const char *arg); void conf_default_string_list(struct conf_option *opt); +int conf_parse_grab(struct conf_option *opt, bool on, const char *arg); +void conf_default_grab(struct conf_option *opt); extern const struct conf_type conf_bool; extern const struct conf_type conf_int; extern const struct conf_type conf_uint; extern const struct conf_type conf_string; extern const struct conf_type conf_string_list; +extern const struct conf_type conf_grab; void conf_free(struct conf_option *opts, size_t len); int conf_parse_argv(struct conf_option *opts, size_t len, diff --git a/src/main.c b/src/main.c index 7e1d1b4..c7736e3 100644 --- a/src/main.c +++ b/src/main.c @@ -31,7 +31,6 @@ #include #include #include -#include #include "conf.h" #include "eloop.h" #include "log.h" @@ -489,107 +488,6 @@ static void print_help() */ } -int conf_parse_grab(struct conf_option *opt, bool on, const char *arg) -{ - char *buf, *tmp, *start; - int ret; - struct uterm_input_grab grab, *gnew; - - memset(&grab, 0, sizeof(grab)); - - buf = strdup(arg); - if (!buf) - return -ENOMEM; - tmp = buf; - -next_mod: - if (*tmp == '<') { - start = tmp; - while (*tmp && *tmp != '>') - ++tmp; - - if (*tmp != '>') { - log_error("missing '>' in grab '%s' near '%s'", - arg, start); - goto err_free; - } - - *tmp++ = 0; - ++start; - if (!strcasecmp(start, "shift")) { - grab.mods |= UTERM_SHIFT_MASK; - } else if (!strcasecmp(start, "lock")) { - grab.mods |= UTERM_LOCK_MASK; - } else if (!strcasecmp(start, "control") || - !strcasecmp(start, "ctrl")) { - grab.mods |= UTERM_CONTROL_MASK; - } else if (!strcasecmp(start, "mod1")) { - grab.mods |= UTERM_MOD1_MASK; - } else if (!strcasecmp(start, "mod2")) { - grab.mods |= UTERM_MOD2_MASK; - } else if (!strcasecmp(start, "mod3")) { - grab.mods |= UTERM_MOD3_MASK; - } else if (!strcasecmp(start, "mod4")) { - grab.mods |= UTERM_MOD4_MASK; - } else if (!strcasecmp(start, "mod5")) { - grab.mods |= UTERM_MOD5_MASK; - } else { - log_error("invalid modifier '%s' in grab '%s'", - start, arg); - goto err_free; - } - - goto next_mod; - } - - if (!*tmp) { - log_error("missing key in grab '%s'", arg); - goto err_free; - } - - ret = uterm_input_string_to_keysym(NULL, tmp, &grab.keysym); - if (ret || !grab.keysym) { - log_error("invalid key '%s' in grab '%s'", tmp, arg); - goto err_free; - } - - gnew = malloc(sizeof(*gnew)); - if (!gnew) - goto err_free; - memcpy(gnew, &grab, sizeof(*gnew)); - - opt->type->free(opt); - *(void**)opt->mem = gnew; - free(buf); - - return 0; - -err_free: - free(buf); - return -EFAULT; -} - -void conf_default_grab(struct conf_option *opt) -{ - *(void**)opt->mem = opt->def; -} - -const struct conf_type conf_grab = { - .flags = CONF_HAS_ARG, - .parse = conf_parse_grab, - .free = conf_free_value, - .set_default = conf_default_grab, -}; - -#define CONF_OPTION_GRAB(_short, _long, _aftercheck, _mem, _def) \ - CONF_OPTION(0, \ - _short, \ - _long, \ - &conf_grab, \ - _aftercheck, \ - _mem, \ - _def) - int conf_parse_vt(struct conf_option *opt, bool on, const char *arg) { static const char prefix[] = "/dev/"; @@ -692,23 +590,23 @@ static int aftercheck_seats(struct conf_option *opt, int argc, char **argv, static char *def_seats[] = { "seat0", NULL }; -static struct uterm_input_grab def_grab_scroll_up = { - .mods = UTERM_SHIFT_MASK, +static struct conf_grab def_grab_scroll_up = { + .mods = SHL_SHIFT_MASK, .keysym = XKB_KEY_Up, }; -static struct uterm_input_grab def_grab_scroll_down = { - .mods = UTERM_SHIFT_MASK, +static struct conf_grab def_grab_scroll_down = { + .mods = SHL_SHIFT_MASK, .keysym = XKB_KEY_Down, }; -static struct uterm_input_grab def_grab_page_up = { - .mods = UTERM_SHIFT_MASK, +static struct conf_grab def_grab_page_up = { + .mods = SHL_SHIFT_MASK, .keysym = XKB_KEY_Prior, }; -static struct uterm_input_grab def_grab_page_down = { - .mods = UTERM_SHIFT_MASK, +static struct conf_grab def_grab_page_down = { + .mods = SHL_SHIFT_MASK, .keysym = XKB_KEY_Next, }; diff --git a/src/main.h b/src/main.h index 03cc549..ebb796d 100644 --- a/src/main.h +++ b/src/main.h @@ -33,7 +33,7 @@ #include #include -#include "uterm.h" +#include "conf.h" struct kmscon_conf_t { /* show help/usage information */ @@ -71,13 +71,13 @@ struct kmscon_conf_t { /* terminal scroll-back buffer size */ unsigned int sb_size; /* scroll-up grab */ - struct uterm_input_grab *grab_scroll_up; + struct conf_grab *grab_scroll_up; /* scroll-down grab */ - struct uterm_input_grab *grab_scroll_down; + struct conf_grab *grab_scroll_down; /* page-up grab */ - struct uterm_input_grab *grab_page_up; + struct conf_grab *grab_page_up; /* page-down grab */ - struct uterm_input_grab *grab_page_down; + struct conf_grab *grab_page_down; /* seats */ char **seats; diff --git a/src/shl_misc.h b/src/shl_misc.h index 2d8909b..724a7c0 100644 --- a/src/shl_misc.h +++ b/src/shl_misc.h @@ -36,8 +36,10 @@ #include #include #include +#include -int shl_strtou(const char *input, unsigned int *output) { +static inline int shl_strtou(const char *input, unsigned int *output) +{ unsigned long val; unsigned int res; char *tmp = NULL; @@ -57,4 +59,38 @@ int shl_strtou(const char *input, unsigned int *output) { return 0; } +/* TODO: xkbcommon should provide these flags! + * We currently copy them into each library API we use so we need to keep + * them in sync. Currently, they're used in uterm-input and tsm-vte. */ +enum shl_xkb_mods { + SHL_SHIFT_MASK = (1 << 0), + SHL_LOCK_MASK = (1 << 1), + SHL_CONTROL_MASK = (1 << 2), + SHL_ALT_MASK = (1 << 3), + SHL_LOGO_MASK = (1 << 4), +}; + +static inline unsigned int shl_get_xkb_mods(struct xkb_state *state) +{ + unsigned int mods = 0; + + if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_SHIFT, + XKB_STATE_EFFECTIVE)) + mods |= SHL_SHIFT_MASK; + if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CAPS, + XKB_STATE_EFFECTIVE)) + mods |= SHL_LOCK_MASK; + if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL, + XKB_STATE_EFFECTIVE)) + mods |= SHL_CONTROL_MASK; + if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT, + XKB_STATE_EFFECTIVE)) + mods |= SHL_ALT_MASK; + if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_LOGO, + XKB_STATE_EFFECTIVE)) + mods |= SHL_LOGO_MASK; + + return mods; +} + #endif /* SHL_MISC_H */ diff --git a/src/tsm_vte.c b/src/tsm_vte.c index 358d610..72a214f 100644 --- a/src/tsm_vte.c +++ b/src/tsm_vte.c @@ -2164,7 +2164,7 @@ bool tsm_vte_handle_keyboard(struct tsm_vte *vte, uint32_t keysym, * Also check whether altSendsEscape should be the default (xterm * disables this by default, why?) and whether we should implement the * fallback shifting that xterm does. */ - if (mods & TSM_MOD1_MASK) + if (mods & TSM_ALT_MASK) vte->flags |= FLAG_PREPEND_ESCAPE; if (mods & TSM_CONTROL_MASK) { diff --git a/src/tsm_vte.h b/src/tsm_vte.h index 8124aa1..7c72471 100644 --- a/src/tsm_vte.h +++ b/src/tsm_vte.h @@ -50,18 +50,16 @@ extern tsm_vte_charset tsm_vte_dec_special_graphics; struct tsm_vte; -/* keep in sync with uterm_input_modifier */ +/* keep in sync with shl_xkb_mods */ enum tsm_vte_modifier { TSM_SHIFT_MASK = (1 << 0), TSM_LOCK_MASK = (1 << 1), TSM_CONTROL_MASK = (1 << 2), - TSM_MOD1_MASK = (1 << 3), - TSM_MOD2_MASK = (1 << 4), - TSM_MOD3_MASK = (1 << 5), - TSM_MOD4_MASK = (1 << 6), - TSM_MOD5_MASK = (1 << 7), + TSM_ALT_MASK = (1 << 3), + TSM_LOGO_MASK = (1 << 4), }; +/* keep in sync with TSM_INPUT_INVALID */ #define TSM_VTE_INVALID 0xffffffff typedef void (*tsm_vte_write_cb) (struct tsm_vte *vte, diff --git a/src/uterm.h b/src/uterm.h index 98232ad..8912df1 100644 --- a/src/uterm.h +++ b/src/uterm.h @@ -256,18 +256,16 @@ void uterm_video_poll(struct uterm_video *video); struct uterm_input; -/* keep in sync with tsm_vte_modified */ +/* keep in sync with shl_xkb_mods */ enum uterm_input_modifier { UTERM_SHIFT_MASK = (1 << 0), UTERM_LOCK_MASK = (1 << 1), UTERM_CONTROL_MASK = (1 << 2), - UTERM_MOD1_MASK = (1 << 3), - UTERM_MOD2_MASK = (1 << 4), - UTERM_MOD3_MASK = (1 << 5), - UTERM_MOD4_MASK = (1 << 6), - UTERM_MOD5_MASK = (1 << 7), + UTERM_ALT_MASK = (1 << 3), + UTERM_LOGO_MASK = (1 << 4), }; +/* keep in sync with TSM_VTE_INVALID */ #define UTERM_INPUT_INVALID 0xffffffff struct uterm_input_event { @@ -279,11 +277,6 @@ struct uterm_input_event { #define UTERM_INPUT_HAS_MODS(_ev, _mods) (((_ev)->mods & (_mods)) == (_mods)) -struct uterm_input_grab { - unsigned int mods; - uint32_t keysym; -}; - typedef void (*uterm_input_cb) (struct uterm_input *input, struct uterm_input_event *ev, void *data); diff --git a/src/uterm_input_plain.c b/src/uterm_input_plain.c index 44de350..91926ee 100644 --- a/src/uterm_input_plain.c +++ b/src/uterm_input_plain.c @@ -271,13 +271,12 @@ static const struct { [KEY_LEFTCTRL] = { UTERM_CONTROL_MASK, MOD_NORMAL }, [KEY_LEFTSHIFT] = { UTERM_SHIFT_MASK, MOD_NORMAL }, [KEY_RIGHTSHIFT] = { UTERM_SHIFT_MASK, MOD_NORMAL }, - [KEY_LEFTALT] = { UTERM_MOD1_MASK, MOD_NORMAL }, + [KEY_LEFTALT] = { UTERM_ALT_MASK, MOD_NORMAL }, [KEY_CAPSLOCK] = { UTERM_LOCK_MASK, MOD_LOCK }, - [KEY_NUMLOCK] = { UTERM_MOD2_MASK, MOD_LOCK }, [KEY_RIGHTCTRL] = { UTERM_CONTROL_MASK, MOD_NORMAL }, - [KEY_RIGHTALT] = { UTERM_MOD1_MASK, MOD_NORMAL }, - [KEY_LEFTMETA] = { UTERM_MOD4_MASK, MOD_NORMAL }, - [KEY_RIGHTMETA] = { UTERM_MOD4_MASK, MOD_NORMAL }, + [KEY_RIGHTALT] = { UTERM_ALT_MASK, MOD_NORMAL }, + [KEY_LEFTMETA] = { UTERM_LOGO_MASK, MOD_NORMAL }, + [KEY_RIGHTMETA] = { UTERM_LOGO_MASK, MOD_NORMAL }, }; static void plain_dev_ref(struct kbd_dev *kbd) @@ -303,8 +302,6 @@ static void plain_dev_reset(struct kbd_dev *kbd, const unsigned long *ledbits) kbd->plain.mods = 0; - if (input_bit_is_set(ledbits, LED_NUML)) - kbd->plain.mods |= UTERM_MOD2_MASK; if (input_bit_is_set(ledbits, LED_CAPSL)) kbd->plain.mods |= UTERM_LOCK_MASK; } @@ -352,8 +349,6 @@ static int plain_dev_process(struct kbd_dev *kbd, keysym = 0; - if (!keysym && kbd->plain.mods & UTERM_MOD2_MASK) - keysym = keytab_numlock[code]; if (!keysym && kbd->plain.mods & UTERM_SHIFT_MASK) keysym = keytab_shift[code]; if (!keysym && kbd->plain.mods & UTERM_LOCK_MASK) diff --git a/src/uterm_input_uxkb.c b/src/uterm_input_uxkb.c index 59a5b85..ddc9b67 100644 --- a/src/uterm_input_uxkb.c +++ b/src/uterm_input_uxkb.c @@ -32,6 +32,7 @@ #include #include #include "log.h" +#include "shl_misc.h" #include "uterm.h" #include "uterm_input.h" @@ -62,29 +63,6 @@ enum { KEY_REPEATED = 2, }; -static unsigned int get_effective_modmask(struct xkb_state *state) -{ - unsigned int mods = 0; - - if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_SHIFT, - XKB_STATE_EFFECTIVE)) - mods |= UTERM_SHIFT_MASK; - if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CAPS, - XKB_STATE_EFFECTIVE)) - mods |= UTERM_LOCK_MASK; - if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL, - XKB_STATE_EFFECTIVE)) - mods |= UTERM_CONTROL_MASK; - if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT, - XKB_STATE_EFFECTIVE)) - mods |= UTERM_MOD1_MASK; - if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_LOGO, - XKB_STATE_EFFECTIVE)) - mods |= UTERM_MOD4_MASK; - - return mods; -} - static int uxkb_dev_process(struct kbd_dev *kbd, uint16_t key_state, uint16_t code, @@ -126,7 +104,7 @@ static int uxkb_dev_process(struct kbd_dev *kbd, */ out->keycode = code; out->keysym = keysyms[0]; - out->mods = get_effective_modmask(state); + out->mods = shl_get_xkb_mods(state); out->unicode = xkb_keysym_to_utf32(out->keysym) ? : UTERM_INPUT_INVALID; return 0; diff --git a/src/uterm_vt.c b/src/uterm_vt.c index 8f713af..a427ad4 100644 --- a/src/uterm_vt.c +++ b/src/uterm_vt.c @@ -419,7 +419,7 @@ static void vt_input(struct uterm_input *input, { struct uterm_vt *vt = data; - if (UTERM_INPUT_HAS_MODS(ev, UTERM_MOD4_MASK | UTERM_CONTROL_MASK)) { + if (UTERM_INPUT_HAS_MODS(ev, UTERM_LOGO_MASK | UTERM_CONTROL_MASK)) { if (ev->keysym == XKB_KEY_F12) { if (vt->active) { log_debug("deactivating fake VT due to user input"); diff --git a/src/wlt_toolkit.c b/src/wlt_toolkit.c index 37b07b0..0b11cf5 100644 --- a/src/wlt_toolkit.c +++ b/src/wlt_toolkit.c @@ -40,6 +40,7 @@ #include "log.h" #include "shl_dlist.h" #include "shl_hook.h" +#include "shl_misc.h" #include "tsm_vte.h" #include "wlt_toolkit.h" @@ -617,29 +618,6 @@ static void keyboard_leave(void *data, struct wl_keyboard *keyboard, ev_timer_update(disp->repeat_timer, NULL); } -static unsigned int get_effective_modmask(struct xkb_state *state) -{ - unsigned int mods = 0; - - if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_SHIFT, - XKB_STATE_EFFECTIVE)) - mods |= TSM_SHIFT_MASK; - if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CAPS, - XKB_STATE_EFFECTIVE)) - mods |= TSM_LOCK_MASK; - if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL, - XKB_STATE_EFFECTIVE)) - mods |= TSM_CONTROL_MASK; - if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT, - XKB_STATE_EFFECTIVE)) - mods |= TSM_MOD1_MASK; - if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_LOGO, - XKB_STATE_EFFECTIVE)) - mods |= TSM_MOD4_MASK; - - return mods; -} - static void keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state_w) @@ -663,7 +641,7 @@ static void keyboard_key(void *data, struct wl_keyboard *keyboard, if (!wnd) return; - mask = get_effective_modmask(disp->xkb_state); + mask = shl_get_xkb_mods(disp->xkb_state); num_syms = xkb_key_get_syms(disp->xkb_state, code, &syms); sym = XKB_KEY_NoSymbol; if (num_syms == 1) @@ -700,7 +678,7 @@ static void repeat_event(struct ev_timer *timer, uint64_t num, void *data) if (!wnd) return; - mask = get_effective_modmask(disp->xkb_state); + mask = shl_get_xkb_mods(disp->xkb_state); shl_dlist_for_each(iter, &wnd->widget_list) { widget = shl_dlist_entry(iter, struct wlt_widget, list); if (widget->keyboard_cb)