Removed build dependency on xproto.
[platform/upstream/libxkbcommon.git] / src / xkbcomp / keymap.c
index 78ba966..0aaed1f 100644 (file)
  *         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 & MOD_REAL_MASK_ALL;
-
-    darray_enumerate(i, mod, keymap->mods)
-        if (mods->mods & (1 << i))
-            mods->mask |= mod->mapping;
+    mods->mask = mod_mask_get_effective(keymap, mods->mods);
 }
 
 static void
@@ -66,7 +60,7 @@ static const struct xkb_sym_interpret default_interpret = {
     .match = MATCH_ANY_OR_NONE,
     .mods = 0,
     .virtual_mod = XKB_MOD_INVALID,
-    .act = { .type = ACTION_TYPE_NONE },
+    .action = { .type = ACTION_TYPE_NONE },
 };
 
 /**
@@ -78,7 +72,6 @@ static const struct xkb_sym_interpret *
 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;
 
@@ -90,23 +83,25 @@ FindInterpForKey(struct xkb_keymap *keymap, const struct xkb_key *key,
     /*
      * 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;
@@ -114,7 +109,7 @@ FindInterpForKey(struct xkb_keymap *keymap, const struct xkb_key *key,
             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);
@@ -122,9 +117,6 @@ FindInterpForKey(struct xkb_keymap *keymap, const struct xkb_key *key,
         case MATCH_EXACTLY:
             found = (interp->mods == mods);
             break;
-        default:
-            found = false;
-            break;
         }
 
         if (found)
@@ -146,7 +138,7 @@ ApplyInterpsToKey(struct xkb_keymap *keymap, struct xkb_key *key)
         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);
@@ -158,14 +150,12 @@ ApplyInterpsToKey(struct xkb_keymap *keymap, struct xkb_key *key)
                 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;
         }
     }
 
@@ -184,21 +174,21 @@ ApplyInterpsToKey(struct xkb_keymap *keymap, struct xkb_key *key)
 static bool
 UpdateDerivedKeymapFields(struct xkb_keymap *keymap)
 {
+    struct xkb_key *key;
     struct xkb_mod *mod;
-    struct xkb_indicator_map *im;
+    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 (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. */
@@ -206,51 +196,29 @@ UpdateDerivedKeymapFields(struct xkb_keymap *keymap)
         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. */
-    darray_foreach(im, keymap->indicators)
-        ComputeEffectiveMask(keymap, &im->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);
@@ -266,36 +234,35 @@ bool
 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, XKB_LOG_MESSAGE_NO_ID,
+                        "Cannot define %s in a keymap file\n",
+                        xkb_file_type_to_string(file->file_type));
+            }
             continue;
         }
 
         if (files[file->file_type]) {
-            log_err(ctx,
+            log_err(ctx, XKB_LOG_MESSAGE_NO_ID,
                     "More than one %s section in keymap file; "
                     "All sections after the first ignored\n",
                     xkb_file_type_to_string(file->file_type));
             continue;
         }
 
-        if (!file->topName) {
-            free(file->topName);
-            file->topName = strdup(main_name);
-        }
-
         files[file->file_type] = file;
     }
 
@@ -308,7 +275,8 @@ CompileKeymap(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
          type <= LAST_KEYMAP_FILE_TYPE;
          type++) {
         if (files[type] == NULL) {
-            log_err(ctx, "Required section %s missing from keymap\n",
+            log_err(ctx, XKB_LOG_MESSAGE_NO_ID,
+                    "Required section %s missing from keymap\n",
                     xkb_file_type_to_string(type));
             ok = false;
         }
@@ -316,19 +284,18 @@ CompileKeymap(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
     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);
+        log_dbg(ctx, XKB_LOG_MESSAGE_NO_ID,
+                "Compiling %s \"%s\"\n",
+                xkb_file_type_to_string(type), files[type]->name);
 
         ok = compile_file_fns[type](files[type], keymap, merge);
         if (!ok) {
-            log_err(ctx, "Failed to compile %s\n",
+            log_err(ctx, XKB_LOG_MESSAGE_NO_ID,
+                    "Failed to compile %s\n",
                     xkb_file_type_to_string(type));
             return false;
         }