6 #include <wayland-server.h>
9 #include "libds/interfaces/keyboard.h"
12 static bool keyboard_modifier_update(struct ds_keyboard *keyboard);
13 static void keyboard_key_update(struct ds_keyboard *keyboard,
14 struct ds_event_keyboard_key *event);
15 static void keyboard_led_update(struct ds_keyboard *keyboard);
18 ds_keyboard_set_keymap(struct ds_keyboard *keyboard, struct xkb_keymap *keymap)
20 char *tmp_keymap_string;
23 xkb_keycode_t keycode;
24 const char *led_names[DS_LED_COUNT] = {
29 const char *mod_names[DS_MODIFIER_COUNT] = {
41 xkb_keymap_unref(keyboard->keymap);
43 keyboard->keymap = xkb_keymap_ref(keymap);
45 if (keyboard->xkb_state)
46 xkb_state_unref(keyboard->xkb_state);
48 keyboard->xkb_state = xkb_state_new(keyboard->keymap);
49 if (!keyboard->xkb_state) {
50 ds_err("Failed to create XKB state");
54 for (size_t i = 0; i < DS_LED_COUNT; i++) {
55 keyboard->led_indexes[i] =
56 xkb_map_led_get_index(keyboard->keymap, led_names[i]);
59 for (size_t i = 0; i < DS_MODIFIER_COUNT; i++) {
60 keyboard->mod_indexes[i] =
61 xkb_map_mod_get_index(keyboard->keymap, mod_names[i]);
64 tmp_keymap_string = xkb_keymap_get_as_string(keyboard->keymap,
65 XKB_KEYMAP_FORMAT_TEXT_V1);
66 if (!tmp_keymap_string) {
67 ds_err("Failed to get string version of keymap");
68 goto err_keymap_string;
71 if (keyboard->keymap_string)
72 free(keyboard->keymap_string);
73 keyboard->keymap_string = tmp_keymap_string;
74 keyboard->keymap_size = strlen(keyboard->keymap_string) + 1;
76 if (!allocate_shm_file_pair(keyboard->keymap_size, &rw_fd, &ro_fd)) {
77 ds_err("Failed to allocate shm_file for keymap");
81 dst = mmap(NULL, keyboard->keymap_size, PROT_READ | PROT_WRITE,
82 MAP_SHARED, rw_fd, 0);
83 if (dst == MAP_FAILED) {
84 ds_log_errno(DS_ERR, "mmap failed");
88 memcpy(dst, keyboard->keymap_string, keyboard->keymap_size);
89 munmap(dst, keyboard->keymap_size);
92 if (keyboard->keymap_fd >= 0)
93 close(keyboard->keymap_fd);
94 keyboard->keymap_fd = ro_fd;
96 for (size_t i = 0; i < keyboard->num_keycodes; i++) {
97 keycode = keyboard->keycodes[i] + 8;
98 xkb_state_update_key(keyboard->xkb_state, keycode, XKB_KEY_DOWN);
101 keyboard_modifier_update(keyboard);
103 wl_signal_emit(&keyboard->events.keymap, keyboard);
111 free(keyboard->keymap_string);
112 keyboard->keymap_string = NULL;
114 xkb_state_unref(keyboard->xkb_state);
115 keyboard->xkb_state = NULL;
117 xkb_keymap_unref(keymap);
118 keyboard->keymap = NULL;
124 ds_keyboard_set_repeat_info(struct ds_keyboard *keyboard,
125 int32_t rate, int32_t delay)
127 if (keyboard->repeat_info.rate == rate &&
128 keyboard->repeat_info.delay == delay)
130 keyboard->repeat_info.rate = rate;
131 keyboard->repeat_info.delay = delay;
133 wl_signal_emit(&keyboard->events.repeat_info, keyboard);
137 ds_keyboard_get_modifiers(struct ds_keyboard *keyboard)
140 uint32_t modifiers = 0;
142 mask = keyboard->modifiers.depressed | keyboard->modifiers.latched;
143 for (size_t i = 0; i < DS_MODIFIER_COUNT; i++) {
144 if (keyboard->mod_indexes[i] != XKB_MOD_INVALID &&
145 (mask & (1 << keyboard->mod_indexes[i])))
146 modifiers |= (1 << i);
152 WL_EXPORT struct xkb_state *
153 ds_keyboard_get_xkb_state(struct ds_keyboard *keyboard)
155 return keyboard->xkb_state;
159 ds_keyboard_notify_key(struct ds_keyboard *keyboard,
160 struct ds_event_keyboard_key *event)
163 enum xkb_key_direction dir;
166 keyboard_key_update(keyboard, event);
168 wl_signal_emit(&keyboard->events.key, event);
170 if (!keyboard->xkb_state)
173 if (event->update_state) {
174 keycode = event->keycode + 8;
175 dir = (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) ?
176 XKB_KEY_DOWN : XKB_KEY_UP;
177 xkb_state_update_key(keyboard->xkb_state, keycode, dir);
180 updated = keyboard_modifier_update(keyboard);
182 wl_signal_emit(&keyboard->events.modifiers, keyboard);
184 keyboard_led_update(keyboard);
188 ds_keyboard_notify_modifiers(struct ds_keyboard *keyboard,
189 uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked,
194 if (!keyboard->xkb_state)
197 xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched,
198 mods_locked, 0, 0, group);
200 updated = keyboard_modifier_update(keyboard);
202 wl_signal_emit(&keyboard->events.modifiers, keyboard);
204 keyboard_led_update(keyboard);
208 ds_keyboard_add_destroy_listener(struct ds_keyboard *keyboard,
209 struct wl_listener *listener)
211 wl_signal_add(&keyboard->events.destroy, listener);
215 ds_keyboard_add_key_listener(struct ds_keyboard *keyboard,
216 struct wl_listener *listener)
218 wl_signal_add(&keyboard->events.key, listener);
222 ds_keyboard_add_modifiers_listener(struct ds_keyboard *keyboard,
223 struct wl_listener *listener)
225 wl_signal_add(&keyboard->events.modifiers, listener);
229 ds_keyboard_add_keymap_listener(struct ds_keyboard *keyboard,
230 struct wl_listener *listener)
232 wl_signal_add(&keyboard->events.keymap, listener);
236 ds_keyboard_add_repeat_info_listener(struct ds_keyboard *keyboard,
237 struct wl_listener *listener)
239 wl_signal_add(&keyboard->events.repeat_info, listener);
243 ds_keyboard_init(struct ds_keyboard *keyboard,
244 const struct ds_keyboard_interface *iface)
246 keyboard->iface = iface;
247 keyboard->keymap_fd = -1;
249 wl_signal_init(&keyboard->events.destroy);
250 wl_signal_init(&keyboard->events.key);
251 wl_signal_init(&keyboard->events.modifiers);
252 wl_signal_init(&keyboard->events.keymap);
253 wl_signal_init(&keyboard->events.repeat_info);
257 ds_keyboard_destroy(struct ds_keyboard *keyboard)
259 if (keyboard->iface && keyboard->iface->destroy)
260 keyboard->iface->destroy(keyboard);
266 keyboard_modifier_update(struct ds_keyboard *keyboard)
268 xkb_mod_mask_t depressed, latched, locked, group;
270 if (!keyboard->xkb_state)
273 depressed = xkb_state_serialize_mods(keyboard->xkb_state,
274 XKB_STATE_MODS_DEPRESSED);
275 latched = xkb_state_serialize_mods(keyboard->xkb_state,
276 XKB_STATE_MODS_LATCHED);
277 locked = xkb_state_serialize_mods(keyboard->xkb_state,
278 XKB_STATE_MODS_LOCKED);
279 group = xkb_state_serialize_layout(keyboard->xkb_state,
280 XKB_STATE_LAYOUT_EFFECTIVE);
281 if (depressed == keyboard->modifiers.depressed &&
282 latched == keyboard->modifiers.latched &&
283 locked == keyboard->modifiers.locked &&
284 group == keyboard->modifiers.group)
287 keyboard->modifiers.depressed = depressed;
288 keyboard->modifiers.latched = latched;
289 keyboard->modifiers.locked = locked;
290 keyboard->modifiers.group = group;
295 static void keyboard_key_update(struct ds_keyboard *keyboard,
296 struct ds_event_keyboard_key *event)
301 static void keyboard_led_update(struct ds_keyboard *keyboard)