AtlatestRepositorysigil-wm

sigil-wm / tree / src / ckeyboard-settings.h

1/* SPDX-License-Identifier: BSD-3-Clause */
2static bool configure_keyboard(struct server *s, const int64_t *words, size_t count) {
3 if (count < 10 || words[1] < 0 || words[1] > 1000 ||
4 words[2] < 0 || words[2] > 10000 || words[3] < 0 ||
5 (words[4] != 0 && words[4] != 1)) return false;
6 char fields[5][256] = {{0}};
7 size_t offset = 10;
8 for (unsigned field = 0; field < 5; field++) {
9 int64_t length = words[5 + field];
10 if (length < 0 || length > 255 || offset + (size_t)length > count) return false;
11 for (int64_t index = 0; index < length; index++) {
12 int64_t value = words[offset++];
13 if (value < 32 || value > 126) return false;
14 fields[field][index] = value;
15 }
16 }
17 if (offset != count) return false;
18 struct keyboard *keyboard = find_keyboard(s, words[0]);
19 if (!keyboard) return false;
20 struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
21 if (!context) return false;
22 struct xkb_rule_names names = {
23 .layout = fields[0][0] ? fields[0] : NULL,
24 .options = fields[1][0] ? fields[1] : NULL,
25 .variant = fields[2][0] ? fields[2] : NULL,
26 .rules = fields[3][0] ? fields[3] : NULL,
27 .model = fields[4][0] ? fields[4] : NULL,
28 };
29 struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
30 xkb_context_unref(context);
31 if (!keymap) return false;
32 if (words[3] >= xkb_keymap_num_layouts(keymap)) {
33 xkb_keymap_unref(keymap);
34 return false;
35 }
36 struct xkb_state *emulation = keyboard == &s->synthetic_owner ? xkb_state_new(keymap) : NULL;
37 if (keyboard == &s->synthetic_owner && !emulation) {
38 xkb_keymap_unref(keymap);
39 return false;
40 }
41 bool previous_fixed = keyboard->fixed_group;
42 uint32_t previous_group = keyboard->group;
43 keyboard->fixed_group = words[4] != 0;
44 keyboard->group = words[3];
45 bool accepted = wlr_keyboard_set_keymap(keyboard->native, keymap);
46 xkb_keymap_unref(keymap);
47 if (accepted) {
48 wlr_keyboard_set_repeat_info(keyboard->native, words[1], words[2]);
49 if (emulation) {
50 if (s->emulation_state) xkb_state_unref(s->emulation_state);
51 s->emulation_state = emulation;
52 }
53 struct wlr_keyboard_modifiers *mods = &keyboard->native->modifiers;
54 wlr_keyboard_notify_modifiers(keyboard->native, mods->depressed, mods->latched,
55 mods->locked, words[3]);
56 if (emulation) xkb_state_update_mask(emulation, 0, 0, 0, 0, 0, words[3]);
57 EVENT(41, keyboard->id, keyboard->native->modifiers.group,
58 xkb_keymap_num_layouts(keyboard->native->keymap));
59 } else {
60 keyboard->fixed_group = previous_fixed;
61 keyboard->group = previous_group;
62 if (emulation) xkb_state_unref(emulation);
63 }
64 return accepted;
67static bool set_keyboard_group(struct server *s, uint64_t id, int64_t group, bool fixed) {
68 struct keyboard *keyboard = find_keyboard(s, id);
69 if (!keyboard || !keyboard->native->keymap || group < 0 ||
70 group >= xkb_keymap_num_layouts(keyboard->native->keymap)) return false;
71 keyboard->group = group;
72 keyboard->fixed_group = fixed;
73 struct wlr_keyboard *native = keyboard->native;
74 wlr_keyboard_notify_modifiers(native, native->modifiers.depressed,
75 native->modifiers.latched, native->modifiers.locked, group);
76 if (keyboard == &s->synthetic_owner && s->emulation_state)
77 xkb_state_update_mask(s->emulation_state, 0, 0, 0, 0, 0, group);
78 EVENT(41, id, group, xkb_keymap_num_layouts(native->keymap));
79 return true;
82static uint32_t base_keysym(struct wlr_keyboard *keyboard, uint32_t code, bool first_layout) {
83 if (!keyboard->keymap || !keyboard->xkb_state) return 0;
84 const xkb_keysym_t *symbols;
85 xkb_layout_index_t layout = first_layout ? 0 :
86 xkb_state_key_get_layout(keyboard->xkb_state, code + 8);
87 int count = xkb_keymap_key_get_syms_by_level(keyboard->keymap, code + 8, layout, 0, &symbols);
88 return count > 0 ? symbols[0] : 0;