* Ran Benita <ran234@gmail.com>
*/
+#include "config.h"
+
#include "xkbcomp-priv.h"
static void
ComputeEffectiveMask(struct xkb_keymap *keymap, struct xkb_mods *mods)
{
- const struct xkb_mod *mod;
- xkb_mod_index_t i;
-
- /* The effective mask is only real mods for now. */
- mods->mask = mods->mods & 0xff;
-
- darray_enumerate(i, mod, keymap->mods)
- if (mod->type == MOD_VIRT && mods->mods & (1 << i))
- mods->mask |= mod->mapping;
+ mods->mask = mod_mask_get_effective(keymap, mods->mods);
}
static void
.match = MATCH_ANY_OR_NONE,
.mods = 0,
.virtual_mod = XKB_MOD_INVALID,
- .act = { .type = ACTION_TYPE_NONE },
+ .action = { .type = ACTION_TYPE_NONE },
};
/**
FindInterpForKey(struct xkb_keymap *keymap, const struct xkb_key *key,
xkb_layout_index_t group, xkb_level_index_t level)
{
- const struct xkb_sym_interpret *interp;
const xkb_keysym_t *syms;
int num_syms;
/*
* There may be multiple matchings interprets; we should always return
* the most specific. Here we rely on compat.c to set up the
- * sym_interpret array from the most specific to the least specific,
+ * sym_interprets array from the most specific to the least specific,
* such that when we find a match we return immediately.
*/
- darray_foreach(interp, keymap->sym_interpret) {
+ for (unsigned i = 0; i < keymap->num_sym_interprets; i++) {
+ const struct xkb_sym_interpret *interp = &keymap->sym_interprets[i];
+
xkb_mod_mask_t mods;
- bool found;
+ bool found = false;
if ((num_syms > 1 || interp->sym != syms[0]) &&
interp->sym != XKB_KEY_NoSymbol)
continue;
- if (level == 0 || !(interp->match & MATCH_LEVEL_ONE_ONLY))
- mods = key->modmap;
- else
+ if (interp->level_one_only && level != 0)
mods = 0;
+ else
+ mods = key->modmap;
- switch (interp->match & MATCH_OP_MASK) {
+ switch (interp->match) {
case MATCH_NONE:
found = !(interp->mods & mods);
break;
found = (!mods || (interp->mods & mods));
break;
case MATCH_ANY:
- found = !!(interp->mods & mods);
+ found = (interp->mods & mods);
break;
case MATCH_ALL:
found = ((interp->mods & mods) == interp->mods);
case MATCH_EXACTLY:
found = (interp->mods == mods);
break;
- default:
- found = false;
- break;
}
if (found)
return true;
for (group = 0; group < key->num_groups; group++) {
- for (level = 0; level < XkbKeyGroupWidth(key, group); level++) {
+ for (level = 0; level < XkbKeyNumLevels(key, group); level++) {
const struct xkb_sym_interpret *interp;
interp = FindInterpForKey(keymap, key, group, level);
if (!(key->explicit & EXPLICIT_REPEAT) && interp->repeat)
key->repeats = true;
- if ((group == 0 && level == 0) ||
- !(interp->match & MATCH_LEVEL_ONE_ONLY)) {
+ if ((group == 0 && level == 0) || !interp->level_one_only)
if (interp->virtual_mod != XKB_MOD_INVALID)
- vmodmap |= (1 << interp->virtual_mod);
- }
+ vmodmap |= (1u << interp->virtual_mod);
- if (interp->act.type != ACTION_TYPE_NONE)
- key->groups[group].levels[level].action = interp->act;
+ if (interp->action.type != ACTION_TYPE_NONE)
+ key->groups[group].levels[level].action = interp->action;
}
}
static bool
UpdateDerivedKeymapFields(struct xkb_keymap *keymap)
{
+ struct xkb_key *key;
struct xkb_mod *mod;
- xkb_led_index_t led;
+ struct xkb_led *led;
unsigned int i, j;
- struct xkb_key *key;
/* Find all the interprets for the key and bind them to actions,
* which will also update the vmodmap. */
- xkb_foreach_key(key, keymap)
+ xkb_keys_foreach(key, keymap)
if (!ApplyInterpsToKey(keymap, key))
return false;
/* Update keymap->mods, the virtual -> real mod mapping. */
- xkb_foreach_key(key, keymap)
- darray_enumerate(i, mod, keymap->mods)
- if (mod->type == MOD_VIRT && key->vmodmap & (1 << i))
+ xkb_keys_foreach(key, keymap)
+ xkb_mods_enumerate(i, mod, &keymap->mods)
+ if (key->vmodmap & (1u << i))
mod->mapping |= key->modmap;
/* Now update the level masks for all the types to reflect the vmods. */
ComputeEffectiveMask(keymap, &keymap->types[i].mods);
for (j = 0; j < keymap->types[i].num_entries; j++) {
- ComputeEffectiveMask(keymap, &keymap->types[i].map[j].mods);
- ComputeEffectiveMask(keymap, &keymap->types[i].map[j].preserve);
+ ComputeEffectiveMask(keymap, &keymap->types[i].entries[j].mods);
+ ComputeEffectiveMask(keymap, &keymap->types[i].entries[j].preserve);
}
}
/* Update action modifiers. */
- xkb_foreach_key(key, keymap)
+ xkb_keys_foreach(key, keymap)
for (i = 0; i < key->num_groups; i++)
- for (j = 0; j < XkbKeyGroupWidth(key, i); j++)
+ for (j = 0; j < XkbKeyNumLevels(key, i); j++)
UpdateActionMods(keymap, &key->groups[i].levels[j].action,
key->modmap);
- /* Update vmod -> indicator maps. */
- for (led = 0; led < XKB_NUM_INDICATORS; led++)
- ComputeEffectiveMask(keymap, &keymap->indicators[led].mods);
+ /* Update vmod -> led maps. */
+ xkb_leds_foreach(led, keymap)
+ ComputeEffectiveMask(keymap, &led->mods);
/* Find maximum number of groups out of all keys in the keymap. */
- xkb_foreach_key(key, keymap)
+ xkb_keys_foreach(key, keymap)
keymap->num_groups = MAX(keymap->num_groups, key->num_groups);
return true;
}
-static bool
-UpdateBuiltinKeymapFields(struct xkb_keymap *keymap)
-{
- struct xkb_context *ctx = keymap->ctx;
-
- /*
- * Add predefined (AKA real, core, X11) modifiers.
- * The order is important!
- */
- darray_appends(keymap->mods,
- { .name = xkb_atom_intern(ctx, "Shift"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Lock"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Control"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Mod1"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Mod2"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Mod3"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Mod4"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Mod5"), .type = MOD_REAL });
-
- return true;
-}
-
typedef bool (*compile_file_fn)(XkbFile *file,
struct xkb_keymap *keymap,
enum merge_mode merge);
CompileKeymap(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
{
bool ok;
- const char *main_name;
XkbFile *files[LAST_KEYMAP_FILE_TYPE + 1] = { NULL };
enum xkb_file_type type;
struct xkb_context *ctx = keymap->ctx;
- main_name = file->name ? file->name : "(unnamed)";
-
/* Collect section files and check for duplicates. */
for (file = (XkbFile *) file->defs; file;
file = (XkbFile *) file->common.next) {
if (file->file_type < FIRST_KEYMAP_FILE_TYPE ||
file->file_type > LAST_KEYMAP_FILE_TYPE) {
- log_err(ctx, "Cannot define %s in a keymap file\n",
- xkb_file_type_to_string(file->file_type));
+ if (file->file_type == FILE_TYPE_GEOMETRY) {
+ log_vrb(ctx, 1,
+ XKB_WARNING_UNSUPPORTED_GEOMETRY_SECTION,
+ "Geometry sections are not supported; ignoring\n");
+ } else {
+ log_err(ctx, "Cannot define %s in a keymap file\n",
+ xkb_file_type_to_string(file->file_type));
+ }
continue;
}
continue;
}
- if (!file->topName) {
- free(file->topName);
- file->topName = strdup(main_name);
- }
-
files[file->file_type] = file;
}
if (!ok)
return false;
- if (!UpdateBuiltinKeymapFields(keymap))
- return false;
-
/* Compile sections. */
for (type = FIRST_KEYMAP_FILE_TYPE;
type <= LAST_KEYMAP_FILE_TYPE;
type++) {
log_dbg(ctx, "Compiling %s \"%s\"\n",
- xkb_file_type_to_string(type), files[type]->topName);
+ xkb_file_type_to_string(type), files[type]->name);
ok = compile_file_fns[type](files[type], keymap, merge);
if (!ok) {