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