aboutsummaryrefslogtreecommitdiffstats
path: root/swaylock
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-04-02 23:07:43 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-04-04 18:47:48 -0400
commit0bd40ce86bf53b4349aae1e98aae50bcd86b2505 (patch)
tree86bb65364544839aeab55e286b4b7d5e3dd70bdf /swaylock
parentGrab keyboard off of the seat (diff)
downloadsway-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.c104
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
30enum 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
41enum 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
53const 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
64const 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
75struct 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
28struct swaylock_state { 83struct 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
101static void keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, 157static 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
106static void keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, 184static 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
116static void keyboard_key(void *data, struct wl_keyboard *wl_keyboard, 194static 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
121static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, 205static 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
127static void keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, 221static 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);