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