symbols.c revision f46a6179
1f46a6179Smrg/* $Xorg: symbols.c,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */ 2f46a6179Smrg/************************************************************ 3f46a6179Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 4f46a6179Smrg 5f46a6179Smrg Permission to use, copy, modify, and distribute this 6f46a6179Smrg software and its documentation for any purpose and without 7f46a6179Smrg fee is hereby granted, provided that the above copyright 8f46a6179Smrg notice appear in all copies and that both that copyright 9f46a6179Smrg notice and this permission notice appear in supporting 10f46a6179Smrg documentation, and that the name of Silicon Graphics not be 11f46a6179Smrg used in advertising or publicity pertaining to distribution 12f46a6179Smrg of the software without specific prior written permission. 13f46a6179Smrg Silicon Graphics makes no representation about the suitability 14f46a6179Smrg of this software for any purpose. It is provided "as is" 15f46a6179Smrg without any express or implied warranty. 16f46a6179Smrg 17f46a6179Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 18f46a6179Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19f46a6179Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 20f46a6179Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 21f46a6179Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22f46a6179Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 23f46a6179Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 24f46a6179Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 25f46a6179Smrg 26f46a6179Smrg ********************************************************/ 27f46a6179Smrg/* $XFree86: xc/programs/xkbcomp/symbols.c,v 3.15 2003/04/19 12:25:31 pascal Exp $ */ 28f46a6179Smrg 29f46a6179Smrg#include "xkbcomp.h" 30f46a6179Smrg#include "tokens.h" 31f46a6179Smrg#include "expr.h" 32f46a6179Smrg 33f46a6179Smrg#include <X11/keysym.h> 34f46a6179Smrg#include <X11/Xutil.h> 35f46a6179Smrg#include <stdlib.h> 36f46a6179Smrg 37f46a6179Smrg#include "expr.h" 38f46a6179Smrg#include "vmod.h" 39f46a6179Smrg#include "action.h" 40f46a6179Smrg#include "keycodes.h" 41f46a6179Smrg#include "misc.h" 42f46a6179Smrg#include "alias.h" 43f46a6179Smrg 44f46a6179Smrgextern Atom tok_ONE_LEVEL; 45f46a6179Smrgextern Atom tok_TWO_LEVEL; 46f46a6179Smrgextern Atom tok_KEYPAD; 47f46a6179Smrg 48f46a6179Smrg/***====================================================================***/ 49f46a6179Smrg 50f46a6179Smrg#define RepeatYes 1 51f46a6179Smrg#define RepeatNo 0 52f46a6179Smrg#define RepeatUndefined ~((unsigned)0) 53f46a6179Smrg 54f46a6179Smrg#define _Key_Syms (1<<0) 55f46a6179Smrg#define _Key_Acts (1<<1) 56f46a6179Smrg#define _Key_Repeat (1<<2) 57f46a6179Smrg#define _Key_Behavior (1<<3) 58f46a6179Smrg#define _Key_Type_Dflt (1<<4) 59f46a6179Smrg#define _Key_Types (1<<5) 60f46a6179Smrg#define _Key_GroupInfo (1<<6) 61f46a6179Smrg#define _Key_VModMap (1<<7) 62f46a6179Smrg 63f46a6179Smrgtypedef struct _KeyInfo { 64f46a6179Smrg CommonInfo defs; 65f46a6179Smrg unsigned long name; 66f46a6179Smrg unsigned char groupInfo; 67f46a6179Smrg unsigned char typesDefined; 68f46a6179Smrg unsigned char symsDefined; 69f46a6179Smrg unsigned char actsDefined; 70f46a6179Smrg short numLevels[XkbNumKbdGroups]; 71f46a6179Smrg KeySym * syms[XkbNumKbdGroups]; 72f46a6179Smrg XkbAction * acts[XkbNumKbdGroups]; 73f46a6179Smrg Atom types[XkbNumKbdGroups]; 74f46a6179Smrg unsigned repeat; 75f46a6179Smrg XkbBehavior behavior; 76f46a6179Smrg unsigned short vmodmap; 77f46a6179Smrg unsigned long nameForOverlayKey; 78f46a6179Smrg unsigned long allowNone; 79f46a6179Smrg Atom dfltType; 80f46a6179Smrg} KeyInfo; 81f46a6179Smrg 82f46a6179Smrgstatic void 83f46a6179SmrgInitKeyInfo(KeyInfo *info) 84f46a6179Smrg{ 85f46a6179Smrgregister int i; 86f46a6179Smrgstatic char dflt[4]= "*"; 87f46a6179Smrg 88f46a6179Smrg info->defs.defined= 0; 89f46a6179Smrg info->defs.fileID= 0; 90f46a6179Smrg info->defs.merge= MergeOverride; 91f46a6179Smrg info->defs.next= NULL; 92f46a6179Smrg info->name= KeyNameToLong(dflt); 93f46a6179Smrg info->groupInfo= 0; 94f46a6179Smrg info->typesDefined= info->symsDefined= info->actsDefined= 0; 95f46a6179Smrg for (i=0;i<XkbNumKbdGroups;i++) { 96f46a6179Smrg info->numLevels[i]= 0; 97f46a6179Smrg info->types[i]= None; 98f46a6179Smrg info->syms[i]= NULL; 99f46a6179Smrg info->acts[i]= NULL; 100f46a6179Smrg } 101f46a6179Smrg info->dfltType= None; 102f46a6179Smrg info->behavior.type= XkbKB_Default; 103f46a6179Smrg info->behavior.data= 0; 104f46a6179Smrg info->vmodmap= 0; 105f46a6179Smrg info->nameForOverlayKey= 0; 106f46a6179Smrg info->repeat= RepeatUndefined; 107f46a6179Smrg info->allowNone= 0; 108f46a6179Smrg return; 109f46a6179Smrg} 110f46a6179Smrg 111f46a6179Smrgstatic void 112f46a6179SmrgFreeKeyInfo(KeyInfo *info) 113f46a6179Smrg{ 114f46a6179Smrgregister int i; 115f46a6179Smrg 116f46a6179Smrg info->defs.defined= 0; 117f46a6179Smrg info->defs.fileID= 0; 118f46a6179Smrg info->defs.merge= MergeOverride; 119f46a6179Smrg info->defs.next= NULL; 120f46a6179Smrg info->groupInfo= 0; 121f46a6179Smrg info->typesDefined= info->symsDefined= info->actsDefined= 0; 122f46a6179Smrg for (i=0;i<XkbNumKbdGroups;i++) { 123f46a6179Smrg info->numLevels[i]= 0; 124f46a6179Smrg info->types[i]= None; 125f46a6179Smrg if (info->syms[i]!=NULL) 126f46a6179Smrg uFree(info->syms[i]); 127f46a6179Smrg info->syms[i]= NULL; 128f46a6179Smrg if (info->acts[i]!=NULL) 129f46a6179Smrg uFree(info->acts[i]); 130f46a6179Smrg info->acts[i]= NULL; 131f46a6179Smrg } 132f46a6179Smrg info->dfltType= None; 133f46a6179Smrg info->behavior.type= XkbKB_Default; 134f46a6179Smrg info->behavior.data= 0; 135f46a6179Smrg info->vmodmap= 0; 136f46a6179Smrg info->nameForOverlayKey= 0; 137f46a6179Smrg info->repeat= RepeatUndefined; 138f46a6179Smrg return; 139f46a6179Smrg} 140f46a6179Smrg 141f46a6179Smrgstatic Bool 142f46a6179SmrgCopyKeyInfo(KeyInfo *old,KeyInfo *new,Bool clearOld) 143f46a6179Smrg{ 144f46a6179Smrgregister int i; 145f46a6179Smrg 146f46a6179Smrg *new= *old; 147f46a6179Smrg new->defs.next= NULL; 148f46a6179Smrg if (clearOld) { 149f46a6179Smrg for (i=0;i<XkbNumKbdGroups;i++) { 150f46a6179Smrg old->numLevels[i]= 0; 151f46a6179Smrg old->syms[i]= NULL; 152f46a6179Smrg old->acts[i]= NULL; 153f46a6179Smrg } 154f46a6179Smrg } 155f46a6179Smrg else { 156f46a6179Smrg int width; 157f46a6179Smrg for (i=0;i<XkbNumKbdGroups;i++) { 158f46a6179Smrg width= new->numLevels[i]; 159f46a6179Smrg if (old->syms[i]!=NULL) { 160f46a6179Smrg new->syms[i]= uTypedCalloc(width,KeySym); 161f46a6179Smrg if (!new->syms[i]) { 162f46a6179Smrg new->syms[i]= NULL; 163f46a6179Smrg new->numLevels[i]= 0; 164f46a6179Smrg return False; 165f46a6179Smrg } 166f46a6179Smrg memcpy((char *)new->syms[i],(char *)old->syms[i], 167f46a6179Smrg width*sizeof(KeySym)); 168f46a6179Smrg } 169f46a6179Smrg if (old->acts[i]!=NULL) { 170f46a6179Smrg new->acts[i]= uTypedCalloc(width,XkbAction); 171f46a6179Smrg if (!new->acts[i]) { 172f46a6179Smrg new->acts[i]= NULL; 173f46a6179Smrg return False; 174f46a6179Smrg } 175f46a6179Smrg memcpy((char *)new->acts[i],(char *)old->acts[i], 176f46a6179Smrg width*sizeof(XkbAction)); 177f46a6179Smrg } 178f46a6179Smrg } 179f46a6179Smrg } 180f46a6179Smrg return True; 181f46a6179Smrg} 182f46a6179Smrg 183f46a6179Smrg/***====================================================================***/ 184f46a6179Smrg 185f46a6179Smrgtypedef struct _ModMapEntry { 186f46a6179Smrg CommonInfo defs; 187f46a6179Smrg Bool haveSymbol; 188f46a6179Smrg int modifier; 189f46a6179Smrg union { 190f46a6179Smrg unsigned long keyName; 191f46a6179Smrg KeySym keySym; 192f46a6179Smrg } u; 193f46a6179Smrg} ModMapEntry; 194f46a6179Smrg 195f46a6179Smrg#define SYMBOLS_INIT_SIZE 110 196f46a6179Smrg#define SYMBOLS_CHUNK 20 197f46a6179Smrgtypedef struct _SymbolsInfo { 198f46a6179Smrg char * name; 199f46a6179Smrg int errorCount; 200f46a6179Smrg unsigned fileID; 201f46a6179Smrg unsigned merge; 202f46a6179Smrg unsigned explicit_group; 203f46a6179Smrg unsigned groupInfo; 204f46a6179Smrg unsigned szKeys; 205f46a6179Smrg unsigned nKeys; 206f46a6179Smrg KeyInfo * keys; 207f46a6179Smrg KeyInfo dflt; 208f46a6179Smrg VModInfo vmods; 209f46a6179Smrg ActionInfo * action; 210f46a6179Smrg Atom groupNames[XkbNumKbdGroups]; 211f46a6179Smrg 212f46a6179Smrg ModMapEntry * modMap; 213f46a6179Smrg AliasInfo * aliases; 214f46a6179Smrg} SymbolsInfo; 215f46a6179Smrg 216f46a6179Smrgstatic void 217f46a6179SmrgInitSymbolsInfo(SymbolsInfo *info,XkbDescPtr xkb) 218f46a6179Smrg{ 219f46a6179Smrgregister int i; 220f46a6179Smrg 221f46a6179Smrg tok_ONE_LEVEL= XkbInternAtom(NULL,"ONE_LEVEL",False); 222f46a6179Smrg tok_TWO_LEVEL= XkbInternAtom(NULL,"TWO_LEVEL",False); 223f46a6179Smrg tok_KEYPAD= XkbInternAtom(NULL,"KEYPAD",False); 224f46a6179Smrg info->name= NULL; 225f46a6179Smrg info->explicit_group= 0; 226f46a6179Smrg info->errorCount= 0; 227f46a6179Smrg info->fileID= 0; 228f46a6179Smrg info->merge= MergeOverride; 229f46a6179Smrg info->groupInfo= 0; 230f46a6179Smrg info->szKeys= SYMBOLS_INIT_SIZE; 231f46a6179Smrg info->nKeys= 0; 232f46a6179Smrg info->keys= uTypedCalloc(SYMBOLS_INIT_SIZE,KeyInfo); 233f46a6179Smrg info->modMap= NULL; 234f46a6179Smrg for (i=0;i<XkbNumKbdGroups;i++) 235f46a6179Smrg info->groupNames[i]= None; 236f46a6179Smrg InitKeyInfo(&info->dflt); 237f46a6179Smrg InitVModInfo(&info->vmods,xkb); 238f46a6179Smrg info->action= NULL; 239f46a6179Smrg info->aliases= NULL; 240f46a6179Smrg return; 241f46a6179Smrg} 242f46a6179Smrg 243f46a6179Smrgstatic void 244f46a6179SmrgFreeSymbolsInfo(SymbolsInfo *info) 245f46a6179Smrg{ 246f46a6179Smrgregister int i; 247f46a6179Smrg 248f46a6179Smrg if (info->name) 249f46a6179Smrg uFree(info->name); 250f46a6179Smrg info->name= NULL; 251f46a6179Smrg if (info->keys) { 252f46a6179Smrg for (i=0;i<info->nKeys;i++) { 253f46a6179Smrg FreeKeyInfo(&info->keys[i]); 254f46a6179Smrg } 255f46a6179Smrg uFree(info->keys); 256f46a6179Smrg info->keys= NULL; 257f46a6179Smrg } 258f46a6179Smrg if (info->modMap) { 259f46a6179Smrg ClearCommonInfo(&info->modMap->defs); 260f46a6179Smrg info->modMap= NULL; 261f46a6179Smrg } 262f46a6179Smrg if (info->aliases) { 263f46a6179Smrg ClearAliases(&info->aliases); 264f46a6179Smrg info->aliases= NULL; 265f46a6179Smrg } 266f46a6179Smrg bzero((char *)info,sizeof(SymbolsInfo)); 267f46a6179Smrg return; 268f46a6179Smrg} 269f46a6179Smrg 270f46a6179Smrgstatic Bool 271f46a6179SmrgResizeKeyGroup( KeyInfo * key, 272f46a6179Smrg unsigned group, 273f46a6179Smrg unsigned atLeastSize, 274f46a6179Smrg Bool forceActions) 275f46a6179Smrg{ 276f46a6179SmrgBool tooSmall; 277f46a6179Smrgunsigned newWidth; 278f46a6179Smrg 279f46a6179Smrg tooSmall= (key->numLevels[group]<atLeastSize); 280f46a6179Smrg if (tooSmall) newWidth= atLeastSize; 281f46a6179Smrg else newWidth= key->numLevels[group]; 282f46a6179Smrg 283f46a6179Smrg if ((key->syms[group]==NULL)||tooSmall) { 284f46a6179Smrg key->syms[group]= uTypedRecalloc(key->syms[group], 285f46a6179Smrg key->numLevels[group],newWidth, 286f46a6179Smrg KeySym); 287f46a6179Smrg if (!key->syms[group]) 288f46a6179Smrg return False; 289f46a6179Smrg } 290f46a6179Smrg if (((forceActions)&&(tooSmall||(key->acts[group]==NULL)))|| 291f46a6179Smrg (tooSmall&&(key->acts[group]!=NULL))) { 292f46a6179Smrg key->acts[group]= uTypedRecalloc(key->acts[group], 293f46a6179Smrg key->numLevels[group],newWidth, 294f46a6179Smrg XkbAction); 295f46a6179Smrg if (!key->acts[group]) 296f46a6179Smrg return False; 297f46a6179Smrg } 298f46a6179Smrg key->numLevels[group]= newWidth; 299f46a6179Smrg return True; 300f46a6179Smrg} 301f46a6179Smrg 302f46a6179Smrgstatic Bool 303f46a6179SmrgMergeKeyGroups( SymbolsInfo * info, 304f46a6179Smrg KeyInfo * into, 305f46a6179Smrg KeyInfo * from, 306f46a6179Smrg unsigned group) 307f46a6179Smrg{ 308f46a6179SmrgKeySym * resultSyms; 309f46a6179SmrgXkbAction * resultActs; 310f46a6179Smrgint resultWidth; 311f46a6179Smrgregister int i; 312f46a6179SmrgBool report,clobber; 313f46a6179Smrg 314f46a6179Smrg clobber= (from->defs.merge!=MergeAugment); 315f46a6179Smrg report= (warningLevel>9)|| 316f46a6179Smrg ((into->defs.fileID==from->defs.fileID)&&(warningLevel>0)); 317f46a6179Smrg if (into->numLevels[group]>=from->numLevels[group]) { 318f46a6179Smrg resultSyms= into->syms[group]; 319f46a6179Smrg resultActs= into->acts[group]; 320f46a6179Smrg resultWidth= into->numLevels[group]; 321f46a6179Smrg } 322f46a6179Smrg else { 323f46a6179Smrg resultSyms= from->syms[group]; 324f46a6179Smrg resultActs= from->acts[group]; 325f46a6179Smrg resultWidth= from->numLevels[group]; 326f46a6179Smrg } 327f46a6179Smrg if (resultSyms==NULL) { 328f46a6179Smrg resultSyms= uTypedCalloc(resultWidth,KeySym); 329f46a6179Smrg if (!resultSyms) { 330f46a6179Smrg WSGO("Could not allocate symbols for group merge\n"); 331f46a6179Smrg ACTION2("Group %d of key %s not merged\n",group, 332f46a6179Smrg longText(into->name,XkbMessage)); 333f46a6179Smrg return False; 334f46a6179Smrg } 335f46a6179Smrg } 336f46a6179Smrg if ((resultActs==NULL)&&(into->acts[group]||from->acts[group])) { 337f46a6179Smrg resultActs= uTypedCalloc(resultWidth,XkbAction); 338f46a6179Smrg if (!resultActs) { 339f46a6179Smrg WSGO("Could not allocate actions for group merge\n"); 340f46a6179Smrg ACTION2("Group %d of key %s not merged\n",group, 341f46a6179Smrg longText(into->name,XkbMessage)); 342f46a6179Smrg return False; 343f46a6179Smrg } 344f46a6179Smrg } 345f46a6179Smrg for (i=0;i<resultWidth;i++) { 346f46a6179Smrg KeySym fromSym,toSym; 347f46a6179Smrg if (from->syms[group] && (i<from->numLevels[group])) 348f46a6179Smrg fromSym= from->syms[group][i]; 349f46a6179Smrg else fromSym= NoSymbol; 350f46a6179Smrg if (into->syms[group] && (i<into->numLevels[group])) 351f46a6179Smrg toSym= into->syms[group][i]; 352f46a6179Smrg else toSym= NoSymbol; 353f46a6179Smrg if ((fromSym==NoSymbol)||(fromSym==toSym)) 354f46a6179Smrg resultSyms[i]= toSym; 355f46a6179Smrg else if (toSym==NoSymbol) 356f46a6179Smrg resultSyms[i]= fromSym; 357f46a6179Smrg else { 358f46a6179Smrg KeySym use,ignore; 359f46a6179Smrg if (clobber) { use= fromSym; ignore= toSym; } 360f46a6179Smrg else { use= toSym; ignore= fromSym; } 361f46a6179Smrg if (report) { 362f46a6179Smrg WARN3("Multiple symbols for level %d/group %d on key %s\n", 363f46a6179Smrg i+1,group+1,longText(into->name,XkbMessage)); 364f46a6179Smrg ACTION2("Using %s, ignoring %s\n",XkbKeysymText(use,XkbMessage), 365f46a6179Smrg XkbKeysymText(ignore,XkbMessage)); 366f46a6179Smrg } 367f46a6179Smrg resultSyms[i]= use; 368f46a6179Smrg } 369f46a6179Smrg if (resultActs!=NULL) { 370f46a6179Smrg XkbAction *fromAct,*toAct; 371f46a6179Smrg fromAct= (from->acts[group]?&from->acts[group][i]:NULL); 372f46a6179Smrg toAct= (into->acts[group]?&into->acts[group][i]:NULL); 373f46a6179Smrg if (((fromAct==NULL)||(fromAct->type==XkbSA_NoAction))&& 374f46a6179Smrg (toAct!=NULL)) { 375f46a6179Smrg resultActs[i]= *toAct; 376f46a6179Smrg } 377f46a6179Smrg else if (((toAct==NULL)||(toAct->type==XkbSA_NoAction))&& 378f46a6179Smrg (fromAct!=NULL)) { 379f46a6179Smrg resultActs[i]= *fromAct; 380f46a6179Smrg } 381f46a6179Smrg else { 382f46a6179Smrg XkbAction *use,*ignore; 383f46a6179Smrg if (clobber) { use= fromAct; ignore= toAct; } 384f46a6179Smrg else { use= toAct; ignore= fromAct; } 385f46a6179Smrg if (report) { 386f46a6179Smrg WARN3("Multiple actions for level %d/group %d on key %s\n", 387f46a6179Smrg i+1,group+1,longText(into->name,XkbMessage)); 388f46a6179Smrg ACTION2("Using %s, ignoring %s\n", 389f46a6179Smrg XkbActionTypeText(use->type,XkbMessage), 390f46a6179Smrg XkbActionTypeText(ignore->type,XkbMessage)); 391f46a6179Smrg } 392f46a6179Smrg resultActs[i]= *use; 393f46a6179Smrg } 394f46a6179Smrg } 395f46a6179Smrg } 396f46a6179Smrg if ((into->syms[group]!=NULL)&&(resultSyms!=into->syms[group])) 397f46a6179Smrg uFree(into->syms[group]); 398f46a6179Smrg if ((from->syms[group]!=NULL)&&(resultSyms!=from->syms[group])) 399f46a6179Smrg uFree(from->syms[group]); 400f46a6179Smrg if ((into->acts[group]!=NULL)&&(resultActs!=into->acts[group])) 401f46a6179Smrg uFree(into->acts[group]); 402f46a6179Smrg if ((from->acts[group]!=NULL)&&(resultActs!=from->acts[group])) 403f46a6179Smrg uFree(from->acts[group]); 404f46a6179Smrg into->numLevels[group]= resultWidth; 405f46a6179Smrg into->syms[group]= resultSyms; 406f46a6179Smrg from->syms[group]= NULL; 407f46a6179Smrg into->acts[group]= resultActs; 408f46a6179Smrg from->acts[group]= NULL; 409f46a6179Smrg into->symsDefined|= (1<<group); 410f46a6179Smrg from->symsDefined&= ~(1<<group); 411f46a6179Smrg into->actsDefined|= (1<<group); 412f46a6179Smrg from->actsDefined&= ~(1<<group); 413f46a6179Smrg return True; 414f46a6179Smrg} 415f46a6179Smrg 416f46a6179Smrgstatic Bool 417f46a6179SmrgMergeKeys(SymbolsInfo *info,KeyInfo *into,KeyInfo *from) 418f46a6179Smrg{ 419f46a6179Smrgregister int i; 420f46a6179Smrgunsigned collide= 0; 421f46a6179SmrgBool report; 422f46a6179Smrg 423f46a6179Smrg if (from->defs.merge==MergeReplace) { 424f46a6179Smrg for (i=0;i<XkbNumKbdGroups;i++) { 425f46a6179Smrg if (into->numLevels[i]!=0) { 426f46a6179Smrg if (into->syms[i]) 427f46a6179Smrg uFree(into->syms[i]); 428f46a6179Smrg if (into->acts[i]) 429f46a6179Smrg uFree(into->acts[i]); 430f46a6179Smrg } 431f46a6179Smrg } 432f46a6179Smrg *into= *from; 433f46a6179Smrg bzero(from,sizeof(KeyInfo)); 434f46a6179Smrg return True; 435f46a6179Smrg } 436f46a6179Smrg report= ((warningLevel>9)|| 437f46a6179Smrg ((into->defs.fileID==from->defs.fileID)&&(warningLevel>0))); 438f46a6179Smrg for (i=0;i<XkbNumKbdGroups;i++) { 439f46a6179Smrg if (from->numLevels[i]>0) { 440f46a6179Smrg if (into->numLevels[i]==0) { 441f46a6179Smrg into->numLevels[i]= from->numLevels[i]; 442f46a6179Smrg into->syms[i]= from->syms[i]; 443f46a6179Smrg into->acts[i]= from->acts[i]; 444f46a6179Smrg into->symsDefined|= (1<<i); 445f46a6179Smrg from->syms[i]= NULL; 446f46a6179Smrg from->acts[i]= NULL; 447f46a6179Smrg from->numLevels[i]= 0; 448f46a6179Smrg from->symsDefined&= ~(1<<i); 449f46a6179Smrg if (into->syms[i]) into->defs.defined|= _Key_Syms; 450f46a6179Smrg if (into->acts[i]) into->defs.defined|= _Key_Acts; 451f46a6179Smrg } 452f46a6179Smrg else { 453f46a6179Smrg if (report) { 454f46a6179Smrg if (into->syms[i]) collide|= _Key_Syms; 455f46a6179Smrg if (into->acts[i]) collide|= _Key_Acts; 456f46a6179Smrg } 457f46a6179Smrg MergeKeyGroups(info,into,from,(unsigned)i); 458f46a6179Smrg } 459f46a6179Smrg } 460f46a6179Smrg if (from->types[i]!=None) { 461f46a6179Smrg if ((into->types[i]!=None)&&(report)&& 462f46a6179Smrg (into->types[i]!=from->types[i])) { 463f46a6179Smrg Atom use,ignore; 464f46a6179Smrg collide|= _Key_Types; 465f46a6179Smrg if (from->defs.merge!=MergeAugment) { 466f46a6179Smrg use= from->types[i]; 467f46a6179Smrg ignore= into->types[i]; 468f46a6179Smrg } 469f46a6179Smrg else { 470f46a6179Smrg use= into->types[i]; 471f46a6179Smrg ignore= from->types[i]; 472f46a6179Smrg } 473f46a6179Smrg WARN2("Multiple definitions for group %d type of key %s\n", 474f46a6179Smrg i,longText(into->name,XkbMessage)); 475f46a6179Smrg ACTION2("Using %s, ignoring %s\n", 476f46a6179Smrg XkbAtomText(NULL,use,XkbMessage), 477f46a6179Smrg XkbAtomText(NULL,ignore,XkbMessage)); 478f46a6179Smrg } 479f46a6179Smrg if ((from->defs.merge!=MergeAugment)||(into->types[i]==None)) { 480f46a6179Smrg into->types[i]= from->types[i]; 481f46a6179Smrg } 482f46a6179Smrg } 483f46a6179Smrg } 484f46a6179Smrg if (UseNewField(_Key_Behavior,&into->defs,&from->defs,&collide)) { 485f46a6179Smrg into->behavior= from->behavior; 486f46a6179Smrg into->nameForOverlayKey= from->nameForOverlayKey; 487f46a6179Smrg into->defs.defined|= _Key_Behavior; 488f46a6179Smrg } 489f46a6179Smrg if (UseNewField(_Key_VModMap,&into->defs,&from->defs,&collide)) { 490f46a6179Smrg into->vmodmap= from->vmodmap; 491f46a6179Smrg into->defs.defined|= _Key_VModMap; 492f46a6179Smrg } 493f46a6179Smrg if (UseNewField(_Key_Repeat,&into->defs,&from->defs,&collide)) { 494f46a6179Smrg into->repeat= from->repeat; 495f46a6179Smrg into->defs.defined|= _Key_Repeat; 496f46a6179Smrg } 497f46a6179Smrg if (UseNewField(_Key_Type_Dflt,&into->defs,&from->defs,&collide)) { 498f46a6179Smrg into->dfltType= from->dfltType; 499f46a6179Smrg into->defs.defined|= _Key_Type_Dflt; 500f46a6179Smrg } 501f46a6179Smrg if (UseNewField(_Key_GroupInfo,&into->defs,&from->defs,&collide)) { 502f46a6179Smrg into->groupInfo= from->groupInfo; 503f46a6179Smrg into->defs.defined|= _Key_GroupInfo; 504f46a6179Smrg } 505f46a6179Smrg if ( collide ) { 506f46a6179Smrg WARN1("Symbol map for key %s redefined\n", 507f46a6179Smrg longText(into->name,XkbMessage)); 508f46a6179Smrg ACTION1("Using %s definition for conflicting fields\n", 509f46a6179Smrg (from->defs.merge==MergeAugment?"first":"last")); 510f46a6179Smrg } 511f46a6179Smrg return True; 512f46a6179Smrg} 513f46a6179Smrg 514f46a6179Smrgstatic Bool 515f46a6179SmrgAddKeySymbols(SymbolsInfo *info,KeyInfo *key,XkbDescPtr xkb) 516f46a6179Smrg{ 517f46a6179Smrgregister int i; 518f46a6179Smrgunsigned long real_name; 519f46a6179Smrg 520f46a6179Smrg for (i=0;i<info->nKeys;i++) { 521f46a6179Smrg if (info->keys[i].name==key->name) 522f46a6179Smrg return MergeKeys(info,&info->keys[i],key); 523f46a6179Smrg } 524f46a6179Smrg if(FindKeyNameForAlias(xkb, key->name, &real_name)) { 525f46a6179Smrg for (i=0;i<info->nKeys;i++) { 526f46a6179Smrg if (info->keys[i].name==real_name) 527f46a6179Smrg return MergeKeys(info,&info->keys[i],key); 528f46a6179Smrg } 529f46a6179Smrg } 530f46a6179Smrg if (info->nKeys>=info->szKeys) { 531f46a6179Smrg info->szKeys+= SYMBOLS_CHUNK; 532f46a6179Smrg info->keys= uTypedRecalloc(info->keys,info->nKeys,info->szKeys,KeyInfo); 533f46a6179Smrg if (!info->keys) { 534f46a6179Smrg WSGO("Could not allocate key symbols descriptions\n"); 535f46a6179Smrg ACTION("Some key symbols definitions may be lost\n"); 536f46a6179Smrg return False; 537f46a6179Smrg } 538f46a6179Smrg } 539f46a6179Smrg return CopyKeyInfo(key,&info->keys[info->nKeys++],True); 540f46a6179Smrg} 541f46a6179Smrg 542f46a6179Smrgstatic Bool 543f46a6179SmrgAddModMapEntry(SymbolsInfo *info,ModMapEntry *new) 544f46a6179Smrg{ 545f46a6179SmrgModMapEntry * mm; 546f46a6179SmrgBool clobber; 547f46a6179Smrg 548f46a6179Smrg clobber= (new->defs.merge!=MergeAugment); 549f46a6179Smrg for (mm=info->modMap;mm!=NULL;mm= (ModMapEntry *)mm->defs.next) { 550f46a6179Smrg if (new->haveSymbol&&mm->haveSymbol&&(new->u.keySym==mm->u.keySym)) { 551f46a6179Smrg unsigned use,ignore; 552f46a6179Smrg if (mm->modifier!=new->modifier) { 553f46a6179Smrg if (clobber) { 554f46a6179Smrg use= new->modifier; 555f46a6179Smrg ignore= mm->modifier; 556f46a6179Smrg } 557f46a6179Smrg else { 558f46a6179Smrg use= mm->modifier; 559f46a6179Smrg ignore= new->modifier; 560f46a6179Smrg } 561f46a6179Smrg ERROR1("%s added to symbol map for multiple modifiers\n", 562f46a6179Smrg XkbKeysymText(new->u.keySym,XkbMessage)); 563f46a6179Smrg ACTION2("Using %s, ignoring %s.\n", 564f46a6179Smrg XkbModIndexText(use,XkbMessage), 565f46a6179Smrg XkbModIndexText(ignore,XkbMessage)); 566f46a6179Smrg mm->modifier= use; 567f46a6179Smrg } 568f46a6179Smrg return True; 569f46a6179Smrg } 570f46a6179Smrg if ((!new->haveSymbol)&&(!mm->haveSymbol)&& 571f46a6179Smrg (new->u.keyName==mm->u.keyName)) { 572f46a6179Smrg unsigned use,ignore; 573f46a6179Smrg if (mm->modifier!=new->modifier) { 574f46a6179Smrg if (clobber) { 575f46a6179Smrg use= new->modifier; 576f46a6179Smrg ignore= mm->modifier; 577f46a6179Smrg } 578f46a6179Smrg else { 579f46a6179Smrg use= mm->modifier; 580f46a6179Smrg ignore= new->modifier; 581f46a6179Smrg } 582f46a6179Smrg ERROR1("Key %s added to map for multiple modifiers\n", 583f46a6179Smrg longText(new->u.keyName,XkbMessage)); 584f46a6179Smrg ACTION2("Using %s, ignoring %s.\n", 585f46a6179Smrg XkbModIndexText(use,XkbMessage), 586f46a6179Smrg XkbModIndexText(ignore,XkbMessage)); 587f46a6179Smrg mm->modifier= use; 588f46a6179Smrg } 589f46a6179Smrg return True; 590f46a6179Smrg } 591f46a6179Smrg } 592f46a6179Smrg mm= uTypedAlloc(ModMapEntry); 593f46a6179Smrg if (mm==NULL) { 594f46a6179Smrg WSGO("Could not allocate modifier map entry\n"); 595f46a6179Smrg ACTION1("Modifier map for %s will be incomplete\n", 596f46a6179Smrg XkbModIndexText(new->modifier,XkbMessage)); 597f46a6179Smrg return False; 598f46a6179Smrg } 599f46a6179Smrg *mm= *new; 600f46a6179Smrg mm->defs.next= &info->modMap->defs; 601f46a6179Smrg info->modMap= mm; 602f46a6179Smrg return True; 603f46a6179Smrg} 604f46a6179Smrg 605f46a6179Smrg/***====================================================================***/ 606f46a6179Smrg 607f46a6179Smrgstatic void 608f46a6179SmrgMergeIncludedSymbols(SymbolsInfo *into,SymbolsInfo *from, 609f46a6179Smrg unsigned merge,XkbDescPtr xkb) 610f46a6179Smrg{ 611f46a6179Smrgregister int i; 612f46a6179SmrgKeyInfo * key; 613f46a6179Smrg 614f46a6179Smrg if (from->errorCount>0) { 615f46a6179Smrg into->errorCount+= from->errorCount; 616f46a6179Smrg return; 617f46a6179Smrg } 618f46a6179Smrg if (into->name==NULL) { 619f46a6179Smrg into->name= from->name; 620f46a6179Smrg from->name= NULL; 621f46a6179Smrg } 622f46a6179Smrg for (i=0;i<XkbNumKbdGroups;i++) { 623f46a6179Smrg if (from->groupNames[i]!=None) { 624f46a6179Smrg if ((merge!=MergeAugment)||(into->groupNames[i]==None)) 625f46a6179Smrg into->groupNames[i]= from->groupNames[i]; 626f46a6179Smrg } 627f46a6179Smrg } 628f46a6179Smrg for (i=0,key=from->keys;i<from->nKeys;i++,key++) { 629f46a6179Smrg if (merge!=MergeDefault) 630f46a6179Smrg key->defs.merge= merge; 631f46a6179Smrg if (!AddKeySymbols(into,key,xkb)) 632f46a6179Smrg into->errorCount++; 633f46a6179Smrg } 634f46a6179Smrg if (from->modMap!=NULL) { 635f46a6179Smrg ModMapEntry *mm,*next; 636f46a6179Smrg for (mm=from->modMap;mm!=NULL;mm=next) { 637f46a6179Smrg if (merge!=MergeDefault) 638f46a6179Smrg mm->defs.merge= merge; 639f46a6179Smrg if (!AddModMapEntry(into,mm)) 640f46a6179Smrg into->errorCount++; 641f46a6179Smrg next= (ModMapEntry *)mm->defs.next; 642f46a6179Smrg uFree(mm); 643f46a6179Smrg } 644f46a6179Smrg from->modMap= NULL; 645f46a6179Smrg } 646f46a6179Smrg if (!MergeAliases(&into->aliases,&from->aliases,merge)) 647f46a6179Smrg into->errorCount++; 648f46a6179Smrg return; 649f46a6179Smrg} 650f46a6179Smrg 651f46a6179Smrgtypedef void (*FileHandler)( 652f46a6179Smrg XkbFile * /* rtrn */, 653f46a6179Smrg XkbDescPtr /* xkb */, 654f46a6179Smrg unsigned /* merge */, 655f46a6179Smrg SymbolsInfo * /* included */ 656f46a6179Smrg); 657f46a6179Smrg 658f46a6179Smrgstatic Bool 659f46a6179SmrgHandleIncludeSymbols( IncludeStmt * stmt, 660f46a6179Smrg XkbDescPtr xkb, 661f46a6179Smrg SymbolsInfo * info, 662f46a6179Smrg FileHandler hndlr) 663f46a6179Smrg{ 664f46a6179Smrgunsigned newMerge; 665f46a6179SmrgXkbFile * rtrn; 666f46a6179SmrgSymbolsInfo included; 667f46a6179SmrgBool haveSelf; 668f46a6179Smrg 669f46a6179Smrg haveSelf= False; 670f46a6179Smrg if ((stmt->file==NULL)&&(stmt->map==NULL)) { 671f46a6179Smrg haveSelf= True; 672f46a6179Smrg included= *info; 673f46a6179Smrg bzero(info,sizeof(SymbolsInfo)); 674f46a6179Smrg } 675f46a6179Smrg else if (ProcessIncludeFile(stmt,XkmSymbolsIndex,&rtrn,&newMerge)) { 676f46a6179Smrg InitSymbolsInfo(&included,xkb); 677f46a6179Smrg included.fileID= included.dflt.defs.fileID= rtrn->id; 678f46a6179Smrg included.merge= included.dflt.defs.merge= MergeOverride; 679f46a6179Smrg if (stmt->modifier) { 680f46a6179Smrg included.explicit_group= atoi(stmt->modifier) - 1; 681f46a6179Smrg } else { 682f46a6179Smrg included.explicit_group= info->explicit_group; 683f46a6179Smrg } 684f46a6179Smrg (*hndlr)(rtrn,xkb,MergeOverride,&included); 685f46a6179Smrg if (stmt->stmt!=NULL) { 686f46a6179Smrg if (included.name!=NULL) 687f46a6179Smrg uFree(included.name); 688f46a6179Smrg included.name= stmt->stmt; 689f46a6179Smrg stmt->stmt= NULL; 690f46a6179Smrg } 691f46a6179Smrg } 692f46a6179Smrg else { 693f46a6179Smrg info->errorCount+= 10; 694f46a6179Smrg return False; 695f46a6179Smrg } 696f46a6179Smrg if ((stmt->next!=NULL)&&(included.errorCount<1)) { 697f46a6179Smrg IncludeStmt * next; 698f46a6179Smrg unsigned op; 699f46a6179Smrg SymbolsInfo next_incl; 700f46a6179Smrg 701f46a6179Smrg for (next=stmt->next;next!=NULL;next=next->next) { 702f46a6179Smrg if ((next->file==NULL)&&(next->map==NULL)) { 703f46a6179Smrg haveSelf= True; 704f46a6179Smrg MergeIncludedSymbols(&included,info,next->merge,xkb); 705f46a6179Smrg FreeSymbolsInfo(info); 706f46a6179Smrg } 707f46a6179Smrg else if (ProcessIncludeFile(next,XkmSymbolsIndex,&rtrn,&op)) { 708f46a6179Smrg InitSymbolsInfo(&next_incl,xkb); 709f46a6179Smrg next_incl.fileID= next_incl.dflt.defs.fileID= rtrn->id; 710f46a6179Smrg next_incl.merge= next_incl.dflt.defs.merge= MergeOverride; 711f46a6179Smrg if (next->modifier) { 712f46a6179Smrg next_incl.explicit_group= atoi(next->modifier) - 1; 713f46a6179Smrg } else { 714f46a6179Smrg next_incl.explicit_group= info->explicit_group; 715f46a6179Smrg } 716f46a6179Smrg (*hndlr)(rtrn,xkb,MergeOverride,&next_incl); 717f46a6179Smrg MergeIncludedSymbols(&included,&next_incl,op,xkb); 718f46a6179Smrg FreeSymbolsInfo(&next_incl); 719f46a6179Smrg } 720f46a6179Smrg else { 721f46a6179Smrg info->errorCount+= 10; 722f46a6179Smrg return False; 723f46a6179Smrg } 724f46a6179Smrg } 725f46a6179Smrg } 726f46a6179Smrg if (haveSelf) 727f46a6179Smrg *info= included; 728f46a6179Smrg else { 729f46a6179Smrg MergeIncludedSymbols(info,&included,newMerge,xkb); 730f46a6179Smrg FreeSymbolsInfo(&included); 731f46a6179Smrg } 732f46a6179Smrg return (info->errorCount==0); 733f46a6179Smrg} 734f46a6179Smrg 735f46a6179Smrgstatic LookupEntry groupNames[]= { 736f46a6179Smrg { "group1", 1 }, 737f46a6179Smrg { "group2", 2 }, 738f46a6179Smrg { "group3", 3 }, 739f46a6179Smrg { "group4", 4 }, 740f46a6179Smrg { "group5", 5 }, 741f46a6179Smrg { "group6", 6 }, 742f46a6179Smrg { "group7", 7 }, 743f46a6179Smrg { "group8", 8 }, 744f46a6179Smrg { NULL, 0 } 745f46a6179Smrg}; 746f46a6179Smrg 747f46a6179Smrg 748f46a6179Smrg#define SYMBOLS 1 749f46a6179Smrg#define ACTIONS 2 750f46a6179Smrg 751f46a6179Smrgstatic Bool 752f46a6179SmrgGetGroupIndex( KeyInfo * key, 753f46a6179Smrg ExprDef * arrayNdx, 754f46a6179Smrg unsigned what, 755f46a6179Smrg unsigned * ndx_rtrn) 756f46a6179Smrg{ 757f46a6179Smrgconst char *name; 758f46a6179SmrgExprResult tmp; 759f46a6179Smrg 760f46a6179Smrg if (what==SYMBOLS) name= "symbols"; 761f46a6179Smrg else name= "actions"; 762f46a6179Smrg 763f46a6179Smrg if (arrayNdx==NULL) { 764f46a6179Smrg register int i; 765f46a6179Smrg unsigned defined; 766f46a6179Smrg if (what==SYMBOLS) defined= key->symsDefined; 767f46a6179Smrg else defined= key->actsDefined; 768f46a6179Smrg 769f46a6179Smrg for (i=0;i<XkbNumKbdGroups;i++) { 770f46a6179Smrg if ((defined&(1<<i))==0) { 771f46a6179Smrg *ndx_rtrn= i; 772f46a6179Smrg return True; 773f46a6179Smrg } 774f46a6179Smrg } 775f46a6179Smrg ERROR3("Too many groups of %s for key %s (max %d)\n",name, 776f46a6179Smrg longText(key->name,XkbMessage), 777f46a6179Smrg XkbNumKbdGroups+1); 778f46a6179Smrg ACTION1("Ignoring %s defined for extra groups\n",name); 779f46a6179Smrg return False; 780f46a6179Smrg } 781f46a6179Smrg if (!ExprResolveInteger(arrayNdx,&tmp,SimpleLookup,(XPointer)groupNames)) { 782f46a6179Smrg ERROR2("Illegal group index for %s of key %s\n",name, 783f46a6179Smrg longText(key->name,XkbMessage)); 784f46a6179Smrg ACTION("Definition with non-integer array index ignored\n"); 785f46a6179Smrg return False; 786f46a6179Smrg } 787f46a6179Smrg if ((tmp.uval<1)||(tmp.uval>XkbNumKbdGroups)) { 788f46a6179Smrg ERROR3("Group index for %s of key %s is out of range (1..%d)\n",name, 789f46a6179Smrg longText(key->name,XkbMessage), 790f46a6179Smrg XkbNumKbdGroups+1); 791f46a6179Smrg ACTION2("Ignoring %s for group %d\n",name,tmp.uval); 792f46a6179Smrg return False; 793f46a6179Smrg } 794f46a6179Smrg *ndx_rtrn= tmp.uval-1; 795f46a6179Smrg return True; 796f46a6179Smrg} 797f46a6179Smrg 798f46a6179Smrgstatic Bool 799f46a6179SmrgAddSymbolsToKey( KeyInfo * key, 800f46a6179Smrg XkbDescPtr xkb, 801f46a6179Smrg char * field, 802f46a6179Smrg ExprDef * arrayNdx, 803f46a6179Smrg ExprDef * value, 804f46a6179Smrg SymbolsInfo * info) 805f46a6179Smrg{ 806f46a6179Smrgunsigned ndx,nSyms; 807f46a6179Smrgint i; 808f46a6179Smrg 809f46a6179Smrg if (!GetGroupIndex(key,arrayNdx,SYMBOLS,&ndx)) 810f46a6179Smrg return False; 811f46a6179Smrg if (value==NULL) { 812f46a6179Smrg key->symsDefined|= (1<<ndx); 813f46a6179Smrg return True; 814f46a6179Smrg } 815f46a6179Smrg if (value->op!=ExprKeysymList) { 816f46a6179Smrg ERROR1("Expected a list of symbols, found %s\n",exprOpText(value->op)); 817f46a6179Smrg ACTION2("Ignoring symbols for group %d of %s\n",ndx, 818f46a6179Smrg longText(key->name,XkbMessage)); 819f46a6179Smrg return False; 820f46a6179Smrg } 821f46a6179Smrg if (key->syms[ndx]!=NULL) { 822f46a6179Smrg WSGO2("Symbols for key %s, group %d already defined\n", 823f46a6179Smrg longText(key->name,XkbMessage), 824f46a6179Smrg ndx); 825f46a6179Smrg return False; 826f46a6179Smrg } 827f46a6179Smrg nSyms= value->value.list.nSyms; 828f46a6179Smrg if (((key->numLevels[ndx]<nSyms)||(key->syms[ndx]==NULL))&& 829f46a6179Smrg (!ResizeKeyGroup(key,ndx,nSyms,False))) { 830f46a6179Smrg WSGO2("Could not resize group %d of key %s\n",ndx, 831f46a6179Smrg longText(key->name,XkbMessage)); 832f46a6179Smrg ACTION("Symbols lost\n"); 833f46a6179Smrg return False; 834f46a6179Smrg } 835f46a6179Smrg key->symsDefined|= (1<<ndx); 836f46a6179Smrg memcpy((char *)key->syms[ndx],(char *)value->value.list.syms, 837f46a6179Smrg nSyms*sizeof(KeySym)); 838f46a6179Smrg for (i=key->numLevels[ndx]-1;(i>=0)&&(key->syms[ndx][i]==NoSymbol);i--) { 839f46a6179Smrg key->numLevels[ndx]--; 840f46a6179Smrg } 841f46a6179Smrg return True; 842f46a6179Smrg} 843f46a6179Smrg 844f46a6179Smrgstatic Bool 845f46a6179SmrgAddActionsToKey( KeyInfo * key, 846f46a6179Smrg XkbDescPtr xkb, 847f46a6179Smrg char * field, 848f46a6179Smrg ExprDef * arrayNdx, 849f46a6179Smrg ExprDef * value, 850f46a6179Smrg SymbolsInfo * info) 851f46a6179Smrg{ 852f46a6179Smrgregister int i; 853f46a6179Smrgunsigned ndx,nActs; 854f46a6179SmrgExprDef * act; 855f46a6179SmrgXkbAnyAction * toAct; 856f46a6179Smrg 857f46a6179Smrg if (!GetGroupIndex(key,arrayNdx,ACTIONS,&ndx)) 858f46a6179Smrg return False; 859f46a6179Smrg 860f46a6179Smrg if (value==NULL) { 861f46a6179Smrg key->actsDefined|= (1<<ndx); 862f46a6179Smrg return True; 863f46a6179Smrg } 864f46a6179Smrg if (value->op!=ExprActionList) { 865f46a6179Smrg WSGO1("Bad expression type (%d) for action list value\n",value->op); 866f46a6179Smrg ACTION2("Ignoring actions for group %d of %s\n",ndx, 867f46a6179Smrg longText(key->name,XkbMessage)); 868f46a6179Smrg return False; 869f46a6179Smrg } 870f46a6179Smrg if (key->acts[ndx]!=NULL) { 871f46a6179Smrg WSGO2("Actions for key %s, group %d already defined\n", 872f46a6179Smrg longText(key->name,XkbMessage), 873f46a6179Smrg ndx); 874f46a6179Smrg return False; 875f46a6179Smrg } 876f46a6179Smrg for (nActs=0,act= value->value.child;act!=NULL;nActs++) { 877f46a6179Smrg act= (ExprDef *)act->common.next; 878f46a6179Smrg } 879f46a6179Smrg if (nActs<1) { 880f46a6179Smrg WSGO("Action list but not actions in AddActionsToKey\n"); 881f46a6179Smrg return False; 882f46a6179Smrg } 883f46a6179Smrg if (((key->numLevels[ndx]<nActs)||(key->acts[ndx]==NULL))&& 884f46a6179Smrg (!ResizeKeyGroup(key,ndx,nActs,True))) { 885f46a6179Smrg WSGO2("Could not resize group %d of key %s\n",ndx, 886f46a6179Smrg longText(key->name,XkbMessage)); 887f46a6179Smrg ACTION("Actions lost\n"); 888f46a6179Smrg return False; 889f46a6179Smrg } 890f46a6179Smrg key->actsDefined|= (1<<ndx); 891f46a6179Smrg 892f46a6179Smrg toAct= (XkbAnyAction *)key->acts[ndx]; 893f46a6179Smrg act= value->value.child; 894f46a6179Smrg for (i=0;i<nActs;i++,toAct++) { 895f46a6179Smrg if (!HandleActionDef(act,xkb,toAct,MergeOverride,info->action)) { 896f46a6179Smrg ERROR1("Illegal action definition for %s\n", 897f46a6179Smrg longText(key->name,XkbMessage)); 898f46a6179Smrg ACTION2("Action for group %d/level %d ignored\n",ndx+1,i+1); 899f46a6179Smrg } 900f46a6179Smrg act= (ExprDef *)act->common.next; 901f46a6179Smrg } 902f46a6179Smrg return True; 903f46a6179Smrg} 904f46a6179Smrg 905f46a6179Smrgstatic int 906f46a6179SmrgSetAllowNone(KeyInfo *key,ExprDef *arrayNdx,ExprDef *value) 907f46a6179Smrg{ 908f46a6179SmrgExprResult tmp; 909f46a6179Smrgunsigned radio_groups= 0; 910f46a6179Smrg 911f46a6179Smrg if (arrayNdx==NULL) { 912f46a6179Smrg radio_groups= XkbAllRadioGroupsMask; 913f46a6179Smrg } 914f46a6179Smrg else { 915f46a6179Smrg if (!ExprResolveInteger(arrayNdx,&tmp,RadioLookup,NULL)){ 916f46a6179Smrg ERROR("Illegal index in group name definition\n"); 917f46a6179Smrg ACTION("Definition with non-integer array index ignored\n"); 918f46a6179Smrg return False; 919f46a6179Smrg } 920f46a6179Smrg if ((tmp.uval<1)||(tmp.uval>XkbMaxRadioGroups)) { 921f46a6179Smrg ERROR1("Illegal radio group specified (must be 1..%d)\n", 922f46a6179Smrg XkbMaxRadioGroups+1); 923f46a6179Smrg ACTION1("Value of \"allow none\" for group %d ignored\n",tmp.uval); 924f46a6179Smrg return False; 925f46a6179Smrg } 926f46a6179Smrg radio_groups|= (1<<(tmp.uval-1)); 927f46a6179Smrg } 928f46a6179Smrg if (!ExprResolveBoolean(value,&tmp,NULL,NULL)) { 929f46a6179Smrg ERROR1("Illegal \"allow none\" value for %s\n", 930f46a6179Smrg longText(key->name,XkbMessage)); 931f46a6179Smrg ACTION("Non-boolean value ignored\n"); 932f46a6179Smrg return False; 933f46a6179Smrg } 934f46a6179Smrg if (tmp.uval) key->allowNone|= radio_groups; 935f46a6179Smrg else key->allowNone&= ~radio_groups; 936f46a6179Smrg return True; 937f46a6179Smrg} 938f46a6179Smrg 939f46a6179Smrg 940f46a6179Smrgstatic LookupEntry lockingEntries[] = { 941f46a6179Smrg { "true", XkbKB_Lock }, 942f46a6179Smrg { "yes", XkbKB_Lock }, 943f46a6179Smrg { "on", XkbKB_Lock }, 944f46a6179Smrg { "false", XkbKB_Default }, 945f46a6179Smrg { "no", XkbKB_Default }, 946f46a6179Smrg { "off", XkbKB_Default }, 947f46a6179Smrg { "permanent", XkbKB_Lock|XkbKB_Permanent }, 948f46a6179Smrg { NULL, 0 } 949f46a6179Smrg}; 950f46a6179Smrg 951f46a6179Smrgstatic LookupEntry repeatEntries[]= { 952f46a6179Smrg { "true", RepeatYes }, 953f46a6179Smrg { "yes", RepeatYes }, 954f46a6179Smrg { "on", RepeatYes }, 955f46a6179Smrg { "false", RepeatNo }, 956f46a6179Smrg { "no", RepeatNo }, 957f46a6179Smrg { "off", RepeatNo }, 958f46a6179Smrg { "default", RepeatUndefined }, 959f46a6179Smrg { NULL, 0 } 960f46a6179Smrg}; 961f46a6179Smrg 962f46a6179Smrgstatic LookupEntry rgEntries[]= { 963f46a6179Smrg { "none", 0 }, 964f46a6179Smrg { NULL, 0 } 965f46a6179Smrg}; 966f46a6179Smrg 967f46a6179Smrgstatic Bool 968f46a6179SmrgSetSymbolsField( KeyInfo * key, 969f46a6179Smrg XkbDescPtr xkb, 970f46a6179Smrg char * field, 971f46a6179Smrg ExprDef * arrayNdx, 972f46a6179Smrg ExprDef * value, 973f46a6179Smrg SymbolsInfo * info) 974f46a6179Smrg{ 975f46a6179SmrgBool ok= True; 976f46a6179SmrgExprResult tmp; 977f46a6179Smrg 978f46a6179Smrg if (uStrCaseCmp(field,"type")==0) { 979f46a6179Smrg ExprResult ndx; 980f46a6179Smrg if ((!ExprResolveString(value,&tmp,NULL,NULL))&&(warningLevel>0)) { 981f46a6179Smrg WARN("The type field of a key symbol map must be a string\n"); 982f46a6179Smrg ACTION("Ignoring illegal type definition\n"); 983f46a6179Smrg } 984f46a6179Smrg if (arrayNdx==NULL) { 985f46a6179Smrg key->dfltType= XkbInternAtom(NULL,tmp.str,False); 986f46a6179Smrg key->defs.defined|= _Key_Type_Dflt; 987f46a6179Smrg } 988f46a6179Smrg else if (!ExprResolveInteger(arrayNdx,&ndx,SimpleLookup, 989f46a6179Smrg (XPointer)groupNames)) { 990f46a6179Smrg ERROR1("Illegal group index for type of key %s\n", 991f46a6179Smrg longText(key->name,XkbMessage)); 992f46a6179Smrg ACTION("Definition with non-integer array index ignored\n"); 993f46a6179Smrg return False; 994f46a6179Smrg } 995f46a6179Smrg else if ((ndx.uval<1)||(ndx.uval>XkbNumKbdGroups)) { 996f46a6179Smrg ERROR2("Group index for type of key %s is out of range (1..%d)\n", 997f46a6179Smrg longText(key->name,XkbMessage), 998f46a6179Smrg XkbNumKbdGroups+1); 999f46a6179Smrg ACTION1("Ignoring type for group %d\n",ndx.uval); 1000f46a6179Smrg return False; 1001f46a6179Smrg } 1002f46a6179Smrg else { 1003f46a6179Smrg key->types[ndx.uval-1]= XkbInternAtom(NULL,tmp.str,False); 1004f46a6179Smrg key->typesDefined|= (1<<(ndx.uval-1)); 1005f46a6179Smrg } 1006f46a6179Smrg } 1007f46a6179Smrg else if (uStrCaseCmp(field,"symbols")==0) 1008f46a6179Smrg return AddSymbolsToKey(key,xkb,field,arrayNdx,value,info); 1009f46a6179Smrg else if (uStrCaseCmp(field,"actions")==0) 1010f46a6179Smrg return AddActionsToKey(key,xkb,field,arrayNdx,value,info); 1011f46a6179Smrg else if ((uStrCaseCmp(field,"vmods")==0)|| 1012f46a6179Smrg (uStrCaseCmp(field,"virtualmods")==0)|| 1013f46a6179Smrg (uStrCaseCmp(field,"virtualmodifiers")==0)) { 1014f46a6179Smrg ok= ExprResolveModMask(value,&tmp,LookupVModMask,(XPointer)xkb); 1015f46a6179Smrg if (ok) { 1016f46a6179Smrg key->vmodmap= (tmp.uval>>8); 1017f46a6179Smrg key->defs.defined|= _Key_VModMap; 1018f46a6179Smrg } 1019f46a6179Smrg else { 1020f46a6179Smrg ERROR1("Expected a virtual modifier mask, found %s\n", 1021f46a6179Smrg exprOpText(value->op)); 1022f46a6179Smrg ACTION1("Ignoring virtual modifiers definition for key %s\n", 1023f46a6179Smrg longText(key->name,XkbMessage)); 1024f46a6179Smrg } 1025f46a6179Smrg } 1026f46a6179Smrg else if ((uStrCaseCmp(field,"locking")==0)||(uStrCaseCmp(field,"lock")==0)|| 1027f46a6179Smrg (uStrCaseCmp(field,"locks")==0)) { 1028f46a6179Smrg ok= ExprResolveEnum(value,&tmp,lockingEntries); 1029f46a6179Smrg if (ok) 1030f46a6179Smrg key->behavior.type= tmp.uval; 1031f46a6179Smrg key->defs.defined|= _Key_Behavior; 1032f46a6179Smrg } 1033f46a6179Smrg else if ((uStrCaseCmp(field,"radiogroup")==0)|| 1034f46a6179Smrg (uStrCaseCmp(field,"permanentradiogroup")==0)) { 1035f46a6179Smrg Bool permanent= False; 1036f46a6179Smrg if (uStrCaseCmp(field,"permanentradiogroup")==0) 1037f46a6179Smrg permanent= True; 1038f46a6179Smrg ok= ExprResolveInteger(value,&tmp,SimpleLookup,(XPointer)rgEntries); 1039f46a6179Smrg if (!ok) { 1040f46a6179Smrg ERROR1("Illegal radio group specification for %s\n", 1041f46a6179Smrg longText(key->name,XkbMessage)); 1042f46a6179Smrg ACTION("Non-integer radio group ignored\n"); 1043f46a6179Smrg return False; 1044f46a6179Smrg } 1045f46a6179Smrg if (tmp.uval==0) { 1046f46a6179Smrg key->behavior.type= XkbKB_Default; 1047f46a6179Smrg key->behavior.data= 0; 1048f46a6179Smrg return ok; 1049f46a6179Smrg } 1050f46a6179Smrg if ((tmp.uval<1)||(tmp.uval>XkbMaxRadioGroups)) { 1051f46a6179Smrg ERROR1("Radio group specification for %s out of range (1..32)\n", 1052f46a6179Smrg longText(key->name,XkbMessage)); 1053f46a6179Smrg ACTION1("Illegal radio group %d ignored\n",tmp.uval); 1054f46a6179Smrg return False; 1055f46a6179Smrg } 1056f46a6179Smrg key->behavior.type= XkbKB_RadioGroup|(permanent?XkbKB_Permanent:0); 1057f46a6179Smrg key->behavior.data= tmp.uval-1; 1058f46a6179Smrg if (key->allowNone&(1<<(tmp.uval-1))) 1059f46a6179Smrg key->behavior.data|= XkbKB_RGAllowNone; 1060f46a6179Smrg key->defs.defined|= _Key_Behavior; 1061f46a6179Smrg } 1062f46a6179Smrg else if (uStrCaseEqual(field,"allownone")) { 1063f46a6179Smrg ok= SetAllowNone(key,arrayNdx,value); 1064f46a6179Smrg } 1065f46a6179Smrg else if (uStrCasePrefix("overlay",field)|| 1066f46a6179Smrg uStrCasePrefix("permanentoverlay",field)) { 1067f46a6179Smrg Bool permanent= False; 1068f46a6179Smrg char *which; 1069f46a6179Smrg int overlayNdx; 1070f46a6179Smrg if (uStrCasePrefix("permanent",field)) { 1071f46a6179Smrg permanent= True; 1072f46a6179Smrg which= &field[sizeof("permanentoverlay")-1]; 1073f46a6179Smrg } 1074f46a6179Smrg else { 1075f46a6179Smrg which= &field[sizeof("overlay")-1]; 1076f46a6179Smrg } 1077f46a6179Smrg if (sscanf(which,"%d",&overlayNdx)==1) { 1078f46a6179Smrg if (((overlayNdx<1)||(overlayNdx>2))&&(warningLevel>0)) { 1079f46a6179Smrg ERROR2("Illegal overlay %d specified for %s\n", 1080f46a6179Smrg overlayNdx, 1081f46a6179Smrg longText(key->name,XkbMessage)); 1082f46a6179Smrg ACTION("Ignored\n"); 1083f46a6179Smrg return False; 1084f46a6179Smrg } 1085f46a6179Smrg } 1086f46a6179Smrg else if (*which=='\0') 1087f46a6179Smrg overlayNdx=1; 1088f46a6179Smrg else if (warningLevel>0) { 1089f46a6179Smrg ERROR2("Illegal overlay \"%s\" specified for %s\n", 1090f46a6179Smrg which, 1091f46a6179Smrg longText(key->name,XkbMessage)); 1092f46a6179Smrg ACTION("Ignored\n"); 1093f46a6179Smrg return False; 1094f46a6179Smrg } 1095f46a6179Smrg ok= ExprResolveKeyName(value,&tmp,NULL,NULL); 1096f46a6179Smrg if (!ok) { 1097f46a6179Smrg ERROR1("Illegal overlay key specification for %s\n", 1098f46a6179Smrg longText(key->name,XkbMessage)); 1099f46a6179Smrg ACTION("Overlay key must be specified by name\n"); 1100f46a6179Smrg return False; 1101f46a6179Smrg } 1102f46a6179Smrg if (overlayNdx==1) key->behavior.type= XkbKB_Overlay1; 1103f46a6179Smrg else key->behavior.type= XkbKB_Overlay2; 1104f46a6179Smrg if (permanent) 1105f46a6179Smrg key->behavior.type|= XkbKB_Permanent; 1106f46a6179Smrg 1107f46a6179Smrg key->behavior.data= 0; 1108f46a6179Smrg key->nameForOverlayKey= KeyNameToLong(tmp.keyName.name); 1109f46a6179Smrg key->defs.defined|= _Key_Behavior; 1110f46a6179Smrg } 1111f46a6179Smrg else if ((uStrCaseCmp(field,"repeating")==0)|| 1112f46a6179Smrg (uStrCaseCmp(field,"repeats")==0)|| 1113f46a6179Smrg (uStrCaseCmp(field,"repeat")==0)){ 1114f46a6179Smrg ok= ExprResolveEnum(value,&tmp,repeatEntries); 1115f46a6179Smrg if (!ok) { 1116f46a6179Smrg ERROR1("Illegal repeat setting for %s\n", 1117f46a6179Smrg longText(key->name,XkbMessage)); 1118f46a6179Smrg ACTION("Non-boolean repeat setting ignored\n"); 1119f46a6179Smrg return False; 1120f46a6179Smrg } 1121f46a6179Smrg key->repeat= tmp.uval; 1122f46a6179Smrg key->defs.defined|= _Key_Repeat; 1123f46a6179Smrg } 1124f46a6179Smrg else if ((uStrCaseCmp(field,"groupswrap")==0)|| 1125f46a6179Smrg (uStrCaseCmp(field,"wrapgroups")==0)) { 1126f46a6179Smrg ok= ExprResolveBoolean(value,&tmp,NULL,NULL); 1127f46a6179Smrg if (!ok) { 1128f46a6179Smrg ERROR1("Illegal groupsWrap setting for %s\n", 1129f46a6179Smrg longText(key->name,XkbMessage)); 1130f46a6179Smrg ACTION("Non-boolean value ignored\n"); 1131f46a6179Smrg return False; 1132f46a6179Smrg } 1133f46a6179Smrg if (tmp.uval) key->groupInfo= XkbWrapIntoRange; 1134f46a6179Smrg else key->groupInfo= XkbClampIntoRange; 1135f46a6179Smrg key->defs.defined|= _Key_GroupInfo; 1136f46a6179Smrg } 1137f46a6179Smrg else if ((uStrCaseCmp(field,"groupsclamp")==0)|| 1138f46a6179Smrg (uStrCaseCmp(field,"clampgroups")==0)) { 1139f46a6179Smrg ok= ExprResolveBoolean(value,&tmp,NULL,NULL); 1140f46a6179Smrg if (!ok) { 1141f46a6179Smrg ERROR1("Illegal groupsClamp setting for %s\n", 1142f46a6179Smrg longText(key->name,XkbMessage)); 1143f46a6179Smrg ACTION("Non-boolean value ignored\n"); 1144f46a6179Smrg return False; 1145f46a6179Smrg } 1146f46a6179Smrg if (tmp.uval) key->groupInfo= XkbClampIntoRange; 1147f46a6179Smrg else key->groupInfo= XkbWrapIntoRange; 1148f46a6179Smrg key->defs.defined|= _Key_GroupInfo; 1149f46a6179Smrg } 1150f46a6179Smrg else if ((uStrCaseCmp(field,"groupsredirect")==0)|| 1151f46a6179Smrg (uStrCaseCmp(field,"redirectgroups")==0)) { 1152f46a6179Smrg if (!ExprResolveInteger(value,&tmp,SimpleLookup,(XPointer)groupNames)) { 1153f46a6179Smrg ERROR1("Illegal group index for redirect of key %s\n", 1154f46a6179Smrg longText(key->name,XkbMessage)); 1155f46a6179Smrg ACTION("Definition with non-integer group ignored\n"); 1156f46a6179Smrg return False; 1157f46a6179Smrg } 1158f46a6179Smrg if ((tmp.uval<1)||(tmp.uval>XkbNumKbdGroups)) { 1159f46a6179Smrg ERROR2("Out-of-range (1..%d) group for redirect of key %s\n", 1160f46a6179Smrg XkbNumKbdGroups, 1161f46a6179Smrg longText(key->name,XkbMessage)); 1162f46a6179Smrg ERROR1("Ignoring illegal group %d\n",tmp.uval); 1163f46a6179Smrg return False; 1164f46a6179Smrg } 1165f46a6179Smrg key->groupInfo= XkbSetGroupInfo(0,XkbRedirectIntoRange,tmp.uval-1); 1166f46a6179Smrg key->defs.defined|= _Key_GroupInfo; 1167f46a6179Smrg } 1168f46a6179Smrg else { 1169f46a6179Smrg ERROR1("Unknown field %s in a symbol interpretation\n",field); 1170f46a6179Smrg ACTION("Definition ignored\n"); 1171f46a6179Smrg ok= False; 1172f46a6179Smrg } 1173f46a6179Smrg return ok; 1174f46a6179Smrg} 1175f46a6179Smrg 1176f46a6179Smrgstatic int 1177f46a6179SmrgSetGroupName(SymbolsInfo *info,ExprDef *arrayNdx,ExprDef *value) 1178f46a6179Smrg{ 1179f46a6179SmrgExprResult tmp,name; 1180f46a6179Smrg 1181f46a6179Smrg if ((arrayNdx==NULL)&&(warningLevel>0)) { 1182f46a6179Smrg WARN("You must specify an index when specifying a group name\n"); 1183f46a6179Smrg ACTION("Group name definition without array subscript ignored\n"); 1184f46a6179Smrg return False; 1185f46a6179Smrg } 1186f46a6179Smrg if (!ExprResolveInteger(arrayNdx,&tmp,SimpleLookup,(XPointer)groupNames)) { 1187f46a6179Smrg ERROR("Illegal index in group name definition\n"); 1188f46a6179Smrg ACTION("Definition with non-integer array index ignored\n"); 1189f46a6179Smrg return False; 1190f46a6179Smrg } 1191f46a6179Smrg if ((tmp.uval<1)||(tmp.uval>XkbNumKbdGroups)) { 1192f46a6179Smrg ERROR1("Attempt to specify name for illegal group (must be 1..%d)\n", 1193f46a6179Smrg XkbNumKbdGroups+1); 1194f46a6179Smrg ACTION1("Name for group %d ignored\n",tmp.uval); 1195f46a6179Smrg return False; 1196f46a6179Smrg } 1197f46a6179Smrg if (!ExprResolveString(value,&name,NULL,NULL)) { 1198f46a6179Smrg ERROR("Group name must be a string\n"); 1199f46a6179Smrg ACTION1("Illegal name for group %d ignored\n",tmp.uval); 1200f46a6179Smrg return False; 1201f46a6179Smrg } 1202f46a6179Smrg info->groupNames[tmp.uval-1+info->explicit_group]= 1203f46a6179Smrg XkbInternAtom(NULL,name.str,False); 1204f46a6179Smrg 1205f46a6179Smrg return True; 1206f46a6179Smrg} 1207f46a6179Smrg 1208f46a6179Smrgstatic int 1209f46a6179SmrgHandleSymbolsVar(VarDef *stmt,XkbDescPtr xkb,SymbolsInfo *info) 1210f46a6179Smrg{ 1211f46a6179SmrgExprResult elem,field,tmp; 1212f46a6179SmrgExprDef * arrayNdx; 1213f46a6179Smrg 1214f46a6179Smrg if (ExprResolveLhs(stmt->name,&elem,&field,&arrayNdx)==0) 1215f46a6179Smrg return 0; /* internal error, already reported */ 1216f46a6179Smrg if (elem.str&&(uStrCaseCmp(elem.str,"key")==0)) { 1217f46a6179Smrg return SetSymbolsField(&info->dflt,xkb,field.str,arrayNdx,stmt->value, 1218f46a6179Smrg info); 1219f46a6179Smrg } 1220f46a6179Smrg else if ((elem.str==NULL)&&((uStrCaseCmp(field.str,"name")==0)|| 1221f46a6179Smrg (uStrCaseCmp(field.str,"groupname")==0))) { 1222f46a6179Smrg return SetGroupName(info,arrayNdx,stmt->value); 1223f46a6179Smrg } 1224f46a6179Smrg else if ((elem.str==NULL)&&((uStrCaseCmp(field.str,"groupswrap")==0)|| 1225f46a6179Smrg (uStrCaseCmp(field.str,"wrapgroups")==0))) { 1226f46a6179Smrg if (!ExprResolveBoolean(stmt->value,&tmp,NULL,NULL)) { 1227f46a6179Smrg ERROR("Illegal setting for global groupsWrap\n"); 1228f46a6179Smrg ACTION("Non-boolean value ignored\n"); 1229f46a6179Smrg return False; 1230f46a6179Smrg } 1231f46a6179Smrg if (tmp.uval) info->groupInfo= XkbWrapIntoRange; 1232f46a6179Smrg else info->groupInfo= XkbClampIntoRange; 1233f46a6179Smrg return True; 1234f46a6179Smrg } 1235f46a6179Smrg else if ((elem.str==NULL)&&((uStrCaseCmp(field.str,"groupsclamp")==0)|| 1236f46a6179Smrg (uStrCaseCmp(field.str,"clampgroups")==0))) { 1237f46a6179Smrg if (!ExprResolveBoolean(stmt->value,&tmp,NULL,NULL)) { 1238f46a6179Smrg ERROR("Illegal setting for global groupsClamp\n"); 1239f46a6179Smrg ACTION("Non-boolean value ignored\n"); 1240f46a6179Smrg return False; 1241f46a6179Smrg } 1242f46a6179Smrg if (tmp.uval) info->groupInfo= XkbClampIntoRange; 1243f46a6179Smrg else info->groupInfo= XkbWrapIntoRange; 1244f46a6179Smrg return True; 1245f46a6179Smrg } 1246f46a6179Smrg else if ((elem.str==NULL)&&((uStrCaseCmp(field.str,"groupsredirect")==0)|| 1247f46a6179Smrg (uStrCaseCmp(field.str,"redirectgroups")==0))) { 1248f46a6179Smrg if (!ExprResolveInteger(stmt->value,&tmp, 1249f46a6179Smrg SimpleLookup,(XPointer)groupNames)) { 1250f46a6179Smrg ERROR("Illegal group index for global groupsRedirect\n"); 1251f46a6179Smrg ACTION("Definition with non-integer group ignored\n"); 1252f46a6179Smrg return False; 1253f46a6179Smrg } 1254f46a6179Smrg if ((tmp.uval<1)||(tmp.uval>XkbNumKbdGroups)) { 1255f46a6179Smrg ERROR1("Out-of-range (1..%d) group for global groupsRedirect\n", 1256f46a6179Smrg XkbNumKbdGroups); 1257f46a6179Smrg ACTION1("Ignoring illegal group %d\n",tmp.uval); 1258f46a6179Smrg return False; 1259f46a6179Smrg } 1260f46a6179Smrg info->groupInfo= XkbSetGroupInfo(0,XkbRedirectIntoRange,tmp.uval); 1261f46a6179Smrg return True; 1262f46a6179Smrg } 1263f46a6179Smrg else if ((elem.str==NULL)&&(uStrCaseCmp(field.str,"allownone")==0)) { 1264f46a6179Smrg return SetAllowNone(&info->dflt,arrayNdx,stmt->value); 1265f46a6179Smrg } 1266f46a6179Smrg return SetActionField(xkb,elem.str,field.str,arrayNdx,stmt->value, 1267f46a6179Smrg &info->action); 1268f46a6179Smrg} 1269f46a6179Smrg 1270f46a6179Smrgstatic Bool 1271f46a6179SmrgHandleSymbolsBody( VarDef * def, 1272f46a6179Smrg XkbDescPtr xkb, 1273f46a6179Smrg KeyInfo * key, 1274f46a6179Smrg SymbolsInfo * info) 1275f46a6179Smrg{ 1276f46a6179SmrgBool ok= True; 1277f46a6179SmrgExprResult tmp,field; 1278f46a6179SmrgExprDef * arrayNdx; 1279f46a6179Smrg 1280f46a6179Smrg for (;def!=NULL;def= (VarDef *)def->common.next) { 1281f46a6179Smrg if ((def->name)&&(def->name->type==ExprFieldRef)) { 1282f46a6179Smrg ok= HandleSymbolsVar(def,xkb,info); 1283f46a6179Smrg continue; 1284f46a6179Smrg } 1285f46a6179Smrg else { 1286f46a6179Smrg if (def->name==NULL) { 1287f46a6179Smrg if ((def->value==NULL)||(def->value->op==ExprKeysymList)) 1288f46a6179Smrg field.str= "symbols"; 1289f46a6179Smrg else field.str= "actions"; 1290f46a6179Smrg arrayNdx= NULL; 1291f46a6179Smrg } 1292f46a6179Smrg else { 1293f46a6179Smrg ok= ExprResolveLhs(def->name,&tmp,&field,&arrayNdx); 1294f46a6179Smrg } 1295f46a6179Smrg if (ok) 1296f46a6179Smrg ok= SetSymbolsField(key,xkb,field.str,arrayNdx,def->value,info); 1297f46a6179Smrg } 1298f46a6179Smrg } 1299f46a6179Smrg return ok; 1300f46a6179Smrg} 1301f46a6179Smrg 1302f46a6179Smrgstatic Bool 1303f46a6179SmrgSetExplicitGroup( SymbolsInfo * info, 1304f46a6179Smrg KeyInfo * key) 1305f46a6179Smrg{ 1306f46a6179Smrg unsigned group = info->explicit_group; 1307f46a6179Smrg 1308f46a6179Smrg if (group == 0) 1309f46a6179Smrg return True; 1310f46a6179Smrg 1311f46a6179Smrg if ((key->typesDefined|key->symsDefined|key->actsDefined) & ~1) { 1312f46a6179Smrg int i; 1313f46a6179Smrg WARN1("For the map %s an explicit group specified\n", info->name); 1314f46a6179Smrg WARN1("but key %s has more than one group defined\n", 1315f46a6179Smrg longText(key->name,XkbMessage)); 1316f46a6179Smrg ACTION("All groups except first one will be ignored\n"); 1317f46a6179Smrg for (i = 1; i < XkbNumKbdGroups ; i++) { 1318f46a6179Smrg key->numLevels[i]= 0; 1319f46a6179Smrg if (key->syms[i]!=NULL) 1320f46a6179Smrg uFree(key->syms[i]); 1321f46a6179Smrg key->syms[i]= (KeySym*) NULL; 1322f46a6179Smrg if (key->acts[i]!=NULL) 1323f46a6179Smrg uFree(key->acts[i]); 1324f46a6179Smrg key->acts[i]= (XkbAction*) NULL; 1325f46a6179Smrg key->types[i]= (Atom) 0; 1326f46a6179Smrg } 1327f46a6179Smrg } 1328f46a6179Smrg key->typesDefined = key->symsDefined = key->actsDefined = 1 << group; 1329f46a6179Smrg 1330f46a6179Smrg key->numLevels[group]= key->numLevels[0]; 1331f46a6179Smrg key->numLevels[0]= 0; 1332f46a6179Smrg key->syms[group]= key->syms[0]; 1333f46a6179Smrg key->syms[0]= (KeySym*) NULL; 1334f46a6179Smrg key->acts[group]= key->acts[0]; 1335f46a6179Smrg key->acts[0]= (XkbAction*) NULL; 1336f46a6179Smrg key->types[group]= key->types[0]; 1337f46a6179Smrg key->types[0]= (Atom) 0; 1338f46a6179Smrg return True; 1339f46a6179Smrg} 1340f46a6179Smrg 1341f46a6179Smrgstatic int 1342f46a6179SmrgHandleSymbolsDef( SymbolsDef * stmt, 1343f46a6179Smrg XkbDescPtr xkb, 1344f46a6179Smrg unsigned merge, 1345f46a6179Smrg SymbolsInfo * info) 1346f46a6179Smrg{ 1347f46a6179SmrgKeyInfo key; 1348f46a6179Smrg 1349f46a6179Smrg InitKeyInfo(&key); 1350f46a6179Smrg CopyKeyInfo(&info->dflt,&key,False); 1351f46a6179Smrg key.defs.merge= stmt->merge; 1352f46a6179Smrg key.name= KeyNameToLong(stmt->keyName); 1353f46a6179Smrg if (!HandleSymbolsBody((VarDef *)stmt->symbols,xkb,&key,info)) { 1354f46a6179Smrg info->errorCount++; 1355f46a6179Smrg return False; 1356f46a6179Smrg } 1357f46a6179Smrg 1358f46a6179Smrg if (!SetExplicitGroup(info,&key)) { 1359f46a6179Smrg info->errorCount++; 1360f46a6179Smrg return False; 1361f46a6179Smrg } 1362f46a6179Smrg 1363f46a6179Smrg if (!AddKeySymbols(info,&key,xkb)) { 1364f46a6179Smrg info->errorCount++; 1365f46a6179Smrg return False; 1366f46a6179Smrg } 1367f46a6179Smrg return True; 1368f46a6179Smrg} 1369f46a6179Smrg 1370f46a6179Smrgstatic Bool 1371f46a6179SmrgHandleModMapDef( ModMapDef * def, 1372f46a6179Smrg XkbDescPtr xkb, 1373f46a6179Smrg unsigned merge, 1374f46a6179Smrg SymbolsInfo * info) 1375f46a6179Smrg{ 1376f46a6179SmrgExprDef * key; 1377f46a6179SmrgModMapEntry tmp; 1378f46a6179SmrgExprResult rtrn; 1379f46a6179SmrgBool ok; 1380f46a6179Smrg 1381f46a6179Smrg if (!LookupModIndex(NULL,None,def->modifier,TypeInt,&rtrn)) { 1382f46a6179Smrg ERROR("Illegal modifier map definition\n"); 1383f46a6179Smrg ACTION1("Ignoring map for non-modifier \"%s\"\n", 1384f46a6179Smrg XkbAtomText(NULL,def->modifier,XkbMessage)); 1385f46a6179Smrg return False; 1386f46a6179Smrg } 1387f46a6179Smrg ok= True; 1388f46a6179Smrg tmp.modifier= rtrn.uval; 1389f46a6179Smrg for (key=def->keys;key!=NULL;key=(ExprDef *)key->common.next) { 1390f46a6179Smrg if ((key->op==ExprValue)&&(key->type==TypeKeyName)) { 1391f46a6179Smrg tmp.haveSymbol= False; 1392f46a6179Smrg tmp.u.keyName= KeyNameToLong(key->value.keyName); 1393f46a6179Smrg } 1394f46a6179Smrg else if (ExprResolveKeySym(key,&rtrn,NULL,NULL)) { 1395f46a6179Smrg tmp.haveSymbol= True; 1396f46a6179Smrg tmp.u.keySym= rtrn.uval; 1397f46a6179Smrg } 1398f46a6179Smrg else { 1399f46a6179Smrg ERROR("Modmap entries may contain only key names or keysyms\n"); 1400f46a6179Smrg ACTION1("Illegal definition for %s modifier ignored\n", 1401f46a6179Smrg XkbModIndexText(tmp.modifier,XkbMessage)); 1402f46a6179Smrg continue; 1403f46a6179Smrg } 1404f46a6179Smrg 1405f46a6179Smrg ok= AddModMapEntry(info,&tmp)&&ok; 1406f46a6179Smrg } 1407f46a6179Smrg return ok; 1408f46a6179Smrg} 1409f46a6179Smrg 1410f46a6179Smrgstatic void 1411f46a6179SmrgHandleSymbolsFile( XkbFile * file, 1412f46a6179Smrg XkbDescPtr xkb, 1413f46a6179Smrg unsigned merge, 1414f46a6179Smrg SymbolsInfo * info) 1415f46a6179Smrg{ 1416f46a6179SmrgParseCommon *stmt; 1417f46a6179Smrg 1418f46a6179Smrg info->name= uStringDup(file->name); 1419f46a6179Smrg stmt= file->defs; 1420f46a6179Smrg while (stmt) { 1421f46a6179Smrg switch (stmt->stmtType) { 1422f46a6179Smrg case StmtInclude: 1423f46a6179Smrg if (!HandleIncludeSymbols((IncludeStmt *)stmt,xkb,info, 1424f46a6179Smrg HandleSymbolsFile)) 1425f46a6179Smrg info->errorCount++; 1426f46a6179Smrg break; 1427f46a6179Smrg case StmtSymbolsDef: 1428f46a6179Smrg if (!HandleSymbolsDef((SymbolsDef *)stmt,xkb,merge,info)) 1429f46a6179Smrg info->errorCount++; 1430f46a6179Smrg break; 1431f46a6179Smrg case StmtVarDef: 1432f46a6179Smrg if (!HandleSymbolsVar((VarDef *)stmt,xkb,info)) 1433f46a6179Smrg info->errorCount++; 1434f46a6179Smrg break; 1435f46a6179Smrg case StmtVModDef: 1436f46a6179Smrg if (!HandleVModDef((VModDef *)stmt,merge,&info->vmods)) 1437f46a6179Smrg info->errorCount++; 1438f46a6179Smrg break; 1439f46a6179Smrg case StmtInterpDef: 1440f46a6179Smrg ERROR("Interpretation files may not include other types\n"); 1441f46a6179Smrg ACTION("Ignoring definition of symbol interpretation\n"); 1442f46a6179Smrg info->errorCount++; 1443f46a6179Smrg break; 1444f46a6179Smrg case StmtKeycodeDef: 1445f46a6179Smrg ERROR("Interpretation files may not include other types\n"); 1446f46a6179Smrg ACTION("Ignoring definition of key name\n"); 1447f46a6179Smrg info->errorCount++; 1448f46a6179Smrg break; 1449f46a6179Smrg case StmtModMapDef: 1450f46a6179Smrg if (!HandleModMapDef((ModMapDef *)stmt,xkb,merge,info)) 1451f46a6179Smrg info->errorCount++; 1452f46a6179Smrg break; 1453f46a6179Smrg default: 1454f46a6179Smrg WSGO1("Unexpected statement type %d in HandleSymbolsFile\n", 1455f46a6179Smrg stmt->stmtType); 1456f46a6179Smrg break; 1457f46a6179Smrg } 1458f46a6179Smrg stmt= stmt->next; 1459f46a6179Smrg if (info->errorCount>10) { 1460f46a6179Smrg#ifdef NOISY 1461f46a6179Smrg ERROR("Too many errors\n"); 1462f46a6179Smrg#endif 1463f46a6179Smrg ACTION1("Abandoning symbols file \"%s\"\n",file->topName); 1464f46a6179Smrg break; 1465f46a6179Smrg } 1466f46a6179Smrg } 1467f46a6179Smrg return; 1468f46a6179Smrg} 1469f46a6179Smrg 1470f46a6179Smrgstatic Bool 1471f46a6179SmrgFindKeyForSymbol(XkbDescPtr xkb,KeySym sym,unsigned int *kc_rtrn) 1472f46a6179Smrg{ 1473f46a6179Smrgregister int i, j; 1474f46a6179Smrgregister Bool gotOne; 1475f46a6179Smrg 1476f46a6179Smrg j= 0; 1477f46a6179Smrg do { 1478f46a6179Smrg gotOne= False; 1479f46a6179Smrg for (i = xkb->min_key_code; i <= (int)xkb->max_key_code; i++) { 1480f46a6179Smrg if ( j<(int)XkbKeyNumSyms(xkb,i) ) { 1481f46a6179Smrg gotOne = True; 1482f46a6179Smrg if ((XkbKeySym(xkb,i,j)==sym)) { 1483f46a6179Smrg *kc_rtrn= i; 1484f46a6179Smrg return True; 1485f46a6179Smrg } 1486f46a6179Smrg } 1487f46a6179Smrg } 1488f46a6179Smrg j++; 1489f46a6179Smrg } while (gotOne); 1490f46a6179Smrg return False; 1491f46a6179Smrg} 1492f46a6179Smrg 1493f46a6179Smrgstatic Bool 1494f46a6179SmrgFindNamedType(XkbDescPtr xkb,Atom name,unsigned *type_rtrn) 1495f46a6179Smrg{ 1496f46a6179Smrgregister unsigned n; 1497f46a6179Smrg 1498f46a6179Smrg if (xkb&&xkb->map&&xkb->map->types) { 1499f46a6179Smrg for (n=0;n<xkb->map->num_types;n++) { 1500f46a6179Smrg if (xkb->map->types[n].name==(Atom)name) { 1501f46a6179Smrg *type_rtrn= n; 1502f46a6179Smrg return True; 1503f46a6179Smrg } 1504f46a6179Smrg } 1505f46a6179Smrg } 1506f46a6179Smrg return False; 1507f46a6179Smrg} 1508f46a6179Smrg 1509f46a6179Smrgstatic Bool 1510f46a6179SmrgKSIsLower (KeySym ks) 1511f46a6179Smrg{ 1512f46a6179Smrg KeySym lower, upper; 1513f46a6179Smrg XConvertCase(ks, &lower, &upper); 1514f46a6179Smrg 1515f46a6179Smrg if (lower == upper) 1516f46a6179Smrg return False; 1517f46a6179Smrg return (ks == lower ? True : False); 1518f46a6179Smrg} 1519f46a6179Smrg 1520f46a6179Smrgstatic Bool 1521f46a6179SmrgKSIsUpper (KeySym ks) 1522f46a6179Smrg{ 1523f46a6179Smrg KeySym lower, upper; 1524f46a6179Smrg XConvertCase(ks, &lower, &upper); 1525f46a6179Smrg 1526f46a6179Smrg if (lower == upper) 1527f46a6179Smrg return False; 1528f46a6179Smrg return (ks == upper ? True : False); 1529f46a6179Smrg} 1530f46a6179Smrg 1531f46a6179Smrgstatic Bool 1532f46a6179SmrgFindAutomaticType(int width,KeySym *syms,Atom *typeNameRtrn, Bool *autoType) 1533f46a6179Smrg{ 1534f46a6179Smrg *autoType = False; 1535f46a6179Smrg if ((width==1)||(width==0)) { 1536f46a6179Smrg *typeNameRtrn= XkbInternAtom(NULL,"ONE_LEVEL",False); 1537f46a6179Smrg *autoType = True; 1538f46a6179Smrg } else if (width == 2) { 1539f46a6179Smrg if ( syms && KSIsLower(syms[0]) && KSIsUpper(syms[1]) ) { 1540f46a6179Smrg *typeNameRtrn= XkbInternAtom(NULL,"ALPHABETIC",False); 1541f46a6179Smrg } else if ( syms && 1542f46a6179Smrg (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])) ) { 1543f46a6179Smrg *typeNameRtrn= XkbInternAtom(NULL,"KEYPAD",False); 1544f46a6179Smrg *autoType = True; 1545f46a6179Smrg } else { 1546f46a6179Smrg *typeNameRtrn= XkbInternAtom(NULL,"TWO_LEVEL",False); 1547f46a6179Smrg *autoType = True; 1548f46a6179Smrg } 1549f46a6179Smrg } else if (width <= 4 ) { 1550f46a6179Smrg if ( syms && KSIsLower(syms[0]) && KSIsUpper(syms[1]) ) 1551f46a6179Smrg if ( KSIsLower(syms[2]) && KSIsUpper(syms[3]) ) 1552f46a6179Smrg *typeNameRtrn= XkbInternAtom(NULL, 1553f46a6179Smrg "FOUR_LEVEL_ALPHABETIC",False); 1554f46a6179Smrg else 1555f46a6179Smrg *typeNameRtrn= XkbInternAtom(NULL, 1556f46a6179Smrg "FOUR_LEVEL_SEMIALPHABETIC",False); 1557f46a6179Smrg 1558f46a6179Smrg else if ( syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])) ) 1559f46a6179Smrg *typeNameRtrn= XkbInternAtom(NULL, 1560f46a6179Smrg "FOUR_LEVEL_KEYPAD",False); 1561f46a6179Smrg else *typeNameRtrn= XkbInternAtom(NULL,"FOUR_LEVEL",False); 1562f46a6179Smrg } 1563f46a6179Smrg return ((width>=0)&&(width<=4)); 1564f46a6179Smrg} 1565f46a6179Smrg 1566f46a6179Smrgstatic void 1567f46a6179SmrgPrepareKeyDef(KeyInfo *key) 1568f46a6179Smrg{ 1569f46a6179Smrg int i, j, width, defined, lastGroup; 1570f46a6179Smrg Bool identical; 1571f46a6179Smrg 1572f46a6179Smrg defined = key->symsDefined | key->actsDefined | key->typesDefined; 1573f46a6179Smrg for (i = XkbNumKbdGroups - 1; i >= 0; i--) { 1574f46a6179Smrg if (defined & (1<<i)) 1575f46a6179Smrg break; 1576f46a6179Smrg } 1577f46a6179Smrg lastGroup = i; 1578f46a6179Smrg 1579f46a6179Smrg if (lastGroup == 0) 1580f46a6179Smrg return; 1581f46a6179Smrg 1582f46a6179Smrg /* If there are empty groups between non-empty ones fill them with data */ 1583f46a6179Smrg /* from the first group. */ 1584f46a6179Smrg /* We can make a wrong assumption here. But leaving gaps is worse. */ 1585f46a6179Smrg for (i = lastGroup; i > 0; i--) { 1586f46a6179Smrg if (defined & (1<<i)) 1587f46a6179Smrg continue; 1588f46a6179Smrg width = key->numLevels[0]; 1589f46a6179Smrg if (key->typesDefined & 1) { 1590f46a6179Smrg for (j = 0; j < width; j++) { 1591f46a6179Smrg key->types[i] = key->types[0]; 1592f46a6179Smrg } 1593f46a6179Smrg key->typesDefined |= 1 << i; 1594f46a6179Smrg } 1595f46a6179Smrg if ((key->actsDefined & 1) && key->acts[0]) { 1596f46a6179Smrg key->acts[i]= uTypedCalloc(width, XkbAction); 1597f46a6179Smrg if (key->acts[i] == NULL) 1598f46a6179Smrg continue; 1599f46a6179Smrg memcpy((void *) key->acts[i], (void *) key->acts[0], 1600f46a6179Smrg width * sizeof(XkbAction)); 1601f46a6179Smrg key->actsDefined |= 1 << i; 1602f46a6179Smrg } 1603f46a6179Smrg if ((key->symsDefined & 1) && key->syms[0]) { 1604f46a6179Smrg key->syms[i]= uTypedCalloc(width, KeySym); 1605f46a6179Smrg if (key->syms[i] == NULL) 1606f46a6179Smrg continue; 1607f46a6179Smrg memcpy((void *) key->syms[i], (void *) key->syms[0], 1608f46a6179Smrg width * sizeof(KeySym)); 1609f46a6179Smrg key->symsDefined |= 1 << i; 1610f46a6179Smrg } 1611f46a6179Smrg if (defined & 1) { 1612f46a6179Smrg key->numLevels[i] = key->numLevels[0]; 1613f46a6179Smrg } 1614f46a6179Smrg } 1615f46a6179Smrg /* If all groups are completely identical remove them all */ 1616f46a6179Smrg /* exept the first one. */ 1617f46a6179Smrg identical = True; 1618f46a6179Smrg for (i = lastGroup; i > 0; i--) { 1619f46a6179Smrg if ((key->numLevels[i] != key->numLevels[0]) || 1620f46a6179Smrg (key->types[i] != key->types[0])) { 1621f46a6179Smrg identical = False; 1622f46a6179Smrg break; 1623f46a6179Smrg } 1624f46a6179Smrg if ((key->syms[i] != key->syms[0]) && 1625f46a6179Smrg (key->syms[i] == NULL || key->syms[0] == NULL || 1626f46a6179Smrg memcmp((void*) key->syms[i], (void*) key->syms[0], 1627f46a6179Smrg sizeof(KeySym) * key->numLevels[0])) ) { 1628f46a6179Smrg identical = False; 1629f46a6179Smrg break; 1630f46a6179Smrg } 1631f46a6179Smrg if ((key->acts[i] != key->acts[0]) && 1632f46a6179Smrg (key->acts[i] == NULL || key->acts[0] == NULL || 1633f46a6179Smrg memcmp((void*) key->acts[i], (void*) key->acts[0], 1634f46a6179Smrg sizeof(XkbAction) * key->numLevels[0]))) { 1635f46a6179Smrg identical = False; 1636f46a6179Smrg break; 1637f46a6179Smrg } 1638f46a6179Smrg } 1639f46a6179Smrg if (identical) { 1640f46a6179Smrg for (i = lastGroup; i > 0; i--) { 1641f46a6179Smrg key->numLevels[i]= 0; 1642f46a6179Smrg if (key->syms[i] != NULL) 1643f46a6179Smrg uFree(key->syms[i]); 1644f46a6179Smrg key->syms[i]= (KeySym*) NULL; 1645f46a6179Smrg if (key->acts[i] != NULL) 1646f46a6179Smrg uFree(key->acts[i]); 1647f46a6179Smrg key->acts[i]= (XkbAction*) NULL; 1648f46a6179Smrg key->types[i]= (Atom) 0; 1649f46a6179Smrg } 1650f46a6179Smrg key->symsDefined &= 1; 1651f46a6179Smrg key->actsDefined &= 1; 1652f46a6179Smrg key->typesDefined &= 1; 1653f46a6179Smrg } 1654f46a6179Smrg return; 1655f46a6179Smrg} 1656f46a6179Smrg 1657f46a6179Smrgstatic Bool 1658f46a6179SmrgCopySymbolsDef(XkbFileInfo *result,KeyInfo *key,int start_from) 1659f46a6179Smrg{ 1660f46a6179Smrgregister int i; 1661f46a6179Smrgunsigned okc,kc,width,tmp,nGroups; 1662f46a6179SmrgXkbKeyTypePtr type; 1663f46a6179SmrgBool haveActions,autoType,useAlias; 1664f46a6179SmrgKeySym * outSyms; 1665f46a6179SmrgXkbAction * outActs; 1666f46a6179SmrgXkbDescPtr xkb; 1667f46a6179Smrgunsigned types[XkbNumKbdGroups]; 1668f46a6179Smrg 1669f46a6179Smrg xkb= result->xkb; 1670f46a6179Smrg useAlias= (start_from==0); 1671f46a6179Smrg if (!FindNamedKey(xkb,key->name,&kc,useAlias,CreateKeyNames(xkb), 1672f46a6179Smrg start_from)) { 1673f46a6179Smrg if ((start_from==0)&&(warningLevel>=5)) { 1674f46a6179Smrg WARN2("Key %s not found in %s keycodes\n", 1675f46a6179Smrg longText(key->name,XkbMessage), 1676f46a6179Smrg XkbAtomText(NULL,xkb->names->keycodes,XkbMessage)); 1677f46a6179Smrg ACTION("Symbols ignored\n"); 1678f46a6179Smrg } 1679f46a6179Smrg return False; 1680f46a6179Smrg } 1681f46a6179Smrg 1682f46a6179Smrg haveActions= False; 1683f46a6179Smrg for (i=width=nGroups=0;i<XkbNumKbdGroups;i++) { 1684f46a6179Smrg if (((i+1)>nGroups)&&(((key->symsDefined|key->actsDefined)&(1<<i))|| 1685f46a6179Smrg (key->typesDefined)&(1<<i))) 1686f46a6179Smrg nGroups= i+1; 1687f46a6179Smrg if (key->acts[i]) 1688f46a6179Smrg haveActions= True; 1689f46a6179Smrg autoType= False; 1690f46a6179Smrg if (key->types[i]==None) { 1691f46a6179Smrg if (key->dfltType!=None) 1692f46a6179Smrg key->types[i]= key->dfltType; 1693f46a6179Smrg else if (FindAutomaticType(key->numLevels[i],key->syms[i], 1694f46a6179Smrg &key->types[i], &autoType)) { 1695f46a6179Smrg } 1696f46a6179Smrg else { 1697f46a6179Smrg if (warningLevel>=5) { 1698f46a6179Smrg WARN1("No automatic type for %d symbols\n", 1699f46a6179Smrg (unsigned int)key->numLevels[i]); 1700f46a6179Smrg ACTION3("Using %s for the %s key (keycode %d)\n", 1701f46a6179Smrg XkbAtomText(NULL,key->types[i],XkbMessage), 1702f46a6179Smrg longText(key->name,XkbMessage),kc); 1703f46a6179Smrg } 1704f46a6179Smrg } 1705f46a6179Smrg } 1706f46a6179Smrg if (FindNamedType(xkb,key->types[i],&types[i])) { 1707f46a6179Smrg if (!autoType || key->numLevels[i] > 2) 1708f46a6179Smrg xkb->server->explicit[kc]|= (1<<i); 1709f46a6179Smrg } 1710f46a6179Smrg else { 1711f46a6179Smrg if (warningLevel>=3) { 1712f46a6179Smrg WARN1("Type \"%s\" is not defined\n", 1713f46a6179Smrg XkbAtomText(NULL,key->types[i],XkbMessage)); 1714f46a6179Smrg ACTION2("Using TWO_LEVEL for the %s key (keycode %d)\n", 1715f46a6179Smrg longText(key->name,XkbMessage),kc); 1716f46a6179Smrg } 1717f46a6179Smrg types[i]= XkbTwoLevelIndex; 1718f46a6179Smrg } 1719f46a6179Smrg type= &xkb->map->types[types[i]]; 1720f46a6179Smrg if (type->num_levels<key->numLevels[i]) { 1721f46a6179Smrg if (warningLevel>0) { 1722f46a6179Smrg WARN4("Type \"%s\" has %d levels, but %s has %d symbols\n", 1723f46a6179Smrg XkbAtomText(NULL,type->name,XkbMessage), 1724f46a6179Smrg (unsigned int)type->num_levels, 1725f46a6179Smrg longText(key->name,XkbMessage), 1726f46a6179Smrg (unsigned int)key->numLevels[i]); 1727f46a6179Smrg ACTION("Ignoring extra symbols\n"); 1728f46a6179Smrg } 1729f46a6179Smrg key->numLevels[i]= type->num_levels; 1730f46a6179Smrg } 1731f46a6179Smrg if (key->numLevels[i]>width) 1732f46a6179Smrg width= key->numLevels[i]; 1733f46a6179Smrg if (type->num_levels>width) 1734f46a6179Smrg width= type->num_levels; 1735f46a6179Smrg } 1736f46a6179Smrg 1737f46a6179Smrg i= width*nGroups; 1738f46a6179Smrg outSyms= XkbResizeKeySyms(xkb,kc,i); 1739f46a6179Smrg if (outSyms==NULL) { 1740f46a6179Smrg WSGO2("Could not enlarge symbols for %s (keycode %d)\n", 1741f46a6179Smrg longText(key->name,XkbMessage),kc); 1742f46a6179Smrg return False; 1743f46a6179Smrg } 1744f46a6179Smrg if (haveActions) { 1745f46a6179Smrg outActs= XkbResizeKeyActions(xkb,kc,i); 1746f46a6179Smrg if (outActs==NULL) { 1747f46a6179Smrg WSGO2("Could not enlarge actions for %s (key %d)\n", 1748f46a6179Smrg longText(key->name,XkbMessage),kc); 1749f46a6179Smrg return False; 1750f46a6179Smrg } 1751f46a6179Smrg xkb->server->explicit[kc]|= XkbExplicitInterpretMask; 1752f46a6179Smrg } 1753f46a6179Smrg else outActs= NULL; 1754f46a6179Smrg if (key->defs.defined&_Key_GroupInfo) 1755f46a6179Smrg i= key->groupInfo; 1756f46a6179Smrg else i= xkb->map->key_sym_map[kc].group_info; 1757f46a6179Smrg xkb->map->key_sym_map[kc].group_info= XkbSetNumGroups(i,nGroups); 1758f46a6179Smrg xkb->map->key_sym_map[kc].width= width; 1759f46a6179Smrg for (i=0;i<nGroups;i++) { 1760f46a6179Smrg xkb->map->key_sym_map[kc].kt_index[i]= types[i]; 1761f46a6179Smrg if (key->syms[i]!=NULL) { 1762f46a6179Smrg for (tmp=0;tmp<width;tmp++) { 1763f46a6179Smrg if (tmp<key->numLevels[i]) 1764f46a6179Smrg outSyms[tmp]= key->syms[i][tmp]; 1765f46a6179Smrg else outSyms[tmp]= NoSymbol; 1766f46a6179Smrg if ((outActs!=NULL)&&(key->acts[i]!=NULL)) { 1767f46a6179Smrg if (tmp<key->numLevels[i]) 1768f46a6179Smrg outActs[tmp]= key->acts[i][tmp]; 1769f46a6179Smrg else outActs[tmp].type= XkbSA_NoAction; 1770f46a6179Smrg } 1771f46a6179Smrg } 1772f46a6179Smrg } 1773f46a6179Smrg outSyms+= width; 1774f46a6179Smrg if (outActs) 1775f46a6179Smrg outActs+= width; 1776f46a6179Smrg } 1777f46a6179Smrg switch (key->behavior.type&XkbKB_OpMask) { 1778f46a6179Smrg case XkbKB_Default: 1779f46a6179Smrg break; 1780f46a6179Smrg case XkbKB_Overlay1: 1781f46a6179Smrg case XkbKB_Overlay2: 1782f46a6179Smrg /* find key by name! */ 1783f46a6179Smrg if (!FindNamedKey(xkb,key->nameForOverlayKey,&okc,True, 1784f46a6179Smrg CreateKeyNames(xkb),0)) { 1785f46a6179Smrg if (warningLevel>=1) { 1786f46a6179Smrg WARN2("Key %s not found in %s keycodes\n", 1787f46a6179Smrg longText(key->nameForOverlayKey,XkbMessage), 1788f46a6179Smrg XkbAtomText(NULL,xkb->names->keycodes,XkbMessage)); 1789f46a6179Smrg ACTION1("Not treating %s as an overlay key \n", 1790f46a6179Smrg longText(key->name,XkbMessage)); 1791f46a6179Smrg } 1792f46a6179Smrg break; 1793f46a6179Smrg } 1794f46a6179Smrg key->behavior.data= okc; 1795f46a6179Smrg default: 1796f46a6179Smrg xkb->server->behaviors[kc]= key->behavior; 1797f46a6179Smrg xkb->server->explicit[kc]|= XkbExplicitBehaviorMask; 1798f46a6179Smrg break; 1799f46a6179Smrg } 1800f46a6179Smrg if (key->defs.defined&_Key_VModMap) { 1801f46a6179Smrg xkb->server->vmodmap[kc]= key->vmodmap; 1802f46a6179Smrg xkb->server->explicit[kc]|= XkbExplicitVModMapMask; 1803f46a6179Smrg } 1804f46a6179Smrg if (key->repeat!=RepeatUndefined) { 1805f46a6179Smrg if (key->repeat==RepeatYes) 1806f46a6179Smrg xkb->ctrls->per_key_repeat[kc/8]|= (1<<(kc%8)); 1807f46a6179Smrg else xkb->ctrls->per_key_repeat[kc/8]&= ~(1<<(kc%8)); 1808f46a6179Smrg xkb->server->explicit[kc]|= XkbExplicitAutoRepeatMask; 1809f46a6179Smrg } 1810f46a6179Smrg CopySymbolsDef(result,key,kc+1); 1811f46a6179Smrg return True; 1812f46a6179Smrg} 1813f46a6179Smrg 1814f46a6179Smrgstatic Bool 1815f46a6179SmrgCopyModMapDef(XkbFileInfo *result,ModMapEntry *entry) 1816f46a6179Smrg{ 1817f46a6179Smrgunsigned kc; 1818f46a6179SmrgXkbDescPtr xkb; 1819f46a6179Smrg 1820f46a6179Smrg xkb= result->xkb; 1821f46a6179Smrg if ((!entry->haveSymbol)&&(!FindNamedKey(xkb,entry->u.keyName,&kc,True, 1822f46a6179Smrg CreateKeyNames(xkb),0))) { 1823f46a6179Smrg if (warningLevel>=5) { 1824f46a6179Smrg WARN2("Key %s not found in %s keycodes\n", 1825f46a6179Smrg longText(entry->u.keyName,XkbMessage), 1826f46a6179Smrg XkbAtomText(NULL,xkb->names->keycodes,XkbMessage)); 1827f46a6179Smrg ACTION1("Modifier map entry for %s not updated\n", 1828f46a6179Smrg XkbModIndexText(entry->modifier,XkbMessage)); 1829f46a6179Smrg } 1830f46a6179Smrg return False; 1831f46a6179Smrg } 1832f46a6179Smrg else if (entry->haveSymbol&&(!FindKeyForSymbol(xkb,entry->u.keySym,&kc))) { 1833f46a6179Smrg if (warningLevel>5) { 1834f46a6179Smrg WARN2("Key \"%s\" not found in %s symbol map\n", 1835f46a6179Smrg XkbKeysymText(entry->u.keySym,XkbMessage), 1836f46a6179Smrg XkbAtomText(NULL,xkb->names->symbols,XkbMessage)); 1837f46a6179Smrg ACTION1("Modifier map entry for %s not updated\n", 1838f46a6179Smrg XkbModIndexText(entry->modifier,XkbMessage)); 1839f46a6179Smrg } 1840f46a6179Smrg return False; 1841f46a6179Smrg } 1842f46a6179Smrg xkb->map->modmap[kc]|= (1<<entry->modifier); 1843f46a6179Smrg return True; 1844f46a6179Smrg} 1845f46a6179Smrg 1846f46a6179SmrgBool 1847f46a6179SmrgCompileSymbols(XkbFile *file,XkbFileInfo *result,unsigned merge) 1848f46a6179Smrg{ 1849f46a6179Smrgregister int i; 1850f46a6179SmrgSymbolsInfo info; 1851f46a6179SmrgXkbDescPtr xkb; 1852f46a6179Smrg 1853f46a6179Smrg xkb= result->xkb; 1854f46a6179Smrg InitSymbolsInfo(&info,xkb); 1855f46a6179Smrg info.dflt.defs.fileID= file->id; 1856f46a6179Smrg info.dflt.defs.merge= merge; 1857f46a6179Smrg HandleSymbolsFile(file,xkb,merge,&info); 1858f46a6179Smrg 1859f46a6179Smrg if (info.nKeys == 0) 1860f46a6179Smrg return True; 1861f46a6179Smrg if (info.errorCount==0) { 1862f46a6179Smrg KeyInfo *key; 1863f46a6179Smrg if (XkbAllocNames(xkb,XkbSymbolsNameMask|XkbGroupNamesMask,0,0) 1864f46a6179Smrg !=Success) { 1865f46a6179Smrg WSGO("Can not allocate names in CompileSymbols\n"); 1866f46a6179Smrg ACTION("Symbols not added\n"); 1867f46a6179Smrg return False; 1868f46a6179Smrg } 1869f46a6179Smrg if(XkbAllocClientMap(xkb,XkbKeySymsMask|XkbModifierMapMask,0)!=Success){ 1870f46a6179Smrg WSGO("Could not allocate client map in CompileSymbols\n"); 1871f46a6179Smrg ACTION("Symbols not added\n"); 1872f46a6179Smrg return False; 1873f46a6179Smrg } 1874f46a6179Smrg if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,32)!=Success) { 1875f46a6179Smrg WSGO("Could not allocate server map in CompileSymbols\n"); 1876f46a6179Smrg ACTION("Symbols not added\n"); 1877f46a6179Smrg return False; 1878f46a6179Smrg } 1879f46a6179Smrg if (XkbAllocControls(xkb,XkbPerKeyRepeatMask)!=Success) { 1880f46a6179Smrg WSGO("Could not allocate controls in CompileSymbols\n"); 1881f46a6179Smrg ACTION("Symbols not added\n"); 1882f46a6179Smrg return False; 1883f46a6179Smrg } 1884f46a6179Smrg xkb->names->symbols= XkbInternAtom(xkb->dpy,info.name,False); 1885f46a6179Smrg if (info.aliases) 1886f46a6179Smrg ApplyAliases(xkb,False,&info.aliases); 1887f46a6179Smrg for (i=0;i<XkbNumKbdGroups;i++) { 1888f46a6179Smrg if (info.groupNames[i]!=None) 1889f46a6179Smrg xkb->names->groups[i]= info.groupNames[i]; 1890f46a6179Smrg } 1891f46a6179Smrg for (key=info.keys,i=0;i<info.nKeys;i++,key++) { 1892f46a6179Smrg PrepareKeyDef(key); 1893f46a6179Smrg } 1894f46a6179Smrg for (key=info.keys,i=0;i<info.nKeys;i++,key++) { 1895f46a6179Smrg if (!CopySymbolsDef(result,key,0)) 1896f46a6179Smrg info.errorCount++; 1897f46a6179Smrg } 1898f46a6179Smrg if (warningLevel>3) { 1899f46a6179Smrg for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 1900f46a6179Smrg if (xkb->names->keys[i].name[0]=='\0') 1901f46a6179Smrg continue; 1902f46a6179Smrg if (XkbKeyNumGroups(xkb,i)<1) { 1903f46a6179Smrg char buf[5]; 1904f46a6179Smrg memcpy(buf,xkb->names->keys[i].name,4); 1905f46a6179Smrg buf[4]= '\0'; 1906f46a6179Smrg WARN2("No symbols defined for <%s> (keycode %d)\n",buf,i); 1907f46a6179Smrg } 1908f46a6179Smrg } 1909f46a6179Smrg } 1910f46a6179Smrg if (info.modMap) { 1911f46a6179Smrg ModMapEntry *mm,*next; 1912f46a6179Smrg for (mm=info.modMap;mm!=NULL;mm=next) { 1913f46a6179Smrg if (!CopyModMapDef(result,mm)) 1914f46a6179Smrg info.errorCount++; 1915f46a6179Smrg next= (ModMapEntry *)mm->defs.next; 1916f46a6179Smrg } 1917f46a6179Smrg } 1918f46a6179Smrg return True; 1919f46a6179Smrg } 1920f46a6179Smrg return False; 1921f46a6179Smrg} 1922