AtlatestRepositorysigil-wm
1
/* SPDX-License-Identifier: BSD-3-Clause */2
static 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;65
}67
static 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;80
}82
static 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;89
}