Home | History | Annotate | Download | only in xkbcomp
      1 /************************************************************
      2  * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
      3  *
      4  * Permission to use, copy, modify, and distribute this
      5  * software and its documentation for any purpose and without
      6  * fee is hereby granted, provided that the above copyright
      7  * notice appear in all copies and that both that copyright
      8  * notice and this permission notice appear in supporting
      9  * documentation, and that the name of Silicon Graphics not be
     10  * used in advertising or publicity pertaining to distribution
     11  * of the software without specific prior written permission.
     12  * Silicon Graphics makes no representation about the suitability
     13  * of this software for any purpose. It is provided "as is"
     14  * without any express or implied warranty.
     15  *
     16  * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
     17  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
     18  * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
     19  * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
     20  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     21  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
     22  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
     23  * THE USE OR PERFORMANCE OF THIS SOFTWARE.
     24  *
     25  ********************************************************/
     26 
     27 #include "xkbcomp-priv.h"
     28 #include "text.h"
     29 #include "vmod.h"
     30 #include "expr.h"
     31 #include "include.h"
     32 
     33 enum type_field {
     34     TYPE_FIELD_MASK = (1 << 0),
     35     TYPE_FIELD_MAP = (1 << 1),
     36     TYPE_FIELD_PRESERVE = (1 << 2),
     37     TYPE_FIELD_LEVEL_NAME = (1 << 3),
     38 };
     39 
     40 typedef struct {
     41     enum type_field defined;
     42     enum merge_mode merge;
     43 
     44     xkb_atom_t name;
     45     xkb_mod_mask_t mods;
     46     xkb_level_index_t num_levels;
     47     darray(struct xkb_key_type_entry) entries;
     48     darray(xkb_atom_t) level_names;
     49 } KeyTypeInfo;
     50 
     51 typedef struct {
     52     char *name;
     53     int errorCount;
     54 
     55     darray(KeyTypeInfo) types;
     56     struct xkb_mod_set mods;
     57 
     58     struct xkb_context *ctx;
     59 } KeyTypesInfo;
     60 
     61 /***====================================================================***/
     62 
     63 static inline const char *
     64 MapEntryTxt(KeyTypesInfo *info, struct xkb_key_type_entry *entry)
     65 {
     66     return ModMaskText(info->ctx, &info->mods, entry->mods.mods);
     67 }
     68 
     69 static inline const char *
     70 TypeTxt(KeyTypesInfo *info, KeyTypeInfo *type)
     71 {
     72     return xkb_atom_text(info->ctx, type->name);
     73 }
     74 
     75 static inline const char *
     76 TypeMaskTxt(KeyTypesInfo *info, KeyTypeInfo *type)
     77 {
     78     return ModMaskText(info->ctx, &info->mods, type->mods);
     79 }
     80 
     81 static inline bool
     82 ReportTypeShouldBeArray(KeyTypesInfo *info, KeyTypeInfo *type,
     83                         const char *field)
     84 {
     85     return ReportShouldBeArray(info->ctx, "key type", field,
     86                                TypeTxt(info, type));
     87 }
     88 
     89 static inline bool
     90 ReportTypeBadType(KeyTypesInfo *info, KeyTypeInfo *type,
     91                   const char *field, const char *wanted)
     92 {
     93     return ReportBadType(info->ctx, "key type", field,
     94                          TypeTxt(info, type), wanted);
     95 }
     96 
     97 /***====================================================================***/
     98 
     99 static void
    100 InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_context *ctx,
    101                  const struct xkb_mod_set *mods)
    102 {
    103     memset(info, 0, sizeof(*info));
    104     info->ctx = ctx;
    105     info->mods = *mods;
    106 }
    107 
    108 static void
    109 ClearKeyTypeInfo(KeyTypeInfo *type)
    110 {
    111     darray_free(type->entries);
    112     darray_free(type->level_names);
    113 }
    114 
    115 static void
    116 ClearKeyTypesInfo(KeyTypesInfo *info)
    117 {
    118     free(info->name);
    119     darray_free(info->types);
    120 }
    121 
    122 static KeyTypeInfo *
    123 FindMatchingKeyType(KeyTypesInfo *info, xkb_atom_t name)
    124 {
    125     KeyTypeInfo *old;
    126 
    127     darray_foreach(old, info->types)
    128         if (old->name == name)
    129             return old;
    130 
    131     return NULL;
    132 }
    133 
    134 static bool
    135 AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new, bool same_file)
    136 {
    137     KeyTypeInfo *old;
    138     const int verbosity = xkb_context_get_log_verbosity(info->ctx);
    139 
    140     old = FindMatchingKeyType(info, new->name);
    141     if (old) {
    142         if (new->merge == MERGE_REPLACE || new->merge == MERGE_OVERRIDE) {
    143             if ((same_file && verbosity > 0) || verbosity > 9) {
    144                 log_warn(info->ctx,
    145                          "Multiple definitions of the %s key type; "
    146                          "Earlier definition ignored\n",
    147                          xkb_atom_text(info->ctx, new->name));
    148             }
    149 
    150             ClearKeyTypeInfo(old);
    151             *old = *new;
    152             darray_init(new->entries);
    153             darray_init(new->level_names);
    154             return true;
    155         }
    156 
    157         if (same_file)
    158             log_vrb(info->ctx, 4,
    159                     "Multiple definitions of the %s key type; "
    160                     "Later definition ignored\n",
    161                     xkb_atom_text(info->ctx, new->name));
    162 
    163         ClearKeyTypeInfo(new);
    164         return true;
    165     }
    166 
    167     darray_append(info->types, *new);
    168     return true;
    169 }
    170 
    171 /***====================================================================***/
    172 
    173 static void
    174 MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
    175                       enum merge_mode merge)
    176 {
    177     KeyTypeInfo *type;
    178 
    179     if (from->errorCount > 0) {
    180         into->errorCount += from->errorCount;
    181         return;
    182     }
    183 
    184     into->mods = from->mods;
    185 
    186     if (into->name == NULL) {
    187         into->name = from->name;
    188         from->name = NULL;
    189     }
    190 
    191     if (darray_empty(into->types)) {
    192         into->types = from->types;
    193         darray_init(from->types);
    194     }
    195     else {
    196         darray_foreach(type, from->types) {
    197             type->merge = (merge == MERGE_DEFAULT ? type->merge : merge);
    198             if (!AddKeyType(into, type, false))
    199                 into->errorCount++;
    200         }
    201     }
    202 }
    203 
    204 static void
    205 HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge);
    206 
    207 static bool
    208 HandleIncludeKeyTypes(KeyTypesInfo *info, IncludeStmt *include)
    209 {
    210     KeyTypesInfo included;
    211 
    212     InitKeyTypesInfo(&included, info->ctx, &info->mods);
    213     included.name = include->stmt;
    214     include->stmt = NULL;
    215 
    216     for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) {
    217         KeyTypesInfo next_incl;
    218         XkbFile *file;
    219 
    220         file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_TYPES);
    221         if (!file) {
    222             info->errorCount += 10;
    223             ClearKeyTypesInfo(&included);
    224             return false;
    225         }
    226 
    227         InitKeyTypesInfo(&next_incl, info->ctx, &included.mods);
    228 
    229         HandleKeyTypesFile(&next_incl, file, stmt->merge);
    230 
    231         MergeIncludedKeyTypes(&included, &next_incl, stmt->merge);
    232 
    233         ClearKeyTypesInfo(&next_incl);
    234         FreeXkbFile(file);
    235     }
    236 
    237     MergeIncludedKeyTypes(info, &included, include->merge);
    238     ClearKeyTypesInfo(&included);
    239 
    240     return (info->errorCount == 0);
    241 }
    242 
    243 /***====================================================================***/
    244 
    245 static bool
    246 SetModifiers(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
    247              ExprDef *value)
    248 {
    249     xkb_mod_mask_t mods;
    250 
    251     if (arrayNdx)
    252         log_warn(info->ctx,
    253                  "The modifiers field of a key type is not an array; "
    254                  "Illegal array subscript ignored\n");
    255 
    256     if (!ExprResolveModMask(info->ctx, value, MOD_BOTH, &info->mods, &mods)) {
    257         log_err(info->ctx,
    258                 "Key type mask field must be a modifier mask; "
    259                 "Key type definition ignored\n");
    260         return false;
    261     }
    262 
    263     if (type->defined & TYPE_FIELD_MASK) {
    264         log_warn(info->ctx,
    265                  "Multiple modifier mask definitions for key type %s; "
    266                  "Using %s, ignoring %s\n",
    267                  xkb_atom_text(info->ctx, type->name),
    268                  TypeMaskTxt(info, type),
    269                  ModMaskText(info->ctx, &info->mods, mods));
    270         return false;
    271     }
    272 
    273     type->mods = mods;
    274     return true;
    275 }
    276 
    277 /***====================================================================***/
    278 
    279 static struct xkb_key_type_entry *
    280 FindMatchingMapEntry(KeyTypeInfo *type, xkb_mod_mask_t mods)
    281 {
    282     struct xkb_key_type_entry *entry;
    283 
    284     darray_foreach(entry, type->entries)
    285         if (entry->mods.mods == mods)
    286             return entry;
    287 
    288     return NULL;
    289 }
    290 
    291 static bool
    292 AddMapEntry(KeyTypesInfo *info, KeyTypeInfo *type,
    293             struct xkb_key_type_entry *new, bool clobber, bool report)
    294 {
    295     struct xkb_key_type_entry *old;
    296 
    297     old = FindMatchingMapEntry(type, new->mods.mods);
    298     if (old) {
    299         if (report && old->level != new->level) {
    300             log_warn(info->ctx,
    301                      "Multiple map entries for %s in %s; "
    302                      "Using %d, ignoring %d\n",
    303                      MapEntryTxt(info, new), TypeTxt(info, type),
    304                      (clobber ? new->level : old->level) + 1,
    305                      (clobber ? old->level : new->level) + 1);
    306         }
    307         else {
    308             log_vrb(info->ctx, 10,
    309                     "Multiple occurrences of map[%s]= %d in %s; Ignored\n",
    310                     MapEntryTxt(info, new), new->level + 1,
    311                     TypeTxt(info, type));
    312             return true;
    313         }
    314 
    315         if (clobber) {
    316             if (new->level >= type->num_levels)
    317                 type->num_levels = new->level + 1;
    318             old->level = new->level;
    319         }
    320 
    321         return true;
    322     }
    323 
    324     if (new->level >= type->num_levels)
    325         type->num_levels = new->level + 1;
    326 
    327     darray_append(type->entries, *new);
    328     return true;
    329 }
    330 
    331 static bool
    332 SetMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
    333             ExprDef *value)
    334 {
    335     struct xkb_key_type_entry entry;
    336 
    337     if (arrayNdx == NULL)
    338         return ReportTypeShouldBeArray(info, type, "map entry");
    339 
    340     if (!ExprResolveModMask(info->ctx, arrayNdx, MOD_BOTH, &info->mods,
    341                             &entry.mods.mods))
    342         return ReportTypeBadType(info, type, "map entry", "modifier mask");
    343 
    344     if (entry.mods.mods & (~type->mods)) {
    345         log_vrb(info->ctx, 1,
    346                 "Map entry for unused modifiers in %s; "
    347                 "Using %s instead of %s\n",
    348                 TypeTxt(info, type),
    349                 ModMaskText(info->ctx, &info->mods,
    350                             entry.mods.mods & type->mods),
    351                 MapEntryTxt(info, &entry));
    352         entry.mods.mods &= type->mods;
    353     }
    354 
    355     if (!ExprResolveLevel(info->ctx, value, &entry.level)) {
    356         log_err(info->ctx,
    357                 "Level specifications in a key type must be integer; "
    358                 "Ignoring malformed level specification\n");
    359         return false;
    360     }
    361 
    362     entry.preserve.mods = 0;
    363 
    364     return AddMapEntry(info, type, &entry, true, true);
    365 }
    366 
    367 /***====================================================================***/
    368 
    369 static bool
    370 AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type,
    371             xkb_mod_mask_t mods, xkb_mod_mask_t preserve_mods)
    372 {
    373     struct xkb_key_type_entry *entry;
    374     struct xkb_key_type_entry new;
    375 
    376     darray_foreach(entry, type->entries) {
    377         if (entry->mods.mods != mods)
    378             continue;
    379 
    380         /* Map exists without previous preserve (or "None"); override. */
    381         if (entry->preserve.mods == 0) {
    382             entry->preserve.mods = preserve_mods;
    383             return true;
    384         }
    385 
    386         /* Map exists with same preserve; do nothing. */
    387         if (entry->preserve.mods == preserve_mods) {
    388             log_vrb(info->ctx, 10,
    389                     "Identical definitions for preserve[%s] in %s; "
    390                     "Ignored\n",
    391                     ModMaskText(info->ctx, &info->mods, mods),
    392                     TypeTxt(info, type));
    393             return true;
    394         }
    395 
    396         /* Map exists with different preserve; latter wins. */
    397         log_vrb(info->ctx, 1,
    398                 "Multiple definitions for preserve[%s] in %s; "
    399                 "Using %s, ignoring %s\n",
    400                 ModMaskText(info->ctx, &info->mods, mods),
    401                 TypeTxt(info, type),
    402                 ModMaskText(info->ctx, &info->mods, preserve_mods),
    403                 ModMaskText(info->ctx, &info->mods, entry->preserve.mods));
    404 
    405         entry->preserve.mods = preserve_mods;
    406         return true;
    407     }
    408 
    409     /*
    410      * Map does not exist, i.e. preserve[] came before map[].
    411      * Create a map with the specified mask mapping to Level1. The level
    412      * may be overridden later with an explicit map[] statement.
    413      */
    414     new.level = 0;
    415     new.mods.mods = mods;
    416     new.preserve.mods = preserve_mods;
    417     darray_append(type->entries, new);
    418     return true;
    419 }
    420 
    421 static bool
    422 SetPreserve(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
    423             ExprDef *value)
    424 {
    425     xkb_mod_mask_t mods, preserve_mods;
    426 
    427     if (arrayNdx == NULL)
    428         return ReportTypeShouldBeArray(info, type, "preserve entry");
    429 
    430     if (!ExprResolveModMask(info->ctx, arrayNdx, MOD_BOTH, &info->mods, &mods))
    431         return ReportTypeBadType(info, type, "preserve entry",
    432                                  "modifier mask");
    433 
    434     if (mods & ~type->mods) {
    435         const char *before, *after;
    436 
    437         before = ModMaskText(info->ctx, &info->mods, mods);
    438         mods &= type->mods;
    439         after = ModMaskText(info->ctx, &info->mods, mods);
    440 
    441         log_vrb(info->ctx, 1,
    442                 "Preserve for modifiers not used by the %s type; "
    443                 "Index %s converted to %s\n",
    444                 TypeTxt(info, type), before, after);
    445     }
    446 
    447     if (!ExprResolveModMask(info->ctx, value, MOD_BOTH, &info->mods,
    448                             &preserve_mods)) {
    449         log_err(info->ctx,
    450                 "Preserve value in a key type is not a modifier mask; "
    451                 "Ignoring preserve[%s] in type %s\n",
    452                 ModMaskText(info->ctx, &info->mods, mods),
    453                 TypeTxt(info, type));
    454         return false;
    455     }
    456 
    457     if (preserve_mods & ~mods) {
    458         const char *before, *after;
    459 
    460         before = ModMaskText(info->ctx, &info->mods, preserve_mods);
    461         preserve_mods &= mods;
    462         after = ModMaskText(info->ctx, &info->mods, preserve_mods);
    463 
    464         log_vrb(info->ctx, 1,
    465                 "Illegal value for preserve[%s] in type %s; "
    466                 "Converted %s to %s\n",
    467                 ModMaskText(info->ctx, &info->mods, mods),
    468                 TypeTxt(info, type), before, after);
    469     }
    470 
    471     return AddPreserve(info, type, mods, preserve_mods);
    472 }
    473 
    474 /***====================================================================***/
    475 
    476 static bool
    477 AddLevelName(KeyTypesInfo *info, KeyTypeInfo *type,
    478              xkb_level_index_t level, xkb_atom_t name, bool clobber)
    479 {
    480     /* New name. */
    481     if (level >= darray_size(type->level_names)) {
    482         darray_resize0(type->level_names, level + 1);
    483         goto finish;
    484     }
    485 
    486     /* Same level, same name. */
    487     if (darray_item(type->level_names, level) == name) {
    488         log_vrb(info->ctx, 10,
    489                 "Duplicate names for level %d of key type %s; Ignored\n",
    490                 level + 1, TypeTxt(info, type));
    491         return true;
    492     }
    493 
    494     /* Same level, different name. */
    495     if (darray_item(type->level_names, level) != XKB_ATOM_NONE) {
    496         const char *old, *new;
    497         old = xkb_atom_text(info->ctx,
    498                             darray_item(type->level_names, level));
    499         new = xkb_atom_text(info->ctx, name);
    500         log_vrb(info->ctx, 1,
    501                 "Multiple names for level %d of key type %s; "
    502                 "Using %s, ignoring %s\n",
    503                 level + 1, TypeTxt(info, type),
    504                 (clobber ? new : old), (clobber ? old : new));
    505 
    506         if (!clobber)
    507             return true;
    508     }
    509 
    510     /* XXX: What about different level, same name? */
    511 
    512 finish:
    513     darray_item(type->level_names, level) = name;
    514     return true;
    515 }
    516 
    517 static bool
    518 SetLevelName(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
    519              ExprDef *value)
    520 {
    521     xkb_level_index_t level;
    522     xkb_atom_t level_name;
    523 
    524     if (arrayNdx == NULL)
    525         return ReportTypeShouldBeArray(info, type, "level name");
    526 
    527     if (!ExprResolveLevel(info->ctx, arrayNdx, &level))
    528         return ReportTypeBadType(info, type, "level name", "integer");
    529 
    530     if (!ExprResolveString(info->ctx, value, &level_name)) {
    531         log_err(info->ctx,
    532                 "Non-string name for level %d in key type %s; "
    533                 "Ignoring illegal level name definition\n",
    534                 level + 1, xkb_atom_text(info->ctx, type->name));
    535         return false;
    536     }
    537 
    538     return AddLevelName(info, type, level, level_name, true);
    539 }
    540 
    541 /***====================================================================***/
    542 
    543 static bool
    544 SetKeyTypeField(KeyTypesInfo *info, KeyTypeInfo *type,
    545                 const char *field, ExprDef *arrayNdx, ExprDef *value)
    546 {
    547     bool ok = false;
    548     enum type_field type_field = 0;
    549 
    550     if (istreq(field, "modifiers")) {
    551         type_field = TYPE_FIELD_MASK;
    552         ok = SetModifiers(info, type, arrayNdx, value);
    553     }
    554     else if (istreq(field, "map")) {
    555         type_field = TYPE_FIELD_MAP;
    556         ok = SetMapEntry(info, type, arrayNdx, value);
    557     }
    558     else if (istreq(field, "preserve")) {
    559         type_field = TYPE_FIELD_PRESERVE;
    560         ok = SetPreserve(info, type, arrayNdx, value);
    561     }
    562     else if (istreq(field, "levelname") || istreq(field, "level_name")) {
    563         type_field = TYPE_FIELD_LEVEL_NAME;
    564         ok = SetLevelName(info, type, arrayNdx, value);
    565     } else {
    566         log_err(info->ctx,
    567                 "Unknown field %s in key type %s; Definition ignored\n",
    568                 field, TypeTxt(info, type));
    569     }
    570 
    571     type->defined |= type_field;
    572     return ok;
    573 }
    574 
    575 static bool
    576 HandleKeyTypeBody(KeyTypesInfo *info, VarDef *def, KeyTypeInfo *type)
    577 {
    578     bool ok = true;
    579     const char *elem, *field;
    580     ExprDef *arrayNdx;
    581 
    582     for (; def; def = (VarDef *) def->common.next) {
    583         ok = ExprResolveLhs(info->ctx, def->name, &elem, &field,
    584                             &arrayNdx);
    585         if (!ok)
    586             continue;
    587 
    588         if (elem && istreq(elem, "type")) {
    589             log_err(info->ctx,
    590                     "Support for changing the default type has been removed; "
    591                     "Statement ignored\n");
    592             continue;
    593         }
    594 
    595         ok = SetKeyTypeField(info, type, field, arrayNdx, def->value);
    596     }
    597 
    598     return ok;
    599 }
    600 
    601 static bool
    602 HandleKeyTypeDef(KeyTypesInfo *info, KeyTypeDef *def, enum merge_mode merge)
    603 {
    604     KeyTypeInfo type = {
    605         .defined = 0,
    606         .merge = (def->merge == MERGE_DEFAULT ? merge : def->merge),
    607         .name = def->name,
    608         .mods = 0,
    609         .num_levels = 1,
    610         .entries = darray_new(),
    611         .level_names = darray_new(),
    612     };
    613 
    614     if (!HandleKeyTypeBody(info, def->body, &type)) {
    615         info->errorCount++;
    616         return false;
    617     }
    618 
    619     if (!AddKeyType(info, &type, true)) {
    620         info->errorCount++;
    621         return false;
    622     }
    623 
    624     return true;
    625 }
    626 
    627 static void
    628 HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge)
    629 {
    630     bool ok;
    631 
    632     free(info->name);
    633     info->name = strdup_safe(file->name);
    634 
    635     for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) {
    636         switch (stmt->type) {
    637         case STMT_INCLUDE:
    638             ok = HandleIncludeKeyTypes(info, (IncludeStmt *) stmt);
    639             break;
    640         case STMT_TYPE:
    641             ok = HandleKeyTypeDef(info, (KeyTypeDef *) stmt, merge);
    642             break;
    643         case STMT_VAR:
    644             log_err(info->ctx,
    645                     "Support for changing the default type has been removed; "
    646                     "Statement ignored\n");
    647             ok = true;
    648             break;
    649         case STMT_VMOD:
    650             ok = HandleVModDef(info->ctx, &info->mods, (VModDef *) stmt, merge);
    651             break;
    652         default:
    653             log_err(info->ctx,
    654                     "Key type files may not include other declarations; "
    655                     "Ignoring %s\n", stmt_type_to_string(stmt->type));
    656             ok = false;
    657             break;
    658         }
    659 
    660         if (!ok)
    661             info->errorCount++;
    662 
    663         if (info->errorCount > 10) {
    664             log_err(info->ctx,
    665                     "Abandoning keytypes file \"%s\"\n", file->topName);
    666             break;
    667         }
    668     }
    669 }
    670 
    671 /***====================================================================***/
    672 
    673 static bool
    674 CopyKeyTypesToKeymap(struct xkb_keymap *keymap, KeyTypesInfo *info)
    675 {
    676     unsigned num_types;
    677     struct xkb_key_type *types;
    678 
    679     num_types = darray_empty(info->types) ? 1 : darray_size(info->types);
    680     types = calloc(num_types, sizeof(*types));
    681     if (!types)
    682         return false;
    683 
    684     /*
    685      * If no types were specified, a default unnamed one-level type is
    686      * used for all keys.
    687      */
    688     if (darray_empty(info->types)) {
    689         struct xkb_key_type *type = &types[0];
    690 
    691         type->mods.mods = 0;
    692         type->num_levels = 1;
    693         type->entries = NULL;
    694         type->num_entries = 0;
    695         type->name = xkb_atom_intern_literal(keymap->ctx, "default");
    696         type->level_names = NULL;
    697     }
    698     else {
    699         for (unsigned i = 0; i < num_types; i++) {
    700             KeyTypeInfo *def = &darray_item(info->types, i);
    701             struct xkb_key_type *type = &types[i];
    702 
    703             type->name = def->name;
    704             type->mods.mods = def->mods;
    705             darray_steal(def->level_names,
    706                          &type->level_names, &type->num_levels);
    707             darray_steal(def->entries,
    708                          &type->entries, &type->num_entries);
    709         }
    710     }
    711 
    712     keymap->types_section_name = strdup_safe(info->name);
    713     XkbEscapeMapName(keymap->types_section_name);
    714     keymap->num_types = num_types;
    715     keymap->types = types;
    716     keymap->mods = info->mods;
    717     return true;
    718 }
    719 
    720 /***====================================================================***/
    721 
    722 bool
    723 CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap,
    724                 enum merge_mode merge)
    725 {
    726     KeyTypesInfo info;
    727 
    728     InitKeyTypesInfo(&info, keymap->ctx, &keymap->mods);
    729 
    730     HandleKeyTypesFile(&info, file, merge);
    731     if (info.errorCount != 0)
    732         goto err_info;
    733 
    734     if (!CopyKeyTypesToKeymap(keymap, &info))
    735         goto err_info;
    736 
    737     ClearKeyTypesInfo(&info);
    738     return true;
    739 
    740 err_info:
    741     ClearKeyTypesInfo(&info);
    742     return false;
    743 }
    744