swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

commit d50987538ff11a13a72f1f06d1538d99b46f9ee1
parent b752d5487c56c71ceee49caa5b74e58bff9cc48c
Author: Michael Forney <mforney@mforney.org>
Date:   Wed, 20 May 2015 05:05:51 +0000

Fold xkb.{c,h} into keyboard.{c,h}

Diffstat:
Mlibswc/keyboard.c | 111++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Mlibswc/keyboard.h | 22++++++++++++++++++++--
Mlibswc/local.mk | 1-
Dlibswc/xkb.c | 159-------------------------------------------------------------------------------
Dlibswc/xkb.h | 54------------------------------------------------------
5 files changed, 124 insertions(+), 223 deletions(-)

diff --git a/libswc/keyboard.c b/libswc/keyboard.c @@ -33,11 +33,15 @@ #include "util.h" #include <assert.h> +#include <fcntl.h> #include <stdio.h> #include <string.h> +#include <sys/mman.h> +#include <unistd.h> #include <xkbcommon/xkbcommon.h> static const int repeat_delay = 500, repeat_rate = 40; +static const char keymap_file_template[] = "swc-xkb-keymap-XXXXXX"; static void enter(struct input_focus_handler *handler, struct wl_resource *resource, struct compositor_view *view) @@ -103,16 +107,91 @@ client_handle_modifiers(struct keyboard *keyboard, const struct keyboard_modifie return true; } +static bool +update_keymap(struct xkb *xkb) +{ + const char *keymap_directory = getenv("XDG_RUNTIME_DIR") ?: "/tmp"; + char *keymap_string; + char keymap_path[strlen(keymap_directory) + 1 + sizeof keymap_file_template]; + + xkb->indices.ctrl = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_CTRL); + xkb->indices.alt = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_ALT); + xkb->indices.super = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_LOGO); + xkb->indices.shift = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_SHIFT); + + /* In order to send the keymap to clients, we must first convert it to a + * string and then mmap it to a file. */ + keymap_string = xkb_keymap_get_as_string(xkb->keymap.map, XKB_KEYMAP_FORMAT_TEXT_V1); + + if (!keymap_string) { + WARNING("Could not get XKB keymap as a string\n"); + goto error0; + } + + sprintf(keymap_path, "%s/%s", keymap_directory, keymap_file_template); + + xkb->keymap.size = strlen(keymap_string) + 1; + xkb->keymap.fd = mkostemp(keymap_path, O_CLOEXEC); + + if (xkb->keymap.fd == -1) { + WARNING("Could not create XKB keymap file\n"); + goto error1; + } + + unlink(keymap_path); + + if (posix_fallocate(xkb->keymap.fd, 0, xkb->keymap.size) != 0) { + WARNING("Could not resize XKB keymap file\n"); + goto error2; + } + + xkb->keymap.area = mmap(NULL, xkb->keymap.size, PROT_READ | PROT_WRITE, MAP_SHARED, xkb->keymap.fd, 0); + + if (xkb->keymap.area == MAP_FAILED) { + WARNING("Could not mmap XKB keymap string\n"); + goto error2; + } + + strcpy(xkb->keymap.area, keymap_string); + free(keymap_string); + + return true; + +error2: + close(xkb->keymap.fd); +error1: + free(keymap_string); +error0: + return false; +} + bool keyboard_initialize(struct keyboard *keyboard) { - if (!xkb_initialize(&keyboard->xkb)) { - ERROR("Could not initialize XKB\n"); + struct xkb *xkb = &keyboard->xkb; + + if (!(xkb->context = xkb_context_new(0))) { + ERROR("Could not create XKB context\n"); goto error0; } - if (!input_focus_initialize(&keyboard->focus, &keyboard->focus_handler)) + if (!(xkb->keymap.map = xkb_keymap_new_from_names(xkb->context, NULL, 0))) { + ERROR("Could not create XKB keymap\n"); goto error1; + } + + if (!(xkb->state = xkb_state_new(xkb->keymap.map))) { + ERROR("Could not create XKB state\n"); + goto error2; + } + + if (!update_keymap(xkb)) { + ERROR("Could not update XKB keymap\n"); + goto error3; + } + + if (!input_focus_initialize(&keyboard->focus, &keyboard->focus_handler)) + goto error3; keyboard->modifier_state = (struct keyboard_modifier_state){}; keyboard->modifiers = 0; @@ -127,8 +206,12 @@ keyboard_initialize(struct keyboard *keyboard) return true; +error3: + xkb_state_unref(keyboard->xkb.state); +error2: + xkb_keymap_unref(keyboard->xkb.keymap.map); error1: - xkb_finalize(&keyboard->xkb); + xkb_context_unref(keyboard->xkb.context); error0: return false; } @@ -139,14 +222,19 @@ keyboard_finalize(struct keyboard *keyboard) wl_array_release(&keyboard->client_keys); wl_array_release(&keyboard->keys); input_focus_finalize(&keyboard->focus); - xkb_finalize(&keyboard->xkb); + munmap(keyboard->xkb.keymap.area, keyboard->xkb.keymap.size); + close(keyboard->xkb.keymap.fd); + xkb_state_unref(keyboard->xkb.state); + xkb_keymap_unref(keyboard->xkb.keymap.map); + xkb_context_unref(keyboard->xkb.context); } -void +bool keyboard_reset(struct keyboard *keyboard) { struct key *key; uint32_t time = get_time(); + struct xkb_state *state; /* Send simulated key release events for all current key handlers. */ wl_array_for_each (key, &keyboard->keys) { @@ -165,7 +253,16 @@ keyboard_reset(struct keyboard *keyboard) keyboard->keys.size = 0; keyboard->modifier_state = (struct keyboard_modifier_state){}; keyboard->modifiers = 0; - xkb_reset_state(&keyboard->xkb); + + if (!(state = xkb_state_new(keyboard->xkb.keymap.map))) { + ERROR("Failed to allocate new XKB state\n"); + return false; + } + + xkb_state_unref(keyboard->xkb.state); + keyboard->xkb.state = state; + + return true; } /** diff --git a/libswc/keyboard.h b/libswc/keyboard.h @@ -25,10 +25,12 @@ #define SWC_KEYBOARD_H #include "input.h" -#include "xkb.h" #include <wayland-util.h> +/* Keycodes are offset by 8 in XKB. */ +#define XKB_KEY(key) ((key) + 8) + struct keyboard; struct wl_client; @@ -51,6 +53,22 @@ struct keyboard_handler { struct wl_list link; }; +struct xkb { + struct xkb_context *context; + struct xkb_state *state; + + struct { + struct xkb_keymap *map; + int fd; + uint32_t size; + char *area; + } keymap; + + struct { + uint32_t ctrl, alt, super, shift; + } indices; +}; + struct keyboard { struct input_focus focus; struct input_focus_handler focus_handler; @@ -67,7 +85,7 @@ struct keyboard { bool keyboard_initialize(struct keyboard *keyboard); void keyboard_finalize(struct keyboard *keyboard); -void keyboard_reset(struct keyboard *keyboard); +bool keyboard_reset(struct keyboard *keyboard); void keyboard_set_focus(struct keyboard *keyboard, struct compositor_view *view); struct wl_resource *keyboard_bind(struct keyboard *keyboard, struct wl_client *client, uint32_t version, uint32_t id); void keyboard_handle_key(struct keyboard *keyboard, uint32_t time, uint32_t key, uint32_t state); diff --git a/libswc/local.mk b/libswc/local.mk @@ -54,7 +54,6 @@ SWC_SOURCES = \ libswc/xdg_popup.c \ libswc/xdg_shell.c \ libswc/xdg_surface.c \ - libswc/xkb.c \ protocol/swc-protocol.c \ protocol/wayland-drm-protocol.c \ protocol/xdg-shell-protocol.c diff --git a/libswc/xkb.c b/libswc/xkb.c @@ -1,159 +0,0 @@ -/* swc: libswc/xkb.c - * - * Copyright (c) 2013, 2014 Michael Forney - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "xkb.h" -#include "util.h" - -#include <stdlib.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <sys/mman.h> -#include <xkbcommon/xkbcommon.h> - -static const char keymap_file_template[] = "swc-xkb-keymap-XXXXXX"; - -bool -xkb_initialize(struct xkb *xkb) -{ - xkb->context = xkb_context_new(0); - - if (!xkb->context) { - ERROR("Could not create XKB context\n"); - goto error0; - } - - xkb->keymap.map = xkb_keymap_new_from_names(xkb->context, NULL, 0); - - if (!xkb->keymap.map) { - ERROR("Could not create XKB keymap\n"); - goto error1; - } - - xkb->state = xkb_state_new(xkb->keymap.map); - - if (!xkb->state) { - ERROR("Could not create XKB state\n"); - goto error2; - } - - if (!xkb_update_keymap(xkb)) { - ERROR("Could not update XKB keymap\n"); - goto error3; - } - - return true; - -error3: - xkb_state_unref(xkb->state); -error2: - xkb_keymap_unref(xkb->keymap.map); -error1: - xkb_context_unref(xkb->context); -error0: - return false; -} - -void -xkb_finalize(struct xkb *xkb) -{ - munmap(xkb->keymap.area, xkb->keymap.size); - close(xkb->keymap.fd); - xkb_state_unref(xkb->state); - xkb_keymap_unref(xkb->keymap.map); - xkb_context_unref(xkb->context); -} - -bool -xkb_reset_state(struct xkb *xkb) -{ - struct xkb_state *state; - - if (!(state = xkb_state_new(xkb->keymap.map))) { - ERROR("Failed to allocate new XKB state\n"); - return false; - } - - xkb_state_unref(xkb->state); - xkb->state = state; - return true; -} - -bool -xkb_update_keymap(struct xkb *xkb) -{ - const char *keymap_directory = getenv("XDG_RUNTIME_DIR") ?: "/tmp"; - char *keymap_string; - char keymap_path[strlen(keymap_directory) + 1 + sizeof keymap_file_template]; - - xkb->indices.ctrl = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_CTRL); - xkb->indices.alt = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_ALT); - xkb->indices.super = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_LOGO); - xkb->indices.shift = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_SHIFT); - - /* In order to send the keymap to clients, we must first convert it to a - * string and then mmap it to a file. */ - keymap_string = xkb_keymap_get_as_string(xkb->keymap.map, XKB_KEYMAP_FORMAT_TEXT_V1); - - if (!keymap_string) { - WARNING("Could not get XKB keymap as a string\n"); - goto error0; - } - - sprintf(keymap_path, "%s/%s", keymap_directory, keymap_file_template); - - xkb->keymap.size = strlen(keymap_string) + 1; - xkb->keymap.fd = mkostemp(keymap_path, O_CLOEXEC); - - if (xkb->keymap.fd == -1) { - WARNING("Could not create XKB keymap file\n"); - goto error1; - } - - unlink(keymap_path); - - if (posix_fallocate(xkb->keymap.fd, 0, xkb->keymap.size) != 0) { - WARNING("Could not resize XKB keymap file\n"); - goto error2; - } - - xkb->keymap.area = mmap(NULL, xkb->keymap.size, PROT_READ | PROT_WRITE, MAP_SHARED, xkb->keymap.fd, 0); - - if (xkb->keymap.area == MAP_FAILED) { - WARNING("Could not mmap XKB keymap string\n"); - goto error2; - } - - strcpy(xkb->keymap.area, keymap_string); - - free(keymap_string); - - return true; - -error2: - close(xkb->keymap.fd); -error1: - free(keymap_string); -error0: - return false; -} diff --git a/libswc/xkb.h b/libswc/xkb.h @@ -1,54 +0,0 @@ -/* swc: libswc/xkb.h - * - * Copyright (c) 2013, 2014 Michael Forney - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef SWC_XKB_H -#define SWC_XKB_H - -#include <stdbool.h> -#include <stdint.h> - -/* Keycodes are offset by 8 in XKB. */ -#define XKB_KEY(key) ((key) + 8) - -struct xkb { - struct xkb_context *context; - struct xkb_state *state; - - struct { - struct xkb_keymap *map; - int fd; - uint32_t size; - char *area; - } keymap; - - struct { - uint32_t ctrl, alt, super, shift; - } indices; -}; - -bool xkb_initialize(struct xkb *xkb); -void xkb_finalize(struct xkb *xkb); -bool xkb_reset_state(struct xkb *xkb); -bool xkb_update_keymap(struct xkb *xkb); - -#endif