diff options
Diffstat (limited to 'sway/ipc-server.c')
-rw-r--r-- | sway/ipc-server.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 72031e24..8fceafa2 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c | |||
@@ -3,12 +3,18 @@ | |||
3 | // Any value will hide SOCK_CLOEXEC on FreeBSD (__BSD_VISIBLE=0) | 3 | // Any value will hide SOCK_CLOEXEC on FreeBSD (__BSD_VISIBLE=0) |
4 | #define _XOPEN_SOURCE 700 | 4 | #define _XOPEN_SOURCE 700 |
5 | #endif | 5 | #endif |
6 | #ifdef __linux__ | ||
7 | #include <linux/input-event-codes.h> | ||
8 | #elif __FreeBSD__ | ||
9 | #include <dev/evdev/input-event-codes.h> | ||
10 | #endif | ||
6 | #include <assert.h> | 11 | #include <assert.h> |
7 | #include <errno.h> | 12 | #include <errno.h> |
8 | #include <fcntl.h> | 13 | #include <fcntl.h> |
9 | #include <json-c/json.h> | 14 | #include <json-c/json.h> |
10 | #include <stdbool.h> | 15 | #include <stdbool.h> |
11 | #include <stdint.h> | 16 | #include <stdint.h> |
17 | #include <stdio.h> | ||
12 | #include <stdlib.h> | 18 | #include <stdlib.h> |
13 | #include <string.h> | 19 | #include <string.h> |
14 | #include <sys/socket.h> | 20 | #include <sys/socket.h> |
@@ -28,6 +34,7 @@ | |||
28 | #include "sway/tree/view.h" | 34 | #include "sway/tree/view.h" |
29 | #include "list.h" | 35 | #include "list.h" |
30 | #include "log.h" | 36 | #include "log.h" |
37 | #include "util.h" | ||
31 | 38 | ||
32 | static int ipc_socket = -1; | 39 | static int ipc_socket = -1; |
33 | static struct wl_event_source *ipc_event_source = NULL; | 40 | static struct wl_event_source *ipc_event_source = NULL; |
@@ -367,6 +374,75 @@ void ipc_event_shutdown(const char *reason) { | |||
367 | json_object_put(json); | 374 | json_object_put(json); |
368 | } | 375 | } |
369 | 376 | ||
377 | void ipc_event_binding(struct sway_binding *binding) { | ||
378 | if (!ipc_has_event_listeners(IPC_EVENT_BINDING)) { | ||
379 | return; | ||
380 | } | ||
381 | wlr_log(WLR_DEBUG, "Sending binding event"); | ||
382 | |||
383 | json_object *json_binding = json_object_new_object(); | ||
384 | json_object_object_add(json_binding, "command", json_object_new_string(binding->command)); | ||
385 | |||
386 | const char *names[10]; | ||
387 | int len = get_modifier_names(names, binding->modifiers); | ||
388 | json_object *modifiers = json_object_new_array(); | ||
389 | for (int i = 0; i < len; ++i) { | ||
390 | json_object_array_add(modifiers, json_object_new_string(names[i])); | ||
391 | } | ||
392 | json_object_object_add(json_binding, "event_state_mask", modifiers); | ||
393 | |||
394 | json_object *input_codes = json_object_new_array(); | ||
395 | int input_code = 0; | ||
396 | json_object *symbols = json_object_new_array(); | ||
397 | json_object *symbol = NULL; | ||
398 | |||
399 | if (binding->type == BINDING_KEYCODE) { // bindcode: populate input_codes | ||
400 | uint32_t keycode; | ||
401 | for (int i = 0; i < binding->keys->length; ++i) { | ||
402 | keycode = *(uint32_t *)binding->keys->items[i]; | ||
403 | json_object_array_add(input_codes, json_object_new_int(keycode)); | ||
404 | if (i == 0) { | ||
405 | input_code = keycode; | ||
406 | } | ||
407 | } | ||
408 | } else { // bindsym/mouse: populate symbols | ||
409 | uint32_t keysym; | ||
410 | char buffer[64]; | ||
411 | for (int i = 0; i < binding->keys->length; ++i) { | ||
412 | keysym = *(uint32_t *)binding->keys->items[i]; | ||
413 | if (keysym >= BTN_LEFT && keysym <= BTN_LEFT + 8) { | ||
414 | snprintf(buffer, 64, "button%u", keysym - BTN_LEFT + 1); | ||
415 | } else if (xkb_keysym_get_name(keysym, buffer, 64) < 0) { | ||
416 | continue; | ||
417 | } | ||
418 | |||
419 | json_object *str = json_object_new_string(buffer); | ||
420 | if (i == 0) { | ||
421 | // str is owned by both symbol and symbols. Make sure | ||
422 | // to bump the ref count. | ||
423 | json_object_array_add(symbols, json_object_get(str)); | ||
424 | symbol = str; | ||
425 | } else { | ||
426 | json_object_array_add(symbols, str); | ||
427 | } | ||
428 | } | ||
429 | } | ||
430 | |||
431 | json_object_object_add(json_binding, "input_codes", input_codes); | ||
432 | json_object_object_add(json_binding, "input_code", json_object_new_int(input_code)); | ||
433 | json_object_object_add(json_binding, "symbols", symbols); | ||
434 | json_object_object_add(json_binding, "symbol", symbol); | ||
435 | json_object_object_add(json_binding, "input_type", binding->type == BINDING_MOUSE ? | ||
436 | json_object_new_string("mouse") : json_object_new_string("keyboard")); | ||
437 | |||
438 | json_object *json = json_object_new_object(); | ||
439 | json_object_object_add(json, "change", json_object_new_string("run")); | ||
440 | json_object_object_add(json, "binding", json_binding); | ||
441 | const char *json_string = json_object_to_json_string(json); | ||
442 | ipc_send_event(json_string, IPC_EVENT_BINDING); | ||
443 | json_object_put(json); | ||
444 | } | ||
445 | |||
370 | int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { | 446 | int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { |
371 | struct ipc_client *client = data; | 447 | struct ipc_client *client = data; |
372 | 448 | ||