summaryrefslogtreecommitdiff
path: root/sway/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/config.c')
-rw-r--r--sway/config.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/sway/config.c b/sway/config.c
index e14ea83a..45d16758 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -33,6 +33,31 @@
struct sway_config *config = NULL;
+static struct keysym_translation_data new_keysym_translation_data(
+ const char *layout) {
+ struct xkb_rule_names rules = {
+ .layout = layout,
+ };
+
+ struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_names(
+ xkb_context_new(XKB_CONTEXT_NO_FLAGS),
+ &rules,
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
+
+ struct keysym_translation_data result = {
+ .xkb_keymap = xkb_keymap,
+ .xkb_state = xkb_state_new(xkb_keymap),
+ };
+
+ return result;
+}
+
+static void free_keysym_translation_data(
+ struct keysym_translation_data config) {
+ xkb_state_unref(config.xkb_state);
+ xkb_keymap_unref(config.xkb_keymap);
+}
+
static void free_mode(struct sway_mode *mode) {
if (!mode) {
return;
@@ -146,6 +171,7 @@ void free_config(struct sway_config *config) {
free(config->swaynag_command);
free((char *)config->current_config_path);
free((char *)config->current_config);
+ free_keysym_translation_data(config->keysym_translation);
free(config);
}
@@ -317,6 +343,9 @@ static void config_defaults(struct sway_config *config) {
if (!(config->feature_policies = create_list())) goto cleanup;
if (!(config->ipc_policies = create_list())) goto cleanup;
+ // The keysym to keycode translation
+ config->keysym_translation = new_keysym_translation_data(getenv("XKB_DEFAULT_LAYOUT"));
+
return;
cleanup:
sway_abort("Unable to allocate config structures");
@@ -937,3 +966,50 @@ void config_update_font_height(bool recalculate) {
arrange_root();
}
}
+
+static void translate_binding_list(list_t *bindings, list_t *bindsyms,
+ list_t *bindcodes) {
+ for (int i = 0; i < bindings->length; ++i) {
+ struct sway_binding *binding = bindings->items[i];
+ translate_binding(binding);
+
+ list_t *bindings;
+ switch (binding->type) {
+ case BINDING_KEYSYM:
+ bindings = bindsyms;
+ break;
+ case BINDING_KEYCODE:
+ bindings = bindcodes;
+ break;
+ default:
+ sway_assert(false, "unexpected translated binding type: %d",
+ binding->type);
+ break;
+ }
+
+ binding_add_translated(binding, bindings);
+ }
+}
+
+void translate_keysyms(const char *layout) {
+ free_keysym_translation_data(config->keysym_translation);
+ config->keysym_translation = new_keysym_translation_data(layout);
+
+ for (int i = 0; i < config->modes->length; ++i) {
+ struct sway_mode *mode = config->modes->items[i];
+
+ list_t *bindsyms = create_list();
+ list_t *bindcodes = create_list();
+
+ translate_binding_list(mode->keysym_bindings, bindsyms, bindcodes);
+ translate_binding_list(mode->keycode_bindings, bindsyms, bindcodes);
+
+ list_free(mode->keysym_bindings);
+ list_free(mode->keycode_bindings);
+
+ mode->keysym_bindings = bindsyms;
+ mode->keycode_bindings = bindcodes;
+ }
+
+ sway_log(SWAY_DEBUG, "Translated keysyms for layout %s", layout);
+}