diff options
author | Drew DeVault <sir@cmpwn.com> | 2017-09-23 18:32:03 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2017-09-23 18:32:03 -0400 |
commit | b84d59403fa8649817e84c486e701508f191c949 (patch) | |
tree | ee98da8284ff9a414618d17cf46b30695bb1b48d /rootston | |
parent | 0ca7932c3f23dddd7e8375a89e727223d665c8d5 (diff) |
Initial keyboard support in rootston
Diffstat (limited to 'rootston')
-rw-r--r-- | rootston/input.c | 2 | ||||
-rw-r--r-- | rootston/keyboard.c | 92 | ||||
-rw-r--r-- | rootston/meson.build | 1 |
3 files changed, 94 insertions, 1 deletions
diff --git a/rootston/input.c b/rootston/input.c index 4925226a..ac8e7396 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -31,7 +31,7 @@ static void input_add_notify(struct wl_listener *listener, void *data) { device->vendor, device->product, device_type(device->type)); switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - //keyboard_add(device, input); + keyboard_add(device, input); break; case WLR_INPUT_DEVICE_POINTER: pointer_add(device, input); diff --git a/rootston/keyboard.c b/rootston/keyboard.c new file mode 100644 index 00000000..54ae3f8f --- /dev/null +++ b/rootston/keyboard.c @@ -0,0 +1,92 @@ +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <wayland-server.h> +#include <wlr/types/wlr_input_device.h> +#include <wlr/types/wlr_pointer.h> +#include <wlr/backend/multi.h> +#include <wlr/backend/session.h> +#include <wlr/util/log.h> +#include <xkbcommon/xkbcommon.h> +#include "rootston/input.h" + +static void keyboard_led_update(struct roots_keyboard *keyboard) { + uint32_t leds = 0; + for (uint32_t i = 0; i < WLR_LED_LAST; ++i) { + if (xkb_state_led_index_is_active( + keyboard->xkb_state, keyboard->leds[i])) { + leds |= (1 << i); + } + } + wlr_keyboard_led_update(keyboard->device->keyboard, leds); +} + +static void keyboard_key_notify(struct wl_listener *listener, void *data) { + struct wlr_event_keyboard_key *event = data; + struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); + struct roots_input *input = keyboard->input; + struct roots_server *server = input->server; + uint32_t keycode = event->keycode + 8; + enum wlr_key_state key_state = event->state; + const xkb_keysym_t *syms; + int nsyms = xkb_state_key_get_syms(keyboard->xkb_state, keycode, &syms); + xkb_state_update_key(keyboard->xkb_state, keycode, + event->state == WLR_KEY_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP); + keyboard_led_update(keyboard); + for (int i = 0; i < nsyms; ++i) { + xkb_keysym_t sym = syms[i]; + char name[64]; + int l = xkb_keysym_get_name(sym, name, sizeof(name)); + if (l != -1 && l != sizeof(name)) { + wlr_log(L_DEBUG, "Key event: %s %s", name, + key_state == WLR_KEY_PRESSED ? "pressed" : "released"); + } + // TODO: pass key to clients + if (sym == XKB_KEY_Escape) { + // TEMPORARY, probably + wl_display_terminate(server->wl_display); + } else if (key_state == WLR_KEY_PRESSED && + sym >= XKB_KEY_XF86Switch_VT_1 && + sym <= XKB_KEY_XF86Switch_VT_12) { + if (wlr_backend_is_multi(server->backend)) { + struct wlr_session *session = + wlr_multi_get_session(server->backend); + if (session) { + wlr_session_change_vt(session, sym - XKB_KEY_XF86Switch_VT_1 + 1); + } + } + } + } +} + +void keyboard_add(struct wlr_input_device *device, struct roots_input *input) { + struct roots_keyboard *keyboard = calloc(sizeof(struct roots_keyboard), 1); + keyboard->device = device; + keyboard->input = input; + wl_list_init(&keyboard->key.link); + keyboard->key.notify = keyboard_key_notify; + wl_signal_add(&device->keyboard->events.key, &keyboard->key); + wl_list_insert(&input->keyboards, &keyboard->link); + + struct xkb_rule_names rules; + memset(&rules, 0, sizeof(rules)); + rules.rules = getenv("XKB_DEFAULT_RULES"); + rules.model = getenv("XKB_DEFAULT_MODEL"); + rules.layout = getenv("XKB_DEFAULT_LAYOUT"); + rules.variant = getenv("XKB_DEFAULT_VARIANT"); + rules.options = getenv("XKB_DEFAULT_OPTIONS"); + struct xkb_context *context; + assert(context = xkb_context_new(XKB_CONTEXT_NO_FLAGS)); + assert(keyboard->keymap = xkb_map_new_from_names(context, &rules, + XKB_KEYMAP_COMPILE_NO_FLAGS)); + xkb_context_unref(context); + assert(keyboard->xkb_state = xkb_state_new(keyboard->keymap)); + const char *led_names[3] = { + XKB_LED_NAME_NUM, + XKB_LED_NAME_CAPS, + XKB_LED_NAME_SCROLL + }; + for (uint32_t i = 0; i < 3; ++i) { + keyboard->leds[i] = xkb_map_led_get_index(keyboard->keymap, led_names[i]); + } +} diff --git a/rootston/meson.build b/rootston/meson.build index 7c0a7f8a..30ae1548 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -5,6 +5,7 @@ executable( 'desktop.c', 'ini.c', 'input.c', + 'keyboard.c', 'main.c', 'output.c', 'pointer.c', |