aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/bind.c
diff options
context:
space:
mode:
authorLibravatar Tony Crisci <tony@dubstepdish.com>2017-12-27 10:08:18 -0500
committerLibravatar Tony Crisci <tony@dubstepdish.com>2017-12-27 12:31:06 -0500
commitba69f06695c24f98a05d138a53ba130108ebce6f (patch)
treee36dac0c2088492117fb46404cad3a5fb28dffbe /sway/commands/bind.c
parentMerge pull request #1535 from martinetd/libinput (diff)
downloadsway-ba69f06695c24f98a05d138a53ba130108ebce6f.tar.gz
sway-ba69f06695c24f98a05d138a53ba130108ebce6f.tar.zst
sway-ba69f06695c24f98a05d138a53ba130108ebce6f.zip
binding config
Diffstat (limited to 'sway/commands/bind.c')
-rw-r--r--sway/commands/bind.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/sway/commands/bind.c b/sway/commands/bind.c
new file mode 100644
index 00000000..62aa535a
--- /dev/null
+++ b/sway/commands/bind.c
@@ -0,0 +1,173 @@
1#ifdef __linux__
2#include <linux/input-event-codes.h>
3#elif __FreeBSD__
4#include <dev/evdev/input-event-codes.h>
5#endif
6#include <xkbcommon/xkbcommon.h>
7#include <xkbcommon/xkbcommon-names.h>
8#include <strings.h>
9#include "sway/commands.h"
10#include "sway/config.h"
11#include "list.h"
12#include "log.h"
13#include "stringop.h"
14#include "util.h"
15
16int binding_order = 0;
17
18void free_sway_binding(struct sway_binding *binding) {
19 if (binding->keys) {
20 for (int i = 0; i < binding->keys->length; i++) {
21 free(binding->keys->items[i]);
22 }
23 list_free(binding->keys);
24 }
25 if (binding->command) {
26 free(binding->command);
27 }
28 free(binding);
29}
30
31struct cmd_results *cmd_bindsym(int argc, char **argv) {
32 struct cmd_results *error = NULL;
33 if ((error = checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1))) {
34 return error;
35 }
36
37 struct sway_binding *binding = malloc(sizeof(struct sway_binding));
38 if (!binding) {
39 return cmd_results_new(CMD_FAILURE, "bindsym",
40 "Unable to allocate binding");
41 }
42 binding->keys = create_list();
43 binding->modifiers = 0;
44 binding->release = false;
45 binding->bindcode = false;
46
47 // Handle --release
48 if (strcmp("--release", argv[0]) == 0) {
49 if (argc >= 3) {
50 binding->release = true;
51 argv++;
52 argc--;
53 } else {
54 free_sway_binding(binding);
55 return cmd_results_new(CMD_FAILURE, "bindsym",
56 "Invalid bindsym command "
57 "(expected more than 2 arguments, got %d)", argc);
58 }
59 }
60
61 binding->command = join_args(argv + 1, argc - 1);
62
63 list_t *split = split_string(argv[0], "+");
64 for (int i = 0; i < split->length; ++i) {
65 // Check for a modifier key
66 uint32_t mod;
67 if ((mod = get_modifier_mask_by_name(split->items[i])) > 0) {
68 binding->modifiers |= mod;
69 continue;
70 }
71 // Check for xkb key
72 xkb_keysym_t sym = xkb_keysym_from_name(split->items[i],
73 XKB_KEYSYM_CASE_INSENSITIVE);
74
75 // Check for mouse binding
76 if (strncasecmp(split->items[i], "button", strlen("button")) == 0 &&
77 strlen(split->items[i]) == strlen("button0")) {
78 sym = ((char *)split->items[i])[strlen("button")] - '1' + BTN_LEFT;
79 }
80 if (!sym) {
81 struct cmd_results *ret = cmd_results_new(CMD_INVALID, "bindsym",
82 "Unknown key '%s'", (char *)split->items[i]);
83 free_sway_binding(binding);
84 free_flat_list(split);
85 return ret;
86 }
87 xkb_keysym_t *key = malloc(sizeof(xkb_keysym_t));
88 if (!key) {
89 free_sway_binding(binding);
90 free_flat_list(split);
91 return cmd_results_new(CMD_FAILURE, "bindsym",
92 "Unable to allocate binding");
93 }
94 *key = sym;
95 list_add(binding->keys, key);
96 }
97 free_flat_list(split);
98
99 struct sway_mode *mode = config->current_mode;
100 // TODO overwrite the binding if it already exists
101 binding->order = binding_order++;
102 list_add(mode->keysym_bindings, binding);
103
104 sway_log(L_DEBUG, "bindsym - Bound %s to command %s",
105 argv[0], binding->command);
106 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
107}
108
109struct cmd_results *cmd_bindcode(int argc, char **argv) {
110 struct cmd_results *error = NULL;
111 if ((error = checkarg(argc, "bindcode", EXPECTED_MORE_THAN, 1))) {
112 return error;
113 }
114
115 struct sway_binding *binding = malloc(sizeof(struct sway_binding));
116 if (!binding) {
117 return cmd_results_new(CMD_FAILURE, "bindsym",
118 "Unable to allocate binding");
119 }
120 binding->keys = create_list();
121 binding->modifiers = 0;
122 binding->release = false;
123 binding->bindcode = true;
124
125 // Handle --release
126 if (strcmp("--release", argv[0]) == 0) {
127 if (argc >= 3) {
128 binding->release = true;
129 argv++;
130 argc--;
131 } else {
132 free_sway_binding(binding);
133 return cmd_results_new(CMD_FAILURE, "bindcode",
134 "Invalid bindcode command "
135 "(expected more than 2 arguments, got %d)", argc);
136 }
137 }
138
139 binding->command = join_args(argv + 1, argc - 1);
140
141 list_t *split = split_string(argv[0], "+");
142 for (int i = 0; i < split->length; ++i) {
143 // Check for a modifier key
144 uint32_t mod;
145 if ((mod = get_modifier_mask_by_name(split->items[i])) > 0) {
146 binding->modifiers |= mod;
147 continue;
148 }
149 // parse keycode
150 xkb_keycode_t keycode = (int)strtol(split->items[i], NULL, 10);
151 if (!xkb_keycode_is_legal_ext(keycode)) {
152 error =
153 cmd_results_new(CMD_INVALID, "bindcode",
154 "Invalid keycode '%s'", (char *)split->items[i]);
155 free_sway_binding(binding);
156 list_free(split);
157 return error;
158 }
159 xkb_keycode_t *key = malloc(sizeof(xkb_keycode_t));
160 *key = keycode - 8;
161 list_add(binding->keys, key);
162 }
163 free_flat_list(split);
164
165 struct sway_mode *mode = config->current_mode;
166 // TODO overwrite binding if it already exists
167 binding->order = binding_order++;
168 list_add(mode->keycode_bindings, binding);
169
170 sway_log(L_DEBUG, "bindcode - Bound %s to command %s",
171 argv[0], binding->command);
172 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
173}