/** * Copyright © 2012 Intel Corporation * Copyright © 2012 Ran Benita * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Author: Daniel Stone */ #include "keymap.h" static void update_builtin_keymap_fields(struct xkb_keymap *keymap) { /* Predefined (AKA real, core, X11) modifiers. The order is important! */ static const char *const builtin_mods[] = { [0] = "Shift", [1] = "Lock", [2] = "Control", [3] = "Mod1", [4] = "Mod2", [5] = "Mod3", [6] = "Mod4", [7] = "Mod5" }; for (unsigned i = 0; i < ARRAY_SIZE(builtin_mods); i++) { keymap->mods.mods[i].name = xkb_atom_intern(keymap->ctx, builtin_mods[i], strlen(builtin_mods[i])); keymap->mods.mods[i].type = MOD_REAL; } keymap->mods.num_mods = ARRAY_SIZE(builtin_mods); } struct xkb_keymap * xkb_keymap_new(struct xkb_context *ctx, enum xkb_keymap_format format, enum xkb_keymap_compile_flags flags) { struct xkb_keymap *keymap; keymap = calloc(1, sizeof(*keymap)); if (!keymap) return NULL; keymap->refcnt = 1; keymap->ctx = xkb_context_ref(ctx); keymap->format = format; keymap->flags = flags; update_builtin_keymap_fields(keymap); return keymap; } struct xkb_key * XkbKeyByName(struct xkb_keymap *keymap, xkb_atom_t name, bool use_aliases) { struct xkb_key *key; xkb_keys_foreach(key, keymap) if (key->name == name) return key; if (use_aliases) { xkb_atom_t new_name = XkbResolveKeyAlias(keymap, name); if (new_name != XKB_ATOM_NONE) return XkbKeyByName(keymap, new_name, false); } return NULL; } xkb_atom_t XkbResolveKeyAlias(const struct xkb_keymap *keymap, xkb_atom_t name) { for (unsigned i = 0; i < keymap->num_key_aliases; i++) if (keymap->key_aliases[i].alias == name) return keymap->key_aliases[i].real; return XKB_ATOM_NONE; } void XkbEscapeMapName(char *name) { /* * All latin-1 alphanumerics, plus parens, slash, minus, underscore and * wildcards. */ static const unsigned char legal[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83, 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff }; if (!name) return; while (*name) { unsigned char c = *name; if (!(legal[c / 8] & (1 << (c % 8)))) *name = '_'; name++; } } xkb_mod_index_t XkbModNameToIndex(const struct xkb_mod_set *mods, xkb_atom_t name, enum mod_type type) { xkb_mod_index_t i; const struct xkb_mod *mod; xkb_mods_enumerate(i, mod, mods) if ((mod->type & type) && name == mod->name) return i; return XKB_MOD_INVALID; } bool XkbLevelsSameSyms(const struct xkb_level *a, const struct xkb_level *b) { if (a->num_syms != b->num_syms) return false; if (a->num_syms <= 1) return a->u.sym == b->u.sym; return memcmp(a->u.syms, b->u.syms, sizeof(*a->u.syms) * a->num_syms) == 0; }