From 7493bce2f573472d2e4d88ed4d2eefe1d81bab9c Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sun, 20 May 2012 11:53:26 +0300 Subject: [PATCH] xkb: remove old xkb code and add stubs The libxkbcommon API as been revamped completely, making all of the current code redundant and non-working. This commit removes all of the old xkb_desc handling before using the new API. After this commit, kmscon will no longer link to against the old lixkbcommon; please update to a new package or compile from the "master" branch from: git://anongit.freedesktop.org/xorg/lib/libxkbcommon [ This commit also adds a missing kbd_desc_new, which was declared but not copied over from the old files. ] Signed-off-by: Ran Benita Signed-off-by: David Herrmann --- src/uterm_input_xkb.c | 857 +----------------------------------------- 1 file changed, 14 insertions(+), 843 deletions(-) diff --git a/src/uterm_input_xkb.c b/src/uterm_input_xkb.c index 9ed9e08..793e37f 100644 --- a/src/uterm_input_xkb.c +++ b/src/uterm_input_xkb.c @@ -24,41 +24,6 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* - * This mostly involves things the X server does normally and libxkbcommon - * doesn't provide us for free. - * This implements a minimal subset of XKB, mostly ignoring stuff like: - * - The protocol itself - we don't allow changing/querying and do anything - * at init. - * - Everything to do with pointing devices, buttons.. - * - Indicators - * - Controls - * - Bells - * - Dead keys - * - All actions beside group- and modifier-related. - * - Behaviours - * - Geometries - * - And various tweaks to what we do support. - * - * Some references to understand what's going on: - * - * [Lib] The X Keyboard Extension: Library Specification - * http://www.x.org/releases/current/doc/libX11/specs/XKB/xkblib.html - * [Proto] The X Keyboard Extension: Protocol Specification - * http://www.x.org/releases/current/doc/kbproto/xkbproto.html - * [xserver] The X server source code dealing with xkb - * /xkb/ - * [xlib] The Xlib source code dealing with xkb and input methods - * /xkb/ - * /modules/im/ximcp/ - * [Pascal] Some XKB documentation by its maintainer (not the best english) - * http://pascal.tsu.ru/en/xkb/ - * [Headers] Some XKB-related headers - * /usr/include/X11/extensions/XKBcommon.h - * /usr/include/X11/extensions/XKB.h - * /usr/include/X11/keysymdef.h - */ - #include #include #include @@ -75,13 +40,13 @@ struct kbd_desc { unsigned long ref; - struct xkb_desc *desc; + struct xkb_keymap *keymap; }; struct kbd_dev { unsigned long ref; struct kbd_desc *desc; - struct xkb_state state; + struct xkb_state *state; }; int kbd_dev_new(struct kbd_dev **out, struct kbd_desc *desc) @@ -118,455 +83,25 @@ void kbd_dev_unref(struct kbd_dev *kbd) free(kbd); } -static uint8_t virtual_to_real_mods(struct xkb_desc *desc, uint16_t vmods) -{ - int i; - uint32_t bit; - uint8_t mods; - - mods = 0x00; - - for (i = 0, bit = 0x01; i < XkbNumVirtualMods; i++, bit <<= 1) - if (vmods & bit) - mods |= desc->server->vmods[i]; - - return mods; -} - -static uint8_t virtual_and_real_to_mask(struct xkb_desc *desc, - uint16_t vmods, - uint8_t real_mods) -{ - uint8_t mods = 0x00; - - mods |= real_mods; - mods |= virtual_to_real_mods(desc, vmods); - - return mods; -} - -/* - * Helper function for the wrap_group_* functions. - * See [Lib] 11.7.1 for the rules. - */ -static uint8_t wrap_group(int16_t group, int num_groups, uint8_t group_info) -{ - /* No need for wrapping. */ - if (XkbIsLegalGroup(group) && group < num_groups) - return group; - - switch (XkbOutOfRangeGroupAction(group_info)) { - case XkbWrapIntoRange: - /* - * C99 says a negative dividend in a modulo operation - * will always give a negative result. - */ - if (group < 0) - return num_groups + (group % num_groups); - else - return group % num_groups; - - case XkbClampIntoRange: - /* This one seems to be unused. */ - return num_groups - 1; - - case XkbRedirectIntoRange: - /* This one seems to be unused. */ - group = XkbOutOfRangeGroupNumber(group_info); - /* If it's _still_ out of range, use the first group. */ - if (group >= num_groups) - return 0; - } - - return 0; -} - -/* - * Wrap an arbitrary group into a legal effective global group according to - * the GroupsWrap control. - * (Group actions mostly act on the group number in a relative manner [e.g. - * +1, -1]. So if we have N groups, the effective group is N-1, and we get a - * SetGroup +1, this tells us what to do.) - */ -static uint8_t wrap_group_control(struct xkb_desc *desc, int16_t group) -{ - int num_groups; - uint8_t group_info; - - num_groups = desc->ctrls->num_groups; - group_info = desc->ctrls->groups_wrap; - - return wrap_group(group, num_groups, group_info); -} - -/* - * Wrap the effective global group to a legal group for the keycode, according - * to the rule specified for the key. - * (Some keycodes may have more groups than others, and so the effective - * group may not make sense for a certain keycode). - */ -static uint8_t wrap_group_keycode(struct xkb_desc *desc, xkb_keycode_t keycode, - int16_t group) -{ - int num_groups; - uint8_t group_info; - - num_groups = XkbKeyNumGroups(desc, keycode); - group_info = XkbKeyGroupInfo(desc, keycode); - - return wrap_group(group, num_groups, group_info); -} - -/* - * Need to update the effective mods after any changes to the base, latched or - * locked mods. - */ -static void update_effective_mods(struct xkb_desc *desc, - struct xkb_state *state) -{ - state->mods = state->base_mods | state->latched_mods | - state->locked_mods; -} - -/* - * Need to update the effective group after any changes to the base, latched or - * locked group. - */ -static void update_effective_group(struct xkb_desc *desc, - struct xkb_state *state) -{ - int16_t group; - - /* Update the effective group. */ - group = state->base_group + state->locked_group + state->latched_group; - state->group = wrap_group_control(desc, group); -} - -/* - * Updates the group state. - * See [Lib] Table 17.4 for logic. - */ -static bool process_group_action(struct xkb_desc *desc, - struct xkb_state *state, - xkb_keycode_t keycode, - uint16_t key_state, - struct xkb_group_action *action) -{ - int16_t group = action->group; - uint8_t flags = action->flags; - - /* - * action->group is signed and may be negative if GroupAbsolute - * is not set. A group itself cannot be negative and is unsigend. - * Therefore we extend these to int16 to avoid underflow and - * signedness issues. Be careful! - */ - int16_t base_group = state->base_group; - int16_t latched_group = state->latched_group; - int16_t locked_group = state->locked_group; - - /* - * FIXME: Some actions here should be conditioned "and no keys are - * physically depressed when this key is released". - */ - - switch (action->type) { - case XkbSA_SetGroup: - if (key_state == 1) { - if (flags & XkbSA_GroupAbsolute) - base_group = group; - else - base_group += group; - } else if (key_state == 0) { - if (flags & XkbSA_ClearLocks) - locked_group = 0; - } - - break; - case XkbSA_LatchGroup: - if (key_state == 1) { - if (flags & XkbSA_GroupAbsolute) - base_group = group; - else - base_group += group; - } else if (key_state == 0) { - if ((flags & XkbSA_LatchToLock) && latched_group) { - locked_group += group; - latched_group -= group; - } else { - latched_group += group; - } - } - - break; - case XkbSA_LockGroup: - if (key_state == 1) { - if (flags & XkbSA_GroupAbsolute) - locked_group = group; - else - locked_group += group; - } - - break; - } - - /* Bring what was changed back into range. */ - state->base_group = wrap_group_control(desc, base_group); - state->locked_group = wrap_group_control(desc, locked_group); - state->latched_group = wrap_group_control(desc, latched_group); - update_effective_group(desc, state); - return true; -} - -/* - * Updates the modifiers state. - * See [Lib] Table 17.1 for logic. - * */ -static bool process_mod_action(struct xkb_desc *desc, - struct xkb_state *state, - xkb_keycode_t keycode, - uint16_t key_state, - struct xkb_mod_action *action) -{ - uint8_t mods; - uint8_t saved_mods; - uint8_t flags = action->flags; - - if (flags & XkbSA_UseModMapMods) - mods = desc->map->modmap[keycode]; - else - mods = action->mask; - - /* - * FIXME: Some actions here should be conditioned "and no keys are - * physically depressed when this key is released". - */ - - switch (action->type) { - case XkbSA_SetMods: - if (key_state == 1) { - state->base_mods |= mods; - } else if (key_state == 0) { - state->base_mods &= ~mods; - if (flags & XkbSA_ClearLocks) - state->locked_mods &= ~mods; - } - - break; - case XkbSA_LatchMods: - if (key_state == 1) { - state->base_mods |= mods; - } else if (key_state == 0) { - if (flags & XkbSA_ClearLocks) { - saved_mods = state->locked_mods; - state->locked_mods &= ~mods; - mods &= ~(mods & saved_mods); - } - if (flags & XkbSA_LatchToLock) { - saved_mods = mods; - mods = (mods & state->latched_mods); - state->locked_mods |= mods; - state->latched_mods &= ~mods; - mods = saved_mods & (~mods); - } - state->latched_mods |= mods; - } - - break; - case XkbSA_LockMods: - /* We fake a here and toggle both on and off on keypress */ - if (key_state == 1) { - state->base_mods |= mods; - state->locked_mods ^= mods; - } else if (key_state == 0) { - state->base_mods &= ~mods; - } - - break; - } - - update_effective_mods(desc, state); - return true; -} - -/* - * An action dispatcher. The return value indicates whether the keyboard state - * was changed. - */ -static bool process_action(struct xkb_desc *desc, - struct xkb_state *state, - xkb_keycode_t keycode, - uint16_t key_state, - union xkb_action *action) -{ - if (!action) - return false; - - switch (action->type) { - case XkbSA_NoAction: - break; - case XkbSA_SetMods: - case XkbSA_LatchMods: - case XkbSA_LockMods: - return process_mod_action(desc, state, keycode, key_state, - &action->mods); - break; - case XkbSA_SetGroup: - case XkbSA_LatchGroup: - case XkbSA_LockGroup: - return process_group_action(desc, state, keycode, key_state, - &action->group); - break; - default: - /* - * Don't handle other actions. - * Note: There may be useful stuff here, like TerminateServer - * or SwitchScreen. - */ - break; - } - - return false; -} - -/* - * The shift level to use for the keycode (together with the group) is - * determined by the modifier state. There are various "types" of ways to use - * the modifiers to shift the keycode; this is determined by the key_type - * object mapped to the (keycode, group) pair. - */ -static uint16_t find_shift_level(struct xkb_desc *desc, - xkb_keycode_t keycode, - uint8_t mods, - uint8_t group) -{ - int i; - struct xkb_key_type *type; - struct xkb_kt_map_entry *entry; - uint8_t masked_mods; - - type = XkbKeyType(desc, keycode, group); - - masked_mods = type->mods.mask & mods; - - for (i=0; i < type->map_count; i++) { - entry = &type->map[i]; - - if (!entry->active) - continue; - - /* - * Must match exactly after we masked it with the key_type's - * mask. - */ - if (entry->mods.mask == masked_mods) - return entry->level; - } - - /* The default is LevelOne. */ - return 0; -} - -/* Whether to send out a repeat event for the key. */ -static bool should_key_repeat(struct xkb_desc *desc, xkb_keycode_t keycode) -{ - unsigned const char *pkr; - - /* Repeats globally disabled. */ - if (!(desc->ctrls->enabled_ctrls & XkbRepeatKeysMask)) - return false; - - /* Repeats disabled for the specific key. */ - pkr = desc->ctrls->per_key_repeat; - if (!(pkr[keycode / 8] & (0x01 << (keycode % 8)))) - return false; - - /* Don't repeat modifiers. */ - if (desc->map->modmap[keycode] != 0) - return false; - - return true; -} +#define EVDEV_KEYCODE_OFFSET 8 int kbd_dev_process_key(struct kbd_dev *kbd, uint16_t key_state, uint16_t code, struct uterm_input_event *out) { - struct xkb_desc *desc; struct xkb_state *state; xkb_keycode_t keycode; - uint8_t group; - uint16_t shift_level; - uint32_t sym; - union xkb_action *action; - bool state_changed, event_filled; if (!kbd) return -EINVAL; - desc = kbd->desc->desc; - state = &kbd->state; + state = kbd->state; + keycode = code + EVDEV_KEYCODE_OFFSET; - keycode = code + desc->min_key_code; + (void)keycode; (void)state; - /* Valid keycode. */ - if (!XkbKeycodeInRange(desc, keycode)) - return -ENOKEY; - /* Active keycode. */ - if (XkbKeyNumSyms(desc, keycode) == 0) - return -ENOKEY; - /* Unwanted repeat. */ - if (key_state == 2 && - !should_key_repeat(desc, keycode)) - return -ENOKEY; - - group = wrap_group_keycode(desc, keycode, state->group); - shift_level = find_shift_level(desc, keycode, state->mods, group); - sym = XkbKeySymEntry(desc, keycode, shift_level, group); - - state_changed = false; - if (key_state != 2) { - action = XkbKeyActionEntry(desc, keycode, shift_level, group); - state_changed = process_action(desc, state, keycode, - key_state, action); - } - - event_filled = false; - if (key_state != 0 && !state_changed) { - out->keycode = code; - out->keysym = sym; - /* 1-to-1 match - this might change. */ - out->mods = state->mods; - out->unicode = KeysymToUcs4(sym); - - if (out->unicode == 0) - out->unicode = UTERM_INPUT_INVALID; - - event_filled = true; - } - - if (state_changed) { - /* Release latches. */ - state->latched_mods = 0; - update_effective_mods(desc, state); - state->latched_group = 0; - update_effective_group(desc, state); - } - - return event_filled ? 0 : -ENOKEY; -} - -static struct xkb_indicator_map *find_indicator_map(struct xkb_desc *desc, - const char *indicator_name) -{ - int i; - - for (i=0; i < XkbNumIndicators; i++) - if (!strcmp(desc->names->indicators[i], indicator_name)) - return &desc->indicators->maps[i]; - - return NULL; + return -ENOKEY; } /* @@ -577,9 +112,7 @@ static struct xkb_indicator_map *find_indicator_map(struct xkb_desc *desc, void kbd_dev_reset(struct kbd_dev *kbd, const unsigned long *ledbits) { unsigned int i; - struct xkb_desc *desc; struct xkb_state *state; - struct xkb_indicator_map *im; static const struct { int led; const char *indicator_name; @@ -593,374 +126,23 @@ void kbd_dev_reset(struct kbd_dev *kbd, const unsigned long *ledbits) if (!kbd) return; - desc = kbd->desc->desc; - state = &kbd->state; - - state->group = 0; - state->base_group = 0; - state->latched_group = 0; - - state->mods = 0; - state->base_mods = 0; - state->latched_mods = 0; - state->locked_mods = 0; + state = kbd->state; for (i = 0; i < sizeof(led_names) / sizeof(*led_names); i++) { if (!input_bit_is_set(ledbits, led_names[i].led)) continue; - - im = find_indicator_map(desc, led_names[i].indicator_name); - - /* Only locked modifiers really matter here. */ - if (im && im->which_mods == XkbIM_UseLocked) - state->locked_mods |= im->mods.mask; } - update_effective_mods(desc, state); - update_effective_group(desc, state); + (void)state; } -/* - * We don't do soft repeat currently, but we use the controls to filter out - * which evdev repeats to send. - */ -static void init_autorepeat(struct xkb_desc *desc) -{ - /* - * This is taken from /include/site.h - * If a bit is off for a keycode, it should not repeat. - */ - static const char DEFAULT_AUTOREPEATS[XkbPerKeyBitArraySize] = { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - memcpy(desc->ctrls->per_key_repeat, - DEFAULT_AUTOREPEATS, XkbPerKeyBitArraySize); - - desc->ctrls->enabled_ctrls |= XkbRepeatKeysMask; -} - -/* - * Update to the effective modifier mask of the indicator objects. We use them - * to dicover which modifiers to match with which leds. - */ -static void init_indicators(struct xkb_desc *desc) -{ - int i; - struct xkb_indicator_map *im; - struct xkb_mods *mods; - - for (i=0; i < XkbNumIndicators; i++) { - im = &desc->indicators->maps[i]; - mods = &im->mods; - - mods->mask = virtual_and_real_to_mask(desc, mods->vmods, - mods->real_mods); - } -} - -static void init_action(struct xkb_desc *desc, union xkb_action *action) -{ - struct xkb_mod_action *mod_act; - - switch (action->type) { - case XkbSA_SetMods: - case XkbSA_LatchMods: - case XkbSA_LockMods: - mod_act = &action->mods; - - mod_act->mask = virtual_and_real_to_mask(desc, mod_act->vmods, - mod_act->real_mods); - break; - } -} - -/* - * Update the effective modifer mask of the various action objects after we - * initialized the virtual modifiers from compat. The only actions we change - * here are the mod_action types. - */ -static void init_actions(struct xkb_desc *desc) -{ - int i; - union xkb_action *action; - struct xkb_sym_interpret *si; - - for (i=0; i < desc->server->num_acts; i++) { - action = &desc->server->acts[i]; - init_action(desc, action); - } - - for (i=0; i < desc->compat->num_si; i++) { - si = &desc->compat->sym_interpret[i]; - action = (union xkb_action *)&si->act; - init_action(desc, action); - } -} - -/* - * After we figured out the virtual mods from the compat component, we update - * the effective modifiers in the key_types component accordingly, because we - * use it extensively to find the correct shift level. - */ -static void init_key_types(struct xkb_desc *desc) -{ - int i, j; - struct xkb_key_type *type; - struct xkb_kt_map_entry *entry; - struct xkb_mods *mods; - - for (i=0; i < desc->map->num_types; i++) { - type = &desc->map->types[i]; - mods = &type->mods; - - mods->mask = virtual_and_real_to_mask(desc, mods->vmods, - mods->real_mods); - - for (j=0; j < type->map_count; j++) { - entry = &type->map[j]; - mods = &entry->mods; - - mods->mask = virtual_and_real_to_mask(desc, - mods->vmods, mods->real_mods); - - /* - * If the entry's vmods are bound to something, it - * should be active. - */ - if (virtual_to_real_mods(desc, mods->vmods)) - entry->active = true; - } - } -} - -/* - * Check a sym interpret match condition. - * See [Lib] Table 18.1 for the logic. - */ -static bool are_modifiers_matching(uint8_t mods, - unsigned char match, - uint8_t to_mods) -{ - switch (match & XkbSI_OpMask) { - case XkbSI_NoneOf: - return (mods & to_mods) == 0; - case XkbSI_AnyOfOrNone: - return true; - case XkbSI_AnyOf: - return (mods & to_mods) != 0; - case XkbSI_AllOf: - return (mods & to_mods) == mods; - case XkbSI_Exactly: - return mods == to_mods; - } - - return false; -} - -/* - * Look for the most specific symbol interpretation for the keysym. - * See [xserver] XKBMisc.c:_XkbFindMatchingInterp() for the equivalent. - */ -static struct xkb_sym_interpret *find_sym_interpret(struct xkb_desc *desc, - uint32_t sym, uint16_t level, uint8_t key_modmap) -{ - int i; - struct xkb_sym_interpret *si; - struct xkb_sym_interpret *all_syms_si; - - all_syms_si = NULL; - - /* - * If we find a matching interpret specific to our symbol, we return - * it immediatly. - * If we didn't find any, we return the first matching all-catching - * interpret. - */ - - for (i=0; i < desc->compat->num_si; i++) { - si = &desc->compat->sym_interpret[i]; - - if (si->sym != sym && si->sym != 0) - continue; - - /* - * If the interpret specified UseModMapMods=level1, the sym - * must be in the first level of its group. - * Note: [xserver] and [Lib] do different things here, and it - * doesn't seem to matter much. So it's commented for now. - */ - /* if (si->match&XkbSI_LevelOneOnly && level != 0) */ - /* continue; */ - - if (!are_modifiers_matching(si->mods, si->match, key_modmap)) - continue; - - if (si->sym != 0) - return si; - else if (all_syms_si == NULL) - all_syms_si = si; - } - - return all_syms_si; -} - -/* - * Allocate slots for a keycode in the key-action mapping array. xkbcommon - * doesn't do this by itself for actions from compat (that is, almost all of - * them). - * See [xserver] XKBMAlloc.c:XkbResizeKeyActions() for the equivalent. - */ -static int allocate_key_acts(struct xkb_desc *desc, uint8_t keycode) -{ - struct xkb_server_map *server; - int sym_count; - unsigned short index, new_size_acts; - union xkb_action *acts; - - server = desc->server; - sym_count = XkbKeyNumSyms(desc, keycode); - - if (XkbKeyHasActions(desc, keycode)) - return 0; - - index = server->num_acts; - - /* num_acts is the occupied slots, size_acts is the capacity. */ - if (server->num_acts + sym_count > server->size_acts) { - /* - * Don't have enough space, need to allocate. We add some - * extra to avoid repeated reallocs. - */ - new_size_acts = server->num_acts + sym_count + 8; - acts = realloc(server->acts, new_size_acts * sizeof (*acts)); - if (!acts) - return -ENOMEM; - server->acts = acts; - server->size_acts = new_size_acts; - } - - /* XkbSA_NoAction is 0x00 so we're good. */ - memset(&server->acts[index], 0, sym_count * sizeof(*server->acts)); - server->key_acts[keycode] = index; - server->num_acts += sym_count; - - return 0; -} - -static int init_compat_for_keysym(struct xkb_desc *desc, - xkb_keycode_t keycode, - uint8_t group, - uint16_t level) -{ - int ret; - uint8_t key_modmap; - uint32_t sym; - struct xkb_sym_interpret *si; - union xkb_action *action; - - key_modmap = desc->map->modmap[keycode]; - sym = XkbKeySymEntry(desc, keycode, level, group); - si = find_sym_interpret(desc, sym, level, key_modmap); - - if (!si) - return 0; - - /* Set the key action mapping. */ - if (si->act.type != XkbSA_NoAction) { - ret = allocate_key_acts(desc, keycode); - if (ret) - return ret; - - action = XkbKeyActionEntry(desc, keycode, level, group); - *action = (union xkb_action)si->act; - } - - /* Set the key virtual modifier mapping. */ - if (si->virtual_mod != XkbNoModifier) - desc->server->vmodmap[keycode] |= 0x01 << si->virtual_mod; - - return 0; -} - -static int init_compat_for_keycode(struct xkb_desc *desc, - xkb_keycode_t keycode) -{ - int ret; - int i, bit; - - uint8_t group; - uint16_t level; - int num_groups; - int num_levels; - - /* - * It's possible that someone had set some actions for the keycode - * through the symbols file, and so we shouldn't override with the - * compat. This is very uncommon though, only used by the breaks_caps - * option here. - */ - if (XkbKeyHasActions(desc, keycode)) - return 0; - - num_groups = XkbKeyNumGroups(desc, keycode); - - /* - * We need to track the sym level in order to support LevelOneOnly, - * which is used in some symbol interpretations. - */ - - for (group=0, i=0; group < num_groups; group++) { - num_levels = XkbKeyGroupWidth(desc, keycode, group); - - for (level=0; level < num_levels; level++) { - ret = init_compat_for_keysym(desc, keycode, - group, level); - if (ret) - return ret; - } - } - - /* - * Translate the virtual modifiers bound to this key to the real - * modifiers bound to this key. - * See [Lib] 17.4 for vmodmap and friends. - */ - for (i=0, bit=0x01; i < XkbNumVirtualMods; i++, bit<<=1) - if (bit&desc->server->vmodmap[keycode]) - desc->server->vmods[i] |= desc->map->modmap[keycode]; - - return 0; -} - -/* - * This mostly fills out the keycode-action mapping and puts the virtual - * modifier mappings in the right place. - */ -static void init_compat(struct xkb_desc *desc) -{ - /* If we use KeyCode it overflows. */ - unsigned int keycode; - - for (keycode = desc->min_key_code; - keycode <= desc->max_key_code; - keycode++) - init_compat_for_keycode(desc, keycode); -} - -/* - * Create a ready-to-use xkb description object. It is used in most places - * having to do with XKB. - */ int kbd_desc_new(struct kbd_desc **out, const char *layout, const char *variant, const char *options) { struct kbd_desc *desc; - struct xkb_rule_names rmlvo = { + const struct xkb_rule_names rmlvo = { .rules = "evdev", .model = "evdev", .layout = layout, @@ -974,22 +156,12 @@ int kbd_desc_new(struct kbd_desc **out, desc = malloc(sizeof(*desc)); if (!desc) return -ENOMEM; + memset(desc, 0, sizeof(*desc)); desc->ref = 1; - desc->desc = xkb_compile_keymap_from_rules(&rmlvo); - if (!desc->desc) { - log_err("cannot compile keymap from rules"); - free(desc); - return -EFAULT; - } - - /* The order of these is important! */ - init_compat(desc->desc); - init_key_types(desc->desc); - init_actions(desc->desc); - init_indicators(desc->desc); - init_autorepeat(desc->desc); + (void)rmlvo; + desc->keymap = NULL; log_debug("new keyboard description (%s, %s, %s)", layout, variant, options); @@ -1011,11 +183,10 @@ void kbd_desc_unref(struct kbd_desc *desc) return; log_debug("destroying keyboard description"); - xkb_free_keymap(desc->desc); free(desc); } void kbd_keysym_to_string(uint32_t keysym, char *str, size_t size) { - xkb_keysym_to_string(keysym, str, size); + xkb_keysym_get_name(keysym, str, size); }