*
********************************************************/
+#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 _KeyTypeInfo {
+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 _KeyTypesInfo {
+typedef struct {
char *name;
int errorCount;
- unsigned file_id;
darray(KeyTypeInfo) types;
- VModInfo vmods;
- 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 VModMaskText(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 VModMaskText(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;
- InitVModInfo(&info->vmods, keymap);
+ info->ctx = ctx;
+ info->mods = *mods;
}
static void
}
static bool
-AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new)
+AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new, bool same_file)
{
KeyTypeInfo *old;
- int verbosity = xkb_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);
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;
}
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++;
+ }
}
}
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);
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");
- /* get modifier mask for current type */
- 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),
- VModMaskText(info->keymap, mods));
+ ModMaskText(info->ctx, &info->mods, mods));
return false;
}
/***====================================================================***/
-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)
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),
(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;
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),
- VModMaskText(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;
}
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)
/* 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",
- VModMaskText(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",
- VModMaskText(info->keymap, mods),
+ ModMaskText(info->ctx, &info->mods, mods),
TypeTxt(info, type),
- VModMaskText(info->keymap, preserve_mods),
- VModMaskText(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;
/*
* 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;
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 = VModMaskText(info->keymap, mods);
+ before = ModMaskText(info->ctx, &info->mods, mods);
mods &= type->mods;
- after = VModMaskText(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",
- VModMaskText(info->keymap, mods),
+ ModMaskText(info->ctx, &info->mods, mods),
TypeTxt(info, type));
return false;
}
if (preserve_mods & ~mods) {
const char *before, *after;
- before = VModMaskText(info->keymap, preserve_mods);
+ before = ModMaskText(info->ctx, &info->mods, preserve_mods);
preserve_mods &= mods;
- after = VModMaskText(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",
- VModMaskText(info->keymap, mods),
+ ModMaskText(info->ctx, &info->mods, mods),
TypeTxt(info, type), before, after);
}
/* 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;
/* 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),
{
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;
}
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));
}
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;
{
KeyTypeInfo type = {
.defined = 0,
- .file_id = info->file_id,
.merge = (def->merge == MERGE_DEFAULT ? merge : def->merge),
.name = def->name,
.mods = 0,
return false;
}
- if (!AddKeyType(info, &type)) {
+ if (!AddKeyType(info, &type, true)) {
info->errorCount++;
return false;
}
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((VModDef *) stmt, info->keymap, merge,
- &info->vmods);
+ 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;
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)