commit d509875
Michael Forney
·
2015-05-20 05:05:51 +0000 UTC
parent b752d54
Fold xkb.{c,h} into keyboard.{c,h}
5 files changed,
+124,
-223
+104,
-7
1@@ -33,11 +33,15 @@
2 #include "util.h"
3
4 #include <assert.h>
5+#include <fcntl.h>
6 #include <stdio.h>
7 #include <string.h>
8+#include <sys/mman.h>
9+#include <unistd.h>
10 #include <xkbcommon/xkbcommon.h>
11
12 static const int repeat_delay = 500, repeat_rate = 40;
13+static const char keymap_file_template[] = "swc-xkb-keymap-XXXXXX";
14
15 static void
16 enter(struct input_focus_handler *handler, struct wl_resource *resource, struct compositor_view *view)
17@@ -103,16 +107,91 @@ client_handle_modifiers(struct keyboard *keyboard, const struct keyboard_modifie
18 return true;
19 }
20
21+static bool
22+update_keymap(struct xkb *xkb)
23+{
24+ const char *keymap_directory = getenv("XDG_RUNTIME_DIR") ?: "/tmp";
25+ char *keymap_string;
26+ char keymap_path[strlen(keymap_directory) + 1 + sizeof keymap_file_template];
27+
28+ xkb->indices.ctrl = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_CTRL);
29+ xkb->indices.alt = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_ALT);
30+ xkb->indices.super = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_LOGO);
31+ xkb->indices.shift = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_SHIFT);
32+
33+ /* In order to send the keymap to clients, we must first convert it to a
34+ * string and then mmap it to a file. */
35+ keymap_string = xkb_keymap_get_as_string(xkb->keymap.map, XKB_KEYMAP_FORMAT_TEXT_V1);
36+
37+ if (!keymap_string) {
38+ WARNING("Could not get XKB keymap as a string\n");
39+ goto error0;
40+ }
41+
42+ sprintf(keymap_path, "%s/%s", keymap_directory, keymap_file_template);
43+
44+ xkb->keymap.size = strlen(keymap_string) + 1;
45+ xkb->keymap.fd = mkostemp(keymap_path, O_CLOEXEC);
46+
47+ if (xkb->keymap.fd == -1) {
48+ WARNING("Could not create XKB keymap file\n");
49+ goto error1;
50+ }
51+
52+ unlink(keymap_path);
53+
54+ if (posix_fallocate(xkb->keymap.fd, 0, xkb->keymap.size) != 0) {
55+ WARNING("Could not resize XKB keymap file\n");
56+ goto error2;
57+ }
58+
59+ xkb->keymap.area = mmap(NULL, xkb->keymap.size, PROT_READ | PROT_WRITE, MAP_SHARED, xkb->keymap.fd, 0);
60+
61+ if (xkb->keymap.area == MAP_FAILED) {
62+ WARNING("Could not mmap XKB keymap string\n");
63+ goto error2;
64+ }
65+
66+ strcpy(xkb->keymap.area, keymap_string);
67+ free(keymap_string);
68+
69+ return true;
70+
71+error2:
72+ close(xkb->keymap.fd);
73+error1:
74+ free(keymap_string);
75+error0:
76+ return false;
77+}
78+
79 bool
80 keyboard_initialize(struct keyboard *keyboard)
81 {
82- if (!xkb_initialize(&keyboard->xkb)) {
83- ERROR("Could not initialize XKB\n");
84+ struct xkb *xkb = &keyboard->xkb;
85+
86+ if (!(xkb->context = xkb_context_new(0))) {
87+ ERROR("Could not create XKB context\n");
88 goto error0;
89 }
90
91- if (!input_focus_initialize(&keyboard->focus, &keyboard->focus_handler))
92+ if (!(xkb->keymap.map = xkb_keymap_new_from_names(xkb->context, NULL, 0))) {
93+ ERROR("Could not create XKB keymap\n");
94 goto error1;
95+ }
96+
97+ if (!(xkb->state = xkb_state_new(xkb->keymap.map))) {
98+ ERROR("Could not create XKB state\n");
99+ goto error2;
100+ }
101+
102+ if (!update_keymap(xkb)) {
103+ ERROR("Could not update XKB keymap\n");
104+ goto error3;
105+ }
106+
107+ if (!input_focus_initialize(&keyboard->focus, &keyboard->focus_handler))
108+ goto error3;
109
110 keyboard->modifier_state = (struct keyboard_modifier_state){};
111 keyboard->modifiers = 0;
112@@ -127,8 +206,12 @@ keyboard_initialize(struct keyboard *keyboard)
113
114 return true;
115
116+error3:
117+ xkb_state_unref(keyboard->xkb.state);
118+error2:
119+ xkb_keymap_unref(keyboard->xkb.keymap.map);
120 error1:
121- xkb_finalize(&keyboard->xkb);
122+ xkb_context_unref(keyboard->xkb.context);
123 error0:
124 return false;
125 }
126@@ -139,14 +222,19 @@ keyboard_finalize(struct keyboard *keyboard)
127 wl_array_release(&keyboard->client_keys);
128 wl_array_release(&keyboard->keys);
129 input_focus_finalize(&keyboard->focus);
130- xkb_finalize(&keyboard->xkb);
131+ munmap(keyboard->xkb.keymap.area, keyboard->xkb.keymap.size);
132+ close(keyboard->xkb.keymap.fd);
133+ xkb_state_unref(keyboard->xkb.state);
134+ xkb_keymap_unref(keyboard->xkb.keymap.map);
135+ xkb_context_unref(keyboard->xkb.context);
136 }
137
138-void
139+bool
140 keyboard_reset(struct keyboard *keyboard)
141 {
142 struct key *key;
143 uint32_t time = get_time();
144+ struct xkb_state *state;
145
146 /* Send simulated key release events for all current key handlers. */
147 wl_array_for_each (key, &keyboard->keys) {
148@@ -165,7 +253,16 @@ keyboard_reset(struct keyboard *keyboard)
149 keyboard->keys.size = 0;
150 keyboard->modifier_state = (struct keyboard_modifier_state){};
151 keyboard->modifiers = 0;
152- xkb_reset_state(&keyboard->xkb);
153+
154+ if (!(state = xkb_state_new(keyboard->xkb.keymap.map))) {
155+ ERROR("Failed to allocate new XKB state\n");
156+ return false;
157+ }
158+
159+ xkb_state_unref(keyboard->xkb.state);
160+ keyboard->xkb.state = state;
161+
162+ return true;
163 }
164
165 /**
+20,
-2
1@@ -25,10 +25,12 @@
2 #define SWC_KEYBOARD_H
3
4 #include "input.h"
5-#include "xkb.h"
6
7 #include <wayland-util.h>
8
9+/* Keycodes are offset by 8 in XKB. */
10+#define XKB_KEY(key) ((key) + 8)
11+
12 struct keyboard;
13 struct wl_client;
14
15@@ -51,6 +53,22 @@ struct keyboard_handler {
16 struct wl_list link;
17 };
18
19+struct xkb {
20+ struct xkb_context *context;
21+ struct xkb_state *state;
22+
23+ struct {
24+ struct xkb_keymap *map;
25+ int fd;
26+ uint32_t size;
27+ char *area;
28+ } keymap;
29+
30+ struct {
31+ uint32_t ctrl, alt, super, shift;
32+ } indices;
33+};
34+
35 struct keyboard {
36 struct input_focus focus;
37 struct input_focus_handler focus_handler;
38@@ -67,7 +85,7 @@ struct keyboard {
39
40 bool keyboard_initialize(struct keyboard *keyboard);
41 void keyboard_finalize(struct keyboard *keyboard);
42-void keyboard_reset(struct keyboard *keyboard);
43+bool keyboard_reset(struct keyboard *keyboard);
44 void keyboard_set_focus(struct keyboard *keyboard, struct compositor_view *view);
45 struct wl_resource *keyboard_bind(struct keyboard *keyboard, struct wl_client *client, uint32_t version, uint32_t id);
46 void keyboard_handle_key(struct keyboard *keyboard, uint32_t time, uint32_t key, uint32_t state);
+0,
-1
1@@ -54,7 +54,6 @@ SWC_SOURCES = \
2 libswc/xdg_popup.c \
3 libswc/xdg_shell.c \
4 libswc/xdg_surface.c \
5- libswc/xkb.c \
6 protocol/swc-protocol.c \
7 protocol/wayland-drm-protocol.c \
8 protocol/xdg-shell-protocol.c
+0,
-159
1@@ -1,159 +0,0 @@
2-/* swc: libswc/xkb.c
3- *
4- * Copyright (c) 2013, 2014 Michael Forney
5- *
6- * Permission is hereby granted, free of charge, to any person obtaining a copy
7- * of this software and associated documentation files (the "Software"), to deal
8- * in the Software without restriction, including without limitation the rights
9- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10- * copies of the Software, and to permit persons to whom the Software is
11- * furnished to do so, subject to the following conditions:
12- *
13- * The above copyright notice and this permission notice shall be included in
14- * all copies or substantial portions of the Software.
15- *
16- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22- * SOFTWARE.
23- */
24-
25-#include "xkb.h"
26-#include "util.h"
27-
28-#include <stdlib.h>
29-#include <fcntl.h>
30-#include <unistd.h>
31-#include <string.h>
32-#include <sys/mman.h>
33-#include <xkbcommon/xkbcommon.h>
34-
35-static const char keymap_file_template[] = "swc-xkb-keymap-XXXXXX";
36-
37-bool
38-xkb_initialize(struct xkb *xkb)
39-{
40- xkb->context = xkb_context_new(0);
41-
42- if (!xkb->context) {
43- ERROR("Could not create XKB context\n");
44- goto error0;
45- }
46-
47- xkb->keymap.map = xkb_keymap_new_from_names(xkb->context, NULL, 0);
48-
49- if (!xkb->keymap.map) {
50- ERROR("Could not create XKB keymap\n");
51- goto error1;
52- }
53-
54- xkb->state = xkb_state_new(xkb->keymap.map);
55-
56- if (!xkb->state) {
57- ERROR("Could not create XKB state\n");
58- goto error2;
59- }
60-
61- if (!xkb_update_keymap(xkb)) {
62- ERROR("Could not update XKB keymap\n");
63- goto error3;
64- }
65-
66- return true;
67-
68-error3:
69- xkb_state_unref(xkb->state);
70-error2:
71- xkb_keymap_unref(xkb->keymap.map);
72-error1:
73- xkb_context_unref(xkb->context);
74-error0:
75- return false;
76-}
77-
78-void
79-xkb_finalize(struct xkb *xkb)
80-{
81- munmap(xkb->keymap.area, xkb->keymap.size);
82- close(xkb->keymap.fd);
83- xkb_state_unref(xkb->state);
84- xkb_keymap_unref(xkb->keymap.map);
85- xkb_context_unref(xkb->context);
86-}
87-
88-bool
89-xkb_reset_state(struct xkb *xkb)
90-{
91- struct xkb_state *state;
92-
93- if (!(state = xkb_state_new(xkb->keymap.map))) {
94- ERROR("Failed to allocate new XKB state\n");
95- return false;
96- }
97-
98- xkb_state_unref(xkb->state);
99- xkb->state = state;
100- return true;
101-}
102-
103-bool
104-xkb_update_keymap(struct xkb *xkb)
105-{
106- const char *keymap_directory = getenv("XDG_RUNTIME_DIR") ?: "/tmp";
107- char *keymap_string;
108- char keymap_path[strlen(keymap_directory) + 1 + sizeof keymap_file_template];
109-
110- xkb->indices.ctrl = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_CTRL);
111- xkb->indices.alt = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_ALT);
112- xkb->indices.super = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_LOGO);
113- xkb->indices.shift = xkb_keymap_mod_get_index(xkb->keymap.map, XKB_MOD_NAME_SHIFT);
114-
115- /* In order to send the keymap to clients, we must first convert it to a
116- * string and then mmap it to a file. */
117- keymap_string = xkb_keymap_get_as_string(xkb->keymap.map, XKB_KEYMAP_FORMAT_TEXT_V1);
118-
119- if (!keymap_string) {
120- WARNING("Could not get XKB keymap as a string\n");
121- goto error0;
122- }
123-
124- sprintf(keymap_path, "%s/%s", keymap_directory, keymap_file_template);
125-
126- xkb->keymap.size = strlen(keymap_string) + 1;
127- xkb->keymap.fd = mkostemp(keymap_path, O_CLOEXEC);
128-
129- if (xkb->keymap.fd == -1) {
130- WARNING("Could not create XKB keymap file\n");
131- goto error1;
132- }
133-
134- unlink(keymap_path);
135-
136- if (posix_fallocate(xkb->keymap.fd, 0, xkb->keymap.size) != 0) {
137- WARNING("Could not resize XKB keymap file\n");
138- goto error2;
139- }
140-
141- xkb->keymap.area = mmap(NULL, xkb->keymap.size, PROT_READ | PROT_WRITE, MAP_SHARED, xkb->keymap.fd, 0);
142-
143- if (xkb->keymap.area == MAP_FAILED) {
144- WARNING("Could not mmap XKB keymap string\n");
145- goto error2;
146- }
147-
148- strcpy(xkb->keymap.area, keymap_string);
149-
150- free(keymap_string);
151-
152- return true;
153-
154-error2:
155- close(xkb->keymap.fd);
156-error1:
157- free(keymap_string);
158-error0:
159- return false;
160-}
+0,
-54
1@@ -1,54 +0,0 @@
2-/* swc: libswc/xkb.h
3- *
4- * Copyright (c) 2013, 2014 Michael Forney
5- *
6- * Permission is hereby granted, free of charge, to any person obtaining a copy
7- * of this software and associated documentation files (the "Software"), to deal
8- * in the Software without restriction, including without limitation the rights
9- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10- * copies of the Software, and to permit persons to whom the Software is
11- * furnished to do so, subject to the following conditions:
12- *
13- * The above copyright notice and this permission notice shall be included in
14- * all copies or substantial portions of the Software.
15- *
16- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22- * SOFTWARE.
23- */
24-
25-#ifndef SWC_XKB_H
26-#define SWC_XKB_H
27-
28-#include <stdbool.h>
29-#include <stdint.h>
30-
31-/* Keycodes are offset by 8 in XKB. */
32-#define XKB_KEY(key) ((key) + 8)
33-
34-struct xkb {
35- struct xkb_context *context;
36- struct xkb_state *state;
37-
38- struct {
39- struct xkb_keymap *map;
40- int fd;
41- uint32_t size;
42- char *area;
43- } keymap;
44-
45- struct {
46- uint32_t ctrl, alt, super, shift;
47- } indices;
48-};
49-
50-bool xkb_initialize(struct xkb *xkb);
51-void xkb_finalize(struct xkb *xkb);
52-bool xkb_reset_state(struct xkb *xkb);
53-bool xkb_update_keymap(struct xkb *xkb);
54-
55-#endif