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 @@ // Any value will hide SOCK_CLOEXEC on FreeBSD (__BSD_VISIBLE=0) #define _XOPEN_SOURCE 700 #endif +#ifdef __linux__ +#include <linux/input-event-codes.h> +#elif __FreeBSD__ +#include <dev/evdev/input-event-codes.h> +#endif #include <assert.h> #include <errno.h> #include <fcntl.h> #include <json-c/json.h> #include <stdbool.h> #include <stdint.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> @@ -28,6 +34,7 @@ #include "sway/tree/view.h" #include "list.h" #include "log.h" +#include "util.h" static int ipc_socket = -1; static struct wl_event_source *ipc_event_source = NULL; @@ -367,6 +374,75 @@ void ipc_event_shutdown(const char *reason) { json_object_put(json); } +void ipc_event_binding(struct sway_binding *binding) { + if (!ipc_has_event_listeners(IPC_EVENT_BINDING)) { + return; + } + wlr_log(WLR_DEBUG, "Sending binding event"); + + json_object *json_binding = json_object_new_object(); + json_object_object_add(json_binding, "command", json_object_new_string(binding->command)); + + const char *names[10]; + int len = get_modifier_names(names, binding->modifiers); + json_object *modifiers = json_object_new_array(); + for (int i = 0; i < len; ++i) { + json_object_array_add(modifiers, json_object_new_string(names[i])); + } + json_object_object_add(json_binding, "event_state_mask", modifiers); + + json_object *input_codes = json_object_new_array(); + int input_code = 0; + json_object *symbols = json_object_new_array(); + json_object *symbol = NULL; + + if (binding->type == BINDING_KEYCODE) { // bindcode: populate input_codes + uint32_t keycode; + for (int i = 0; i < binding->keys->length; ++i) { + keycode = *(uint32_t *)binding->keys->items[i]; + json_object_array_add(input_codes, json_object_new_int(keycode)); + if (i == 0) { + input_code = keycode; + } + } + } else { // bindsym/mouse: populate symbols + uint32_t keysym; + char buffer[64]; + for (int i = 0; i < binding->keys->length; ++i) { + keysym = *(uint32_t *)binding->keys->items[i]; + if (keysym >= BTN_LEFT && keysym <= BTN_LEFT + 8) { + snprintf(buffer, 64, "button%u", keysym - BTN_LEFT + 1); + } else if (xkb_keysym_get_name(keysym, buffer, 64) < 0) { + continue; + } + + json_object *str = json_object_new_string(buffer); + if (i == 0) { + // str is owned by both symbol and symbols. Make sure + // to bump the ref count. + json_object_array_add(symbols, json_object_get(str)); + symbol = str; + } else { + json_object_array_add(symbols, str); + } + } + } + + json_object_object_add(json_binding, "input_codes", input_codes); + json_object_object_add(json_binding, "input_code", json_object_new_int(input_code)); + json_object_object_add(json_binding, "symbols", symbols); + json_object_object_add(json_binding, "symbol", symbol); + json_object_object_add(json_binding, "input_type", binding->type == BINDING_MOUSE ? + json_object_new_string("mouse") : json_object_new_string("keyboard")); + + json_object *json = json_object_new_object(); + json_object_object_add(json, "change", json_object_new_string("run")); + json_object_object_add(json, "binding", json_binding); + const char *json_string = json_object_to_json_string(json); + ipc_send_event(json_string, IPC_EVENT_BINDING); + json_object_put(json); +} + int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { struct ipc_client *client = data; |