-rw-r--r-- src/keybind.c
1 #include "action.h" 2 #include "keybind.h" 3 #include "parse.h" 4 #include "types.h" 5 6 7 static struct dict mods[] = { 8 { "shift", WLR_MODIFIER_SHIFT }, 9 { "caps", WLR_MODIFIER_CAPS }, 10 { "ctrl", WLR_MODIFIER_CTRL }, 11 { "alt", WLR_MODIFIER_ALT }, 12 { "mod2", WLR_MODIFIER_MOD2 }, 13 { "mod3", WLR_MODIFIER_MOD3 }, 14 { "logo", WLR_MODIFIER_LOGO }, 15 { "mod5", WLR_MODIFIER_MOD5 }, 16 }; 17 18 19 static struct dict mouse_keys[] = { 20 { "motion", MOTION }, 21 { "scroll", SCROLL }, 22 { "drag1", DRAG1 }, 23 { "drag2", DRAG2 }, 24 { "drag3", DRAG3 }, 25 { "pinch", PINCH }, 26 }; 27 28 29 void free_binding(struct binding *kb) { 30 if (kb->data) 31 free(kb->data); 32 wl_list_remove(&kb->link); 33 free(kb); 34 } 35 36 37 void add_binding(char *message, char *response) { 38 char *s; 39 if (!(s = strtok(NULL, " \t\n\r"))) { 40 sprintf(response, "What do you want to bind?"); 41 return; 42 } 43 44 struct binding *kb = calloc(1, sizeof(struct binding)); 45 enum wlr_keyboard_modifier mod; 46 bool is_mouse_binding = false; 47 48 // additional modifiers 49 kb->mods = 0; 50 for (int i = 0; i < 8; i++) { 51 mod = get(mods, s); 52 if (mod == 0) 53 break; 54 kb->mods |= mod; 55 s = strtok(NULL, " \t\n\r"); 56 } 57 58 // key 59 kb->key = xkb_keysym_from_name(s, XKB_KEYSYM_NO_FLAGS); 60 if (kb->key == XKB_KEY_NoSymbol) { 61 kb->key = xkb_keysym_from_name(s, XKB_KEYSYM_CASE_INSENSITIVE); 62 } 63 64 if (kb->key == XKB_KEY_NoSymbol) { 65 kb->key = get(mouse_keys, s); 66 if (kb->key == 0) { 67 sprintf(response, "No such key '%s'.", s); 68 free(kb); 69 return; 70 } 71 is_mouse_binding = true; 72 } 73 74 // action 75 s = strtok(NULL, " \t\n\r"); 76 if (!s) { 77 sprintf(response, "Command malformed/incomplete."); 78 return; 79 } 80 if (!get_action(s, &kb->action, strtok(NULL, "\n\r"), &kb->data, response, kb->key)) { 81 free(kb); 82 return; 83 } 84 85 struct binding *kb_existing, *tmp; 86 struct wl_list *bindings; 87 if (is_mouse_binding) { 88 bindings = &wimp.mouse_bindings; 89 } else { 90 bindings = &wimp.key_bindings; 91 } 92 wl_list_for_each_safe(kb_existing, tmp, bindings, link) { 93 if (kb_existing->key == kb->key && kb_existing->mods == kb->mods) { 94 free_binding(kb_existing); 95 } 96 } 97 wl_list_insert(bindings->prev, &kb->link); 98 } 99 100 101 void set_mod(char *message, char *response) { 102 char *s = strtok(NULL, " \t\n\r"); 103 enum wlr_keyboard_modifier mod = get(mods, s); 104 if (mod) { 105 wimp.mod = mod; 106 } else { 107 sprintf(response, "Invalid modifier name '%s'.", s); 108 } 109 } 110