X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fxkbcomp%2Ftypes.c;h=34e10286cf681713d93fb90eea13f45878bc12dd;hb=c0065c95a479c7111417a6547d26594a5e31378b;hp=ebfc99d2760ed03082c6af83cd57c7f3eccf5be0;hpb=39232e6dae3f7fcaae49ed05cb0e48117a46616e;p=platform%2Fupstream%2Flibxkbcommon.git diff --git a/src/xkbcomp/types.c b/src/xkbcomp/types.c index ebfc99d..34e1028 100644 --- a/src/xkbcomp/types.c +++ b/src/xkbcomp/types.c @@ -24,200 +24,87 @@ * ********************************************************/ +#include "config.h" + #include "xkbcomp-priv.h" #include "text.h" #include "vmod.h" #include "expr.h" #include "include.h" -/* - * The xkb_types section - * ===================== - * This section is the second to be processesed, after xkb_keycodes. - * However, it is completely independent and could have been the first - * to be processed (it does not refer to specific keys as specified in - * the xkb_keycodes section). - * - * This section defines key types, which, given a key and a keyboard - * state (i.e. modifier state and group), determine the shift level to - * be used in translating the key to keysyms. These types are assigned - * to each group in each key, in the xkb_symbols section. - * - * Key types are called this way because, in a way, they really describe - * the "type" of the key (or more correctly, a specific group of the - * key). For example, an ordinary keymap will provide a type called - * "KEYPAD", which consists of two levels, with the second level being - * chosen according to the state of the Num Lock (or Shift) modifiers. - * Another example is a type called "ONE_LEVEL", which is usually - * assigned to keys such as Escape; these have just one level and are - * not affected by the modifier state. Yet more common examples are - * "TWO_LEVEL" (with Shift choosing the second level), "ALPHABETIC" - * (where Caps Lock may also choose the second level), etc. - * - * Type definitions - * ---------------- - * Statements of the form: - * type "FOUR_LEVEL" { ... } - * - * The above would create a new type named "FOUR_LEVEL". - * The body of the definition may include statements of the following - * forms: - * - * - level_name statements (mandatory for each level in the type): - * level_name[Level1] = "Base"; - * - * Gives each level in this type a descriptive name. It isn't used - * for any thing. - * Note: A level may be specified as Level[1-8] or just a number (can - * be more than 8). - * - * - modifiers statement (mandatory, should be specified only once): - * modifiers = Shift+Lock+LevelThree; - * - * A mask of real and virtual modifiers. These are the only modifiers - * being considered when matching the modifier state against the type. - * The other modifiers, whether active or not, are masked out in the - * calculation. - * - * - map entry statements (should have at least as many mappings as there - * are levels in the type): - * map[Shift+LevelThree] = Level4; - * - * If the active modifiers, masked with the type's modifiers (as stated - * above), match (i.e. equal) the modifiers inside the map[] statement, - * then the level in the right hand side is chosen. For example, in the - * above, if in the current keyboard state the Shift and LevelThree - * modifiers are active, while the Lock modifier is not, then the - * keysym(s) in the 4th level of the group will be returned to the - * user. - * - * - preserve statements: - * map[Shift+Lock+LevelThree] = Level5; - * preserve[Shift+Lock+LevelThree] = Lock; - * - * When a map entry matches the active modifiers and the level it - * specified is chosen, then these modifiers are said to be "consumed"; - * for example, in a simple US keymap where the "g" key is assigned an - * ordinary ALPHABETIC key type, if the Lock (Caps Lock) modifier is - * active and the key is pressed, then a "G" keysym is produced (as - * opposed to lower-case "g"). This is because the type definition has - * a map entry like the following: - * map[Lock] = Level2; - * And as such the Lock modifier is consumed. This information is - * relevant for applications which further process the modifiers, - * since by then the consumed modifiers have already "done their part" - * and should be masked out. - * - * However, sometimes even if a modifier is actually used to choose - * the shift level (as Lock above), it should *not* be reported as - * consumed, for various reasons. In this case, a preserve[] statement - * can be used to augment the map entry. The modifiers inside the square - * brackets should match one of the map[] statements in the type. The - * right hand side should consists of modifiers from the left hand - * side; these modifiers are then "preserved" and not reported as - * consumed. - * - * Virtual modifier statements - * --------------------------- - * Statements of the form: - * virtual_modifiers LControl; - * - * Can appear in the xkb_types, xkb_compat, xkb_symbols sections. - * TODO - * - * Effect on keymap - * ---------------- - * After all of the xkb_types sections have been compiled, the following - * members of struct xkb_keymap are finalized: - * struct xkb_key_type *types; - * unsigned int num_types; - * char *types_section_name; - * TODO: virtual modifiers. - */ - enum type_field { - TYPE_FIELD_MASK = (1 << 0), - TYPE_FIELD_MAP = (1 << 1), - TYPE_FIELD_PRESERVE = (1 << 2), + TYPE_FIELD_MASK = (1 << 0), + TYPE_FIELD_MAP = (1 << 1), + TYPE_FIELD_PRESERVE = (1 << 2), TYPE_FIELD_LEVEL_NAME = (1 << 3), }; typedef struct { enum type_field defined; - unsigned file_id; enum merge_mode merge; xkb_atom_t name; xkb_mod_mask_t mods; xkb_level_index_t num_levels; - darray(struct xkb_kt_map_entry) entries; + darray(struct xkb_key_type_entry) entries; darray(xkb_atom_t) level_names; } KeyTypeInfo; typedef struct { char *name; int errorCount; - unsigned file_id; darray(KeyTypeInfo) types; - struct xkb_keymap *keymap; + struct xkb_mod_set mods; + + struct xkb_context *ctx; } KeyTypesInfo; /***====================================================================***/ static inline const char * -MapEntryTxt(KeyTypesInfo *info, struct xkb_kt_map_entry *entry) +MapEntryTxt(KeyTypesInfo *info, struct xkb_key_type_entry *entry) { - return ModMaskText(info->keymap, entry->mods.mods); + return ModMaskText(info->ctx, &info->mods, entry->mods.mods); } static inline const char * TypeTxt(KeyTypesInfo *info, KeyTypeInfo *type) { - return xkb_atom_text(info->keymap->ctx, type->name); + return xkb_atom_text(info->ctx, type->name); } static inline const char * TypeMaskTxt(KeyTypesInfo *info, KeyTypeInfo *type) { - return ModMaskText(info->keymap, type->mods); + return ModMaskText(info->ctx, &info->mods, type->mods); } static inline bool ReportTypeShouldBeArray(KeyTypesInfo *info, KeyTypeInfo *type, const char *field) { - return ReportShouldBeArray(info->keymap, "key type", field, + return ReportShouldBeArray(info->ctx, "key type", field, TypeTxt(info, type)); } static inline bool -ReportTypeBadType(KeyTypesInfo *info, KeyTypeInfo *type, - const char *field, const char *wanted) +ReportTypeBadType(KeyTypesInfo *info, xkb_message_code_t code, + KeyTypeInfo *type, const char *field, const char *wanted) { - return ReportBadType(info->keymap->ctx, "key type", field, + return ReportBadType(info->ctx, code, "key type", field, TypeTxt(info, type), wanted); } -static inline bool -ReportTypeBadWidth(KeyTypesInfo *info, const char *type, int has, int needs) -{ - log_err(info->keymap->ctx, - "Key type \"%s\" has %d levels, must have %d; " - "Illegal type definition ignored\n", - type, has, needs); - return false; -} - /***====================================================================***/ static void -InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap, - unsigned file_id) +InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_context *ctx, + const struct xkb_mod_set *mods) { memset(info, 0, sizeof(*info)); - info->keymap = keymap; - info->file_id = file_id; + info->ctx = ctx; + info->mods = *mods; } static void @@ -247,20 +134,20 @@ FindMatchingKeyType(KeyTypesInfo *info, xkb_atom_t name) } static bool -AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new) +AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new, bool same_file) { KeyTypeInfo *old; - int verbosity = xkb_context_get_log_verbosity(info->keymap->ctx); + const int verbosity = xkb_context_get_log_verbosity(info->ctx); old = FindMatchingKeyType(info, new->name); if (old) { if (new->merge == MERGE_REPLACE || new->merge == MERGE_OVERRIDE) { - if ((old->file_id == new->file_id && verbosity > 0) || - verbosity > 9) { - log_warn(info->keymap->ctx, + if ((same_file && verbosity > 0) || verbosity > 9) { + log_warn(info->ctx, + XKB_WARNING_CONFLICTING_KEY_TYPE_DEFINITIONS, "Multiple definitions of the %s key type; " "Earlier definition ignored\n", - xkb_atom_text(info->keymap->ctx, new->name)); + xkb_atom_text(info->ctx, new->name)); } ClearKeyTypeInfo(old); @@ -270,17 +157,17 @@ AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new) return true; } - if (old->file_id == new->file_id) - log_vrb(info->keymap->ctx, 4, + if (same_file) + log_vrb(info->ctx, 4, + XKB_WARNING_CONFLICTING_KEY_TYPE_DEFINITIONS, "Multiple definitions of the %s key type; " "Later definition ignored\n", - xkb_atom_text(info->keymap->ctx, new->name)); + xkb_atom_text(info->ctx, new->name)); ClearKeyTypeInfo(new); return true; } - new->file_id = info->file_id; darray_append(info->types, *new); return true; } @@ -291,22 +178,29 @@ static void MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from, enum merge_mode merge) { - KeyTypeInfo *type; - if (from->errorCount > 0) { into->errorCount += from->errorCount; return; } + into->mods = from->mods; + if (into->name == NULL) { into->name = from->name; from->name = NULL; } - darray_foreach(type, from->types) { - type->merge = (merge == MERGE_DEFAULT ? type->merge : merge); - if (!AddKeyType(into, type)) - into->errorCount++; + if (darray_empty(into->types)) { + into->types = from->types; + darray_init(from->types); + } + else { + KeyTypeInfo *type; + darray_foreach(type, from->types) { + type->merge = (merge == MERGE_DEFAULT ? type->merge : merge); + if (!AddKeyType(into, type, false)) + into->errorCount++; + } } } @@ -314,38 +208,36 @@ static void HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge); static bool -HandleIncludeKeyTypes(KeyTypesInfo *info, IncludeStmt *stmt) +HandleIncludeKeyTypes(KeyTypesInfo *info, IncludeStmt *include) { - enum merge_mode merge = MERGE_DEFAULT; - XkbFile *rtrn; - KeyTypesInfo included, next_incl; - - InitKeyTypesInfo(&included, info->keymap, info->file_id); - if (stmt->stmt) { - free(included.name); - included.name = stmt->stmt; - stmt->stmt = NULL; - } + KeyTypesInfo included; + + InitKeyTypesInfo(&included, info->ctx, &info->mods); + included.name = include->stmt; + include->stmt = NULL; + + for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) { + KeyTypesInfo next_incl; + XkbFile *file; - for (; stmt; stmt = stmt->next_incl) { - if (!ProcessIncludeFile(info->keymap->ctx, stmt, FILE_TYPE_TYPES, - &rtrn, &merge)) { + file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_TYPES); + if (!file) { info->errorCount += 10; ClearKeyTypesInfo(&included); return false; } - InitKeyTypesInfo(&next_incl, info->keymap, rtrn->id); + InitKeyTypesInfo(&next_incl, info->ctx, &included.mods); - HandleKeyTypesFile(&next_incl, rtrn, merge); + HandleKeyTypesFile(&next_incl, file, stmt->merge); - MergeIncludedKeyTypes(&included, &next_incl, merge); + MergeIncludedKeyTypes(&included, &next_incl, stmt->merge); ClearKeyTypesInfo(&next_incl); - FreeXkbFile(rtrn); + FreeXkbFile(file); } - MergeIncludedKeyTypes(info, &included, merge); + MergeIncludedKeyTypes(info, &included, include->merge); ClearKeyTypesInfo(&included); return (info->errorCount == 0); @@ -360,24 +252,25 @@ SetModifiers(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx, xkb_mod_mask_t mods; if (arrayNdx) - log_warn(info->keymap->ctx, + log_warn(info->ctx, XKB_LOG_MESSAGE_NO_ID, "The modifiers field of a key type is not an array; " "Illegal array subscript ignored\n"); - if (!ExprResolveVModMask(info->keymap, value, &mods)) { - log_err(info->keymap->ctx, + if (!ExprResolveModMask(info->ctx, value, MOD_BOTH, &info->mods, &mods)) { + log_err(info->ctx, + XKB_ERROR_UNSUPPORTED_MODIFIER_MASK, "Key type mask field must be a modifier mask; " "Key type definition ignored\n"); return false; } if (type->defined & TYPE_FIELD_MASK) { - log_warn(info->keymap->ctx, + log_warn(info->ctx, XKB_LOG_MESSAGE_NO_ID, "Multiple modifier mask definitions for key type %s; " "Using %s, ignoring %s\n", - xkb_atom_text(info->keymap->ctx, type->name), + xkb_atom_text(info->ctx, type->name), TypeMaskTxt(info, type), - ModMaskText(info->keymap, mods)); + ModMaskText(info->ctx, &info->mods, mods)); return false; } @@ -387,10 +280,10 @@ SetModifiers(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx, /***====================================================================***/ -static struct xkb_kt_map_entry * +static struct xkb_key_type_entry * FindMatchingMapEntry(KeyTypeInfo *type, xkb_mod_mask_t mods) { - struct xkb_kt_map_entry *entry; + struct xkb_key_type_entry *entry; darray_foreach(entry, type->entries) if (entry->mods.mods == mods) @@ -401,14 +294,15 @@ FindMatchingMapEntry(KeyTypeInfo *type, xkb_mod_mask_t mods) static bool AddMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, - struct xkb_kt_map_entry *new, bool clobber, bool report) + struct xkb_key_type_entry *new, bool clobber, bool report) { - struct xkb_kt_map_entry * old; + struct xkb_key_type_entry *old; old = FindMatchingMapEntry(type, new->mods.mods); if (old) { if (report && old->level != new->level) { - log_warn(info->keymap->ctx, + log_warn(info->ctx, + XKB_WARNING_CONFLICTING_KEY_TYPE_MAP_ENTRY, "Multiple map entries for %s in %s; " "Using %d, ignoring %d\n", MapEntryTxt(info, new), TypeTxt(info, type), @@ -416,8 +310,9 @@ AddMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, (clobber ? old->level : new->level) + 1); } else { - log_vrb(info->keymap->ctx, 10, - "Multiple occurences of map[%s]= %d in %s; Ignored\n", + log_vrb(info->ctx, 10, + XKB_WARNING_CONFLICTING_KEY_TYPE_MAP_ENTRY, + "Multiple occurrences of map[%s]= %d in %s; Ignored\n", MapEntryTxt(info, new), new->level + 1, TypeTxt(info, type)); return true; @@ -443,28 +338,32 @@ static bool SetMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx, ExprDef *value) { - struct xkb_kt_map_entry entry; + struct xkb_key_type_entry entry; if (arrayNdx == NULL) return ReportTypeShouldBeArray(info, type, "map entry"); - if (!ExprResolveVModMask(info->keymap, arrayNdx, &entry.mods.mods)) - return ReportTypeBadType(info, type, "map entry", "modifier mask"); + if (!ExprResolveModMask(info->ctx, arrayNdx, MOD_BOTH, &info->mods, + &entry.mods.mods)) + return ReportTypeBadType(info, XKB_ERROR_UNSUPPORTED_MODIFIER_MASK, + type, "map entry", "modifier mask"); if (entry.mods.mods & (~type->mods)) { - log_vrb(info->keymap->ctx, 1, - "Map entry for unused modifiers in %s; " + log_vrb(info->ctx, 1, + XKB_WARNING_UNDECLARED_MODIFIERS_IN_KEY_TYPE, + "Map entry for modifiers not used by type %s; " "Using %s instead of %s\n", TypeTxt(info, type), - ModMaskText(info->keymap, entry.mods.mods & type->mods), + ModMaskText(info->ctx, &info->mods, + entry.mods.mods & type->mods), MapEntryTxt(info, &entry)); entry.mods.mods &= type->mods; } - if (!ExprResolveLevel(info->keymap->ctx, value, &entry.level)) { - log_err(info->keymap->ctx, - "Level specifications in a key type must be integer; " - "Ignoring malformed level specification\n"); + if (!ExprResolveLevel(info->ctx, value, &entry.level)) { + log_err(info->ctx, XKB_ERROR_UNSUPPORTED_SHIFT_LEVEL, + "Level specifications in a key type must be integer; " + "Ignoring malformed level specification\n"); return false; } @@ -479,8 +378,8 @@ static bool AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type, xkb_mod_mask_t mods, xkb_mod_mask_t preserve_mods) { - struct xkb_kt_map_entry *entry; - struct xkb_kt_map_entry new; + struct xkb_key_type_entry *entry; + struct xkb_key_type_entry new; darray_foreach(entry, type->entries) { if (entry->mods.mods != mods) @@ -494,22 +393,24 @@ AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type, /* Map exists with same preserve; do nothing. */ if (entry->preserve.mods == preserve_mods) { - log_vrb(info->keymap->ctx, 10, + log_vrb(info->ctx, 10, + XKB_WARNING_DUPLICATE_ENTRY, "Identical definitions for preserve[%s] in %s; " "Ignored\n", - ModMaskText(info->keymap, mods), + ModMaskText(info->ctx, &info->mods, mods), TypeTxt(info, type)); return true; } /* Map exists with different preserve; latter wins. */ - log_vrb(info->keymap->ctx, 1, + log_vrb(info->ctx, 1, + XKB_WARNING_CONFLICTING_KEY_TYPE_PRESERVE_ENTRIES, "Multiple definitions for preserve[%s] in %s; " "Using %s, ignoring %s\n", - ModMaskText(info->keymap, mods), + ModMaskText(info->ctx, &info->mods, mods), TypeTxt(info, type), - ModMaskText(info->keymap, preserve_mods), - ModMaskText(info->keymap, entry->preserve.mods)); + ModMaskText(info->ctx, &info->mods, preserve_mods), + ModMaskText(info->ctx, &info->mods, entry->preserve.mods)); entry->preserve.mods = preserve_mods; return true; @@ -518,7 +419,7 @@ AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type, /* * Map does not exist, i.e. preserve[] came before map[]. * Create a map with the specified mask mapping to Level1. The level - * may be overriden later with an explicit map[] statement. + * may be overridden later with an explicit map[] statement. */ new.level = 0; new.mods.mods = mods; @@ -536,28 +437,31 @@ SetPreserve(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx, if (arrayNdx == NULL) return ReportTypeShouldBeArray(info, type, "preserve entry"); - if (!ExprResolveVModMask(info->keymap, arrayNdx, &mods)) - return ReportTypeBadType(info, type, "preserve entry", - "modifier mask"); + if (!ExprResolveModMask(info->ctx, arrayNdx, MOD_BOTH, &info->mods, &mods)) + return ReportTypeBadType(info, XKB_ERROR_UNSUPPORTED_MODIFIER_MASK, + type, "preserve entry", "modifier mask"); if (mods & ~type->mods) { const char *before, *after; - before = ModMaskText(info->keymap, mods); + before = ModMaskText(info->ctx, &info->mods, mods); mods &= type->mods; - after = ModMaskText(info->keymap, mods); + after = ModMaskText(info->ctx, &info->mods, mods); - log_vrb(info->keymap->ctx, 1, - "Preserve for modifiers not used by the %s type; " + log_vrb(info->ctx, 1, + XKB_WARNING_UNDECLARED_MODIFIERS_IN_KEY_TYPE, + "Preserve entry for modifiers not used by the %s type; " "Index %s converted to %s\n", TypeTxt(info, type), before, after); } - if (!ExprResolveVModMask(info->keymap, value, &preserve_mods)) { - log_err(info->keymap->ctx, + if (!ExprResolveModMask(info->ctx, value, MOD_BOTH, &info->mods, + &preserve_mods)) { + log_err(info->ctx, + XKB_ERROR_UNSUPPORTED_MODIFIER_MASK, "Preserve value in a key type is not a modifier mask; " "Ignoring preserve[%s] in type %s\n", - ModMaskText(info->keymap, mods), + ModMaskText(info->ctx, &info->mods, mods), TypeTxt(info, type)); return false; } @@ -565,14 +469,15 @@ SetPreserve(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx, if (preserve_mods & ~mods) { const char *before, *after; - before = ModMaskText(info->keymap, preserve_mods); + before = ModMaskText(info->ctx, &info->mods, preserve_mods); preserve_mods &= mods; - after = ModMaskText(info->keymap, preserve_mods); + after = ModMaskText(info->ctx, &info->mods, preserve_mods); - log_vrb(info->keymap->ctx, 1, + log_vrb(info->ctx, 1, + XKB_WARNING_ILLEGAL_KEY_TYPE_PRESERVE_RESULT, "Illegal value for preserve[%s] in type %s; " "Converted %s to %s\n", - ModMaskText(info->keymap, mods), + ModMaskText(info->ctx, &info->mods, mods), TypeTxt(info, type), before, after); } @@ -593,7 +498,8 @@ AddLevelName(KeyTypesInfo *info, KeyTypeInfo *type, /* Same level, same name. */ if (darray_item(type->level_names, level) == name) { - log_vrb(info->keymap->ctx, 10, + log_vrb(info->ctx, 10, + XKB_WARNING_DUPLICATE_ENTRY, "Duplicate names for level %d of key type %s; Ignored\n", level + 1, TypeTxt(info, type)); return true; @@ -602,10 +508,11 @@ AddLevelName(KeyTypesInfo *info, KeyTypeInfo *type, /* Same level, different name. */ if (darray_item(type->level_names, level) != XKB_ATOM_NONE) { const char *old, *new; - old = xkb_atom_text(info->keymap->ctx, + old = xkb_atom_text(info->ctx, darray_item(type->level_names, level)); - new = xkb_atom_text(info->keymap->ctx, name); - log_vrb(info->keymap->ctx, 1, + new = xkb_atom_text(info->ctx, name); + log_vrb(info->ctx, 1, + XKB_WARNING_CONFLICTING_KEY_TYPE_LEVEL_NAMES, "Multiple names for level %d of key type %s; " "Using %s, ignoring %s\n", level + 1, TypeTxt(info, type), @@ -628,19 +535,20 @@ SetLevelName(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx, { xkb_level_index_t level; xkb_atom_t level_name; - struct xkb_context *ctx = info->keymap->ctx; if (arrayNdx == NULL) return ReportTypeShouldBeArray(info, type, "level name"); - if (!ExprResolveLevel(ctx, arrayNdx, &level)) - return ReportTypeBadType(info, type, "level name", "integer"); + if (!ExprResolveLevel(info->ctx, arrayNdx, &level)) + return ReportTypeBadType(info, XKB_ERROR_UNSUPPORTED_SHIFT_LEVEL, + type, "level name", "integer"); - if (!ExprResolveString(ctx, value, &level_name)) { - log_err(info->keymap->ctx, + if (!ExprResolveString(info->ctx, value, &level_name)) { + log_err(info->ctx, + XKB_ERROR_WRONG_FIELD_TYPE, "Non-string name for level %d in key type %s; " "Ignoring illegal level name definition\n", - level + 1, xkb_atom_text(ctx, type->name)); + level + 1, xkb_atom_text(info->ctx, type->name)); return false; } @@ -672,7 +580,8 @@ SetKeyTypeField(KeyTypesInfo *info, KeyTypeInfo *type, type_field = TYPE_FIELD_LEVEL_NAME; ok = SetLevelName(info, type, arrayNdx, value); } else { - log_err(info->keymap->ctx, + log_err(info->ctx, + XKB_ERROR_UNKNOWN_FIELD, "Unknown field %s in key type %s; Definition ignored\n", field, TypeTxt(info, type)); } @@ -689,13 +598,14 @@ HandleKeyTypeBody(KeyTypesInfo *info, VarDef *def, KeyTypeInfo *type) ExprDef *arrayNdx; for (; def; def = (VarDef *) def->common.next) { - ok = ExprResolveLhs(info->keymap->ctx, def->name, &elem, &field, + ok = ExprResolveLhs(info->ctx, def->name, &elem, &field, &arrayNdx); if (!ok) continue; if (elem && istreq(elem, "type")) { - log_err(info->keymap->ctx, + log_err(info->ctx, + XKB_ERROR_INVALID_SET_DEFAULT_STATEMENT, "Support for changing the default type has been removed; " "Statement ignored\n"); continue; @@ -712,7 +622,6 @@ HandleKeyTypeDef(KeyTypesInfo *info, KeyTypeDef *def, enum merge_mode merge) { KeyTypeInfo type = { .defined = 0, - .file_id = info->file_id, .merge = (def->merge == MERGE_DEFAULT ? merge : def->merge), .name = def->name, .mods = 0, @@ -726,7 +635,7 @@ HandleKeyTypeDef(KeyTypesInfo *info, KeyTypeDef *def, enum merge_mode merge) return false; } - if (!AddKeyType(info, &type)) { + if (!AddKeyType(info, &type, true)) { info->errorCount++; return false; } @@ -738,30 +647,31 @@ static void HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge) { bool ok; - ParseCommon *stmt; free(info->name); info->name = strdup_safe(file->name); - for (stmt = file->defs; stmt; stmt = stmt->next) { + for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) { switch (stmt->type) { case STMT_INCLUDE: ok = HandleIncludeKeyTypes(info, (IncludeStmt *) stmt); break; - case STMT_TYPE: /* e.g. type "ONE_LEVEL" */ + case STMT_TYPE: ok = HandleKeyTypeDef(info, (KeyTypeDef *) stmt, merge); break; case STMT_VAR: - log_err(info->keymap->ctx, + log_err(info->ctx, + XKB_ERROR_WRONG_STATEMENT_TYPE, "Support for changing the default type has been removed; " "Statement ignored\n"); ok = true; break; - case STMT_VMOD: /* virtual_modifiers NumLock, ... */ - ok = HandleVModDef(info->keymap, (VModDef *) stmt); + case STMT_VMOD: + ok = HandleVModDef(info->ctx, &info->mods, (VModDef *) stmt, merge); break; default: - log_err(info->keymap->ctx, + log_err(info->ctx, + XKB_ERROR_WRONG_STATEMENT_TYPE, "Key type files may not include other declarations; " "Ignoring %s\n", stmt_type_to_string(stmt->type)); ok = false; @@ -772,70 +682,72 @@ HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge) info->errorCount++; if (info->errorCount > 10) { - log_err(info->keymap->ctx, - "Abandoning keytypes file \"%s\"\n", file->topName); + log_err(info->ctx, + XKB_ERROR_INVALID_SYNTAX, + "Abandoning keytypes file \"%s\"\n", file->name); break; } } } -static void -CopyDefToKeyType(KeyTypeInfo *def, struct xkb_key_type *type) -{ - type->mods.mods = def->mods; - type->num_levels = def->num_levels; - type->map = darray_mem(def->entries, 0); - type->num_entries = darray_size(def->entries); - darray_init(def->entries); - type->name = def->name; - type->level_names = darray_mem(def->level_names, 0); - darray_init(def->level_names); -} +/***====================================================================***/ static bool CopyKeyTypesToKeymap(struct xkb_keymap *keymap, KeyTypesInfo *info) { - unsigned int i; - unsigned int num_types; + unsigned num_types; + struct xkb_key_type *types; - num_types = darray_size(info->types) ? darray_size(info->types) : 1; - keymap->types = calloc(num_types, sizeof(*keymap->types)); - if (!keymap->types) + num_types = darray_empty(info->types) ? 1 : darray_size(info->types); + types = calloc(num_types, sizeof(*types)); + if (!types) return false; - keymap->num_types = num_types; - /* * If no types were specified, a default unnamed one-level type is * used for all keys. */ if (darray_empty(info->types)) { - KeyTypeInfo dflt = { - .name = xkb_atom_intern(keymap->ctx, "default"), - .mods = 0, - .num_levels = 1, - .entries = darray_new(), - .level_names = darray_new(), - }; - - CopyDefToKeyType(&dflt, &keymap->types[0]); - } else { - for (i = 0; i < num_types; i++) - CopyDefToKeyType(&darray_item(info->types, i), &keymap->types[i]); + struct xkb_key_type *type = &types[0]; + + type->mods.mods = 0; + type->num_levels = 1; + type->entries = NULL; + type->num_entries = 0; + type->name = xkb_atom_intern_literal(keymap->ctx, "default"); + type->level_names = NULL; + type->num_level_names = 0; + } + else { + for (unsigned i = 0; i < num_types; i++) { + KeyTypeInfo *def = &darray_item(info->types, i); + struct xkb_key_type *type = &types[i]; + + type->name = def->name; + type->mods.mods = def->mods; + type->num_levels = def->num_levels; + darray_steal(def->level_names, &type->level_names, &type->num_level_names); + darray_steal(def->entries, &type->entries, &type->num_entries); + } } keymap->types_section_name = strdup_safe(info->name); - + XkbEscapeMapName(keymap->types_section_name); + keymap->num_types = num_types; + keymap->types = types; + keymap->mods = info->mods; return true; } +/***====================================================================***/ + bool CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge) { KeyTypesInfo info; - InitKeyTypesInfo(&info, keymap, file->id); + InitKeyTypesInfo(&info, keymap->ctx, &keymap->mods); HandleKeyTypesFile(&info, file, merge); if (info.errorCount != 0)