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