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