diff options
Diffstat (limited to 'xkbcomp/compat.c')
-rw-r--r-- | xkbcomp/compat.c | 1318 |
1 files changed, 709 insertions, 609 deletions
diff --git a/xkbcomp/compat.c b/xkbcomp/compat.c index 00eb72b81..03c29efdc 100644 --- a/xkbcomp/compat.c +++ b/xkbcomp/compat.c @@ -1,4 +1,3 @@ -/* $Xorg: compat.c,v 1.3 2000/08/17 19:54:30 cpqbld Exp $ */ /************************************************************ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. @@ -24,7 +23,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. ********************************************************/ -/* $XFree86: xc/programs/xkbcomp/compat.c,v 3.3 2001/01/17 23:45:43 dawes Exp $ */ #include <X11/Xos.h> #include "xkbcomp.h" @@ -34,10 +32,12 @@ #include "misc.h" #include "indicators.h" #include "action.h" +#include "compat.h" -typedef struct _SymInterpInfo { - CommonInfo defs; - XkbSymInterpretRec interp; +typedef struct _SymInterpInfo +{ + CommonInfo defs; + XkbSymInterpretRec interp; } SymInterpInfo; #define _SI_VirtualMod (1<<0) @@ -46,26 +46,28 @@ typedef struct _SymInterpInfo { #define _SI_LockingKey (1<<3) #define _SI_LevelOneOnly (1<<4) -typedef struct _GroupCompatInfo { - unsigned char fileID; - unsigned char merge; - unsigned char real_mods; - unsigned short vmods; +typedef struct _GroupCompatInfo +{ + unsigned char fileID; + unsigned char merge; + unsigned char real_mods; + unsigned short vmods; } GroupCompatInfo; -typedef struct _CompatInfo { - char * name; - unsigned fileID; - int errorCount; - int nInterps; - SymInterpInfo * interps; - SymInterpInfo dflt; - LEDInfo ledDflt; - GroupCompatInfo groupCompat[XkbNumKbdGroups]; - LEDInfo * leds; - VModInfo vmods; - ActionInfo * act; - XkbDescPtr xkb; +typedef struct _CompatInfo +{ + char *name; + unsigned fileID; + int errorCount; + int nInterps; + SymInterpInfo *interps; + SymInterpInfo dflt; + LEDInfo ledDflt; + GroupCompatInfo groupCompat[XkbNumKbdGroups]; + LEDInfo *leds; + VModInfo vmods; + ActionInfo *act; + XkbDescPtr xkb; } CompatInfo; /***====================================================================***/ @@ -78,234 +80,265 @@ typedef struct _CompatInfo { /***====================================================================***/ static char * -siText(SymInterpInfo * si,CompatInfo * info) +siText(SymInterpInfo * si, CompatInfo * info) { -static char buf[128]; + static char buf[128]; - if (si==&info->dflt) { - sprintf(buf,"default"); + if (si == &info->dflt) + { + snprintf(buf, sizeof(buf), "default"); } - else { - sprintf(buf,"%s+%s(%s)",XkbKeysymText(si->interp.sym,XkbMessage), - XkbSIMatchText(si->interp.match,XkbMessage), - XkbModMaskText(si->interp.mods,XkbMessage)); + else + { + snprintf(buf, sizeof(buf), "%s+%s(%s)", + XkbKeysymText(si->interp.sym, XkbMessage), + XkbSIMatchText(si->interp.match, XkbMessage), + XkbModMaskText(si->interp.mods, XkbMessage)); } return buf; } static void -InitCompatInfo(CompatInfo *info,XkbDescPtr xkb) +InitCompatInfo(CompatInfo * info, XkbDescPtr xkb) { -register int i; - - info->xkb= xkb; - info->name= NULL; - info->fileID= 0; - info->errorCount= 0; - info->nInterps= 0; - info->interps= NULL; - info->act= NULL; - info->dflt.defs.fileID= info->fileID; - info->dflt.defs.defined= 0; - info->dflt.defs.merge= MergeOverride; - info->dflt.interp.flags= 0; - info->dflt.interp.virtual_mod= XkbNoModifier; - info->dflt.interp.act.type= XkbSA_NoAction; - for (i=0;i<XkbAnyActionDataSize;i++) { - info->dflt.interp.act.data[i]= 0; - } - ClearIndicatorMapInfo(xkb->dpy,&info->ledDflt); - info->ledDflt.defs.fileID= info->fileID; - info->ledDflt.defs.defined= 0; - info->ledDflt.defs.merge= MergeOverride; - bzero((char *)&info->groupCompat[0],XkbNumKbdGroups*sizeof(GroupCompatInfo)); - info->leds= NULL; - InitVModInfo(&info->vmods,xkb); + register int i; + + info->xkb = xkb; + info->name = NULL; + info->fileID = 0; + info->errorCount = 0; + info->nInterps = 0; + info->interps = NULL; + info->act = NULL; + info->dflt.defs.fileID = info->fileID; + info->dflt.defs.defined = 0; + info->dflt.defs.merge = MergeOverride; + info->dflt.interp.flags = 0; + info->dflt.interp.virtual_mod = XkbNoModifier; + info->dflt.interp.act.type = XkbSA_NoAction; + for (i = 0; i < XkbAnyActionDataSize; i++) + { + info->dflt.interp.act.data[i] = 0; + } + ClearIndicatorMapInfo(xkb->dpy, &info->ledDflt); + info->ledDflt.defs.fileID = info->fileID; + info->ledDflt.defs.defined = 0; + info->ledDflt.defs.merge = MergeOverride; + bzero((char *) &info->groupCompat[0], + XkbNumKbdGroups * sizeof(GroupCompatInfo)); + info->leds = NULL; + InitVModInfo(&info->vmods, xkb); return; } static void -ClearCompatInfo(CompatInfo *info,XkbDescPtr xkb) +ClearCompatInfo(CompatInfo * info, XkbDescPtr xkb) { -register int i; - - if (info->name!=NULL) - uFree(info->name); - info->name= NULL; - info->dflt.defs.defined= 0; - info->dflt.defs.merge= MergeAugment; - info->dflt.interp.flags= 0; - info->dflt.interp.virtual_mod= XkbNoModifier; - info->dflt.interp.act.type= XkbSA_NoAction; - for (i=0;i<XkbAnyActionDataSize;i++) { - info->dflt.interp.act.data[i]= 0; - } - ClearIndicatorMapInfo(xkb->dpy,&info->ledDflt); - info->nInterps= 0; - info->interps= (SymInterpInfo *)ClearCommonInfo(&info->interps->defs); - bzero((char *)&info->groupCompat[0],XkbNumKbdGroups*sizeof(GroupCompatInfo)); - info->leds= (LEDInfo *)ClearCommonInfo(&info->leds->defs); + register int i; + + if (info->name != NULL) + uFree(info->name); + info->name = NULL; + info->dflt.defs.defined = 0; + info->dflt.defs.merge = MergeAugment; + info->dflt.interp.flags = 0; + info->dflt.interp.virtual_mod = XkbNoModifier; + info->dflt.interp.act.type = XkbSA_NoAction; + for (i = 0; i < XkbAnyActionDataSize; i++) + { + info->dflt.interp.act.data[i] = 0; + } + ClearIndicatorMapInfo(xkb->dpy, &info->ledDflt); + info->nInterps = 0; + info->interps = (SymInterpInfo *) ClearCommonInfo(&info->interps->defs); + bzero((char *) &info->groupCompat[0], + XkbNumKbdGroups * sizeof(GroupCompatInfo)); + info->leds = (LEDInfo *) ClearCommonInfo(&info->leds->defs); /* 3/30/94 (ef) -- XXX! Should free action info here */ - ClearVModInfo(&info->vmods,xkb); + ClearVModInfo(&info->vmods, xkb); return; } static SymInterpInfo * -NextInterp(CompatInfo *info) +NextInterp(CompatInfo * info) { -SymInterpInfo * si; + SymInterpInfo *si; - si= uTypedAlloc(SymInterpInfo); - if (si) { - bzero((char *)si,sizeof(SymInterpInfo)); - info->interps= (SymInterpInfo *)AddCommonInfo(&info->interps->defs, - (CommonInfo *)si); - info->nInterps++; + si = uTypedAlloc(SymInterpInfo); + if (si) + { + bzero((char *) si, sizeof(SymInterpInfo)); + info->interps = + (SymInterpInfo *) AddCommonInfo(&info->interps->defs, + (CommonInfo *) si); + info->nInterps++; } return si; } static SymInterpInfo * -FindMatchingInterp(CompatInfo *info,SymInterpInfo *new) +FindMatchingInterp(CompatInfo * info, SymInterpInfo * new) { -SymInterpInfo * old; - - for (old= info->interps;old!=NULL;old=(SymInterpInfo *)old->defs.next) { - if ((old->interp.sym==new->interp.sym)&& - (old->interp.mods==new->interp.mods)&& - (old->interp.match==new->interp.match)) { - return old; - } + SymInterpInfo *old; + + for (old = info->interps; old != NULL; + old = (SymInterpInfo *) old->defs.next) + { + if ((old->interp.sym == new->interp.sym) && + (old->interp.mods == new->interp.mods) && + (old->interp.match == new->interp.match)) + { + return old; + } } return NULL; } static Bool -AddInterp(CompatInfo *info,SymInterpInfo *new) +AddInterp(CompatInfo * info, SymInterpInfo * new) { -unsigned collide; -SymInterpInfo * old; - - collide= 0; - old= FindMatchingInterp(info,new); - if (old!=NULL) { - if (new->defs.merge==MergeReplace) { - SymInterpInfo *next= (SymInterpInfo *)old->defs.next; - if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| - (warningLevel>9)) { - WARN1("Multiple definitions for \"%s\"\n",siText(new,info)); - ACTION("Earlier interpretation ignored\n"); - } - *old= *new; - old->defs.next= &next->defs; - return True; - } - if (UseNewField(_SI_VirtualMod,&old->defs,&new->defs,&collide)) { - old->interp.virtual_mod= new->interp.virtual_mod; - old->defs.defined|= _SI_VirtualMod; - } - if (UseNewField(_SI_Action,&old->defs,&new->defs,&collide)) { - old->interp.act= new->interp.act; - old->defs.defined|= _SI_Action; - } - if (UseNewField(_SI_AutoRepeat,&old->defs,&new->defs,&collide)) { - old->interp.flags&= ~XkbSI_AutoRepeat; - old->interp.flags|= (new->interp.flags&XkbSI_AutoRepeat); - old->defs.defined|= _SI_AutoRepeat; - } - if (UseNewField(_SI_LockingKey,&old->defs,&new->defs,&collide)) { - old->interp.flags&= ~XkbSI_LockingKey; - old->interp.flags|= (new->interp.flags&XkbSI_LockingKey); - old->defs.defined|= _SI_LockingKey; - } - if (UseNewField(_SI_LevelOneOnly,&old->defs,&new->defs,&collide)) { - old->interp.match&= ~XkbSI_LevelOneOnly; - old->interp.match|= (new->interp.match&XkbSI_LevelOneOnly); - old->defs.defined|= _SI_LevelOneOnly; - } - if (collide) { - WARN1("Multiple interpretations of \"%s\"\n",siText(new,info)); - ACTION1("Using %s definition for duplicate fields\n", - (new->defs.merge!=MergeAugment?"last":"first")); - } - return True; - } - old= new; - if ((new= NextInterp(info))==NULL) - return False; - *new= *old; - new->defs.next= NULL; + unsigned collide; + SymInterpInfo *old; + + collide = 0; + old = FindMatchingInterp(info, new); + if (old != NULL) + { + if (new->defs.merge == MergeReplace) + { + SymInterpInfo *next = (SymInterpInfo *) old->defs.next; + if (((old->defs.fileID == new->defs.fileID) + && (warningLevel > 0)) || (warningLevel > 9)) + { + WARN1("Multiple definitions for \"%s\"\n", siText(new, info)); + ACTION("Earlier interpretation ignored\n"); + } + *old = *new; + old->defs.next = &next->defs; + return True; + } + if (UseNewField(_SI_VirtualMod, &old->defs, &new->defs, &collide)) + { + old->interp.virtual_mod = new->interp.virtual_mod; + old->defs.defined |= _SI_VirtualMod; + } + if (UseNewField(_SI_Action, &old->defs, &new->defs, &collide)) + { + old->interp.act = new->interp.act; + old->defs.defined |= _SI_Action; + } + if (UseNewField(_SI_AutoRepeat, &old->defs, &new->defs, &collide)) + { + old->interp.flags &= ~XkbSI_AutoRepeat; + old->interp.flags |= (new->interp.flags & XkbSI_AutoRepeat); + old->defs.defined |= _SI_AutoRepeat; + } + if (UseNewField(_SI_LockingKey, &old->defs, &new->defs, &collide)) + { + old->interp.flags &= ~XkbSI_LockingKey; + old->interp.flags |= (new->interp.flags & XkbSI_LockingKey); + old->defs.defined |= _SI_LockingKey; + } + if (UseNewField(_SI_LevelOneOnly, &old->defs, &new->defs, &collide)) + { + old->interp.match &= ~XkbSI_LevelOneOnly; + old->interp.match |= (new->interp.match & XkbSI_LevelOneOnly); + old->defs.defined |= _SI_LevelOneOnly; + } + if (collide) + { + WARN1("Multiple interpretations of \"%s\"\n", siText(new, info)); + ACTION1("Using %s definition for duplicate fields\n", + (new->defs.merge != MergeAugment ? "last" : "first")); + } + return True; + } + old = new; + if ((new = NextInterp(info)) == NULL) + return False; + *new = *old; + new->defs.next = NULL; return True; } static Bool -AddGroupCompat(CompatInfo *info,unsigned group,GroupCompatInfo *newGC) +AddGroupCompat(CompatInfo * info, unsigned group, GroupCompatInfo * newGC) { -GroupCompatInfo * gc; -unsigned merge; - - merge= newGC->merge; - gc= &info->groupCompat[group]; - if (((gc->real_mods==newGC->real_mods)&&(gc->vmods==newGC->vmods))) { - return True; - } - if (((gc->fileID==newGC->fileID)&&(warningLevel>0))||(warningLevel>9)) { - WARN1("Compat map for group %d redefined\n",group+1); - ACTION1("Using %s definition\n",(merge==MergeAugment?"old":"new")); - } - if (merge!=MergeAugment) - *gc= *newGC; + GroupCompatInfo *gc; + unsigned merge; + + merge = newGC->merge; + gc = &info->groupCompat[group]; + if (((gc->real_mods == newGC->real_mods) && (gc->vmods == newGC->vmods))) + { + return True; + } + if (((gc->fileID == newGC->fileID) && (warningLevel > 0)) + || (warningLevel > 9)) + { + WARN1("Compat map for group %d redefined\n", group + 1); + ACTION1("Using %s definition\n", + (merge == MergeAugment ? "old" : "new")); + } + if (merge != MergeAugment) + *gc = *newGC; return True; } /***====================================================================***/ static Bool -ResolveStateAndPredicate( ExprDef * expr, - unsigned * pred_rtrn, - unsigned * mods_rtrn, - CompatInfo * info) +ResolveStateAndPredicate(ExprDef * expr, + unsigned *pred_rtrn, + unsigned *mods_rtrn, CompatInfo * info) { -ExprResult result; - - if (expr==NULL) { - *pred_rtrn= XkbSI_AnyOfOrNone; - *mods_rtrn= ~0; - return True; - } - - *pred_rtrn= XkbSI_Exactly; - if (expr->op==ExprActionDecl) { - char *pred_txt= XkbAtomText(NULL,expr->value.action.name,XkbMessage); - if (uStrCaseCmp(pred_txt,"noneof")==0) - *pred_rtrn= XkbSI_NoneOf; - else if (uStrCaseCmp(pred_txt,"anyofornone")==0) - *pred_rtrn= XkbSI_AnyOfOrNone; - else if (uStrCaseCmp(pred_txt,"anyof")==0) - *pred_rtrn= XkbSI_AnyOf; - else if (uStrCaseCmp(pred_txt,"allof")==0) - *pred_rtrn= XkbSI_AllOf; - else if (uStrCaseCmp(pred_txt,"exactly")==0) - *pred_rtrn= XkbSI_Exactly; - else { - ERROR1("Illegal modifier predicate \"%s\"\n",pred_txt); - ACTION("Ignored\n"); - return False; - } - expr= expr->value.action.args; - } - else if (expr->op==ExprIdent) { - char *pred_txt= XkbAtomText(NULL,expr->value.str,XkbMessage); - if ((pred_txt)&&(uStrCaseCmp(pred_txt,"any")==0)) { - *pred_rtrn= XkbSI_AnyOf; - *mods_rtrn= 0xff; - return True; - } - } - - if (ExprResolveModMask(expr,&result,NULL,NULL)) { - *mods_rtrn= result.uval; - return True; + ExprResult result; + + if (expr == NULL) + { + *pred_rtrn = XkbSI_AnyOfOrNone; + *mods_rtrn = ~0; + return True; + } + + *pred_rtrn = XkbSI_Exactly; + if (expr->op == ExprActionDecl) + { + char *pred_txt = + XkbAtomText(NULL, expr->value.action.name, XkbMessage); + if (uStrCaseCmp(pred_txt, "noneof") == 0) + *pred_rtrn = XkbSI_NoneOf; + else if (uStrCaseCmp(pred_txt, "anyofornone") == 0) + *pred_rtrn = XkbSI_AnyOfOrNone; + else if (uStrCaseCmp(pred_txt, "anyof") == 0) + *pred_rtrn = XkbSI_AnyOf; + else if (uStrCaseCmp(pred_txt, "allof") == 0) + *pred_rtrn = XkbSI_AllOf; + else if (uStrCaseCmp(pred_txt, "exactly") == 0) + *pred_rtrn = XkbSI_Exactly; + else + { + ERROR1("Illegal modifier predicate \"%s\"\n", pred_txt); + ACTION("Ignored\n"); + return False; + } + expr = expr->value.action.args; + } + else if (expr->op == ExprIdent) + { + char *pred_txt = XkbAtomText(NULL, expr->value.str, XkbMessage); + if ((pred_txt) && (uStrCaseCmp(pred_txt, "any") == 0)) + { + *pred_rtrn = XkbSI_AnyOf; + *mods_rtrn = 0xff; + return True; + } + } + + if (ExprResolveModMask(expr, &result, NULL, NULL)) + { + *mods_rtrn = result.uval; + return True; } return False; } @@ -313,468 +346,535 @@ ExprResult result; /***====================================================================***/ static void -MergeIncludedCompatMaps( CompatInfo * into, - CompatInfo * from, - unsigned merge) +MergeIncludedCompatMaps(CompatInfo * into, CompatInfo * from, unsigned merge) { -SymInterpInfo * si; -LEDInfo * led,*rtrn,*next; -GroupCompatInfo * gcm; -register int i; - - if (from->errorCount>0) { - into->errorCount+= from->errorCount; - return; - } - if (into->name==NULL) { - into->name= from->name; - from->name= NULL; - } - for (si=from->interps;si;si=(SymInterpInfo *)si->defs.next) { - if (merge!=MergeDefault) - si->defs.merge= merge; - if (!AddInterp(into,si)) - into->errorCount++; - } - for (i=0,gcm=&from->groupCompat[0];i<XkbNumKbdGroups;i++,gcm++) { - if (merge!=MergeDefault) - gcm->merge= merge; - if (!AddGroupCompat(into,i,gcm)) - into->errorCount++; - } - for (led=from->leds;led!=NULL;led=next) { - next= (LEDInfo *)led->defs.next; - if (merge!=MergeDefault) - led->defs.merge= merge; - rtrn= AddIndicatorMap(into->leds,led); - if (rtrn!=NULL) - into->leds= rtrn; - else into->errorCount++; + SymInterpInfo *si; + LEDInfo *led, *rtrn, *next; + GroupCompatInfo *gcm; + register int i; + + if (from->errorCount > 0) + { + into->errorCount += from->errorCount; + return; + } + if (into->name == NULL) + { + into->name = from->name; + from->name = NULL; + } + for (si = from->interps; si; si = (SymInterpInfo *) si->defs.next) + { + if (merge != MergeDefault) + si->defs.merge = merge; + if (!AddInterp(into, si)) + into->errorCount++; + } + for (i = 0, gcm = &from->groupCompat[0]; i < XkbNumKbdGroups; i++, gcm++) + { + if (merge != MergeDefault) + gcm->merge = merge; + if (!AddGroupCompat(into, i, gcm)) + into->errorCount++; + } + for (led = from->leds; led != NULL; led = next) + { + next = (LEDInfo *) led->defs.next; + if (merge != MergeDefault) + led->defs.merge = merge; + rtrn = AddIndicatorMap(into->leds, led); + if (rtrn != NULL) + into->leds = rtrn; + else + into->errorCount++; } return; } -typedef void (*FileHandler)( - XkbFile * /* rtrn */, - XkbDescPtr /* xkb */, - unsigned /* merge */, - CompatInfo * /* info */ -); +typedef void (*FileHandler) (XkbFile * /* rtrn */ , + XkbDescPtr /* xkb */ , + unsigned /* merge */ , + CompatInfo * /* info */ + ); static Bool -HandleIncludeCompatMap( IncludeStmt * stmt, - XkbDescPtr xkb, - CompatInfo * info, - FileHandler hndlr) +HandleIncludeCompatMap(IncludeStmt * stmt, + XkbDescPtr xkb, CompatInfo * info, FileHandler hndlr) { -unsigned newMerge; -XkbFile * rtrn; -CompatInfo included; -Bool haveSelf; - - haveSelf= False; - if ((stmt->file==NULL)&&(stmt->map==NULL)) { - haveSelf= True; - included= *info; - bzero(info,sizeof(CompatInfo)); - } - else if (ProcessIncludeFile(stmt,XkmCompatMapIndex,&rtrn,&newMerge)) { - InitCompatInfo(&included,xkb); - included.fileID= rtrn->id; - included.dflt= info->dflt; - included.dflt.defs.fileID= rtrn->id; - included.dflt.defs.merge= newMerge; - included.ledDflt.defs.fileID= rtrn->id; - included.ledDflt.defs.merge= newMerge; - included.act= info->act; - (*hndlr)(rtrn,xkb,MergeOverride,&included); - if (stmt->stmt!=NULL) { - if (included.name!=NULL) - uFree(included.name); - included.name= stmt->stmt; - stmt->stmt= NULL; - } - } - else { - info->errorCount+= 10; - return False; - } - if ((stmt->next!=NULL)&&(included.errorCount<1)) { - IncludeStmt * next; - unsigned op; - CompatInfo next_incl; - - for (next=stmt->next;next!=NULL;next=next->next) { - if ((next->file==NULL)&&(next->map==NULL)) { - haveSelf= True; - MergeIncludedCompatMaps(&included,info,next->merge); - ClearCompatInfo(info,xkb); - } - else if (ProcessIncludeFile(next,XkmCompatMapIndex,&rtrn,&op)) { - InitCompatInfo(&next_incl,xkb); - next_incl.fileID= rtrn->id; - next_incl.dflt= info->dflt; - next_incl.dflt.defs.fileID= rtrn->id; - next_incl.dflt.defs.merge= op; - next_incl.ledDflt.defs.fileID= rtrn->id; - next_incl.ledDflt.defs.merge= op; - next_incl.act= info->act; - (*hndlr)(rtrn,xkb,MergeOverride,&next_incl); - MergeIncludedCompatMaps(&included,&next_incl,op); - ClearCompatInfo(&next_incl,xkb); - } - else { - info->errorCount+= 10; - return False; - } - } + unsigned newMerge; + XkbFile *rtrn; + CompatInfo included; + Bool haveSelf; + + haveSelf = False; + if ((stmt->file == NULL) && (stmt->map == NULL)) + { + haveSelf = True; + included = *info; + bzero(info, sizeof(CompatInfo)); + } + else if (ProcessIncludeFile(stmt, XkmCompatMapIndex, &rtrn, &newMerge)) + { + InitCompatInfo(&included, xkb); + included.fileID = rtrn->id; + included.dflt = info->dflt; + included.dflt.defs.fileID = rtrn->id; + included.dflt.defs.merge = newMerge; + included.ledDflt.defs.fileID = rtrn->id; + included.ledDflt.defs.merge = newMerge; + included.act = info->act; + (*hndlr) (rtrn, xkb, MergeOverride, &included); + if (stmt->stmt != NULL) + { + if (included.name != NULL) + uFree(included.name); + included.name = stmt->stmt; + stmt->stmt = NULL; + } + } + else + { + info->errorCount += 10; + return False; + } + if ((stmt->next != NULL) && (included.errorCount < 1)) + { + IncludeStmt *next; + unsigned op; + CompatInfo next_incl; + + for (next = stmt->next; next != NULL; next = next->next) + { + if ((next->file == NULL) && (next->map == NULL)) + { + haveSelf = True; + MergeIncludedCompatMaps(&included, info, next->merge); + ClearCompatInfo(info, xkb); + } + else if (ProcessIncludeFile(next, XkmCompatMapIndex, &rtrn, &op)) + { + InitCompatInfo(&next_incl, xkb); + next_incl.fileID = rtrn->id; + next_incl.dflt = info->dflt; + next_incl.dflt.defs.fileID = rtrn->id; + next_incl.dflt.defs.merge = op; + next_incl.ledDflt.defs.fileID = rtrn->id; + next_incl.ledDflt.defs.merge = op; + next_incl.act = info->act; + (*hndlr) (rtrn, xkb, MergeOverride, &next_incl); + MergeIncludedCompatMaps(&included, &next_incl, op); + ClearCompatInfo(&next_incl, xkb); + } + else + { + info->errorCount += 10; + return False; + } + } } if (haveSelf) - *info= included; - else { - MergeIncludedCompatMaps(info,&included,newMerge); - ClearCompatInfo(&included,xkb); + *info = included; + else + { + MergeIncludedCompatMaps(info, &included, newMerge); + ClearCompatInfo(&included, xkb); } - return (info->errorCount==0); + return (info->errorCount == 0); } static LookupEntry useModMapValues[] = { - { "levelone", 1 }, - { "level1", 1 }, - { "anylevel", 0 }, - { "any", 0 }, - { NULL, 0 } + {"levelone", 1}, + {"level1", 1}, + {"anylevel", 0}, + {"any", 0}, + {NULL, 0} }; static int -SetInterpField( SymInterpInfo * si, - XkbDescPtr xkb, - char * field, - ExprDef * arrayNdx, - ExprDef * value, - CompatInfo * info) +SetInterpField(SymInterpInfo * si, + XkbDescPtr xkb, + char *field, + ExprDef * arrayNdx, ExprDef * value, CompatInfo * info) { -int ok= 1; -ExprResult tmp; - - if (uStrCaseCmp(field,"action")==0) { - if (arrayNdx!=NULL) - return ReportSINotArray(si,field,info); - ok= HandleActionDef(value,xkb,&si->interp.act,si->defs.merge,info->act); - if (ok) - si->defs.defined|= _SI_Action; - } - else if ((uStrCaseCmp(field,"virtualmodifier")==0)|| - (uStrCaseCmp(field,"virtualmod")==0)) { - if (arrayNdx!=NULL) - return ReportSINotArray(si,field,info); - ok= ResolveVirtualModifier(value,&tmp,&info->vmods); - if (ok) { - si->interp.virtual_mod= tmp.uval; - si->defs.defined|= _SI_VirtualMod; - } - else return ReportSIBadType(si,field,"virtual modifier",info); - } - else if (uStrCaseCmp(field,"repeat")==0) { - if (arrayNdx!=NULL) - return ReportSINotArray(si,field,info); - ok= ExprResolveBoolean(value,&tmp,NULL,NULL); - if (ok) { - if (tmp.uval) si->interp.flags|= XkbSI_AutoRepeat; - else si->interp.flags&= ~XkbSI_AutoRepeat; - si->defs.defined|= _SI_AutoRepeat; - } - else return ReportSIBadType(si,field,"boolean",info); - } - else if (uStrCaseCmp(field,"locking")==0) { - if (arrayNdx!=NULL) - return ReportSINotArray(si,field,info); - ok= ExprResolveBoolean(value,&tmp,NULL,NULL); - if (ok) { - if (tmp.uval) si->interp.flags|= XkbSI_LockingKey; - else si->interp.flags&= ~XkbSI_LockingKey; - si->defs.defined|= _SI_LockingKey; - } - else return ReportSIBadType(si,field,"boolean",info); - } - else if ((uStrCaseCmp(field,"usemodmap")==0)|| - (uStrCaseCmp(field,"usemodmapmods")==0)) { - if (arrayNdx!=NULL) - return ReportSINotArray(si,field,info); - ok= ExprResolveEnum(value,&tmp,useModMapValues); - if (ok) { - if (tmp.uval) si->interp.match|= XkbSI_LevelOneOnly; - else si->interp.match&= ~XkbSI_LevelOneOnly; - si->defs.defined|= _SI_LevelOneOnly; - } - else return ReportSIBadType(si,field,"level specification",info); - } - else { - ok= ReportBadField("symbol interpretation",field,siText(si,info)); + int ok = 1; + ExprResult tmp; + + if (uStrCaseCmp(field, "action") == 0) + { + if (arrayNdx != NULL) + return ReportSINotArray(si, field, info); + ok = HandleActionDef(value, xkb, &si->interp.act, si->defs.merge, + info->act); + if (ok) + si->defs.defined |= _SI_Action; + } + else if ((uStrCaseCmp(field, "virtualmodifier") == 0) || + (uStrCaseCmp(field, "virtualmod") == 0)) + { + if (arrayNdx != NULL) + return ReportSINotArray(si, field, info); + ok = ResolveVirtualModifier(value, &tmp, &info->vmods); + if (ok) + { + si->interp.virtual_mod = tmp.uval; + si->defs.defined |= _SI_VirtualMod; + } + else + return ReportSIBadType(si, field, "virtual modifier", info); + } + else if (uStrCaseCmp(field, "repeat") == 0) + { + if (arrayNdx != NULL) + return ReportSINotArray(si, field, info); + ok = ExprResolveBoolean(value, &tmp, NULL, NULL); + if (ok) + { + if (tmp.uval) + si->interp.flags |= XkbSI_AutoRepeat; + else + si->interp.flags &= ~XkbSI_AutoRepeat; + si->defs.defined |= _SI_AutoRepeat; + } + else + return ReportSIBadType(si, field, "boolean", info); + } + else if (uStrCaseCmp(field, "locking") == 0) + { + if (arrayNdx != NULL) + return ReportSINotArray(si, field, info); + ok = ExprResolveBoolean(value, &tmp, NULL, NULL); + if (ok) + { + if (tmp.uval) + si->interp.flags |= XkbSI_LockingKey; + else + si->interp.flags &= ~XkbSI_LockingKey; + si->defs.defined |= _SI_LockingKey; + } + else + return ReportSIBadType(si, field, "boolean", info); + } + else if ((uStrCaseCmp(field, "usemodmap") == 0) || + (uStrCaseCmp(field, "usemodmapmods") == 0)) + { + if (arrayNdx != NULL) + return ReportSINotArray(si, field, info); + ok = ExprResolveEnum(value, &tmp, useModMapValues); + if (ok) + { + if (tmp.uval) + si->interp.match |= XkbSI_LevelOneOnly; + else + si->interp.match &= ~XkbSI_LevelOneOnly; + si->defs.defined |= _SI_LevelOneOnly; + } + else + return ReportSIBadType(si, field, "level specification", info); + } + else + { + ok = ReportBadField("symbol interpretation", field, siText(si, info)); } return ok; } -LookupEntry groupNames[]= { - { "group1", 0x01 }, - { "group2", 0x02 }, - { "group3", 0x04 }, - { "group4", 0x08 }, - { "group5", 0x10 }, - { "group6", 0x20 }, - { "group7", 0x40 }, - { "group8", 0x80 }, - { "none", 0x00 }, - { "all", 0xff }, - { NULL, 0 } +LookupEntry groupNames[] = { + {"group1", 0x01} + , + {"group2", 0x02} + , + {"group3", 0x04} + , + {"group4", 0x08} + , + {"group5", 0x10} + , + {"group6", 0x20} + , + {"group7", 0x40} + , + {"group8", 0x80} + , + {"none", 0x00} + , + {"all", 0xff} + , + {NULL, 0} }; static int -HandleInterpVar(VarDef *stmt,XkbDescPtr xkb,CompatInfo *info) +HandleInterpVar(VarDef * stmt, XkbDescPtr xkb, CompatInfo * info) { -ExprResult elem,field; -ExprDef * ndx; - - if (ExprResolveLhs(stmt->name,&elem,&field,&ndx)==0) - return 0; /* internal error, already reported */ - if (elem.str&&(uStrCaseCmp(elem.str,"interpret")==0)) - return SetInterpField(&info->dflt,xkb,field.str,ndx,stmt->value,info); - if (elem.str&&(uStrCaseCmp(elem.str,"indicator")==0)) { - return SetIndicatorMapField(&info->ledDflt,xkb,field.str,ndx, - stmt->value); - } - return SetActionField(xkb,elem.str,field.str,ndx,stmt->value,&info->act); + ExprResult elem, field; + ExprDef *ndx; + + if (ExprResolveLhs(stmt->name, &elem, &field, &ndx) == 0) + return 0; /* internal error, already reported */ + if (elem.str && (uStrCaseCmp(elem.str, "interpret") == 0)) + return SetInterpField(&info->dflt, xkb, field.str, ndx, stmt->value, + info); + if (elem.str && (uStrCaseCmp(elem.str, "indicator") == 0)) + { + return SetIndicatorMapField(&info->ledDflt, xkb, field.str, ndx, + stmt->value); + } + return SetActionField(xkb, elem.str, field.str, ndx, stmt->value, + &info->act); } static int -HandleInterpBody(VarDef *def,XkbDescPtr xkb,SymInterpInfo *si,CompatInfo *info) +HandleInterpBody(VarDef * def, XkbDescPtr xkb, SymInterpInfo * si, + CompatInfo * info) { -int ok= 1; -ExprResult tmp,field; -ExprDef * arrayNdx; - - for (;def!=NULL;def= (VarDef *)def->common.next) { - if ((def->name)&&(def->name->type==ExprFieldRef)) { - ok= HandleInterpVar(def,xkb,info); - continue; - } - ok= ExprResolveLhs(def->name,&tmp,&field,&arrayNdx); - if (ok) - ok= SetInterpField(si,xkb,field.str,arrayNdx,def->value,info); + int ok = 1; + ExprResult tmp, field; + ExprDef *arrayNdx; + + for (; def != NULL; def = (VarDef *) def->common.next) + { + if ((def->name) && (def->name->type == ExprFieldRef)) + { + ok = HandleInterpVar(def, xkb, info); + continue; + } + ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx); + if (ok) + ok = SetInterpField(si, xkb, field.str, arrayNdx, def->value, + info); } return ok; } static int -HandleInterpDef(InterpDef *def,XkbDescPtr xkb,unsigned merge,CompatInfo *info) +HandleInterpDef(InterpDef * def, XkbDescPtr xkb, unsigned merge, + CompatInfo * info) { -unsigned pred,mods; -SymInterpInfo si; - - if (!ResolveStateAndPredicate(def->match,&pred,&mods,info)) { - ERROR("Couldn't determine matching modifiers\n"); - ACTION("Symbol interpretation ignored\n"); - return False; - } - if (def->merge!=MergeDefault) - merge= def->merge; - - si= info->dflt; - si.defs.merge= merge; - si.interp.sym= def->sym; - si.interp.match= pred & XkbSI_OpMask; - si.interp.mods= mods; - if (!HandleInterpBody(def->def,xkb,&si,info)) { - info->errorCount++; - return False; - } - - if (!AddInterp(info,&si)) { - info->errorCount++; - return False; + unsigned pred, mods; + SymInterpInfo si; + + if (!ResolveStateAndPredicate(def->match, &pred, &mods, info)) + { + ERROR("Couldn't determine matching modifiers\n"); + ACTION("Symbol interpretation ignored\n"); + return False; + } + if (def->merge != MergeDefault) + merge = def->merge; + + si = info->dflt; + si.defs.merge = merge; + si.interp.sym = def->sym; + si.interp.match = pred & XkbSI_OpMask; + si.interp.mods = mods; + if (!HandleInterpBody(def->def, xkb, &si, info)) + { + info->errorCount++; + return False; + } + + if (!AddInterp(info, &si)) + { + info->errorCount++; + return False; } return True; } static int -HandleGroupCompatDef( GroupCompatDef * def, - XkbDescPtr xkb, - unsigned merge, - CompatInfo * info) +HandleGroupCompatDef(GroupCompatDef * def, + XkbDescPtr xkb, unsigned merge, CompatInfo * info) { -ExprResult val; -GroupCompatInfo tmp; - - if (def->merge!=MergeDefault) - merge= def->merge; - if (!XkbIsLegalGroup(def->group-1)) { - ERROR1("Keyboard group must be in the range 1..%d\n",XkbNumKbdGroups+1); - ACTION1("Compatibility map for illegal group %d ignored\n",def->group); - return False; - } - tmp.fileID= info->fileID; - tmp.merge= merge; - if (!ExprResolveModMask(def->def,&val,LookupVModMask,(XPointer)xkb)) { - ERROR("Expected a modifier mask in group compatibility definition\n"); - ACTION1("Ignoring illegal compatibility map for group %d\n",def->group); - return False; - } - tmp.real_mods= val.uval&0xff; - tmp.vmods= (val.uval>>8)&0xffff; - return AddGroupCompat(info,def->group-1,&tmp); + ExprResult val; + GroupCompatInfo tmp; + + if (def->merge != MergeDefault) + merge = def->merge; + if (!XkbIsLegalGroup(def->group - 1)) + { + ERROR1("Keyboard group must be in the range 1..%d\n", + XkbNumKbdGroups + 1); + ACTION1("Compatibility map for illegal group %d ignored\n", + def->group); + return False; + } + tmp.fileID = info->fileID; + tmp.merge = merge; + if (!ExprResolveModMask(def->def, &val, LookupVModMask, (XPointer) xkb)) + { + ERROR("Expected a modifier mask in group compatibility definition\n"); + ACTION1("Ignoring illegal compatibility map for group %d\n", + def->group); + return False; + } + tmp.real_mods = val.uval & 0xff; + tmp.vmods = (val.uval >> 8) & 0xffff; + return AddGroupCompat(info, def->group - 1, &tmp); } static void -HandleCompatMapFile( XkbFile * file, - XkbDescPtr xkb, - unsigned merge, - CompatInfo * info) +HandleCompatMapFile(XkbFile * file, + XkbDescPtr xkb, unsigned merge, CompatInfo * info) { -ParseCommon *stmt; - - if (merge==MergeDefault) - merge= MergeAugment; - info->name= uStringDup(file->name); - stmt= file->defs; - while (stmt) { - switch (stmt->stmtType) { - case StmtInclude: - if (!HandleIncludeCompatMap((IncludeStmt *)stmt,xkb,info, - HandleCompatMapFile)) - info->errorCount++; - break; - case StmtInterpDef: - if (!HandleInterpDef((InterpDef *)stmt,xkb,merge,info)) - info->errorCount++; - break; - case StmtGroupCompatDef: - if (!HandleGroupCompatDef((GroupCompatDef*)stmt,xkb,merge,info)) - info->errorCount++; - break; - case StmtIndicatorMapDef: - { - LEDInfo *rtrn; - rtrn= HandleIndicatorMapDef((IndicatorMapDef *)stmt,xkb, - &info->ledDflt,info->leds, - merge); - if (rtrn!=NULL) - info->leds= rtrn; - else info->errorCount++; - } - break; - case StmtVarDef: - if (!HandleInterpVar((VarDef *)stmt,xkb,info)) - info->errorCount++; - break; - case StmtVModDef: - if (!HandleVModDef((VModDef *)stmt,merge,&info->vmods)) - info->errorCount++; - break; - case StmtKeycodeDef: - ERROR("Interpretation files may not include other types\n"); - ACTION("Ignoring definition of key name\n"); - info->errorCount++; - break; - default: - WSGO1("Unexpected statement type %d in HandleCompatMapFile\n", - stmt->stmtType); - break; - } - stmt= stmt->next; - if (info->errorCount>10) { + ParseCommon *stmt; + + if (merge == MergeDefault) + merge = MergeAugment; + info->name = uStringDup(file->name); + stmt = file->defs; + while (stmt) + { + switch (stmt->stmtType) + { + case StmtInclude: + if (!HandleIncludeCompatMap((IncludeStmt *) stmt, xkb, info, + HandleCompatMapFile)) + info->errorCount++; + break; + case StmtInterpDef: + if (!HandleInterpDef((InterpDef *) stmt, xkb, merge, info)) + info->errorCount++; + break; + case StmtGroupCompatDef: + if (!HandleGroupCompatDef + ((GroupCompatDef *) stmt, xkb, merge, info)) + info->errorCount++; + break; + case StmtIndicatorMapDef: + { + LEDInfo *rtrn; + rtrn = HandleIndicatorMapDef((IndicatorMapDef *) stmt, xkb, + &info->ledDflt, info->leds, merge); + if (rtrn != NULL) + info->leds = rtrn; + else + info->errorCount++; + } + break; + case StmtVarDef: + if (!HandleInterpVar((VarDef *) stmt, xkb, info)) + info->errorCount++; + break; + case StmtVModDef: + if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods)) + info->errorCount++; + break; + case StmtKeycodeDef: + ERROR("Interpretation files may not include other types\n"); + ACTION("Ignoring definition of key name\n"); + info->errorCount++; + break; + default: + WSGO1("Unexpected statement type %d in HandleCompatMapFile\n", + stmt->stmtType); + break; + } + stmt = stmt->next; + if (info->errorCount > 10) + { #ifdef NOISY - ERROR("Too many errors\n"); + ERROR("Too many errors\n"); #endif - ACTION1("Abandoning compatibility map \"%s\"\n",file->topName); - break; - } + ACTION1("Abandoning compatibility map \"%s\"\n", file->topName); + break; + } } return; } static void -CopyInterps( CompatInfo * info, - XkbCompatMapPtr compat, - Bool needSymbol, - unsigned pred) +CopyInterps(CompatInfo * info, + XkbCompatMapPtr compat, Bool needSymbol, unsigned pred) { -SymInterpInfo * si; - - for (si=info->interps;si;si=(SymInterpInfo *)si->defs.next) { - if (((si->interp.match&XkbSI_OpMask)!=pred)|| - (needSymbol&&(si->interp.sym==NoSymbol))|| - ((!needSymbol)&&(si->interp.sym!=NoSymbol))) - continue; - if (compat->num_si>=compat->size_si) { - WSGO("No room to merge symbol interpretations\n"); - ACTION("Symbol interpretations lost\n"); - return; - } - compat->sym_interpret[compat->num_si++]= si->interp; + SymInterpInfo *si; + + for (si = info->interps; si; si = (SymInterpInfo *) si->defs.next) + { + if (((si->interp.match & XkbSI_OpMask) != pred) || + (needSymbol && (si->interp.sym == NoSymbol)) || + ((!needSymbol) && (si->interp.sym != NoSymbol))) + continue; + if (compat->num_si >= compat->size_si) + { + WSGO("No room to merge symbol interpretations\n"); + ACTION("Symbol interpretations lost\n"); + return; + } + compat->sym_interpret[compat->num_si++] = si->interp; } return; } Bool -CompileCompatMap( XkbFile * file, - XkbFileInfo * result, - unsigned merge, - LEDInfo ** unboundLEDs) +CompileCompatMap(XkbFile * file, + XkbFileInfo * result, unsigned merge, LEDInfo ** unboundLEDs) { -int i; -CompatInfo info; -XkbDescPtr xkb; -GroupCompatInfo * gcm; - - xkb= result->xkb; - InitCompatInfo(&info,xkb); - info.dflt.defs.merge= merge; - info.ledDflt.defs.merge= merge; - HandleCompatMapFile(file,xkb,merge,&info); - - if (info.errorCount==0) { - int size; - if (XkbAllocCompatMap(xkb,XkbAllCompatMask,info.nInterps)!=Success) { - WSGO("Couldn't allocate compatibility map\n"); - ACTION("Exiting\n"); - return False; - } - if (info.name!=NULL) { - if (XkbAllocNames(xkb,XkbCompatNameMask,0,0)==Success) - xkb->names->compat= XkbInternAtom(xkb->dpy,info.name,False); - else { - WSGO("Couldn't allocate space for compat name\n"); - ACTION2("Name \"%s\" (from %s) NOT assigned\n",scanFile, - info.name); - } - } - size= info.nInterps*sizeof(XkbSymInterpretRec); - if (size>0) { - CopyInterps(&info,xkb->compat,True,XkbSI_Exactly); - CopyInterps(&info,xkb->compat,True,XkbSI_AllOf|XkbSI_NoneOf); - CopyInterps(&info,xkb->compat,True,XkbSI_AnyOf); - CopyInterps(&info,xkb->compat,True,XkbSI_AnyOfOrNone); - CopyInterps(&info,xkb->compat,False,XkbSI_Exactly); - CopyInterps(&info,xkb->compat,False,XkbSI_AllOf|XkbSI_NoneOf); - CopyInterps(&info,xkb->compat,False,XkbSI_AnyOf); - CopyInterps(&info,xkb->compat,False,XkbSI_AnyOfOrNone); - } - for (i=0,gcm=&info.groupCompat[0];i<XkbNumKbdGroups;i++,gcm++) { - if ((gcm->fileID!=0)||(gcm->real_mods!=0)||(gcm->vmods!=0)) { - xkb->compat->groups[i].mask= gcm->real_mods; - xkb->compat->groups[i].real_mods= gcm->real_mods; - xkb->compat->groups[i].vmods= gcm->vmods; - } - } - if (info.leds!=NULL) { - if (!CopyIndicatorMapDefs(result,info.leds,unboundLEDs)) - info.errorCount++; - info.leds= NULL; - } - ClearCompatInfo(&info,xkb); - return True; - } - if (info.interps!=NULL) - uFree(info.interps); + int i; + CompatInfo info; + XkbDescPtr xkb; + GroupCompatInfo *gcm; + + xkb = result->xkb; + InitCompatInfo(&info, xkb); + info.dflt.defs.merge = merge; + info.ledDflt.defs.merge = merge; + HandleCompatMapFile(file, xkb, merge, &info); + + if (info.errorCount == 0) + { + int size; + if (XkbAllocCompatMap(xkb, XkbAllCompatMask, info.nInterps) != + Success) + { + WSGO("Couldn't allocate compatibility map\n"); + ACTION("Exiting\n"); + return False; + } + if (info.name != NULL) + { + if (XkbAllocNames(xkb, XkbCompatNameMask, 0, 0) == Success) + xkb->names->compat = + XkbInternAtom(xkb->dpy, info.name, False); + else + { + WSGO("Couldn't allocate space for compat name\n"); + ACTION2("Name \"%s\" (from %s) NOT assigned\n", + scanFile, info.name); + } + } + size = info.nInterps * sizeof(XkbSymInterpretRec); + if (size > 0) + { + CopyInterps(&info, xkb->compat, True, XkbSI_Exactly); + CopyInterps(&info, xkb->compat, True, XkbSI_AllOf | XkbSI_NoneOf); + CopyInterps(&info, xkb->compat, True, XkbSI_AnyOf); + CopyInterps(&info, xkb->compat, True, XkbSI_AnyOfOrNone); + CopyInterps(&info, xkb->compat, False, XkbSI_Exactly); + CopyInterps(&info, xkb->compat, False, + XkbSI_AllOf | XkbSI_NoneOf); + CopyInterps(&info, xkb->compat, False, XkbSI_AnyOf); + CopyInterps(&info, xkb->compat, False, XkbSI_AnyOfOrNone); + } + for (i = 0, gcm = &info.groupCompat[0]; i < XkbNumKbdGroups; + i++, gcm++) + { + if ((gcm->fileID != 0) || (gcm->real_mods != 0) + || (gcm->vmods != 0)) + { + xkb->compat->groups[i].mask = gcm->real_mods; + xkb->compat->groups[i].real_mods = gcm->real_mods; + xkb->compat->groups[i].vmods = gcm->vmods; + } + } + if (info.leds != NULL) + { + if (!CopyIndicatorMapDefs(result, info.leds, unboundLEDs)) + info.errorCount++; + info.leds = NULL; + } + ClearCompatInfo(&info, xkb); + return True; + } + if (info.interps != NULL) + uFree(info.interps); return False; } |