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 /* 28 * Copyright 2012 Intel Corporation 29 * Copyright 2012 Ran Benita <ran234 (at) gmail.com> 30 * 31 * Permission is hereby granted, free of charge, to any person obtaining a 32 * copy of this software and associated documentation files (the "Software"), 33 * to deal in the Software without restriction, including without limitation 34 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 35 * and/or sell copies of the Software, and to permit persons to whom the 36 * Software is furnished to do so, subject to the following conditions: 37 * 38 * The above copyright notice and this permission notice (including the next 39 * paragraph) shall be included in all copies or substantial portions of the 40 * Software. 41 * 42 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 43 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 44 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 45 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 46 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 47 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 48 * DEALINGS IN THE SOFTWARE. 49 * 50 * Author: Daniel Stone <daniel (at) fooishbar.org> 51 * Ran Benita <ran234 (at) gmail.com> 52 */ 53 54 #include "xkbcomp-priv.h" 55 #include "text.h" 56 #include "expr.h" 57 #include "action.h" 58 #include "vmod.h" 59 #include "include.h" 60 #include "keysym.h" 61 62 enum key_repeat { 63 KEY_REPEAT_UNDEFINED = 0, 64 KEY_REPEAT_YES = 1, 65 KEY_REPEAT_NO = 2, 66 }; 67 68 enum group_field { 69 GROUP_FIELD_SYMS = (1 << 0), 70 GROUP_FIELD_ACTS = (1 << 1), 71 GROUP_FIELD_TYPE = (1 << 2), 72 }; 73 74 enum key_field { 75 KEY_FIELD_REPEAT = (1 << 0), 76 KEY_FIELD_DEFAULT_TYPE = (1 << 1), 77 KEY_FIELD_GROUPINFO = (1 << 2), 78 KEY_FIELD_VMODMAP = (1 << 3), 79 }; 80 81 typedef struct { 82 enum group_field defined; 83 darray(struct xkb_level) levels; 84 xkb_atom_t type; 85 } GroupInfo; 86 87 typedef struct { 88 enum key_field defined; 89 enum merge_mode merge; 90 91 xkb_atom_t name; 92 93 darray(GroupInfo) groups; 94 95 enum key_repeat repeat; 96 xkb_mod_mask_t vmodmap; 97 xkb_atom_t default_type; 98 99 enum xkb_range_exceed_type out_of_range_group_action; 100 xkb_layout_index_t out_of_range_group_number; 101 } KeyInfo; 102 103 static void 104 ClearLevelInfo(struct xkb_level *leveli) 105 { 106 if (leveli->num_syms > 1) 107 free(leveli->u.syms); 108 } 109 110 static void 111 InitGroupInfo(GroupInfo *groupi) 112 { 113 memset(groupi, 0, sizeof(*groupi)); 114 } 115 116 static void 117 ClearGroupInfo(GroupInfo *groupi) 118 { 119 struct xkb_level *leveli; 120 darray_foreach(leveli, groupi->levels) 121 ClearLevelInfo(leveli); 122 darray_free(groupi->levels); 123 } 124 125 static void 126 CopyGroupInfo(GroupInfo *to, const GroupInfo *from) 127 { 128 to->defined = from->defined; 129 to->type = from->type; 130 darray_init(to->levels); 131 darray_copy(to->levels, from->levels); 132 for (xkb_level_index_t j = 0; j < darray_size(to->levels); j++) 133 if (darray_item(from->levels, j).num_syms > 1) 134 darray_item(to->levels, j).u.syms = 135 memdup(darray_item(from->levels, j).u.syms, 136 darray_item(from->levels, j).num_syms, 137 sizeof(xkb_keysym_t)); 138 } 139 140 static void 141 InitKeyInfo(struct xkb_context *ctx, KeyInfo *keyi) 142 { 143 memset(keyi, 0, sizeof(*keyi)); 144 keyi->merge = MERGE_OVERRIDE; 145 keyi->name = xkb_atom_intern_literal(ctx, "*"); 146 keyi->out_of_range_group_action = RANGE_WRAP; 147 } 148 149 static void 150 ClearKeyInfo(KeyInfo *keyi) 151 { 152 GroupInfo *groupi; 153 darray_foreach(groupi, keyi->groups) 154 ClearGroupInfo(groupi); 155 darray_free(keyi->groups); 156 } 157 158 /***====================================================================***/ 159 160 typedef struct { 161 enum merge_mode merge; 162 bool haveSymbol; 163 xkb_mod_index_t modifier; 164 union { 165 xkb_atom_t keyName; 166 xkb_keysym_t keySym; 167 } u; 168 } ModMapEntry; 169 170 typedef struct { 171 char *name; /* e.g. pc+us+inet(evdev) */ 172 int errorCount; 173 enum merge_mode merge; 174 xkb_layout_index_t explicit_group; 175 darray(KeyInfo) keys; 176 KeyInfo default_key; 177 ActionsInfo *actions; 178 darray(xkb_atom_t) group_names; 179 darray(ModMapEntry) modmaps; 180 struct xkb_mod_set mods; 181 182 struct xkb_context *ctx; 183 /* Needed for AddKeySymbols. */ 184 const struct xkb_keymap *keymap; 185 } SymbolsInfo; 186 187 static void 188 InitSymbolsInfo(SymbolsInfo *info, const struct xkb_keymap *keymap, 189 ActionsInfo *actions, const struct xkb_mod_set *mods) 190 { 191 memset(info, 0, sizeof(*info)); 192 info->ctx = keymap->ctx; 193 info->keymap = keymap; 194 info->merge = MERGE_OVERRIDE; 195 InitKeyInfo(keymap->ctx, &info->default_key); 196 info->actions = actions; 197 info->mods = *mods; 198 info->explicit_group = XKB_LAYOUT_INVALID; 199 } 200 201 static void 202 ClearSymbolsInfo(SymbolsInfo *info) 203 { 204 KeyInfo *keyi; 205 free(info->name); 206 darray_foreach(keyi, info->keys) 207 ClearKeyInfo(keyi); 208 darray_free(info->keys); 209 darray_free(info->group_names); 210 darray_free(info->modmaps); 211 ClearKeyInfo(&info->default_key); 212 } 213 214 static const char * 215 KeyInfoText(SymbolsInfo *info, KeyInfo *keyi) 216 { 217 return KeyNameText(info->ctx, keyi->name); 218 } 219 220 static bool 221 LevelsSameSyms(const struct xkb_level *a, const struct xkb_level *b) 222 { 223 if (a->num_syms != b->num_syms) 224 return false; 225 if (a->num_syms <= 1) 226 return a->u.sym == b->u.sym; 227 else 228 return memcmp(a->u.syms, b->u.syms, 229 sizeof(*a->u.syms) * a->num_syms) == 0; 230 231 } 232 233 static bool 234 MergeGroups(SymbolsInfo *info, GroupInfo *into, GroupInfo *from, bool clobber, 235 bool report, xkb_layout_index_t group, xkb_atom_t key_name) 236 { 237 xkb_level_index_t i, levels_in_both; 238 struct xkb_level *level; 239 240 /* First find the type of the merged group. */ 241 if (into->type != from->type) { 242 if (from->type == XKB_ATOM_NONE) { 243 } 244 else if (into->type == XKB_ATOM_NONE) { 245 into->type = from->type; 246 } 247 else { 248 xkb_atom_t use = (clobber ? from->type : into->type); 249 xkb_atom_t ignore = (clobber ? into->type : from->type); 250 251 if (report) 252 log_warn(info->ctx, 253 "Multiple definitions for group %d type of key %s; " 254 "Using %s, ignoring %s\n", 255 group + 1, KeyNameText(info->ctx, key_name), 256 xkb_atom_text(info->ctx, use), 257 xkb_atom_text(info->ctx, ignore)); 258 259 into->type = use; 260 } 261 } 262 into->defined |= (from->defined & GROUP_FIELD_TYPE); 263 264 /* Now look at the levels. */ 265 266 if (darray_empty(from->levels)) { 267 InitGroupInfo(from); 268 return true; 269 } 270 271 if (darray_empty(into->levels)) { 272 from->type = into->type; 273 *into = *from; 274 InitGroupInfo(from); 275 return true; 276 } 277 278 /* Merge the actions and syms. */ 279 levels_in_both = MIN(darray_size(into->levels), darray_size(from->levels)); 280 for (i = 0; i < levels_in_both; i++) { 281 struct xkb_level *intoLevel = &darray_item(into->levels, i); 282 struct xkb_level *fromLevel = &darray_item(from->levels, i); 283 284 if (fromLevel->action.type == ACTION_TYPE_NONE) { 285 } 286 else if (intoLevel->action.type == ACTION_TYPE_NONE) { 287 intoLevel->action = fromLevel->action; 288 } 289 else { 290 union xkb_action *use, *ignore; 291 use = (clobber ? &fromLevel->action : &intoLevel->action); 292 ignore = (clobber ? &intoLevel->action : &fromLevel->action); 293 294 if (report) 295 log_warn(info->ctx, 296 "Multiple actions for level %d/group %u on key %s; " 297 "Using %s, ignoring %s\n", 298 i + 1, group + 1, KeyNameText(info->ctx, key_name), 299 ActionTypeText(use->type), 300 ActionTypeText(ignore->type)); 301 302 intoLevel->action = *use; 303 } 304 305 if (fromLevel->num_syms == 0) { 306 } 307 else if (intoLevel->num_syms == 0) { 308 intoLevel->num_syms = fromLevel->num_syms; 309 if (fromLevel->num_syms > 1) 310 intoLevel->u.syms = fromLevel->u.syms; 311 else 312 intoLevel->u.sym = fromLevel->u.sym; 313 fromLevel->num_syms = 0; 314 } 315 else if (!LevelsSameSyms(fromLevel, intoLevel)) { 316 if (report) 317 log_warn(info->ctx, 318 "Multiple symbols for level %d/group %u on key %s; " 319 "Using %s, ignoring %s\n", 320 i + 1, group + 1, KeyNameText(info->ctx, key_name), 321 (clobber ? "from" : "to"), 322 (clobber ? "to" : "from")); 323 324 if (clobber) { 325 ClearLevelInfo(intoLevel); 326 intoLevel->num_syms = fromLevel->num_syms; 327 if (fromLevel->num_syms > 1) 328 intoLevel->u.syms = fromLevel->u.syms; 329 else 330 intoLevel->u.sym = fromLevel->u.sym; 331 fromLevel->num_syms = 0; 332 } 333 } 334 } 335 /* If @from has extra levels, get them as well. */ 336 darray_foreach_from(level, from->levels, levels_in_both) { 337 darray_append(into->levels, *level); 338 level->num_syms = 0; 339 } 340 into->defined |= (from->defined & GROUP_FIELD_ACTS); 341 into->defined |= (from->defined & GROUP_FIELD_SYMS); 342 343 return true; 344 } 345 346 static bool 347 UseNewKeyField(enum key_field field, enum key_field old, enum key_field new, 348 bool clobber, bool report, enum key_field *collide) 349 { 350 if (!(old & field)) 351 return (new & field); 352 353 if (new & field) { 354 if (report) 355 *collide |= field; 356 357 if (clobber) 358 return true; 359 } 360 361 return false; 362 } 363 364 static bool 365 MergeKeys(SymbolsInfo *info, KeyInfo *into, KeyInfo *from, bool same_file) 366 { 367 xkb_layout_index_t i; 368 xkb_layout_index_t groups_in_both; 369 enum key_field collide = 0; 370 const int verbosity = xkb_context_get_log_verbosity(info->ctx); 371 const bool clobber = (from->merge != MERGE_AUGMENT); 372 const bool report = (same_file && verbosity > 0) || verbosity > 9; 373 374 if (from->merge == MERGE_REPLACE) { 375 ClearKeyInfo(into); 376 *into = *from; 377 InitKeyInfo(info->ctx, from); 378 return true; 379 } 380 381 groups_in_both = MIN(darray_size(into->groups), darray_size(from->groups)); 382 for (i = 0; i < groups_in_both; i++) 383 MergeGroups(info, 384 &darray_item(into->groups, i), 385 &darray_item(from->groups, i), 386 clobber, report, i, into->name); 387 /* If @from has extra groups, just move them to @into. */ 388 for (i = groups_in_both; i < darray_size(from->groups); i++) { 389 darray_append(into->groups, darray_item(from->groups, i)); 390 InitGroupInfo(&darray_item(from->groups, i)); 391 } 392 393 if (UseNewKeyField(KEY_FIELD_VMODMAP, into->defined, from->defined, 394 clobber, report, &collide)) { 395 into->vmodmap = from->vmodmap; 396 into->defined |= KEY_FIELD_VMODMAP; 397 } 398 if (UseNewKeyField(KEY_FIELD_REPEAT, into->defined, from->defined, 399 clobber, report, &collide)) { 400 into->repeat = from->repeat; 401 into->defined |= KEY_FIELD_REPEAT; 402 } 403 if (UseNewKeyField(KEY_FIELD_DEFAULT_TYPE, into->defined, from->defined, 404 clobber, report, &collide)) { 405 into->default_type = from->default_type; 406 into->defined |= KEY_FIELD_DEFAULT_TYPE; 407 } 408 if (UseNewKeyField(KEY_FIELD_GROUPINFO, into->defined, from->defined, 409 clobber, report, &collide)) { 410 into->out_of_range_group_action = from->out_of_range_group_action; 411 into->out_of_range_group_number = from->out_of_range_group_number; 412 into->defined |= KEY_FIELD_GROUPINFO; 413 } 414 415 if (collide) 416 log_warn(info->ctx, 417 "Symbol map for key %s redefined; " 418 "Using %s definition for conflicting fields\n", 419 KeyNameText(info->ctx, into->name), 420 (clobber ? "first" : "last")); 421 422 ClearKeyInfo(from); 423 InitKeyInfo(info->ctx, from); 424 return true; 425 } 426 427 /* TODO: Make it so this function doesn't need the entire keymap. */ 428 static bool 429 AddKeySymbols(SymbolsInfo *info, KeyInfo *keyi, bool same_file) 430 { 431 xkb_atom_t real_name; 432 KeyInfo *iter; 433 434 /* 435 * Don't keep aliases in the keys array; this guarantees that 436 * searching for keys to merge with by straight comparison (see the 437 * following loop) is enough, and we won't get multiple KeyInfo's 438 * for the same key because of aliases. 439 */ 440 real_name = XkbResolveKeyAlias(info->keymap, keyi->name); 441 if (real_name != XKB_ATOM_NONE) 442 keyi->name = real_name; 443 444 darray_foreach(iter, info->keys) 445 if (iter->name == keyi->name) 446 return MergeKeys(info, iter, keyi, same_file); 447 448 darray_append(info->keys, *keyi); 449 InitKeyInfo(info->ctx, keyi); 450 return true; 451 } 452 453 static bool 454 AddModMapEntry(SymbolsInfo *info, ModMapEntry *new) 455 { 456 ModMapEntry *old; 457 bool clobber = (new->merge != MERGE_AUGMENT); 458 459 darray_foreach(old, info->modmaps) { 460 xkb_mod_index_t use, ignore; 461 462 if ((new->haveSymbol != old->haveSymbol) || 463 (new->haveSymbol && new->u.keySym != old->u.keySym) || 464 (!new->haveSymbol && new->u.keyName != old->u.keyName)) 465 continue; 466 467 if (new->modifier == old->modifier) 468 return true; 469 470 use = (clobber ? new->modifier : old->modifier); 471 ignore = (clobber ? old->modifier : new->modifier); 472 473 if (new->haveSymbol) 474 log_err(info->ctx, 475 "Symbol \"%s\" added to modifier map for multiple modifiers; " 476 "Using %s, ignoring %s\n", 477 KeysymText(info->ctx, new->u.keySym), 478 ModIndexText(info->ctx, &info->mods, use), 479 ModIndexText(info->ctx, &info->mods, ignore)); 480 else 481 log_err(info->ctx, 482 "Key \"%s\" added to modifier map for multiple modifiers; " 483 "Using %s, ignoring %s\n", 484 KeyNameText(info->ctx, new->u.keyName), 485 ModIndexText(info->ctx, &info->mods, use), 486 ModIndexText(info->ctx, &info->mods, ignore)); 487 488 old->modifier = use; 489 return true; 490 } 491 492 darray_append(info->modmaps, *new); 493 return true; 494 } 495 496 /***====================================================================***/ 497 498 static void 499 MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from, 500 enum merge_mode merge) 501 { 502 KeyInfo *keyi; 503 ModMapEntry *mm; 504 xkb_atom_t *group_name; 505 xkb_layout_index_t group_names_in_both; 506 507 if (from->errorCount > 0) { 508 into->errorCount += from->errorCount; 509 return; 510 } 511 512 into->mods = from->mods; 513 514 if (into->name == NULL) { 515 into->name = from->name; 516 from->name = NULL; 517 } 518 519 group_names_in_both = MIN(darray_size(into->group_names), 520 darray_size(from->group_names)); 521 for (xkb_layout_index_t i = 0; i < group_names_in_both; i++) { 522 if (!darray_item(from->group_names, i)) 523 continue; 524 525 if (merge == MERGE_AUGMENT && darray_item(into->group_names, i)) 526 continue; 527 528 darray_item(into->group_names, i) = darray_item(from->group_names, i); 529 } 530 /* If @from has more, get them as well. */ 531 darray_foreach_from(group_name, from->group_names, group_names_in_both) 532 darray_append(into->group_names, *group_name); 533 534 if (darray_empty(into->keys)) { 535 into->keys = from->keys; 536 darray_init(from->keys); 537 } 538 else { 539 darray_foreach(keyi, from->keys) { 540 keyi->merge = (merge == MERGE_DEFAULT ? keyi->merge : merge); 541 if (!AddKeySymbols(into, keyi, false)) 542 into->errorCount++; 543 } 544 } 545 546 if (darray_empty(into->modmaps)) { 547 into->modmaps = from->modmaps; 548 darray_init(from->modmaps); 549 } 550 else { 551 darray_foreach(mm, from->modmaps) { 552 mm->merge = (merge == MERGE_DEFAULT ? mm->merge : merge); 553 if (!AddModMapEntry(into, mm)) 554 into->errorCount++; 555 } 556 } 557 } 558 559 static void 560 HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge); 561 562 static bool 563 HandleIncludeSymbols(SymbolsInfo *info, IncludeStmt *include) 564 { 565 SymbolsInfo included; 566 567 InitSymbolsInfo(&included, info->keymap, info->actions, &info->mods); 568 included.name = include->stmt; 569 include->stmt = NULL; 570 571 for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) { 572 SymbolsInfo next_incl; 573 XkbFile *file; 574 575 file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_SYMBOLS); 576 if (!file) { 577 info->errorCount += 10; 578 ClearSymbolsInfo(&included); 579 return false; 580 } 581 582 InitSymbolsInfo(&next_incl, info->keymap, info->actions, 583 &included.mods); 584 if (stmt->modifier) { 585 next_incl.explicit_group = atoi(stmt->modifier) - 1; 586 if (next_incl.explicit_group >= XKB_MAX_GROUPS) { 587 log_err(info->ctx, 588 "Cannot set explicit group to %d - must be between 1..%d; " 589 "Ignoring group number\n", 590 next_incl.explicit_group + 1, XKB_MAX_GROUPS); 591 next_incl.explicit_group = info->explicit_group; 592 } 593 } 594 else { 595 next_incl.explicit_group = info->explicit_group; 596 } 597 598 HandleSymbolsFile(&next_incl, file, MERGE_OVERRIDE); 599 600 MergeIncludedSymbols(&included, &next_incl, stmt->merge); 601 602 ClearSymbolsInfo(&next_incl); 603 FreeXkbFile(file); 604 } 605 606 MergeIncludedSymbols(info, &included, include->merge); 607 ClearSymbolsInfo(&included); 608 609 return (info->errorCount == 0); 610 } 611 612 #define SYMBOLS 1 613 #define ACTIONS 2 614 615 static bool 616 GetGroupIndex(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, 617 unsigned what, xkb_layout_index_t *ndx_rtrn) 618 { 619 const char *name = (what == SYMBOLS ? "symbols" : "actions"); 620 621 if (arrayNdx == NULL) { 622 xkb_layout_index_t i; 623 GroupInfo *groupi; 624 enum group_field field = (what == SYMBOLS ? 625 GROUP_FIELD_SYMS : GROUP_FIELD_ACTS); 626 627 darray_enumerate(i, groupi, keyi->groups) { 628 if (!(groupi->defined & field)) { 629 *ndx_rtrn = i; 630 return true; 631 } 632 } 633 634 if (i >= XKB_MAX_GROUPS) { 635 log_err(info->ctx, 636 "Too many groups of %s for key %s (max %u); " 637 "Ignoring %s defined for extra groups\n", 638 name, KeyInfoText(info, keyi), XKB_MAX_GROUPS, name); 639 return false; 640 } 641 642 darray_resize0(keyi->groups, darray_size(keyi->groups) + 1); 643 *ndx_rtrn = darray_size(keyi->groups) - 1; 644 return true; 645 } 646 647 if (!ExprResolveGroup(info->ctx, arrayNdx, ndx_rtrn)) { 648 log_err(info->ctx, 649 "Illegal group index for %s of key %s\n" 650 "Definition with non-integer array index ignored\n", 651 name, KeyInfoText(info, keyi)); 652 return false; 653 } 654 655 (*ndx_rtrn)--; 656 if (*ndx_rtrn >= darray_size(keyi->groups)) 657 darray_resize0(keyi->groups, *ndx_rtrn + 1); 658 659 return true; 660 } 661 662 static bool 663 AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, 664 ExprDef *value) 665 { 666 xkb_layout_index_t ndx; 667 GroupInfo *groupi; 668 xkb_level_index_t nLevels; 669 670 if (!GetGroupIndex(info, keyi, arrayNdx, SYMBOLS, &ndx)) 671 return false; 672 673 groupi = &darray_item(keyi->groups, ndx); 674 675 if (value == NULL) { 676 groupi->defined |= GROUP_FIELD_SYMS; 677 return true; 678 } 679 680 if (value->expr.op != EXPR_KEYSYM_LIST) { 681 log_err(info->ctx, 682 "Expected a list of symbols, found %s; " 683 "Ignoring symbols for group %u of %s\n", 684 expr_op_type_to_string(value->expr.op), ndx + 1, 685 KeyInfoText(info, keyi)); 686 return false; 687 } 688 689 if (groupi->defined & GROUP_FIELD_SYMS) { 690 log_err(info->ctx, 691 "Symbols for key %s, group %u already defined; " 692 "Ignoring duplicate definition\n", 693 KeyInfoText(info, keyi), ndx + 1); 694 return false; 695 } 696 697 nLevels = darray_size(value->keysym_list.symsMapIndex); 698 if (darray_size(groupi->levels) < nLevels) 699 darray_resize0(groupi->levels, nLevels); 700 701 groupi->defined |= GROUP_FIELD_SYMS; 702 703 for (xkb_level_index_t i = 0; i < nLevels; i++) { 704 unsigned int sym_index; 705 struct xkb_level *leveli = &darray_item(groupi->levels, i); 706 707 sym_index = darray_item(value->keysym_list.symsMapIndex, i); 708 leveli->num_syms = darray_item(value->keysym_list.symsNumEntries, i); 709 if (leveli->num_syms > 1) 710 leveli->u.syms = calloc(leveli->num_syms, sizeof(*leveli->u.syms)); 711 712 for (unsigned j = 0; j < leveli->num_syms; j++) { 713 xkb_keysym_t keysym = darray_item(value->keysym_list.syms, 714 sym_index + j); 715 716 if (leveli->num_syms == 1) { 717 if (keysym == XKB_KEY_NoSymbol) 718 leveli->num_syms = 0; 719 else 720 leveli->u.sym = keysym; 721 } 722 else if (leveli->num_syms > 1) { 723 leveli->u.syms[j] = keysym; 724 } 725 } 726 } 727 728 return true; 729 } 730 731 static bool 732 AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, 733 ExprDef *value) 734 { 735 xkb_layout_index_t ndx; 736 GroupInfo *groupi; 737 unsigned int nActs; 738 ExprDef *act; 739 740 if (!GetGroupIndex(info, keyi, arrayNdx, ACTIONS, &ndx)) 741 return false; 742 743 groupi = &darray_item(keyi->groups, ndx); 744 745 if (value == NULL) { 746 groupi->defined |= GROUP_FIELD_ACTS; 747 return true; 748 } 749 750 if (value->expr.op != EXPR_ACTION_LIST) { 751 log_wsgo(info->ctx, 752 "Bad expression type (%d) for action list value; " 753 "Ignoring actions for group %u of %s\n", 754 value->expr.op, ndx, KeyInfoText(info, keyi)); 755 return false; 756 } 757 758 if (groupi->defined & GROUP_FIELD_ACTS) { 759 log_wsgo(info->ctx, 760 "Actions for key %s, group %u already defined\n", 761 KeyInfoText(info, keyi), ndx); 762 return false; 763 } 764 765 nActs = 0; 766 for (act = value->unary.child; act; act = (ExprDef *) act->common.next) 767 nActs++; 768 769 if (darray_size(groupi->levels) < nActs) 770 darray_resize0(groupi->levels, nActs); 771 772 groupi->defined |= GROUP_FIELD_ACTS; 773 774 act = value->unary.child; 775 for (unsigned i = 0; i < nActs; i++) { 776 union xkb_action *toAct = &darray_item(groupi->levels, i).action; 777 778 if (!HandleActionDef(info->ctx, info->actions, &info->mods, act, toAct)) 779 log_err(info->ctx, 780 "Illegal action definition for %s; " 781 "Action for group %u/level %u ignored\n", 782 KeyInfoText(info, keyi), ndx + 1, i + 1); 783 784 act = (ExprDef *) act->common.next; 785 } 786 787 return true; 788 } 789 790 static const LookupEntry repeatEntries[] = { 791 { "true", KEY_REPEAT_YES }, 792 { "yes", KEY_REPEAT_YES }, 793 { "on", KEY_REPEAT_YES }, 794 { "false", KEY_REPEAT_NO }, 795 { "no", KEY_REPEAT_NO }, 796 { "off", KEY_REPEAT_NO }, 797 { "default", KEY_REPEAT_UNDEFINED }, 798 { NULL, 0 } 799 }; 800 801 static bool 802 SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, 803 ExprDef *arrayNdx, ExprDef *value) 804 { 805 if (istreq(field, "type")) { 806 xkb_layout_index_t ndx; 807 xkb_atom_t val; 808 809 if (!ExprResolveString(info->ctx, value, &val)) { 810 log_err(info->ctx, 811 "The type field of a key symbol map must be a string; " 812 "Ignoring illegal type definition\n"); 813 return false; 814 } 815 816 if (!arrayNdx) { 817 keyi->default_type = val; 818 keyi->defined |= KEY_FIELD_DEFAULT_TYPE; 819 } 820 else if (!ExprResolveGroup(info->ctx, arrayNdx, &ndx)) { 821 log_err(info->ctx, 822 "Illegal group index for type of key %s; " 823 "Definition with non-integer array index ignored\n", 824 KeyInfoText(info, keyi)); 825 return false; 826 } 827 else { 828 ndx--; 829 if (ndx >= darray_size(keyi->groups)) 830 darray_resize0(keyi->groups, ndx + 1); 831 darray_item(keyi->groups, ndx).type = val; 832 darray_item(keyi->groups, ndx).defined |= GROUP_FIELD_TYPE; 833 } 834 } 835 else if (istreq(field, "symbols")) { 836 return AddSymbolsToKey(info, keyi, arrayNdx, value); 837 } 838 else if (istreq(field, "actions")) { 839 return AddActionsToKey(info, keyi, arrayNdx, value); 840 } 841 else if (istreq(field, "vmods") || 842 istreq(field, "virtualmods") || 843 istreq(field, "virtualmodifiers")) { 844 xkb_mod_mask_t mask; 845 846 if (!ExprResolveModMask(info->ctx, value, MOD_VIRT, &info->mods, 847 &mask)) { 848 log_err(info->ctx, 849 "Expected a virtual modifier mask, found %s; " 850 "Ignoring virtual modifiers definition for key %s\n", 851 expr_op_type_to_string(value->expr.op), 852 KeyInfoText(info, keyi)); 853 return false; 854 } 855 856 keyi->vmodmap = mask; 857 keyi->defined |= KEY_FIELD_VMODMAP; 858 } 859 else if (istreq(field, "locking") || 860 istreq(field, "lock") || 861 istreq(field, "locks")) { 862 log_vrb(info->ctx, 1, 863 "Key behaviors not supported; " 864 "Ignoring locking specification for key %s\n", 865 KeyInfoText(info, keyi)); 866 } 867 else if (istreq(field, "radiogroup") || 868 istreq(field, "permanentradiogroup") || 869 istreq(field, "allownone")) { 870 log_vrb(info->ctx, 1, 871 "Radio groups not supported; " 872 "Ignoring radio group specification for key %s\n", 873 KeyInfoText(info, keyi)); 874 } 875 else if (istreq_prefix("overlay", field) || 876 istreq_prefix("permanentoverlay", field)) { 877 log_vrb(info->ctx, 1, 878 "Overlays not supported; " 879 "Ignoring overlay specification for key %s\n", 880 KeyInfoText(info, keyi)); 881 } 882 else if (istreq(field, "repeating") || 883 istreq(field, "repeats") || 884 istreq(field, "repeat")) { 885 unsigned int val; 886 887 if (!ExprResolveEnum(info->ctx, value, &val, repeatEntries)) { 888 log_err(info->ctx, 889 "Illegal repeat setting for %s; " 890 "Non-boolean repeat setting ignored\n", 891 KeyInfoText(info, keyi)); 892 return false; 893 } 894 895 keyi->repeat = val; 896 keyi->defined |= KEY_FIELD_REPEAT; 897 } 898 else if (istreq(field, "groupswrap") || 899 istreq(field, "wrapgroups")) { 900 bool set; 901 902 if (!ExprResolveBoolean(info->ctx, value, &set)) { 903 log_err(info->ctx, 904 "Illegal groupsWrap setting for %s; " 905 "Non-boolean value ignored\n", 906 KeyInfoText(info, keyi)); 907 return false; 908 } 909 910 keyi->out_of_range_group_action = (set ? RANGE_WRAP : RANGE_SATURATE); 911 keyi->defined |= KEY_FIELD_GROUPINFO; 912 } 913 else if (istreq(field, "groupsclamp") || 914 istreq(field, "clampgroups")) { 915 bool set; 916 917 if (!ExprResolveBoolean(info->ctx, value, &set)) { 918 log_err(info->ctx, 919 "Illegal groupsClamp setting for %s; " 920 "Non-boolean value ignored\n", 921 KeyInfoText(info, keyi)); 922 return false; 923 } 924 925 keyi->out_of_range_group_action = (set ? RANGE_SATURATE : RANGE_WRAP); 926 keyi->defined |= KEY_FIELD_GROUPINFO; 927 } 928 else if (istreq(field, "groupsredirect") || 929 istreq(field, "redirectgroups")) { 930 xkb_layout_index_t grp; 931 932 if (!ExprResolveGroup(info->ctx, value, &grp)) { 933 log_err(info->ctx, 934 "Illegal group index for redirect of key %s; " 935 "Definition with non-integer group ignored\n", 936 KeyInfoText(info, keyi)); 937 return false; 938 } 939 940 keyi->out_of_range_group_action = RANGE_REDIRECT; 941 keyi->out_of_range_group_number = grp - 1; 942 keyi->defined |= KEY_FIELD_GROUPINFO; 943 } 944 else { 945 log_err(info->ctx, 946 "Unknown field %s in a symbol interpretation; " 947 "Definition ignored\n", 948 field); 949 return false; 950 } 951 952 return true; 953 } 954 955 static bool 956 SetGroupName(SymbolsInfo *info, ExprDef *arrayNdx, ExprDef *value) 957 { 958 xkb_layout_index_t group, group_to_use; 959 xkb_atom_t name; 960 961 if (!arrayNdx) { 962 log_vrb(info->ctx, 1, 963 "You must specify an index when specifying a group name; " 964 "Group name definition without array subscript ignored\n"); 965 return false; 966 } 967 968 if (!ExprResolveGroup(info->ctx, arrayNdx, &group)) { 969 log_err(info->ctx, 970 "Illegal index in group name definition; " 971 "Definition with non-integer array index ignored\n"); 972 return false; 973 } 974 975 if (!ExprResolveString(info->ctx, value, &name)) { 976 log_err(info->ctx, 977 "Group name must be a string; " 978 "Illegal name for group %d ignored\n", group); 979 return false; 980 } 981 982 if (info->explicit_group == XKB_LAYOUT_INVALID) { 983 group_to_use = group - 1; 984 } 985 else if (group - 1 == 0) { 986 group_to_use = info->explicit_group; 987 } 988 else { 989 log_warn(info->ctx, 990 "An explicit group was specified for the '%s' map, " 991 "but it provides a name for a group other than Group1 (%d); " 992 "Ignoring group name '%s'\n", 993 info->name, group, 994 xkb_atom_text(info->ctx, name)); 995 return false; 996 } 997 998 if (group_to_use >= darray_size(info->group_names)) 999 darray_resize0(info->group_names, group_to_use + 1); 1000 darray_item(info->group_names, group_to_use) = name; 1001 1002 return true; 1003 } 1004 1005 static bool 1006 HandleGlobalVar(SymbolsInfo *info, VarDef *stmt) 1007 { 1008 const char *elem, *field; 1009 ExprDef *arrayNdx; 1010 bool ret; 1011 1012 if (!ExprResolveLhs(info->ctx, stmt->name, &elem, &field, &arrayNdx)) 1013 return false; 1014 1015 if (elem && istreq(elem, "key")) { 1016 ret = SetSymbolsField(info, &info->default_key, field, arrayNdx, 1017 stmt->value); 1018 } 1019 else if (!elem && (istreq(field, "name") || 1020 istreq(field, "groupname"))) { 1021 ret = SetGroupName(info, arrayNdx, stmt->value); 1022 } 1023 else if (!elem && (istreq(field, "groupswrap") || 1024 istreq(field, "wrapgroups"))) { 1025 log_err(info->ctx, 1026 "Global \"groupswrap\" not supported; Ignored\n"); 1027 ret = true; 1028 } 1029 else if (!elem && (istreq(field, "groupsclamp") || 1030 istreq(field, "clampgroups"))) { 1031 log_err(info->ctx, 1032 "Global \"groupsclamp\" not supported; Ignored\n"); 1033 ret = true; 1034 } 1035 else if (!elem && (istreq(field, "groupsredirect") || 1036 istreq(field, "redirectgroups"))) { 1037 log_err(info->ctx, 1038 "Global \"groupsredirect\" not supported; Ignored\n"); 1039 ret = true; 1040 } 1041 else if (!elem && istreq(field, "allownone")) { 1042 log_err(info->ctx, 1043 "Radio groups not supported; " 1044 "Ignoring \"allownone\" specification\n"); 1045 ret = true; 1046 } 1047 else { 1048 ret = SetActionField(info->ctx, info->actions, &info->mods, 1049 elem, field, arrayNdx, stmt->value); 1050 } 1051 1052 return ret; 1053 } 1054 1055 static bool 1056 HandleSymbolsBody(SymbolsInfo *info, VarDef *def, KeyInfo *keyi) 1057 { 1058 bool ok = true; 1059 const char *elem, *field; 1060 ExprDef *arrayNdx; 1061 1062 for (; def; def = (VarDef *) def->common.next) { 1063 if (def->name && def->name->expr.op == EXPR_FIELD_REF) { 1064 log_err(info->ctx, 1065 "Cannot set a global default value from within a key statement; " 1066 "Move statements to the global file scope\n"); 1067 continue; 1068 } 1069 1070 if (!def->name) { 1071 if (!def->value || def->value->expr.op == EXPR_KEYSYM_LIST) 1072 field = "symbols"; 1073 else 1074 field = "actions"; 1075 arrayNdx = NULL; 1076 } 1077 else { 1078 ok = ExprResolveLhs(info->ctx, def->name, &elem, &field, 1079 &arrayNdx); 1080 } 1081 1082 if (ok) 1083 ok = SetSymbolsField(info, keyi, field, arrayNdx, def->value); 1084 } 1085 1086 return ok; 1087 } 1088 1089 static bool 1090 SetExplicitGroup(SymbolsInfo *info, KeyInfo *keyi) 1091 { 1092 xkb_layout_index_t i; 1093 GroupInfo *groupi; 1094 bool warn = false; 1095 1096 if (info->explicit_group == XKB_LAYOUT_INVALID) 1097 return true; 1098 1099 darray_enumerate_from(i, groupi, keyi->groups, 1) { 1100 if (groupi->defined) { 1101 warn = true; 1102 ClearGroupInfo(groupi); 1103 InitGroupInfo(groupi); 1104 } 1105 } 1106 1107 if (warn) 1108 log_warn(info->ctx, 1109 "For the map %s an explicit group specified, " 1110 "but key %s has more than one group defined; " 1111 "All groups except first one will be ignored\n", 1112 info->name, KeyInfoText(info, keyi)); 1113 1114 darray_resize0(keyi->groups, info->explicit_group + 1); 1115 if (info->explicit_group > 0) { 1116 darray_item(keyi->groups, info->explicit_group) = 1117 darray_item(keyi->groups, 0); 1118 InitGroupInfo(&darray_item(keyi->groups, 0)); 1119 } 1120 1121 return true; 1122 } 1123 1124 static bool 1125 HandleSymbolsDef(SymbolsInfo *info, SymbolsDef *stmt) 1126 { 1127 KeyInfo keyi; 1128 1129 keyi = info->default_key; 1130 darray_init(keyi.groups); 1131 darray_copy(keyi.groups, info->default_key.groups); 1132 for (xkb_layout_index_t i = 0; i < darray_size(keyi.groups); i++) 1133 CopyGroupInfo(&darray_item(keyi.groups, i), 1134 &darray_item(info->default_key.groups, i)); 1135 keyi.merge = stmt->merge; 1136 keyi.name = stmt->keyName; 1137 1138 if (!HandleSymbolsBody(info, stmt->symbols, &keyi)) { 1139 info->errorCount++; 1140 return false; 1141 } 1142 1143 if (!SetExplicitGroup(info, &keyi)) { 1144 info->errorCount++; 1145 return false; 1146 } 1147 1148 if (!AddKeySymbols(info, &keyi, true)) { 1149 info->errorCount++; 1150 return false; 1151 } 1152 1153 return true; 1154 } 1155 1156 static bool 1157 HandleModMapDef(SymbolsInfo *info, ModMapDef *def) 1158 { 1159 ModMapEntry tmp; 1160 xkb_mod_index_t ndx; 1161 bool ok; 1162 struct xkb_context *ctx = info->ctx; 1163 1164 ndx = XkbModNameToIndex(&info->mods, def->modifier, MOD_REAL); 1165 if (ndx == XKB_MOD_INVALID) { 1166 log_err(info->ctx, 1167 "Illegal modifier map definition; " 1168 "Ignoring map for non-modifier \"%s\"\n", 1169 xkb_atom_text(ctx, def->modifier)); 1170 return false; 1171 } 1172 1173 ok = true; 1174 tmp.modifier = ndx; 1175 tmp.merge = def->merge; 1176 1177 for (ExprDef *key = def->keys; key; key = (ExprDef *) key->common.next) { 1178 xkb_keysym_t sym; 1179 1180 if (key->expr.op == EXPR_VALUE && 1181 key->expr.value_type == EXPR_TYPE_KEYNAME) { 1182 tmp.haveSymbol = false; 1183 tmp.u.keyName = key->key_name.key_name; 1184 } 1185 else if (ExprResolveKeySym(ctx, key, &sym)) { 1186 tmp.haveSymbol = true; 1187 tmp.u.keySym = sym; 1188 } 1189 else { 1190 log_err(info->ctx, 1191 "Modmap entries may contain only key names or keysyms; " 1192 "Illegal definition for %s modifier ignored\n", 1193 ModIndexText(info->ctx, &info->mods, tmp.modifier)); 1194 continue; 1195 } 1196 1197 ok = AddModMapEntry(info, &tmp) && ok; 1198 } 1199 return ok; 1200 } 1201 1202 static void 1203 HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge) 1204 { 1205 bool ok; 1206 1207 free(info->name); 1208 info->name = strdup_safe(file->name); 1209 1210 for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) { 1211 switch (stmt->type) { 1212 case STMT_INCLUDE: 1213 ok = HandleIncludeSymbols(info, (IncludeStmt *) stmt); 1214 break; 1215 case STMT_SYMBOLS: 1216 ok = HandleSymbolsDef(info, (SymbolsDef *) stmt); 1217 break; 1218 case STMT_VAR: 1219 ok = HandleGlobalVar(info, (VarDef *) stmt); 1220 break; 1221 case STMT_VMOD: 1222 ok = HandleVModDef(info->ctx, &info->mods, (VModDef *) stmt, merge); 1223 break; 1224 case STMT_MODMAP: 1225 ok = HandleModMapDef(info, (ModMapDef *) stmt); 1226 break; 1227 default: 1228 log_err(info->ctx, 1229 "Symbols files may not include other types; " 1230 "Ignoring %s\n", stmt_type_to_string(stmt->type)); 1231 ok = false; 1232 break; 1233 } 1234 1235 if (!ok) 1236 info->errorCount++; 1237 1238 if (info->errorCount > 10) { 1239 log_err(info->ctx, "Abandoning symbols file \"%s\"\n", 1240 file->topName); 1241 break; 1242 } 1243 } 1244 } 1245 1246 /** 1247 * Given a keysym @sym, return a key which generates it, or NULL. 1248 * This is used for example in a modifier map definition, such as: 1249 * modifier_map Lock { Caps_Lock }; 1250 * where we want to add the Lock modifier to the modmap of the key 1251 * which matches the keysym Caps_Lock. 1252 * Since there can be many keys which generates the keysym, the key 1253 * is chosen first by lowest group in which the keysym appears, than 1254 * by lowest level and than by lowest key code. 1255 */ 1256 static struct xkb_key * 1257 FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym) 1258 { 1259 struct xkb_key *key; 1260 xkb_layout_index_t group; 1261 xkb_level_index_t level; 1262 bool got_one_group, got_one_level; 1263 1264 group = 0; 1265 do { 1266 got_one_group = false; 1267 level = 0; 1268 do { 1269 got_one_level = false; 1270 xkb_keys_foreach(key, keymap) { 1271 if (group < key->num_groups && 1272 level < XkbKeyNumLevels(key, group)) { 1273 got_one_group = got_one_level = true; 1274 if (key->groups[group].levels[level].num_syms == 1 && 1275 key->groups[group].levels[level].u.sym == sym) 1276 return key; 1277 } 1278 } 1279 level++; 1280 } while (got_one_level); 1281 group++; 1282 } while (got_one_group); 1283 1284 return NULL; 1285 } 1286 1287 /* 1288 * Find an appropriate type for a group and return its name. 1289 * 1290 * Simple recipe: 1291 * - ONE_LEVEL for width 0/1 1292 * - ALPHABETIC for 2 shift levels, with lower/upercase keysyms 1293 * - KEYPAD for keypad keys. 1294 * - TWO_LEVEL for other 2 shift level keys. 1295 * and the same for four level keys. 1296 * 1297 * FIXME: Decide how to handle multiple-syms-per-level, and do it. 1298 */ 1299 static xkb_atom_t 1300 FindAutomaticType(struct xkb_context *ctx, GroupInfo *groupi) 1301 { 1302 xkb_keysym_t sym0, sym1, sym2, sym3; 1303 xkb_level_index_t width = darray_size(groupi->levels); 1304 1305 #define GET_SYM(level) \ 1306 (darray_item(groupi->levels, level).num_syms == 0 ? \ 1307 XKB_KEY_NoSymbol : \ 1308 darray_item(groupi->levels, level).num_syms == 1 ? \ 1309 darray_item(groupi->levels, level).u.sym : \ 1310 /* num_syms > 1 */ \ 1311 darray_item(groupi->levels, level).u.syms[0]) 1312 1313 if (width == 1 || width <= 0) 1314 return xkb_atom_intern_literal(ctx, "ONE_LEVEL"); 1315 1316 sym0 = GET_SYM(0); 1317 sym1 = GET_SYM(1); 1318 1319 if (width == 2) { 1320 if (xkb_keysym_is_lower(sym0) && xkb_keysym_is_upper(sym1)) 1321 return xkb_atom_intern_literal(ctx, "ALPHABETIC"); 1322 1323 if (xkb_keysym_is_keypad(sym0) || xkb_keysym_is_keypad(sym1)) 1324 return xkb_atom_intern_literal(ctx, "KEYPAD"); 1325 1326 return xkb_atom_intern_literal(ctx, "TWO_LEVEL"); 1327 } 1328 1329 if (width <= 4) { 1330 if (xkb_keysym_is_lower(sym0) && xkb_keysym_is_upper(sym1)) { 1331 sym2 = GET_SYM(2); 1332 sym3 = (width == 4 ? GET_SYM(3) : XKB_KEY_NoSymbol); 1333 1334 if (xkb_keysym_is_lower(sym2) && xkb_keysym_is_upper(sym3)) 1335 return xkb_atom_intern_literal(ctx, "FOUR_LEVEL_ALPHABETIC"); 1336 1337 return xkb_atom_intern_literal(ctx, "FOUR_LEVEL_SEMIALPHABETIC"); 1338 } 1339 1340 if (xkb_keysym_is_keypad(sym0) || xkb_keysym_is_keypad(sym1)) 1341 return xkb_atom_intern_literal(ctx, "FOUR_LEVEL_KEYPAD"); 1342 1343 return xkb_atom_intern_literal(ctx, "FOUR_LEVEL"); 1344 } 1345 1346 return XKB_ATOM_NONE; 1347 1348 #undef GET_SYM 1349 } 1350 1351 static const struct xkb_key_type * 1352 FindTypeForGroup(struct xkb_keymap *keymap, KeyInfo *keyi, 1353 xkb_layout_index_t group, bool *explicit_type) 1354 { 1355 unsigned int i; 1356 GroupInfo *groupi = &darray_item(keyi->groups, group); 1357 xkb_atom_t type_name = groupi->type; 1358 1359 *explicit_type = true; 1360 1361 if (type_name == XKB_ATOM_NONE) { 1362 if (keyi->default_type != XKB_ATOM_NONE) { 1363 type_name = keyi->default_type; 1364 } 1365 else { 1366 type_name = FindAutomaticType(keymap->ctx, groupi); 1367 if (type_name != XKB_ATOM_NONE) 1368 *explicit_type = false; 1369 } 1370 } 1371 1372 if (type_name == XKB_ATOM_NONE) { 1373 log_warn(keymap->ctx, 1374 "Couldn't find an automatic type for key '%s' group %d with %lu levels; " 1375 "Using the default type\n", 1376 KeyNameText(keymap->ctx, keyi->name), group + 1, 1377 (unsigned long) darray_size(groupi->levels)); 1378 goto use_default; 1379 } 1380 1381 for (i = 0; i < keymap->num_types; i++) 1382 if (keymap->types[i].name == type_name) 1383 break; 1384 1385 if (i >= keymap->num_types) { 1386 log_warn(keymap->ctx, 1387 "The type \"%s\" for key '%s' group %d was not previously defined; " 1388 "Using the default type\n", 1389 xkb_atom_text(keymap->ctx, type_name), 1390 KeyNameText(keymap->ctx, keyi->name), group + 1); 1391 goto use_default; 1392 } 1393 1394 return &keymap->types[i]; 1395 1396 use_default: 1397 /* 1398 * Index 0 is guaranteed to contain something, usually 1399 * ONE_LEVEL or at least some default one-level type. 1400 */ 1401 return &keymap->types[0]; 1402 } 1403 1404 static bool 1405 CopySymbolsDefToKeymap(struct xkb_keymap *keymap, SymbolsInfo *info, 1406 KeyInfo *keyi) 1407 { 1408 struct xkb_key *key; 1409 GroupInfo *groupi; 1410 const GroupInfo *group0; 1411 xkb_layout_index_t i; 1412 1413 /* 1414 * The name is guaranteed to be real and not an alias (see 1415 * AddKeySymbols), so 'false' is safe here. 1416 */ 1417 key = XkbKeyByName(keymap, keyi->name, false); 1418 if (!key) { 1419 log_vrb(info->ctx, 5, 1420 "Key %s not found in keycodes; Symbols ignored\n", 1421 KeyInfoText(info, keyi)); 1422 return false; 1423 } 1424 1425 /* Find the range of groups we need. */ 1426 key->num_groups = 0; 1427 darray_enumerate(i, groupi, keyi->groups) 1428 if (groupi->defined) 1429 key->num_groups = i + 1; 1430 1431 if (key->num_groups <= 0) 1432 return false; /* WSGO */ 1433 1434 darray_resize(keyi->groups, key->num_groups); 1435 1436 /* 1437 * If there are empty groups between non-empty ones, fill them with data 1438 * from the first group. 1439 * We can make a wrong assumption here. But leaving gaps is worse. 1440 */ 1441 group0 = &darray_item(keyi->groups, 0); 1442 darray_foreach_from(groupi, keyi->groups, 1) { 1443 if (groupi->defined) 1444 continue; 1445 1446 CopyGroupInfo(groupi, group0); 1447 } 1448 1449 key->groups = calloc(key->num_groups, sizeof(*key->groups)); 1450 1451 /* Find and assign the groups' types in the keymap. */ 1452 darray_enumerate(i, groupi, keyi->groups) { 1453 const struct xkb_key_type *type; 1454 bool explicit_type; 1455 1456 type = FindTypeForGroup(keymap, keyi, i, &explicit_type); 1457 1458 /* Always have as many levels as the type specifies. */ 1459 if (type->num_levels < darray_size(groupi->levels)) { 1460 struct xkb_level *leveli; 1461 1462 log_vrb(info->ctx, 1, 1463 "Type \"%s\" has %d levels, but %s has %d levels; " 1464 "Ignoring extra symbols\n", 1465 xkb_atom_text(keymap->ctx, type->name), type->num_levels, 1466 KeyInfoText(info, keyi), 1467 (int) darray_size(groupi->levels)); 1468 1469 darray_foreach_from(leveli, groupi->levels, type->num_levels) 1470 ClearLevelInfo(leveli); 1471 } 1472 darray_resize0(groupi->levels, type->num_levels); 1473 1474 key->groups[i].explicit_type = explicit_type; 1475 key->groups[i].type = type; 1476 } 1477 1478 /* Copy levels. */ 1479 darray_enumerate(i, groupi, keyi->groups) 1480 darray_steal(groupi->levels, &key->groups[i].levels, NULL); 1481 1482 key->out_of_range_group_number = keyi->out_of_range_group_number; 1483 key->out_of_range_group_action = keyi->out_of_range_group_action; 1484 1485 if (keyi->defined & KEY_FIELD_VMODMAP) { 1486 key->vmodmap = keyi->vmodmap; 1487 key->explicit |= EXPLICIT_VMODMAP; 1488 } 1489 1490 if (keyi->repeat != KEY_REPEAT_UNDEFINED) { 1491 key->repeats = (keyi->repeat == KEY_REPEAT_YES); 1492 key->explicit |= EXPLICIT_REPEAT; 1493 } 1494 1495 darray_foreach(groupi, keyi->groups) { 1496 if (groupi->defined & GROUP_FIELD_ACTS) { 1497 key->explicit |= EXPLICIT_INTERP; 1498 break; 1499 } 1500 } 1501 1502 return true; 1503 } 1504 1505 static bool 1506 CopyModMapDefToKeymap(struct xkb_keymap *keymap, SymbolsInfo *info, 1507 ModMapEntry *entry) 1508 { 1509 struct xkb_key *key; 1510 1511 if (!entry->haveSymbol) { 1512 key = XkbKeyByName(keymap, entry->u.keyName, true); 1513 if (!key) { 1514 log_vrb(info->ctx, 5, 1515 "Key %s not found in keycodes; " 1516 "Modifier map entry for %s not updated\n", 1517 KeyNameText(info->ctx, entry->u.keyName), 1518 ModIndexText(info->ctx, &info->mods, entry->modifier)); 1519 return false; 1520 } 1521 } 1522 else { 1523 key = FindKeyForSymbol(keymap, entry->u.keySym); 1524 if (!key) { 1525 log_vrb(info->ctx, 5, 1526 "Key \"%s\" not found in symbol map; " 1527 "Modifier map entry for %s not updated\n", 1528 KeysymText(info->ctx, entry->u.keySym), 1529 ModIndexText(info->ctx, &info->mods, entry->modifier)); 1530 return false; 1531 } 1532 } 1533 1534 key->modmap |= (1u << entry->modifier); 1535 return true; 1536 } 1537 1538 static bool 1539 CopySymbolsToKeymap(struct xkb_keymap *keymap, SymbolsInfo *info) 1540 { 1541 KeyInfo *keyi; 1542 ModMapEntry *mm; 1543 1544 keymap->symbols_section_name = strdup_safe(info->name); 1545 XkbEscapeMapName(keymap->symbols_section_name); 1546 1547 keymap->mods = info->mods; 1548 1549 darray_steal(info->group_names, 1550 &keymap->group_names, &keymap->num_group_names); 1551 1552 darray_foreach(keyi, info->keys) 1553 if (!CopySymbolsDefToKeymap(keymap, info, keyi)) 1554 info->errorCount++; 1555 1556 if (xkb_context_get_log_verbosity(keymap->ctx) > 3) { 1557 struct xkb_key *key; 1558 1559 xkb_keys_foreach(key, keymap) { 1560 if (key->name == XKB_ATOM_NONE) 1561 continue; 1562 1563 if (key->num_groups < 1) 1564 log_info(info->ctx, 1565 "No symbols defined for %s\n", 1566 KeyNameText(info->ctx, key->name)); 1567 } 1568 } 1569 1570 darray_foreach(mm, info->modmaps) 1571 if (!CopyModMapDefToKeymap(keymap, info, mm)) 1572 info->errorCount++; 1573 1574 /* XXX: If we don't ignore errorCount, things break. */ 1575 return true; 1576 } 1577 1578 bool 1579 CompileSymbols(XkbFile *file, struct xkb_keymap *keymap, 1580 enum merge_mode merge) 1581 { 1582 SymbolsInfo info; 1583 ActionsInfo *actions; 1584 1585 actions = NewActionsInfo(); 1586 if (!actions) 1587 return false; 1588 1589 InitSymbolsInfo(&info, keymap, actions, &keymap->mods); 1590 info.default_key.merge = merge; 1591 1592 HandleSymbolsFile(&info, file, merge); 1593 1594 if (info.errorCount != 0) 1595 goto err_info; 1596 1597 if (!CopySymbolsToKeymap(keymap, &info)) 1598 goto err_info; 1599 1600 ClearSymbolsInfo(&info); 1601 FreeActionsInfo(actions); 1602 return true; 1603 1604 err_info: 1605 FreeActionsInfo(actions); 1606 ClearSymbolsInfo(&info); 1607 return false; 1608 } 1609