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