diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-04-02 23:07:43 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2018-04-04 18:47:48 -0400 |
commit | 0bd40ce86bf53b4349aae1e98aae50bcd86b2505 (patch) | |
tree | 86bb65364544839aeab55e286b4b7d5e3dd70bdf /swaylock | |
parent | Grab keyboard off of the seat (diff) | |
download | sway-0bd40ce86bf53b4349aae1e98aae50bcd86b2505.tar.gz sway-0bd40ce86bf53b4349aae1e98aae50bcd86b2505.tar.zst sway-0bd40ce86bf53b4349aae1e98aae50bcd86b2505.zip |
Set up an XKB context for the keyboard
Diffstat (limited to 'swaylock')
-rw-r--r-- | swaylock/main.c | 104 |
1 files changed, 99 insertions, 5 deletions
diff --git a/swaylock/main.c b/swaylock/main.c index 948d661b..555b1d64 100644 --- a/swaylock/main.c +++ b/swaylock/main.c | |||
@@ -8,11 +8,13 @@ | |||
8 | #include <stdio.h> | 8 | #include <stdio.h> |
9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
10 | #include <string.h> | 10 | #include <string.h> |
11 | #include <sys/mman.h> | ||
11 | #include <sys/stat.h> | 12 | #include <sys/stat.h> |
12 | #include <time.h> | 13 | #include <time.h> |
13 | #include <unistd.h> | 14 | #include <unistd.h> |
14 | #include <wayland-client.h> | 15 | #include <wayland-client.h> |
15 | #include <wlr/util/log.h> | 16 | #include <wlr/util/log.h> |
17 | #include <xkbcommon/xkbcommon.h> | ||
16 | #include "background-image.h" | 18 | #include "background-image.h" |
17 | #include "pool-buffer.h" | 19 | #include "pool-buffer.h" |
18 | #include "cairo.h" | 20 | #include "cairo.h" |
@@ -25,6 +27,59 @@ struct swaylock_args { | |||
25 | bool show_indicator; | 27 | bool show_indicator; |
26 | }; | 28 | }; |
27 | 29 | ||
30 | enum mod_bit { | ||
31 | MOD_SHIFT = 1<<0, | ||
32 | MOD_CAPS = 1<<1, | ||
33 | MOD_CTRL = 1<<2, | ||
34 | MOD_ALT = 1<<3, | ||
35 | MOD_MOD2 = 1<<4, | ||
36 | MOD_MOD3 = 1<<5, | ||
37 | MOD_LOGO = 1<<6, | ||
38 | MOD_MOD5 = 1<<7, | ||
39 | }; | ||
40 | |||
41 | enum mask { | ||
42 | MASK_SHIFT, | ||
43 | MASK_CAPS, | ||
44 | MASK_CTRL, | ||
45 | MASK_ALT, | ||
46 | MASK_MOD2, | ||
47 | MASK_MOD3, | ||
48 | MASK_LOGO, | ||
49 | MASK_MOD5, | ||
50 | MASK_LAST | ||
51 | }; | ||
52 | |||
53 | const char *XKB_MASK_NAMES[MASK_LAST] = { | ||
54 | XKB_MOD_NAME_SHIFT, | ||
55 | XKB_MOD_NAME_CAPS, | ||
56 | XKB_MOD_NAME_CTRL, | ||
57 | XKB_MOD_NAME_ALT, | ||
58 | "Mod2", | ||
59 | "Mod3", | ||
60 | XKB_MOD_NAME_LOGO, | ||
61 | "Mod5", | ||
62 | }; | ||
63 | |||
64 | const enum mod_bit XKB_MODS[MASK_LAST] = { | ||
65 | MOD_SHIFT, | ||
66 | MOD_CAPS, | ||
67 | MOD_CTRL, | ||
68 | MOD_ALT, | ||
69 | MOD_MOD2, | ||
70 | MOD_MOD3, | ||
71 | MOD_LOGO, | ||
72 | MOD_MOD5 | ||
73 | }; | ||
74 | |||
75 | struct swaylock_xkb { | ||
76 | uint32_t modifiers; | ||
77 | struct xkb_state *state; | ||
78 | struct xkb_context *context; | ||
79 | struct xkb_keymap *keymap; | ||
80 | xkb_mod_mask_t masks[MASK_LAST]; | ||
81 | }; | ||
82 | |||
28 | struct swaylock_state { | 83 | struct swaylock_state { |
29 | struct wl_display *display; | 84 | struct wl_display *display; |
30 | struct wl_compositor *compositor; | 85 | struct wl_compositor *compositor; |
@@ -32,6 +87,7 @@ struct swaylock_state { | |||
32 | struct wl_shm *shm; | 87 | struct wl_shm *shm; |
33 | struct wl_list contexts; | 88 | struct wl_list contexts; |
34 | struct swaylock_args args; | 89 | struct swaylock_args args; |
90 | struct swaylock_xkb xkb; | ||
35 | bool run_display; | 91 | bool run_display; |
36 | }; | 92 | }; |
37 | 93 | ||
@@ -100,7 +156,29 @@ static struct zwlr_layer_surface_v1_listener layer_surface_listener = { | |||
100 | 156 | ||
101 | static void keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, | 157 | static void keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, |
102 | uint32_t format, int32_t fd, uint32_t size) { | 158 | uint32_t format, int32_t fd, uint32_t size) { |
103 | // TODO | 159 | struct swaylock_state *state = data; |
160 | if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { | ||
161 | close(fd); | ||
162 | wlr_log(L_ERROR, "Unknown keymap format %d, aborting", format); | ||
163 | exit(1); | ||
164 | } | ||
165 | char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); | ||
166 | if (map_shm == MAP_FAILED) { | ||
167 | close(fd); | ||
168 | wlr_log(L_ERROR, "Unable to initialize keymap shm, aborting"); | ||
169 | exit(1); | ||
170 | } | ||
171 | struct xkb_keymap *keymap = xkb_keymap_new_from_string( | ||
172 | state->xkb.context, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1, 0); | ||
173 | munmap(map_shm, size); | ||
174 | close(fd); | ||
175 | assert(keymap); | ||
176 | struct xkb_state *xkb_state = xkb_state_new(keymap); | ||
177 | assert(xkb_state); | ||
178 | xkb_keymap_unref(state->xkb.keymap); | ||
179 | xkb_state_unref(state->xkb.state); | ||
180 | state->xkb.keymap = keymap; | ||
181 | state->xkb.state = xkb_state; | ||
104 | } | 182 | } |
105 | 183 | ||
106 | static void keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, | 184 | static void keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, |
@@ -114,14 +192,30 @@ static void keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, | |||
114 | } | 192 | } |
115 | 193 | ||
116 | static void keyboard_key(void *data, struct wl_keyboard *wl_keyboard, | 194 | static void keyboard_key(void *data, struct wl_keyboard *wl_keyboard, |
117 | uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { | 195 | uint32_t serial, uint32_t time, uint32_t key, uint32_t _key_state) { |
118 | // TODO | 196 | struct swaylock_state *state = data; |
197 | enum wl_keyboard_key_state key_state = _key_state; | ||
198 | xkb_keysym_t sym = xkb_state_key_get_one_sym(state->xkb.state, key + 8); | ||
199 | uint32_t keycode = key_state == WL_KEYBOARD_KEY_STATE_PRESSED ? | ||
200 | key + 8 : 0; | ||
201 | uint32_t codepoint = xkb_state_key_get_utf32(state->xkb.state, keycode); | ||
202 | wlr_log(L_DEBUG, "%c %d", codepoint, sym); | ||
119 | } | 203 | } |
120 | 204 | ||
121 | static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, | 205 | static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, |
122 | uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, | 206 | uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, |
123 | uint32_t mods_locked, uint32_t group) { | 207 | uint32_t mods_locked, uint32_t group) { |
124 | // TODO | 208 | struct swaylock_state *state = data; |
209 | xkb_state_update_mask(state->xkb.state, | ||
210 | mods_depressed, mods_latched, mods_locked, 0, 0, group); | ||
211 | xkb_mod_mask_t mask = xkb_state_serialize_mods(state->xkb.state, | ||
212 | XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED); | ||
213 | state->xkb.modifiers = 0; | ||
214 | for (uint32_t i = 0; i < MASK_LAST; ++i) { | ||
215 | if (mask & state->xkb.masks[i]) { | ||
216 | state->xkb.modifiers |= XKB_MODS[i]; | ||
217 | } | ||
218 | } | ||
125 | } | 219 | } |
126 | 220 | ||
127 | static void keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, | 221 | static void keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, |
@@ -345,7 +439,7 @@ int main(int argc, char **argv) { | |||
345 | } | 439 | } |
346 | 440 | ||
347 | wl_list_init(&state.contexts); | 441 | wl_list_init(&state.contexts); |
348 | 442 | state.xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); | |
349 | assert(state.display = wl_display_connect(NULL)); | 443 | assert(state.display = wl_display_connect(NULL)); |
350 | 444 | ||
351 | struct wl_registry *registry = wl_display_get_registry(state.display); | 445 | struct wl_registry *registry = wl_display_get_registry(state.display); |