#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <xkbcommon/xkbcommon.h>
#include "conf.h"
#include "log.h"
+#include "shl_misc.h"
#define LOG_SUBSYSTEM "config"
*(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,
.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)
{
#include <stdbool.h>
#include <stdlib.h>
+/* parsed types */
+
+struct conf_grab {
+ unsigned int mods;
+ uint32_t keysym;
+};
+
/* configuration parser */
struct conf_type;
_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);
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,
#include <stdlib.h>
#include <string.h>
#include <sys/signalfd.h>
-#include <xkbcommon/xkbcommon-keysyms.h>
#include "conf.h"
#include "eloop.h"
#include "log.h"
*/
}
-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/";
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,
};
#include <stdbool.h>
#include <stdlib.h>
-#include "uterm.h"
+#include "conf.h"
struct kmscon_conf_t {
/* show help/usage information */
/* 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;
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
+#include <xkbcommon/xkbcommon.h>
-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;
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 */
* 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) {
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,
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 {
#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);
[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)
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;
}
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)
#include <string.h>
#include <xkbcommon/xkbcommon.h>
#include "log.h"
+#include "shl_misc.h"
#include "uterm.h"
#include "uterm_input.h"
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,
*/
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;
{
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");
#include "log.h"
#include "shl_dlist.h"
#include "shl_hook.h"
+#include "shl_misc.h"
#include "tsm_vte.h"
#include "wlt_toolkit.h"
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)
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)
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)