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.h" 28#include "tokens.h" 29#include "expr.h" 30#include "parseutils.h" 31 32#include <X11/keysym.h> 33#include <X11/Xutil.h> 34#include <stdlib.h> 35 36#include "expr.h" 37#include "vmod.h" 38#include "action.h" 39#include "keycodes.h" 40#include "misc.h" 41#include "alias.h" 42 43/***====================================================================***/ 44 45#define RepeatYes 1 46#define RepeatNo 0 47#define RepeatUndefined ~((unsigned)0) 48 49#define _Key_Syms (1<<0) 50#define _Key_Acts (1<<1) 51#define _Key_Repeat (1<<2) 52#define _Key_Behavior (1<<3) 53#define _Key_Type_Dflt (1<<4) 54#define _Key_Types (1<<5) 55#define _Key_GroupInfo (1<<6) 56#define _Key_VModMap (1<<7) 57 58typedef struct _KeyInfo 59{ 60 CommonInfo defs; 61 unsigned long name; /* the 4 chars of the key name, as long */ 62 unsigned char groupInfo; 63 unsigned char typesDefined; 64 unsigned char symsDefined; 65 unsigned char actsDefined; 66 short numLevels[XkbNumKbdGroups]; 67 KeySym *syms[XkbNumKbdGroups]; 68 XkbAction *acts[XkbNumKbdGroups]; 69 Atom types[XkbNumKbdGroups]; 70 unsigned repeat; 71 XkbBehavior behavior; 72 unsigned short vmodmap; 73 unsigned long nameForOverlayKey; 74 unsigned long allowNone; 75 Atom dfltType; 76} KeyInfo; 77 78/** 79 * Init the given key info to sane values. 80 */ 81static void 82InitKeyInfo(KeyInfo * info) 83{ 84 static char dflt[4] = "*"; 85 86 info->defs.defined = 0; 87 info->defs.fileID = 0; 88 info->defs.merge = MergeOverride; 89 info->defs.next = NULL; 90 info->name = KeyNameToLong(dflt); 91 info->groupInfo = 0; 92 info->typesDefined = info->symsDefined = info->actsDefined = 0; 93 for (int i = 0; i < XkbNumKbdGroups; i++) 94 { 95 info->numLevels[i] = 0; 96 info->types[i] = None; 97 info->syms[i] = NULL; 98 info->acts[i] = NULL; 99 } 100 info->dfltType = None; 101 info->behavior.type = XkbKB_Default; 102 info->behavior.data = 0; 103 info->vmodmap = 0; 104 info->nameForOverlayKey = 0; 105 info->repeat = RepeatUndefined; 106 info->allowNone = 0; 107 return; 108} 109 110/** 111 * Free memory associated with this key info and reset to sane values. 112 */ 113static void 114FreeKeyInfo(KeyInfo * info) 115{ 116 info->defs.defined = 0; 117 info->defs.fileID = 0; 118 info->defs.merge = MergeOverride; 119 info->defs.next = NULL; 120 info->groupInfo = 0; 121 info->typesDefined = info->symsDefined = info->actsDefined = 0; 122 for (int i = 0; i < XkbNumKbdGroups; i++) 123 { 124 info->numLevels[i] = 0; 125 info->types[i] = None; 126 free(info->syms[i]); 127 info->syms[i] = NULL; 128 free(info->acts[i]); 129 info->acts[i] = NULL; 130 } 131 info->dfltType = None; 132 info->behavior.type = XkbKB_Default; 133 info->behavior.data = 0; 134 info->vmodmap = 0; 135 info->nameForOverlayKey = 0; 136 info->repeat = RepeatUndefined; 137 info->allowNone = 0; 138 return; 139} 140 141/** 142 * Copy old into new, optionally reset old to 0. 143 * If old is reset, new simply re-uses old's memory. Otherwise, the memory is 144 * newly allocated and new points to the new memory areas. 145 */ 146static Bool 147CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld) 148{ 149 *new = *old; 150 new->defs.next = NULL; 151 if (clearOld) 152 { 153 for (int i = 0; i < XkbNumKbdGroups; i++) 154 { 155 old->numLevels[i] = 0; 156 old->syms[i] = NULL; 157 old->acts[i] = NULL; 158 } 159 } 160 else 161 { 162 for (int i = 0; i < XkbNumKbdGroups; i++) 163 { 164 int width = new->numLevels[i]; 165 if (old->syms[i] != NULL) 166 { 167 new->syms[i] = calloc(width, sizeof(KeySym)); 168 if (!new->syms[i]) 169 { 170 new->syms[i] = NULL; 171 new->numLevels[i] = 0; 172 return False; 173 } 174 memcpy(new->syms[i], old->syms[i], width * sizeof(KeySym)); 175 } 176 if (old->acts[i] != NULL) 177 { 178 new->acts[i] = calloc(width, sizeof(XkbAction)); 179 if (!new->acts[i]) 180 { 181 new->acts[i] = NULL; 182 return False; 183 } 184 memcpy(new->acts[i], old->acts[i], width * sizeof(XkbAction)); 185 } 186 } 187 } 188 return True; 189} 190 191/***====================================================================***/ 192 193typedef struct _ModMapEntry 194{ 195 CommonInfo defs; 196 Bool haveSymbol; 197 int modifier; 198 union 199 { 200 unsigned long keyName; 201 KeySym keySym; 202 } u; 203} ModMapEntry; 204 205#define SYMBOLS_INIT_SIZE 110 206#define SYMBOLS_CHUNK 20 207typedef struct _SymbolsInfo 208{ 209 char *name; /* e.g. pc+us+inet(evdev) */ 210 int errorCount; 211 unsigned fileID; 212 unsigned merge; 213 unsigned explicit_group; 214 unsigned groupInfo; 215 unsigned szKeys; 216 unsigned nKeys; 217 KeyInfo *keys; 218 KeyInfo dflt; 219 VModInfo vmods; 220 ActionInfo *action; 221 Atom groupNames[XkbNumKbdGroups]; 222 223 ModMapEntry *modMap; 224 AliasInfo *aliases; 225} SymbolsInfo; 226 227static void 228InitSymbolsInfo(SymbolsInfo * info, XkbDescPtr xkb) 229{ 230 tok_ONE_LEVEL = XkbInternAtom(NULL, "ONE_LEVEL", False); 231 tok_TWO_LEVEL = XkbInternAtom(NULL, "TWO_LEVEL", False); 232 tok_KEYPAD = XkbInternAtom(NULL, "KEYPAD", False); 233 info->name = NULL; 234 info->explicit_group = 0; 235 info->errorCount = 0; 236 info->fileID = 0; 237 info->merge = MergeOverride; 238 info->groupInfo = 0; 239 info->szKeys = SYMBOLS_INIT_SIZE; 240 info->nKeys = 0; 241 info->keys = calloc(SYMBOLS_INIT_SIZE, sizeof(KeyInfo)); 242 info->modMap = NULL; 243 for (int i = 0; i < XkbNumKbdGroups; i++) 244 info->groupNames[i] = None; 245 InitKeyInfo(&info->dflt); 246 InitVModInfo(&info->vmods, xkb); 247 info->action = NULL; 248 info->aliases = NULL; 249 return; 250} 251 252static void 253FreeSymbolsInfo(SymbolsInfo * info) 254{ 255 free(info->name); 256 info->name = NULL; 257 if (info->keys) 258 { 259 for (int i = 0; i < info->nKeys; i++) 260 { 261 FreeKeyInfo(&info->keys[i]); 262 } 263 free(info->keys); 264 info->keys = NULL; 265 } 266 if (info->modMap) 267 { 268 ClearCommonInfo(&info->modMap->defs); 269 info->modMap = NULL; 270 } 271 if (info->aliases) 272 { 273 ClearAliases(&info->aliases); 274 info->aliases = NULL; 275 } 276 bzero(info, sizeof(SymbolsInfo)); 277 return; 278} 279 280static Bool 281ResizeKeyGroup(KeyInfo * key, 282 unsigned group, unsigned atLeastSize, Bool forceActions) 283{ 284 Bool tooSmall; 285 unsigned newWidth; 286 287 tooSmall = (key->numLevels[group] < atLeastSize); 288 if (tooSmall) 289 newWidth = atLeastSize; 290 else 291 newWidth = key->numLevels[group]; 292 293 if ((key->syms[group] == NULL) || tooSmall) 294 { 295 key->syms[group] = recallocarray(key->syms[group], 296 key->numLevels[group], newWidth, 297 sizeof(KeySym)); 298 if (!key->syms[group]) 299 return False; 300 } 301 if (((forceActions) && (tooSmall || (key->acts[group] == NULL))) || 302 (tooSmall && (key->acts[group] != NULL))) 303 { 304 key->acts[group] = recallocarray(key->acts[group], 305 key->numLevels[group], newWidth, 306 sizeof(XkbAction)); 307 if (!key->acts[group]) 308 return False; 309 } 310 key->numLevels[group] = newWidth; 311 return True; 312} 313 314static Bool 315MergeKeyGroups(SymbolsInfo * info, 316 KeyInfo * into, KeyInfo * from, unsigned group) 317{ 318 KeySym *resultSyms; 319 XkbAction *resultActs; 320 int resultWidth; 321 Bool report, clobber; 322 323 clobber = (from->defs.merge != MergeAugment); 324 report = (warningLevel > 9) || 325 ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0)); 326 if ((from->numLevels[group] > into->numLevels[group]) 327 || (clobber && (from->types[group] != None))) 328 { 329 resultSyms = from->syms[group]; 330 resultActs = from->acts[group]; 331 resultWidth = from->numLevels[group]; 332 } 333 else 334 { 335 resultSyms = into->syms[group]; 336 resultActs = into->acts[group]; 337 resultWidth = into->numLevels[group]; 338 } 339 if (resultSyms == NULL) 340 { 341 resultSyms = calloc(resultWidth, sizeof(KeySym)); 342 if (!resultSyms) 343 { 344 WSGO("Could not allocate symbols for group merge\n"); 345 ACTION("Group %d of key %s not merged\n", group, 346 longText(into->name, XkbMessage)); 347 return False; 348 } 349 } 350 if ((resultActs == NULL) && (into->acts[group] || from->acts[group])) 351 { 352 resultActs = calloc(resultWidth, sizeof(XkbAction)); 353 if (!resultActs) 354 { 355 WSGO("Could not allocate actions for group merge\n"); 356 ACTION("Group %d of key %s not merged\n", group, 357 longText(into->name, XkbMessage)); 358 return False; 359 } 360 } 361 for (int i = 0; i < resultWidth; i++) 362 { 363 KeySym fromSym, toSym; 364 if (from->syms[group] && (i < from->numLevels[group])) 365 fromSym = from->syms[group][i]; 366 else 367 fromSym = NoSymbol; 368 if (into->syms[group] && (i < into->numLevels[group])) 369 toSym = into->syms[group][i]; 370 else 371 toSym = NoSymbol; 372 if ((fromSym == NoSymbol) || (fromSym == toSym)) 373 resultSyms[i] = toSym; 374 else if (toSym == NoSymbol) 375 resultSyms[i] = fromSym; 376 else 377 { 378 KeySym use, ignore; 379 if (clobber) 380 { 381 use = fromSym; 382 ignore = toSym; 383 } 384 else 385 { 386 use = toSym; 387 ignore = fromSym; 388 } 389 if (report) 390 { 391 WARN 392 ("Multiple symbols for level %d/group %d on key %s\n", 393 i + 1, group + 1, longText(into->name, XkbMessage)); 394 ACTION("Using %s, ignoring %s\n", 395 XkbKeysymText(use, XkbMessage), 396 XkbKeysymText(ignore, XkbMessage)); 397 } 398 resultSyms[i] = use; 399 } 400 if (resultActs != NULL) 401 { 402 XkbAction *fromAct, *toAct; 403 fromAct = (from->acts[group] ? &from->acts[group][i] : NULL); 404 toAct = (into->acts[group] ? &into->acts[group][i] : NULL); 405 if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction)) 406 && (toAct != NULL)) 407 { 408 resultActs[i] = *toAct; 409 } 410 else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction)) 411 && (fromAct != NULL)) 412 { 413 resultActs[i] = *fromAct; 414 } 415 else 416 { 417 XkbAction *use, *ignore; 418 if (clobber) 419 { 420 use = fromAct; 421 ignore = toAct; 422 } 423 else 424 { 425 use = toAct; 426 ignore = fromAct; 427 } 428 if (report) 429 { 430 WARN 431 ("Multiple actions for level %d/group %d on key %s\n", 432 i + 1, group + 1, longText(into->name, XkbMessage)); 433 ACTION("Using %s, ignoring %s\n", 434 XkbActionTypeText(use->type, XkbMessage), 435 XkbActionTypeText(ignore->type, XkbMessage)); 436 } 437 resultActs[i] = *use; 438 } 439 } 440 } 441 if ((into->syms[group] != NULL) && (resultSyms != into->syms[group])) 442 free(into->syms[group]); 443 if ((from->syms[group] != NULL) && (resultSyms != from->syms[group])) 444 free(from->syms[group]); 445 if ((into->acts[group] != NULL) && (resultActs != into->acts[group])) 446 free(into->acts[group]); 447 if ((from->acts[group] != NULL) && (resultActs != from->acts[group])) 448 free(from->acts[group]); 449 into->numLevels[group] = resultWidth; 450 into->syms[group] = resultSyms; 451 from->syms[group] = NULL; 452 into->acts[group] = resultActs; 453 from->acts[group] = NULL; 454 into->symsDefined |= (1U << group); 455 from->symsDefined &= ~(1U << group); 456 into->actsDefined |= (1U << group); 457 from->actsDefined &= ~(1U << group); 458 return True; 459} 460 461static Bool 462MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from) 463{ 464 unsigned collide = 0; 465 Bool report; 466 467 if (from->defs.merge == MergeReplace) 468 { 469 for (int i = 0; i < XkbNumKbdGroups; i++) 470 { 471 if (into->numLevels[i] != 0) 472 { 473 free(into->syms[i]); 474 free(into->acts[i]); 475 } 476 } 477 *into = *from; 478 bzero(from, sizeof(KeyInfo)); 479 return True; 480 } 481 report = ((warningLevel > 9) || 482 ((into->defs.fileID == from->defs.fileID) 483 && (warningLevel > 0))); 484 for (int i = 0; i < XkbNumKbdGroups; i++) 485 { 486 if (from->numLevels[i] > 0) 487 { 488 if (into->numLevels[i] == 0) 489 { 490 into->numLevels[i] = from->numLevels[i]; 491 into->syms[i] = from->syms[i]; 492 into->acts[i] = from->acts[i]; 493 into->symsDefined |= (1U << i); 494 from->syms[i] = NULL; 495 from->acts[i] = NULL; 496 from->numLevels[i] = 0; 497 from->symsDefined &= ~(1U << i); 498 if (into->syms[i]) 499 into->defs.defined |= _Key_Syms; 500 if (into->acts[i]) 501 into->defs.defined |= _Key_Acts; 502 } 503 else 504 { 505 if (report) 506 { 507 if (into->syms[i]) 508 collide |= _Key_Syms; 509 if (into->acts[i]) 510 collide |= _Key_Acts; 511 } 512 MergeKeyGroups(info, into, from, (unsigned) i); 513 } 514 } 515 if (from->types[i] != None) 516 { 517 if ((into->types[i] != None) && (report) && 518 (into->types[i] != from->types[i])) 519 { 520 Atom use, ignore; 521 collide |= _Key_Types; 522 if (from->defs.merge != MergeAugment) 523 { 524 use = from->types[i]; 525 ignore = into->types[i]; 526 } 527 else 528 { 529 use = into->types[i]; 530 ignore = from->types[i]; 531 } 532 WARN 533 ("Multiple definitions for group %d type of key %s\n", 534 i, longText(into->name, XkbMessage)); 535 ACTION("Using %s, ignoring %s\n", 536 XkbAtomText(NULL, use, XkbMessage), 537 XkbAtomText(NULL, ignore, XkbMessage)); 538 } 539 if ((from->defs.merge != MergeAugment) 540 || (into->types[i] == None)) 541 { 542 into->types[i] = from->types[i]; 543 } 544 } 545 } 546 if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide)) 547 { 548 into->behavior = from->behavior; 549 into->nameForOverlayKey = from->nameForOverlayKey; 550 into->defs.defined |= _Key_Behavior; 551 } 552 if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide)) 553 { 554 into->vmodmap = from->vmodmap; 555 into->defs.defined |= _Key_VModMap; 556 } 557 if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide)) 558 { 559 into->repeat = from->repeat; 560 into->defs.defined |= _Key_Repeat; 561 } 562 if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide)) 563 { 564 into->dfltType = from->dfltType; 565 into->defs.defined |= _Key_Type_Dflt; 566 } 567 if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide)) 568 { 569 into->groupInfo = from->groupInfo; 570 into->defs.defined |= _Key_GroupInfo; 571 } 572 if (collide && (warningLevel > 0)) 573 { 574 WARN("Symbol map for key %s redefined\n", 575 longText(into->name, XkbMessage)); 576 ACTION("Using %s definition for conflicting fields\n", 577 (from->defs.merge == MergeAugment ? "first" : "last")); 578 } 579 return True; 580} 581 582static Bool 583AddKeySymbols(SymbolsInfo * info, KeyInfo * key, XkbDescPtr xkb) 584{ 585 unsigned long real_name; 586 587 for (int i = 0; i < info->nKeys; i++) 588 { 589 if (info->keys[i].name == key->name) 590 return MergeKeys(info, &info->keys[i], key); 591 } 592 if (FindKeyNameForAlias(xkb, key->name, &real_name)) 593 { 594 for (int i = 0; i < info->nKeys; i++) 595 { 596 if (info->keys[i].name == real_name) 597 return MergeKeys(info, &info->keys[i], key); 598 } 599 } 600 if (info->nKeys >= info->szKeys) 601 { 602 info->szKeys += SYMBOLS_CHUNK; 603 info->keys = recallocarray(info->keys, info->nKeys, info->szKeys, 604 sizeof(KeyInfo)); 605 if (!info->keys) 606 { 607 WSGO("Could not allocate key symbols descriptions\n"); 608 ACTION("Some key symbols definitions may be lost\n"); 609 return False; 610 } 611 } 612 return CopyKeyInfo(key, &info->keys[info->nKeys++], True); 613} 614 615static Bool 616AddModMapEntry(SymbolsInfo * info, ModMapEntry * new) 617{ 618 ModMapEntry *mm; 619 Bool clobber; 620 621 clobber = (new->defs.merge != MergeAugment); 622 for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next) 623 { 624 if (new->haveSymbol && mm->haveSymbol 625 && (new->u.keySym == mm->u.keySym)) 626 { 627 if (mm->modifier != new->modifier) 628 { 629 unsigned use, ignore; 630 631 if (clobber) 632 { 633 use = new->modifier; 634 ignore = mm->modifier; 635 } 636 else 637 { 638 use = mm->modifier; 639 ignore = new->modifier; 640 } 641 ERROR 642 ("%s added to symbol map for multiple modifiers\n", 643 XkbKeysymText(new->u.keySym, XkbMessage)); 644 ACTION("Using %s, ignoring %s.\n", 645 XkbModIndexText(use, XkbMessage), 646 XkbModIndexText(ignore, XkbMessage)); 647 mm->modifier = use; 648 } 649 return True; 650 } 651 if ((!new->haveSymbol) && (!mm->haveSymbol) && 652 (new->u.keyName == mm->u.keyName)) 653 { 654 if (mm->modifier != new->modifier) 655 { 656 unsigned use, ignore; 657 658 if (clobber) 659 { 660 use = new->modifier; 661 ignore = mm->modifier; 662 } 663 else 664 { 665 use = mm->modifier; 666 ignore = new->modifier; 667 } 668 ERROR("Key %s added to map for multiple modifiers\n", 669 longText(new->u.keyName, XkbMessage)); 670 ACTION("Using %s, ignoring %s.\n", 671 XkbModIndexText(use, XkbMessage), 672 XkbModIndexText(ignore, XkbMessage)); 673 mm->modifier = use; 674 } 675 return True; 676 } 677 } 678 mm = malloc(sizeof(ModMapEntry)); 679 if (mm == NULL) 680 { 681 WSGO("Could not allocate modifier map entry\n"); 682 ACTION("Modifier map for %s will be incomplete\n", 683 XkbModIndexText(new->modifier, XkbMessage)); 684 return False; 685 } 686 *mm = *new; 687 mm->defs.next = &info->modMap->defs; 688 info->modMap = mm; 689 return True; 690} 691 692/***====================================================================***/ 693 694static void 695MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from, 696 unsigned merge, XkbDescPtr xkb) 697{ 698 int i; 699 KeyInfo *key; 700 701 if (from->errorCount > 0) 702 { 703 into->errorCount += from->errorCount; 704 return; 705 } 706 if (into->name == NULL) 707 { 708 into->name = from->name; 709 from->name = NULL; 710 } 711 for (i = 0; i < XkbNumKbdGroups; i++) 712 { 713 if (from->groupNames[i] != None) 714 { 715 if ((merge != MergeAugment) || (into->groupNames[i] == None)) 716 into->groupNames[i] = from->groupNames[i]; 717 } 718 } 719 for (i = 0, key = from->keys; i < from->nKeys; i++, key++) 720 { 721 if (merge != MergeDefault) 722 key->defs.merge = merge; 723 if (!AddKeySymbols(into, key, xkb)) 724 into->errorCount++; 725 } 726 if (from->modMap != NULL) 727 { 728 ModMapEntry *mm, *next; 729 for (mm = from->modMap; mm != NULL; mm = next) 730 { 731 if (merge != MergeDefault) 732 mm->defs.merge = merge; 733 if (!AddModMapEntry(into, mm)) 734 into->errorCount++; 735 next = (ModMapEntry *) mm->defs.next; 736 free(mm); 737 } 738 from->modMap = NULL; 739 } 740 if (!MergeAliases(&into->aliases, &from->aliases, merge)) 741 into->errorCount++; 742 return; 743} 744 745typedef void (*FileHandler) (XkbFile * /* rtrn */ , 746 XkbDescPtr /* xkb */ , 747 unsigned /* merge */ , 748 SymbolsInfo * /* included */ 749 ); 750 751static Bool 752HandleIncludeSymbols(IncludeStmt * stmt, 753 XkbDescPtr xkb, SymbolsInfo * info, FileHandler hndlr) 754{ 755 unsigned newMerge; 756 XkbFile *rtrn; 757 SymbolsInfo included; 758 Bool haveSelf; 759 760 haveSelf = False; 761 if ((stmt->file == NULL) && (stmt->map == NULL)) 762 { 763 haveSelf = True; 764 included = *info; 765 bzero(info, sizeof(SymbolsInfo)); 766 } 767 else if (ProcessIncludeFile(stmt, XkmSymbolsIndex, &rtrn, &newMerge)) 768 { 769 InitSymbolsInfo(&included, xkb); 770 included.fileID = included.dflt.defs.fileID = rtrn->id; 771 included.merge = included.dflt.defs.merge = MergeOverride; 772 if (stmt->modifier) 773 { 774 included.explicit_group = atoi(stmt->modifier) - 1; 775 } 776 else 777 { 778 included.explicit_group = info->explicit_group; 779 } 780 (*hndlr) (rtrn, xkb, MergeOverride, &included); 781 if (stmt->stmt != NULL) 782 { 783 free(included.name); 784 included.name = stmt->stmt; 785 stmt->stmt = NULL; 786 } 787 } 788 else 789 { 790 info->errorCount += 10; 791 return False; 792 } 793 if ((stmt->next != NULL) && (included.errorCount < 1)) 794 { 795 IncludeStmt *next; 796 unsigned op; 797 SymbolsInfo next_incl; 798 799 for (next = stmt->next; next != NULL; next = next->next) 800 { 801 if ((next->file == NULL) && (next->map == NULL)) 802 { 803 haveSelf = True; 804 MergeIncludedSymbols(&included, info, next->merge, xkb); 805 FreeSymbolsInfo(info); 806 } 807 else if (ProcessIncludeFile(next, XkmSymbolsIndex, &rtrn, &op)) 808 { 809 InitSymbolsInfo(&next_incl, xkb); 810 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id; 811 next_incl.merge = next_incl.dflt.defs.merge = MergeOverride; 812 if (next->modifier) 813 { 814 next_incl.explicit_group = atoi(next->modifier) - 1; 815 } 816 else 817 { 818 next_incl.explicit_group = info->explicit_group; 819 } 820 (*hndlr) (rtrn, xkb, MergeOverride, &next_incl); 821 MergeIncludedSymbols(&included, &next_incl, op, xkb); 822 FreeSymbolsInfo(&next_incl); 823 } 824 else 825 { 826 info->errorCount += 10; 827 return False; 828 } 829 } 830 } 831 if (haveSelf) 832 *info = included; 833 else 834 { 835 MergeIncludedSymbols(info, &included, newMerge, xkb); 836 FreeSymbolsInfo(&included); 837 } 838 return (info->errorCount == 0); 839} 840 841static LookupEntry groupNames[] = { 842 {"group1", 1}, 843 {"group2", 2}, 844 {"group3", 3}, 845 {"group4", 4}, 846 {"group5", 5}, 847 {"group6", 6}, 848 {"group7", 7}, 849 {"group8", 8}, 850 {NULL, 0} 851}; 852 853 854#define SYMBOLS 1 855#define ACTIONS 2 856 857static Bool 858GetGroupIndex(KeyInfo *key, const ExprDef *arrayNdx, 859 unsigned what, unsigned *ndx_rtrn) 860{ 861 const char *name; 862 ExprResult tmp; 863 864 if (what == SYMBOLS) 865 name = "symbols"; 866 else 867 name = "actions"; 868 869 if (arrayNdx == NULL) 870 { 871 unsigned defined; 872 if (what == SYMBOLS) 873 defined = key->symsDefined; 874 else 875 defined = key->actsDefined; 876 877 for (int i = 0; i < XkbNumKbdGroups; i++) 878 { 879 if ((defined & (1U << i)) == 0) 880 { 881 *ndx_rtrn = i; 882 return True; 883 } 884 } 885 ERROR("Too many groups of %s for key %s (max %d)\n", name, 886 longText(key->name, XkbMessage), XkbNumKbdGroups + 1); 887 ACTION("Ignoring %s defined for extra groups\n", name); 888 return False; 889 } 890 if (!ExprResolveInteger 891 (arrayNdx, &tmp, SimpleLookup, (XPointer) groupNames)) 892 { 893 ERROR("Illegal group index for %s of key %s\n", name, 894 longText(key->name, XkbMessage)); 895 ACTION("Definition with non-integer array index ignored\n"); 896 return False; 897 } 898 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) 899 { 900 ERROR("Group index for %s of key %s is out of range (1..%d)\n", 901 name, longText(key->name, XkbMessage), XkbNumKbdGroups + 1); 902 ACTION("Ignoring %s for group %d\n", name, tmp.uval); 903 return False; 904 } 905 *ndx_rtrn = tmp.uval - 1; 906 return True; 907} 908 909static Bool 910AddSymbolsToKey(KeyInfo *key, XkbDescPtr xkb, const char *field, 911 const ExprDef *arrayNdx, const ExprDef *value, 912 SymbolsInfo *info) 913{ 914 unsigned ndx, nSyms; 915 916 if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx)) 917 return False; 918 if (value == NULL) 919 { 920 key->symsDefined |= (1U << ndx); 921 return True; 922 } 923 if (value->op != ExprKeysymList) 924 { 925 ERROR("Expected a list of symbols, found %s\n", 926 exprOpText(value->op)); 927 ACTION("Ignoring symbols for group %d of %s\n", ndx, 928 longText(key->name, XkbMessage)); 929 return False; 930 } 931 if (key->syms[ndx] != NULL) 932 { 933 WSGO("Symbols for key %s, group %d already defined\n", 934 longText(key->name, XkbMessage), ndx); 935 return False; 936 } 937 nSyms = value->value.list.nSyms; 938 if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) && 939 (!ResizeKeyGroup(key, ndx, nSyms, False))) 940 { 941 WSGO("Could not resize group %d of key %s\n", ndx, 942 longText(key->name, XkbMessage)); 943 ACTION("Symbols lost\n"); 944 return False; 945 } 946 key->symsDefined |= (1U << ndx); 947 for (int i = 0; i < nSyms; i++) { 948 if (!LookupKeysym(value->value.list.syms[i], &key->syms[ndx][i])) { 949 if (warningLevel > 0) 950 { 951 WARN("Could not resolve keysym %s\n", 952 value->value.list.syms[i]); 953 } 954 key->syms[ndx][i] = NoSymbol; 955 } 956 } 957 for (int i = key->numLevels[ndx] - 1; 958 (i >= 0) && (key->syms[ndx][i] == NoSymbol); i--) 959 { 960 key->numLevels[ndx]--; 961 } 962 return True; 963} 964 965static Bool 966AddActionsToKey(KeyInfo *key, XkbDescPtr xkb, const char *field, 967 const ExprDef *arrayNdx, const ExprDef *value, 968 SymbolsInfo *info) 969{ 970 unsigned ndx, nActs; 971 ExprDef *act; 972 XkbAnyAction *toAct; 973 974 if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx)) 975 return False; 976 977 if (value == NULL) 978 { 979 key->actsDefined |= (1U << ndx); 980 return True; 981 } 982 if (value->op != ExprActionList) 983 { 984 WSGO("Bad expression type (%d) for action list value\n", value->op); 985 ACTION("Ignoring actions for group %d of %s\n", ndx, 986 longText(key->name, XkbMessage)); 987 return False; 988 } 989 if (key->acts[ndx] != NULL) 990 { 991 WSGO("Actions for key %s, group %d already defined\n", 992 longText(key->name, XkbMessage), ndx); 993 return False; 994 } 995 for (nActs = 0, act = value->value.child; act != NULL; nActs++) 996 { 997 act = (ExprDef *) act->common.next; 998 } 999 if (nActs < 1) 1000 { 1001 WSGO("Action list but not actions in AddActionsToKey\n"); 1002 return False; 1003 } 1004 if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) && 1005 (!ResizeKeyGroup(key, ndx, nActs, True))) 1006 { 1007 WSGO("Could not resize group %d of key %s\n", ndx, 1008 longText(key->name, XkbMessage)); 1009 ACTION("Actions lost\n"); 1010 return False; 1011 } 1012 key->actsDefined |= (1U << ndx); 1013 1014 toAct = (XkbAnyAction *) key->acts[ndx]; 1015 act = value->value.child; 1016 for (int i = 0; i < nActs; i++, toAct++) 1017 { 1018 if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action)) 1019 { 1020 ERROR("Illegal action definition for %s\n", 1021 longText(key->name, XkbMessage)); 1022 ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1); 1023 } 1024 act = (ExprDef *) act->common.next; 1025 } 1026 return True; 1027} 1028 1029static int 1030SetAllowNone(KeyInfo *key, const ExprDef *arrayNdx, const ExprDef *value) 1031{ 1032 ExprResult tmp; 1033 unsigned radio_groups = 0; 1034 1035 if (arrayNdx == NULL) 1036 { 1037 radio_groups = XkbAllRadioGroupsMask; 1038 } 1039 else 1040 { 1041 if (!ExprResolveInteger(arrayNdx, &tmp, RadioLookup, NULL)) 1042 { 1043 ERROR("Illegal index in group name definition\n"); 1044 ACTION("Definition with non-integer array index ignored\n"); 1045 return False; 1046 } 1047 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups)) 1048 { 1049 ERROR("Illegal radio group specified (must be 1..%d)\n", 1050 XkbMaxRadioGroups + 1); 1051 ACTION("Value of \"allow none\" for group %d ignored\n", 1052 tmp.uval); 1053 return False; 1054 } 1055 radio_groups |= (1U << (tmp.uval - 1)); 1056 } 1057 if (!ExprResolveBoolean(value, &tmp, NULL, NULL)) 1058 { 1059 ERROR("Illegal \"allow none\" value for %s\n", 1060 longText(key->name, XkbMessage)); 1061 ACTION("Non-boolean value ignored\n"); 1062 return False; 1063 } 1064 if (tmp.uval) 1065 key->allowNone |= radio_groups; 1066 else 1067 key->allowNone &= ~radio_groups; 1068 return True; 1069} 1070 1071 1072static LookupEntry lockingEntries[] = { 1073 {"true", XkbKB_Lock}, 1074 {"yes", XkbKB_Lock}, 1075 {"on", XkbKB_Lock}, 1076 {"false", XkbKB_Default}, 1077 {"no", XkbKB_Default}, 1078 {"off", XkbKB_Default}, 1079 {"permanent", XkbKB_Lock | XkbKB_Permanent}, 1080 {NULL, 0} 1081}; 1082 1083static LookupEntry repeatEntries[] = { 1084 {"true", RepeatYes}, 1085 {"yes", RepeatYes}, 1086 {"on", RepeatYes}, 1087 {"false", RepeatNo}, 1088 {"no", RepeatNo}, 1089 {"off", RepeatNo}, 1090 {"default", RepeatUndefined}, 1091 {NULL, 0} 1092}; 1093 1094static LookupEntry rgEntries[] = { 1095 {"none", 0}, 1096 {NULL, 0} 1097}; 1098 1099static Bool 1100SetSymbolsField(KeyInfo *key, XkbDescPtr xkb, const char *field, 1101 const ExprDef *arrayNdx, const ExprDef *value, 1102 SymbolsInfo *info) 1103{ 1104 Bool ok = True; 1105 ExprResult tmp; 1106 1107 if (uStrCaseCmp(field, "type") == 0) 1108 { 1109 ExprResult ndx; 1110 if ((!ExprResolveString(value, &tmp, NULL, NULL)) 1111 && (warningLevel > 0)) 1112 { 1113 WARN("The type field of a key symbol map must be a string\n"); 1114 ACTION("Ignoring illegal type definition\n"); 1115 } 1116 if (arrayNdx == NULL) 1117 { 1118 key->dfltType = XkbInternAtom(NULL, tmp.str, False); 1119 key->defs.defined |= _Key_Type_Dflt; 1120 } 1121 else if (!ExprResolveInteger(arrayNdx, &ndx, SimpleLookup, 1122 (XPointer) groupNames)) 1123 { 1124 ERROR("Illegal group index for type of key %s\n", 1125 longText(key->name, XkbMessage)); 1126 ACTION("Definition with non-integer array index ignored\n"); 1127 return False; 1128 } 1129 else if ((ndx.uval < 1) || (ndx.uval > XkbNumKbdGroups)) 1130 { 1131 ERROR 1132 ("Group index for type of key %s is out of range (1..%d)\n", 1133 longText(key->name, XkbMessage), XkbNumKbdGroups + 1); 1134 ACTION("Ignoring type for group %d\n", ndx.uval); 1135 return False; 1136 } 1137 else 1138 { 1139 key->types[ndx.uval - 1] = XkbInternAtom(NULL, tmp.str, False); 1140 key->typesDefined |= (1U << (ndx.uval - 1)); 1141 } 1142 } 1143 else if (uStrCaseCmp(field, "symbols") == 0) 1144 return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info); 1145 else if (uStrCaseCmp(field, "actions") == 0) 1146 return AddActionsToKey(key, xkb, field, arrayNdx, value, info); 1147 else if ((uStrCaseCmp(field, "vmods") == 0) || 1148 (uStrCaseCmp(field, "virtualmods") == 0) || 1149 (uStrCaseCmp(field, "virtualmodifiers") == 0)) 1150 { 1151 ok = ExprResolveModMask(value, &tmp, LookupVModMask, (XPointer) xkb); 1152 if (ok) 1153 { 1154 key->vmodmap = (tmp.uval >> 8); 1155 key->defs.defined |= _Key_VModMap; 1156 } 1157 else 1158 { 1159 ERROR("Expected a virtual modifier mask, found %s\n", 1160 exprOpText(value->op)); 1161 ACTION("Ignoring virtual modifiers definition for key %s\n", 1162 longText(key->name, XkbMessage)); 1163 } 1164 } 1165 else if ((uStrCaseCmp(field, "locking") == 0) 1166 || (uStrCaseCmp(field, "lock") == 0) 1167 || (uStrCaseCmp(field, "locks") == 0)) 1168 { 1169 ok = ExprResolveEnum(value, &tmp, lockingEntries); 1170 if (ok) 1171 key->behavior.type = tmp.uval; 1172 key->defs.defined |= _Key_Behavior; 1173 } 1174 else if ((uStrCaseCmp(field, "radiogroup") == 0) || 1175 (uStrCaseCmp(field, "permanentradiogroup") == 0)) 1176 { 1177 Bool permanent = False; 1178 if (uStrCaseCmp(field, "permanentradiogroup") == 0) 1179 permanent = True; 1180 ok = ExprResolveInteger(value, &tmp, SimpleLookup, 1181 (XPointer) rgEntries); 1182 if (!ok) 1183 { 1184 ERROR("Illegal radio group specification for %s\n", 1185 longText(key->name, XkbMessage)); 1186 ACTION("Non-integer radio group ignored\n"); 1187 return False; 1188 } 1189 if (tmp.uval == 0) 1190 { 1191 key->behavior.type = XkbKB_Default; 1192 key->behavior.data = 0; 1193 return ok; 1194 } 1195 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups)) 1196 { 1197 ERROR 1198 ("Radio group specification for %s out of range (1..32)\n", 1199 longText(key->name, XkbMessage)); 1200 ACTION("Illegal radio group %d ignored\n", tmp.uval); 1201 return False; 1202 } 1203 key->behavior.type = 1204 XkbKB_RadioGroup | (permanent ? XkbKB_Permanent : 0); 1205 key->behavior.data = tmp.uval - 1; 1206 if (key->allowNone & (1U << (tmp.uval - 1))) 1207 key->behavior.data |= XkbKB_RGAllowNone; 1208 key->defs.defined |= _Key_Behavior; 1209 } 1210 else if (uStrCaseEqual(field, "allownone")) 1211 { 1212 ok = SetAllowNone(key, arrayNdx, value); 1213 } 1214 else if (uStrCasePrefix("overlay", field) || 1215 uStrCasePrefix("permanentoverlay", field)) 1216 { 1217 Bool permanent = False; 1218 const char *which; 1219 int overlayNdx; 1220 if (uStrCasePrefix("permanent", field)) 1221 { 1222 permanent = True; 1223 which = &field[sizeof("permanentoverlay") - 1]; 1224 } 1225 else 1226 { 1227 which = &field[sizeof("overlay") - 1]; 1228 } 1229 if (sscanf(which, "%d", &overlayNdx) == 1) 1230 { 1231 if (((overlayNdx < 1) || (overlayNdx > 2)) && (warningLevel > 0)) 1232 { 1233 ERROR("Illegal overlay %d specified for %s\n", 1234 overlayNdx, longText(key->name, XkbMessage)); 1235 ACTION("Ignored\n"); 1236 return False; 1237 } 1238 } 1239 else if (*which == '\0') 1240 overlayNdx = 1; 1241 else if (warningLevel > 0) 1242 { 1243 ERROR("Illegal overlay \"%s\" specified for %s\n", 1244 which, longText(key->name, XkbMessage)); 1245 ACTION("Ignored\n"); 1246 return False; 1247 } 1248 ok = ExprResolveKeyName(value, &tmp, NULL, NULL); 1249 if (!ok) 1250 { 1251 ERROR("Illegal overlay key specification for %s\n", 1252 longText(key->name, XkbMessage)); 1253 ACTION("Overlay key must be specified by name\n"); 1254 return False; 1255 } 1256 if (overlayNdx == 1) 1257 key->behavior.type = XkbKB_Overlay1; 1258 else 1259 key->behavior.type = XkbKB_Overlay2; 1260 if (permanent) 1261 key->behavior.type |= XkbKB_Permanent; 1262 1263 key->behavior.data = 0; 1264 key->nameForOverlayKey = KeyNameToLong(tmp.keyName.name); 1265 key->defs.defined |= _Key_Behavior; 1266 } 1267 else if ((uStrCaseCmp(field, "repeating") == 0) || 1268 (uStrCaseCmp(field, "repeats") == 0) || 1269 (uStrCaseCmp(field, "repeat") == 0)) 1270 { 1271 ok = ExprResolveEnum(value, &tmp, repeatEntries); 1272 if (!ok) 1273 { 1274 ERROR("Illegal repeat setting for %s\n", 1275 longText(key->name, XkbMessage)); 1276 ACTION("Non-boolean repeat setting ignored\n"); 1277 return False; 1278 } 1279 key->repeat = tmp.uval; 1280 key->defs.defined |= _Key_Repeat; 1281 } 1282 else if ((uStrCaseCmp(field, "groupswrap") == 0) || 1283 (uStrCaseCmp(field, "wrapgroups") == 0)) 1284 { 1285 ok = ExprResolveBoolean(value, &tmp, NULL, NULL); 1286 if (!ok) 1287 { 1288 ERROR("Illegal groupsWrap setting for %s\n", 1289 longText(key->name, XkbMessage)); 1290 ACTION("Non-boolean value ignored\n"); 1291 return False; 1292 } 1293 if (tmp.uval) 1294 key->groupInfo = XkbWrapIntoRange; 1295 else 1296 key->groupInfo = XkbClampIntoRange; 1297 key->defs.defined |= _Key_GroupInfo; 1298 } 1299 else if ((uStrCaseCmp(field, "groupsclamp") == 0) || 1300 (uStrCaseCmp(field, "clampgroups") == 0)) 1301 { 1302 ok = ExprResolveBoolean(value, &tmp, NULL, NULL); 1303 if (!ok) 1304 { 1305 ERROR("Illegal groupsClamp setting for %s\n", 1306 longText(key->name, XkbMessage)); 1307 ACTION("Non-boolean value ignored\n"); 1308 return False; 1309 } 1310 if (tmp.uval) 1311 key->groupInfo = XkbClampIntoRange; 1312 else 1313 key->groupInfo = XkbWrapIntoRange; 1314 key->defs.defined |= _Key_GroupInfo; 1315 } 1316 else if ((uStrCaseCmp(field, "groupsredirect") == 0) || 1317 (uStrCaseCmp(field, "redirectgroups") == 0)) 1318 { 1319 if (!ExprResolveInteger 1320 (value, &tmp, SimpleLookup, (XPointer) groupNames)) 1321 { 1322 ERROR("Illegal group index for redirect of key %s\n", 1323 longText(key->name, XkbMessage)); 1324 ACTION("Definition with non-integer group ignored\n"); 1325 return False; 1326 } 1327 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) 1328 { 1329 ERROR("Out-of-range (1..%d) group for redirect of key %s\n", 1330 XkbNumKbdGroups, longText(key->name, XkbMessage)); 1331 ERROR("Ignoring illegal group %d\n", tmp.uval); 1332 return False; 1333 } 1334 key->groupInfo = 1335 XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1); 1336 key->defs.defined |= _Key_GroupInfo; 1337 } 1338 else 1339 { 1340 ERROR("Unknown field %s in a symbol interpretation\n", field); 1341 ACTION("Definition ignored\n"); 1342 ok = False; 1343 } 1344 return ok; 1345} 1346 1347static int 1348SetGroupName(SymbolsInfo *info, const ExprDef *arrayNdx,const ExprDef *value) 1349{ 1350 ExprResult tmp, name; 1351 1352 if ((arrayNdx == NULL) && (warningLevel > 0)) 1353 { 1354 WARN("You must specify an index when specifying a group name\n"); 1355 ACTION("Group name definition without array subscript ignored\n"); 1356 return False; 1357 } 1358 if (!ExprResolveInteger 1359 (arrayNdx, &tmp, SimpleLookup, (XPointer) groupNames)) 1360 { 1361 ERROR("Illegal index in group name definition\n"); 1362 ACTION("Definition with non-integer array index ignored\n"); 1363 return False; 1364 } 1365 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) 1366 { 1367 ERROR 1368 ("Attempt to specify name for illegal group (must be 1..%d)\n", 1369 XkbNumKbdGroups + 1); 1370 ACTION("Name for group %d ignored\n", tmp.uval); 1371 return False; 1372 } 1373 if (!ExprResolveString(value, &name, NULL, NULL)) 1374 { 1375 ERROR("Group name must be a string\n"); 1376 ACTION("Illegal name for group %d ignored\n", tmp.uval); 1377 return False; 1378 } 1379 info->groupNames[tmp.uval - 1 + info->explicit_group] = 1380 XkbInternAtom(NULL, name.str, False); 1381 1382 return True; 1383} 1384 1385static int 1386HandleSymbolsVar(VarDef * stmt, XkbDescPtr xkb, SymbolsInfo * info) 1387{ 1388 ExprResult elem, field, tmp; 1389 ExprDef *arrayNdx; 1390 1391 if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0) 1392 return 0; /* internal error, already reported */ 1393 if (elem.str && (uStrCaseCmp(elem.str, "key") == 0)) 1394 { 1395 return SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx, 1396 stmt->value, info); 1397 } 1398 else if ((elem.str == NULL) && ((uStrCaseCmp(field.str, "name") == 0) || 1399 (uStrCaseCmp(field.str, "groupname") == 1400 0))) 1401 { 1402 return SetGroupName(info, arrayNdx, stmt->value); 1403 } 1404 else if ((elem.str == NULL) 1405 && ((uStrCaseCmp(field.str, "groupswrap") == 0) 1406 || (uStrCaseCmp(field.str, "wrapgroups") == 0))) 1407 { 1408 if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL)) 1409 { 1410 ERROR("Illegal setting for global groupsWrap\n"); 1411 ACTION("Non-boolean value ignored\n"); 1412 return False; 1413 } 1414 if (tmp.uval) 1415 info->groupInfo = XkbWrapIntoRange; 1416 else 1417 info->groupInfo = XkbClampIntoRange; 1418 return True; 1419 } 1420 else if ((elem.str == NULL) 1421 && ((uStrCaseCmp(field.str, "groupsclamp") == 0) 1422 || (uStrCaseCmp(field.str, "clampgroups") == 0))) 1423 { 1424 if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL)) 1425 { 1426 ERROR("Illegal setting for global groupsClamp\n"); 1427 ACTION("Non-boolean value ignored\n"); 1428 return False; 1429 } 1430 if (tmp.uval) 1431 info->groupInfo = XkbClampIntoRange; 1432 else 1433 info->groupInfo = XkbWrapIntoRange; 1434 return True; 1435 } 1436 else if ((elem.str == NULL) 1437 && ((uStrCaseCmp(field.str, "groupsredirect") == 0) 1438 || (uStrCaseCmp(field.str, "redirectgroups") == 0))) 1439 { 1440 if (!ExprResolveInteger(stmt->value, &tmp, 1441 SimpleLookup, (XPointer) groupNames)) 1442 { 1443 ERROR("Illegal group index for global groupsRedirect\n"); 1444 ACTION("Definition with non-integer group ignored\n"); 1445 return False; 1446 } 1447 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) 1448 { 1449 ERROR 1450 ("Out-of-range (1..%d) group for global groupsRedirect\n", 1451 XkbNumKbdGroups); 1452 ACTION("Ignoring illegal group %d\n", tmp.uval); 1453 return False; 1454 } 1455 info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval); 1456 return True; 1457 } 1458 else if ((elem.str == NULL) && (uStrCaseCmp(field.str, "allownone") == 0)) 1459 { 1460 return SetAllowNone(&info->dflt, arrayNdx, stmt->value); 1461 } 1462 return SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value, 1463 &info->action); 1464} 1465 1466static Bool 1467HandleSymbolsBody(VarDef * def, 1468 XkbDescPtr xkb, KeyInfo * key, SymbolsInfo * info) 1469{ 1470 Bool ok = True; 1471 1472 for (; def != NULL; def = (VarDef *) def->common.next) 1473 { 1474 if ((def->name) && (def->name->type == ExprFieldRef)) 1475 { 1476 ok = HandleSymbolsVar(def, xkb, info); 1477 continue; 1478 } 1479 else 1480 { 1481 ExprResult tmp, field; 1482 ExprDef *arrayNdx; 1483 1484 if (def->name == NULL) 1485 { 1486 if ((def->value == NULL) 1487 || (def->value->op == ExprKeysymList)) 1488 field.str = "symbols"; 1489 else 1490 field.str = "actions"; 1491 arrayNdx = NULL; 1492 } 1493 else 1494 { 1495 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx); 1496 } 1497 if (ok) 1498 ok = SetSymbolsField(key, xkb, field.str, arrayNdx, 1499 def->value, info); 1500 } 1501 } 1502 return ok; 1503} 1504 1505static Bool 1506SetExplicitGroup(SymbolsInfo * info, KeyInfo * key) 1507{ 1508 unsigned group = info->explicit_group; 1509 1510 if (group == 0) 1511 return True; 1512 1513 if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1) 1514 { 1515 if (warningLevel > 0) 1516 { 1517 WARN("For map %s an explicit group is specified\n", info->name); 1518 WARN("but key %s has more than one group defined\n", 1519 longText(key->name, XkbMessage)); 1520 ACTION("All groups except first one will be ignored\n"); 1521 } 1522 for (int i = 1; i < XkbNumKbdGroups; i++) 1523 { 1524 key->numLevels[i] = 0; 1525 free(key->syms[i]); 1526 key->syms[i] = (KeySym *) NULL; 1527 free(key->acts[i]); 1528 key->acts[i] = (XkbAction *) NULL; 1529 key->types[i] = (Atom) 0; 1530 } 1531 } 1532 key->typesDefined = key->symsDefined = key->actsDefined = 1U << group; 1533 1534 key->numLevels[group] = key->numLevels[0]; 1535 key->numLevels[0] = 0; 1536 key->syms[group] = key->syms[0]; 1537 key->syms[0] = (KeySym *) NULL; 1538 key->acts[group] = key->acts[0]; 1539 key->acts[0] = (XkbAction *) NULL; 1540 key->types[group] = key->types[0]; 1541 key->types[0] = (Atom) 0; 1542 return True; 1543} 1544 1545static int 1546HandleSymbolsDef(SymbolsDef * stmt, 1547 XkbDescPtr xkb, unsigned merge, SymbolsInfo * info) 1548{ 1549 KeyInfo key; 1550 1551 InitKeyInfo(&key); 1552 CopyKeyInfo(&info->dflt, &key, False); 1553 key.defs.merge = stmt->merge; 1554 key.name = KeyNameToLong(stmt->keyName); 1555 if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info)) 1556 { 1557 info->errorCount++; 1558 return False; 1559 } 1560 1561 if (!SetExplicitGroup(info, &key)) 1562 { 1563 info->errorCount++; 1564 return False; 1565 } 1566 1567 if (!AddKeySymbols(info, &key, xkb)) 1568 { 1569 info->errorCount++; 1570 return False; 1571 } 1572 return True; 1573} 1574 1575static Bool 1576HandleModMapDef(ModMapDef * def, 1577 XkbDescPtr xkb, unsigned merge, SymbolsInfo * info) 1578{ 1579 ModMapEntry tmp; 1580 ExprResult rtrn; 1581 Bool ok; 1582 1583 if (!LookupModIndex(NULL, None, def->modifier, TypeInt, &rtrn)) 1584 { 1585 ERROR("Illegal modifier map definition\n"); 1586 ACTION("Ignoring map for non-modifier \"%s\"\n", 1587 XkbAtomText(NULL, def->modifier, XkbMessage)); 1588 return False; 1589 } 1590 ok = True; 1591 tmp.modifier = rtrn.uval; 1592 for (ExprDef *key = def->keys; key != NULL; 1593 key = (ExprDef *) key->common.next) 1594 { 1595 if ((key->op == ExprValue) && (key->type == TypeKeyName)) 1596 { 1597 tmp.haveSymbol = False; 1598 tmp.u.keyName = KeyNameToLong(key->value.keyName); 1599 } 1600 else if (ExprResolveKeySym(key, &rtrn, NULL, NULL)) 1601 { 1602 tmp.haveSymbol = True; 1603 tmp.u.keySym = rtrn.uval; 1604 } 1605 else 1606 { 1607 ERROR("Modmap entries may contain only key names or keysyms\n"); 1608 ACTION("Illegal definition for %s modifier ignored\n", 1609 XkbModIndexText(tmp.modifier, XkbMessage)); 1610 continue; 1611 } 1612 1613 ok = AddModMapEntry(info, &tmp) && ok; 1614 } 1615 return ok; 1616} 1617 1618static void 1619HandleSymbolsFile(XkbFile * file, 1620 XkbDescPtr xkb, unsigned merge, SymbolsInfo * info) 1621{ 1622 ParseCommon *stmt; 1623 1624 info->name = uStringDup(file->name); 1625 stmt = file->defs; 1626 while (stmt) 1627 { 1628 switch (stmt->stmtType) 1629 { 1630 case StmtInclude: 1631 if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info, 1632 HandleSymbolsFile)) 1633 info->errorCount++; 1634 break; 1635 case StmtSymbolsDef: 1636 if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info)) 1637 info->errorCount++; 1638 break; 1639 case StmtVarDef: 1640 if (!HandleSymbolsVar((VarDef *) stmt, xkb, info)) 1641 info->errorCount++; 1642 break; 1643 case StmtVModDef: 1644 if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods)) 1645 info->errorCount++; 1646 break; 1647 case StmtInterpDef: 1648 ERROR("Interpretation files may not include other types\n"); 1649 ACTION("Ignoring definition of symbol interpretation\n"); 1650 info->errorCount++; 1651 break; 1652 case StmtKeycodeDef: 1653 ERROR("Interpretation files may not include other types\n"); 1654 ACTION("Ignoring definition of key name\n"); 1655 info->errorCount++; 1656 break; 1657 case StmtModMapDef: 1658 if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info)) 1659 info->errorCount++; 1660 break; 1661 default: 1662 WSGO("Unexpected statement type %d in HandleSymbolsFile\n", 1663 stmt->stmtType); 1664 break; 1665 } 1666 stmt = stmt->next; 1667 if (info->errorCount > 10) 1668 { 1669#ifdef NOISY 1670 ERROR("Too many errors\n"); 1671#endif 1672 ACTION("Abandoning symbols file \"%s\"\n", file->topName); 1673 break; 1674 } 1675 } 1676 return; 1677} 1678 1679static Bool 1680FindKeyForSymbol(XkbDescPtr xkb, KeySym sym, unsigned int *kc_rtrn) 1681{ 1682 int j; 1683 Bool gotOne; 1684 1685 j = 0; 1686 do 1687 { 1688 gotOne = False; 1689 for (int i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) 1690 { 1691 if (j < (int) XkbKeyNumSyms(xkb, i)) 1692 { 1693 gotOne = True; 1694 if (XkbKeySym(xkb, i, j) == sym) 1695 { 1696 *kc_rtrn = i; 1697 return True; 1698 } 1699 } 1700 } 1701 j++; 1702 } 1703 while (gotOne); 1704 return False; 1705} 1706 1707/** 1708 * Find the given name in the xkb->map->types and return its index. 1709 * 1710 * @param name The atom to search for. 1711 * @param type_rtrn Set to the index of the name if found. 1712 * 1713 * @return True if found, False otherwise. 1714 */ 1715static Bool 1716FindNamedType(const XkbDescPtr xkb, Atom name, unsigned *type_rtrn) 1717{ 1718 if (xkb && xkb->map && xkb->map->types) 1719 { 1720 for (unsigned n = 0; n < xkb->map->num_types; n++) 1721 { 1722 if (xkb->map->types[n].name == (Atom) name) 1723 { 1724 *type_rtrn = n; 1725 return True; 1726 } 1727 } 1728 } 1729 return False; 1730} 1731 1732static Bool 1733KSIsLower(KeySym ks) 1734{ 1735 KeySym lower, upper; 1736 XConvertCase(ks, &lower, &upper); 1737 1738 if (lower == upper) 1739 return False; 1740 return (ks == lower ? True : False); 1741} 1742 1743static Bool 1744KSIsUpper(KeySym ks) 1745{ 1746 KeySym lower, upper; 1747 XConvertCase(ks, &lower, &upper); 1748 1749 if (lower == upper) 1750 return False; 1751 return (ks == upper ? True : False); 1752} 1753 1754/** 1755 * Assign a type to the given sym and return the Atom for the type assigned. 1756 * 1757 * Simple recipe: 1758 * - ONE_LEVEL for width 0/1 1759 * - ALPHABETIC for 2 shift levels, with lower/uppercase 1760 * - KEYPAD for keypad keys. 1761 * - TWO_LEVEL for other 2 shift level keys. 1762 * and the same for four level keys. 1763 * 1764 * @param width Number of syms in syms. 1765 * @param syms The keysyms for the given key (must be size width). 1766 * @param typeNameRtrn Set to the Atom of the type name. 1767 * 1768 * @returns True if a type could be found, False otherwise. 1769 */ 1770static Bool 1771FindAutomaticType(int width, const KeySym *syms, 1772 Atom *typeNameRtrn, Bool *autoType) 1773{ 1774 *autoType = False; 1775 if ((width == 1) || (width == 0)) 1776 { 1777 *typeNameRtrn = XkbInternAtom(NULL, "ONE_LEVEL", False); 1778 *autoType = True; 1779 } 1780 else if (width == 2) 1781 { 1782 if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1])) 1783 { 1784 *typeNameRtrn = XkbInternAtom(NULL, "ALPHABETIC", False); 1785 } 1786 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1]))) 1787 { 1788 *typeNameRtrn = XkbInternAtom(NULL, "KEYPAD", False); 1789 *autoType = True; 1790 } 1791 else 1792 { 1793 *typeNameRtrn = XkbInternAtom(NULL, "TWO_LEVEL", False); 1794 *autoType = True; 1795 } 1796 } 1797 else if (width <= 4) 1798 { 1799 if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1])) 1800 if (KSIsLower(syms[2]) && KSIsUpper(syms[3])) 1801 *typeNameRtrn = 1802 XkbInternAtom(NULL, "FOUR_LEVEL_ALPHABETIC", False); 1803 else 1804 *typeNameRtrn = XkbInternAtom(NULL, 1805 "FOUR_LEVEL_SEMIALPHABETIC", 1806 False); 1807 1808 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1]))) 1809 *typeNameRtrn = XkbInternAtom(NULL, "FOUR_LEVEL_KEYPAD", False); 1810 else 1811 *typeNameRtrn = XkbInternAtom(NULL, "FOUR_LEVEL", False); 1812 /* XXX: why not set autoType here? */ 1813 } 1814 return ((width >= 0) && (width <= 4)); 1815} 1816 1817/** 1818 * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the 1819 * groups, and reduce to one group if all groups are identical anyway. 1820 */ 1821static void 1822PrepareKeyDef(KeyInfo * key) 1823{ 1824 int i, defined, lastGroup; 1825 Bool identical; 1826 1827 defined = key->symsDefined | key->actsDefined | key->typesDefined; 1828 /* get highest group number */ 1829 for (i = XkbNumKbdGroups - 1; i >= 0; i--) 1830 { 1831 if (defined & (1U << i)) 1832 break; 1833 } 1834 lastGroup = i; 1835 1836 if (lastGroup == 0) 1837 return; 1838 1839 /* If there are empty groups between non-empty ones fill them with data */ 1840 /* from the first group. */ 1841 /* We can make a wrong assumption here. But leaving gaps is worse. */ 1842 for (i = lastGroup; i > 0; i--) 1843 { 1844 int width; 1845 1846 if (defined & (1U << i)) 1847 continue; 1848 width = key->numLevels[0]; 1849 if (key->typesDefined & 1) 1850 { 1851 for (int j = 0; j < width; j++) 1852 { 1853 key->types[i] = key->types[0]; 1854 } 1855 key->typesDefined |= 1U << i; 1856 } 1857 if ((key->actsDefined & 1) && key->acts[0]) 1858 { 1859 key->acts[i] = calloc(width, sizeof(XkbAction)); 1860 if (key->acts[i] == NULL) 1861 continue; 1862 memcpy(key->acts[i], key->acts[0], width * sizeof(XkbAction)); 1863 key->actsDefined |= 1U << i; 1864 } 1865 if ((key->symsDefined & 1) && key->syms[0]) 1866 { 1867 key->syms[i] = calloc(width, sizeof(KeySym)); 1868 if (key->syms[i] == NULL) 1869 continue; 1870 memcpy(key->syms[i], key->syms[0], width * sizeof(KeySym)); 1871 key->symsDefined |= 1U << i; 1872 } 1873 if (defined & 1) 1874 { 1875 key->numLevels[i] = key->numLevels[0]; 1876 } 1877 } 1878 /* If all groups are completely identical remove them all */ 1879 /* except the first one. */ 1880 identical = True; 1881 for (i = lastGroup; i > 0; i--) 1882 { 1883 if ((key->numLevels[i] != key->numLevels[0]) || 1884 (key->types[i] != key->types[0])) 1885 { 1886 identical = False; 1887 break; 1888 } 1889 if ((key->syms[i] != key->syms[0]) && 1890 (key->syms[i] == NULL || key->syms[0] == NULL || 1891 memcmp((void *) key->syms[i], (void *) key->syms[0], 1892 sizeof(KeySym) * key->numLevels[0]))) 1893 { 1894 identical = False; 1895 break; 1896 } 1897 if ((key->acts[i] != key->acts[0]) && 1898 (key->acts[i] == NULL || key->acts[0] == NULL || 1899 memcmp((void *) key->acts[i], (void *) key->acts[0], 1900 sizeof(XkbAction) * key->numLevels[0]))) 1901 { 1902 identical = False; 1903 break; 1904 } 1905 } 1906 if (identical) 1907 { 1908 for (i = lastGroup; i > 0; i--) 1909 { 1910 key->numLevels[i] = 0; 1911 free(key->syms[i]); 1912 key->syms[i] = (KeySym *) NULL; 1913 free(key->acts[i]); 1914 key->acts[i] = (XkbAction *) NULL; 1915 key->types[i] = (Atom) 0; 1916 } 1917 key->symsDefined &= 1; 1918 key->actsDefined &= 1; 1919 key->typesDefined &= 1; 1920 } 1921 return; 1922} 1923 1924/** 1925 * Copy the KeyInfo into result. 1926 * 1927 * This function recurses. 1928 */ 1929static Bool 1930CopySymbolsDef(XkbFileInfo * result, KeyInfo * key, int start_from) 1931{ 1932 int i; 1933 unsigned kc, width, nGroups; 1934 XkbKeyTypePtr type; 1935 Bool haveActions, autoType, useAlias; 1936 KeySym *outSyms; 1937 XkbAction *outActs; 1938 XkbDescPtr xkb; 1939 unsigned types[XkbNumKbdGroups]; 1940 1941 xkb = result->xkb; 1942 useAlias = (start_from == 0); 1943 1944 /* get the keycode for the key. */ 1945 if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb), 1946 start_from)) 1947 { 1948 if ((start_from == 0) && (warningLevel >= 5)) 1949 { 1950 WARN("Key %s not found in %s keycodes\n", 1951 longText(key->name, XkbMessage), 1952 XkbAtomText(NULL, xkb->names->keycodes, XkbMessage)); 1953 ACTION("Symbols ignored\n"); 1954 } 1955 return False; 1956 } 1957 1958 haveActions = False; 1959 for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++) 1960 { 1961 if (((i + 1) > nGroups) 1962 && (((key->symsDefined | key->actsDefined) & (1U << i)) 1963 || (key->typesDefined) & (1U << i))) 1964 nGroups = i + 1; 1965 if (key->acts[i]) 1966 haveActions = True; 1967 autoType = False; 1968 /* Assign the type to the key, if it is missing. */ 1969 if (key->types[i] == None) 1970 { 1971 if (key->dfltType != None) 1972 key->types[i] = key->dfltType; 1973 else if (FindAutomaticType(key->numLevels[i], key->syms[i], 1974 &key->types[i], &autoType)) 1975 { 1976 } 1977 else 1978 { 1979 if (warningLevel >= 5) 1980 { 1981 WARN("No automatic type for %d symbols\n", 1982 (unsigned int) key->numLevels[i]); 1983 ACTION("Using %s for the %s key (keycode %d)\n", 1984 XkbAtomText(NULL, key->types[i], 1985 XkbMessage), 1986 longText(key->name, XkbMessage), kc); 1987 } 1988 } 1989 } 1990 if (FindNamedType(xkb, key->types[i], &types[i])) 1991 { 1992 if (!autoType || key->numLevels[i] > 2) 1993 xkb->server->explicit[kc] |= (1U << i); 1994 } 1995 else 1996 { 1997 if (warningLevel >= 3) 1998 { 1999 WARN("Type \"%s\" is not defined\n", 2000 XkbAtomText(NULL, key->types[i], XkbMessage)); 2001 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n", 2002 longText(key->name, XkbMessage), kc); 2003 } 2004 types[i] = XkbTwoLevelIndex; 2005 } 2006 /* if the type specifies less syms than the key has, shrink the key */ 2007 type = &xkb->map->types[types[i]]; 2008 if (type->num_levels < key->numLevels[i]) 2009 { 2010 if (warningLevel > 5) 2011 { 2012 WARN 2013 ("Type \"%s\" has %d levels, but %s has %d symbols\n", 2014 XkbAtomText(NULL, type->name, XkbMessage), 2015 (unsigned int) type->num_levels, 2016 longText(key->name, XkbMessage), 2017 (unsigned int) key->numLevels[i]); 2018 ACTION("Ignoring extra symbols\n"); 2019 } 2020 key->numLevels[i] = type->num_levels; 2021 } 2022 if (key->numLevels[i] > width) 2023 width = key->numLevels[i]; 2024 if (type->num_levels > width) 2025 width = type->num_levels; 2026 } 2027 2028 /* width is now the largest width found */ 2029 2030 i = width * nGroups; 2031 outSyms = XkbResizeKeySyms(xkb, kc, i); 2032 if (outSyms == NULL) 2033 { 2034 WSGO("Could not enlarge symbols for %s (keycode %d)\n", 2035 longText(key->name, XkbMessage), kc); 2036 return False; 2037 } 2038 if (haveActions) 2039 { 2040 outActs = XkbResizeKeyActions(xkb, kc, i); 2041 if (outActs == NULL) 2042 { 2043 WSGO("Could not enlarge actions for %s (key %d)\n", 2044 longText(key->name, XkbMessage), kc); 2045 return False; 2046 } 2047 xkb->server->explicit[kc] |= XkbExplicitInterpretMask; 2048 } 2049 else 2050 outActs = NULL; 2051 if (key->defs.defined & _Key_GroupInfo) 2052 i = key->groupInfo; 2053 else 2054 i = xkb->map->key_sym_map[kc].group_info; 2055 2056 xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups); 2057 xkb->map->key_sym_map[kc].width = width; 2058 for (i = 0; i < nGroups; i++) 2059 { 2060 /* assign kt_index[i] to the index of the type in map->types. 2061 * kt_index[i] may have been set by a previous run (if we have two 2062 * layouts specified). Let's not overwrite it with the ONE_LEVEL 2063 * default group if we don't even have keys for this group anyway. 2064 * 2065 * FIXME: There should be a better fix for this. 2066 */ 2067 if (key->numLevels[i]) 2068 xkb->map->key_sym_map[kc].kt_index[i] = types[i]; 2069 if (key->syms[i] != NULL) 2070 { 2071 /* fill key to "width" symbols*/ 2072 for (unsigned tmp = 0; tmp < width; tmp++) 2073 { 2074 if (tmp < key->numLevels[i]) 2075 outSyms[tmp] = key->syms[i][tmp]; 2076 else 2077 outSyms[tmp] = NoSymbol; 2078 if ((outActs != NULL) && (key->acts[i] != NULL)) 2079 { 2080 if (tmp < key->numLevels[i]) 2081 outActs[tmp] = key->acts[i][tmp]; 2082 else 2083 outActs[tmp].type = XkbSA_NoAction; 2084 } 2085 } 2086 } 2087 outSyms += width; 2088 if (outActs) 2089 outActs += width; 2090 } 2091 switch (key->behavior.type & XkbKB_OpMask) 2092 { 2093 case XkbKB_Default: 2094 break; 2095 case XkbKB_Overlay1: 2096 case XkbKB_Overlay2: 2097 { 2098 unsigned okc; 2099 /* find key by name! */ 2100 if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True, 2101 CreateKeyNames(xkb), 0)) 2102 { 2103 if (warningLevel >= 1) 2104 { 2105 WARN("Key %s not found in %s keycodes\n", 2106 longText(key->nameForOverlayKey, XkbMessage), 2107 XkbAtomText(NULL, xkb->names->keycodes, XkbMessage)); 2108 ACTION("Not treating %s as an overlay key \n", 2109 longText(key->name, XkbMessage)); 2110 } 2111 break; 2112 } 2113 key->behavior.data = okc; 2114 } 2115 default: 2116 xkb->server->behaviors[kc] = key->behavior; 2117 xkb->server->explicit[kc] |= XkbExplicitBehaviorMask; 2118 break; 2119 } 2120 if (key->defs.defined & _Key_VModMap) 2121 { 2122 xkb->server->vmodmap[kc] = key->vmodmap; 2123 xkb->server->explicit[kc] |= XkbExplicitVModMapMask; 2124 } 2125 if (key->repeat != RepeatUndefined) 2126 { 2127 if (key->repeat == RepeatYes) 2128 xkb->ctrls->per_key_repeat[kc / 8] |= (1U << (kc % 8)); 2129 else 2130 xkb->ctrls->per_key_repeat[kc / 8] &= ~(1U << (kc % 8)); 2131 xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask; 2132 } 2133 2134 /* do the same thing for the next key */ 2135 CopySymbolsDef(result, key, kc + 1); 2136 return True; 2137} 2138 2139static Bool 2140CopyModMapDef(XkbFileInfo * result, ModMapEntry * entry) 2141{ 2142 unsigned kc; 2143 XkbDescPtr xkb; 2144 2145 xkb = result->xkb; 2146 if ((!entry->haveSymbol) 2147 && 2148 (!FindNamedKey 2149 (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0))) 2150 { 2151 if (warningLevel >= 5) 2152 { 2153 WARN("Key %s not found in %s keycodes\n", 2154 longText(entry->u.keyName, XkbMessage), 2155 XkbAtomText(NULL, xkb->names->keycodes, XkbMessage)); 2156 ACTION("Modifier map entry for %s not updated\n", 2157 XkbModIndexText(entry->modifier, XkbMessage)); 2158 } 2159 return False; 2160 } 2161 else if (entry->haveSymbol 2162 && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc))) 2163 { 2164 if (warningLevel > 5) 2165 { 2166 WARN("Key \"%s\" not found in %s symbol map\n", 2167 XkbKeysymText(entry->u.keySym, XkbMessage), 2168 XkbAtomText(NULL, xkb->names->symbols, XkbMessage)); 2169 ACTION("Modifier map entry for %s not updated\n", 2170 XkbModIndexText(entry->modifier, XkbMessage)); 2171 } 2172 return False; 2173 } 2174 xkb->map->modmap[kc] |= (1U << entry->modifier); 2175 return True; 2176} 2177 2178/** 2179 * Handle the xkb_symbols section of an xkb file. 2180 * 2181 * @param file The parsed xkb_symbols section of the xkb file. 2182 * @param result Handle to the data to store the result in. 2183 * @param merge Merge strategy (e.g. MergeOverride). 2184 */ 2185Bool 2186CompileSymbols(XkbFile * file, XkbFileInfo * result, unsigned merge) 2187{ 2188 SymbolsInfo info; 2189 XkbDescPtr xkb; 2190 2191 xkb = result->xkb; 2192 InitSymbolsInfo(&info, xkb); 2193 info.dflt.defs.fileID = file->id; 2194 info.dflt.defs.merge = merge; 2195 HandleSymbolsFile(file, xkb, merge, &info); 2196 2197 if (info.nKeys == 0) 2198 return True; 2199 if (info.errorCount == 0) 2200 { 2201 int i; 2202 KeyInfo *key; 2203 2204 /* alloc memory in the xkb struct */ 2205 if (XkbAllocNames(xkb, XkbSymbolsNameMask | XkbGroupNamesMask, 0, 0) 2206 != Success) 2207 { 2208 WSGO("Can not allocate names in CompileSymbols\n"); 2209 ACTION("Symbols not added\n"); 2210 return False; 2211 } 2212 if (XkbAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0) 2213 != Success) 2214 { 2215 WSGO("Could not allocate client map in CompileSymbols\n"); 2216 ACTION("Symbols not added\n"); 2217 return False; 2218 } 2219 if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success) 2220 { 2221 WSGO("Could not allocate server map in CompileSymbols\n"); 2222 ACTION("Symbols not added\n"); 2223 return False; 2224 } 2225 if (XkbAllocControls(xkb, XkbPerKeyRepeatMask) != Success) 2226 { 2227 WSGO("Could not allocate controls in CompileSymbols\n"); 2228 ACTION("Symbols not added\n"); 2229 return False; 2230 } 2231 2232 /* now copy info into xkb. */ 2233 xkb->names->symbols = XkbInternAtom(xkb->dpy, info.name, False); 2234 if (info.aliases) 2235 ApplyAliases(xkb, False, &info.aliases); 2236 for (i = 0; i < XkbNumKbdGroups; i++) 2237 { 2238 if (info.groupNames[i] != None) 2239 xkb->names->groups[i] = info.groupNames[i]; 2240 } 2241 /* sanitize keys */ 2242 for (key = info.keys, i = 0; i < info.nKeys; i++, key++) 2243 { 2244 PrepareKeyDef(key); 2245 } 2246 /* copy! */ 2247 for (key = info.keys, i = 0; i < info.nKeys; i++, key++) 2248 { 2249 if (!CopySymbolsDef(result, key, 0)) 2250 info.errorCount++; 2251 } 2252 if (warningLevel > 3) 2253 { 2254 for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) 2255 { 2256 if (xkb->names->keys[i].name[0] == '\0') 2257 continue; 2258 if (XkbKeyNumGroups(xkb, i) < 1) 2259 { 2260 char buf[5]; 2261 memcpy(buf, xkb->names->keys[i].name, 4); 2262 buf[4] = '\0'; 2263 INFO("No symbols defined for <%s> (keycode %d)\n", 2264 buf, i); 2265 } 2266 } 2267 } 2268 if (info.modMap) 2269 { 2270 ModMapEntry *mm, *next; 2271 for (mm = info.modMap; mm != NULL; mm = next) 2272 { 2273 if (!CopyModMapDef(result, mm)) 2274 info.errorCount++; 2275 next = (ModMapEntry *) mm->defs.next; 2276 } 2277 } 2278 return True; 2279 } 2280 return False; 2281} 2282