diff options
Diffstat (limited to 'xkbcomp/keycodes.c')
-rw-r--r-- | xkbcomp/keycodes.c | 1323 |
1 files changed, 735 insertions, 588 deletions
diff --git a/xkbcomp/keycodes.c b/xkbcomp/keycodes.c index a86592e4d..1bff7fa14 100644 --- a/xkbcomp/keycodes.c +++ b/xkbcomp/keycodes.c @@ -1,4 +1,3 @@ -/* $Xorg: keycodes.c,v 1.4 2000/08/17 19:54:32 cpqbld Exp $ */ /************************************************************ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. @@ -24,7 +23,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. ********************************************************/ -/* $XFree86$ */ #include "xkbcomp.h" #include "tokens.h" @@ -34,715 +32,864 @@ #include "alias.h" char * -longText(unsigned long val,unsigned format) +longText(unsigned long val, unsigned format) { -char buf[4]; + char buf[4]; - LongToKeyName(val,buf); - return XkbKeyNameText(buf,format); + LongToKeyName(val, buf); + return XkbKeyNameText(buf, format); } /***====================================================================***/ void -LongToKeyName(unsigned long val,char *name) +LongToKeyName(unsigned long val, char *name) { - name[0]= ((val>>24)&0xff); - name[1]= ((val>>16)&0xff); - name[2]= ((val>>8)&0xff); - name[3]= (val&0xff); + name[0] = ((val >> 24) & 0xff); + name[1] = ((val >> 16) & 0xff); + name[2] = ((val >> 8) & 0xff); + name[3] = (val & 0xff); return; } /***====================================================================***/ -typedef struct _IndicatorNameInfo { - CommonInfo defs; - int ndx; - Atom name; - Bool virtual; +typedef struct _IndicatorNameInfo +{ + CommonInfo defs; + int ndx; + Atom name; + Bool virtual; } IndicatorNameInfo; -typedef struct _KeyNamesInfo { - char * name; - int errorCount; - unsigned fileID; - unsigned merge; - int computedMin; - int computedMax; - int explicitMin; - int explicitMax; - int effectiveMin; - int effectiveMax; - unsigned long names[XkbMaxLegalKeyCode+1]; - unsigned files[XkbMaxLegalKeyCode+1]; - unsigned char has_alt_forms[XkbMaxLegalKeyCode+1]; - IndicatorNameInfo * leds; - AliasInfo * aliases; +typedef struct _KeyNamesInfo +{ + char *name; /* e.g. evdev+aliases(qwerty) */ + int errorCount; + unsigned fileID; + unsigned merge; + int computedMin; /* lowest keycode stored */ + int computedMax; /* highest keycode stored */ + int explicitMin; + int explicitMax; + int effectiveMin; + int effectiveMax; + unsigned long names[XkbMaxLegalKeyCode + 1]; /* 4-letter name of key, keycode is the index */ + unsigned files[XkbMaxLegalKeyCode + 1]; + unsigned char has_alt_forms[XkbMaxLegalKeyCode + 1]; + IndicatorNameInfo *leds; + AliasInfo *aliases; } KeyNamesInfo; +static void HandleKeycodesFile(XkbFile * file, + XkbDescPtr xkb, + unsigned merge, + KeyNamesInfo * info); + static void -InitIndicatorNameInfo(IndicatorNameInfo *ii,KeyNamesInfo *info) +InitIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info) { - ii->defs.defined= 0; - ii->defs.merge= info->merge; - ii->defs.fileID= info->fileID; - ii->defs.next= NULL; - ii->ndx= 0; - ii->name= None; - ii->virtual= False; + ii->defs.defined = 0; + ii->defs.merge = info->merge; + ii->defs.fileID = info->fileID; + ii->defs.next = NULL; + ii->ndx = 0; + ii->name = None; + ii->virtual = False; return; } -static void -ClearIndicatorNameInfo(IndicatorNameInfo *ii,KeyNamesInfo *info) +static void +ClearIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info) { - if (ii==info->leds) { - ClearCommonInfo(&ii->defs); - info->leds= NULL; + if (ii == info->leds) + { + ClearCommonInfo(&ii->defs); + info->leds = NULL; } return; } static IndicatorNameInfo * -NextIndicatorName(KeyNamesInfo *info) +NextIndicatorName(KeyNamesInfo * info) { -IndicatorNameInfo * ii; + IndicatorNameInfo *ii; - ii= uTypedAlloc(IndicatorNameInfo); - if (ii) { - InitIndicatorNameInfo(ii,info); - info->leds= (IndicatorNameInfo *)AddCommonInfo(&info->leds->defs, - (CommonInfo *)ii); + ii = uTypedAlloc(IndicatorNameInfo); + if (ii) + { + InitIndicatorNameInfo(ii, info); + info->leds = (IndicatorNameInfo *) AddCommonInfo(&info->leds->defs, + (CommonInfo *) ii); } return ii; } static IndicatorNameInfo * -FindIndicatorByIndex(KeyNamesInfo *info,int ndx) +FindIndicatorByIndex(KeyNamesInfo * info, int ndx) { -IndicatorNameInfo * old; + IndicatorNameInfo *old; - for (old= info->leds;old!=NULL;old=(IndicatorNameInfo *)old->defs.next) { - if (old->ndx==ndx) - return old; + for (old = info->leds; old != NULL; + old = (IndicatorNameInfo *) old->defs.next) + { + if (old->ndx == ndx) + return old; } return NULL; } static IndicatorNameInfo * -FindIndicatorByName(KeyNamesInfo *info,Atom name) +FindIndicatorByName(KeyNamesInfo * info, Atom name) { -IndicatorNameInfo * old; + IndicatorNameInfo *old; - for (old= info->leds;old!=NULL;old=(IndicatorNameInfo *)old->defs.next) { - if (old->name==name) - return old; + for (old = info->leds; old != NULL; + old = (IndicatorNameInfo *) old->defs.next) + { + if (old->name == name) + return old; } return NULL; } static Bool -AddIndicatorName(KeyNamesInfo *info,IndicatorNameInfo *new) +AddIndicatorName(KeyNamesInfo * info, IndicatorNameInfo * new) { -IndicatorNameInfo *old; -Bool replace; -const char *action; - - replace= (new->defs.merge==MergeReplace)|| - (new->defs.merge==MergeOverride); - old= FindIndicatorByName(info,new->name); - if (old) { - if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| - (warningLevel>9)) { - WARN1("Multiple indicators named %s\n", - XkbAtomText(NULL,new->name,XkbMessage)); - if (old->ndx==new->ndx) { - if (old->virtual!=new->virtual) { - if (replace) - old->virtual= new->virtual; - action= "Using %s instead of %s\n"; - } - else { - action= "Identical definitions ignored\n"; - } - ACTION2(action,(old->virtual?"virtual":"real"), - (old->virtual?"real":"virtual")); - return True; - } - else { - if (replace) action= "Ignoring %d, using %d\n"; - else action= "Using %d, ignoring %d\n"; - ACTION2(action,old->ndx,new->ndx); - } - if (replace) { - if (info->leds==old) - info->leds= (IndicatorNameInfo *)old->defs.next; - else { - IndicatorNameInfo *tmp; - tmp= info->leds; - for (;tmp!=NULL;tmp=(IndicatorNameInfo *)tmp->defs.next) { - if (tmp->defs.next==(CommonInfo *)old) { - tmp->defs.next= old->defs.next; - break; - } - } - } - uFree(old); - } - } - } - old= FindIndicatorByIndex(info,new->ndx); - if (old) { - if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| - (warningLevel>9)) { - WARN1("Multiple names for indicator %d\n",new->ndx); - if ((old->name==new->name)&&(old->virtual==new->virtual)) - action= "Identical definitions ignored\n"; - else { - const char *oldType,*newType; - Atom using,ignoring; - if (old->virtual) oldType= "virtual indicator"; - else oldType= "real indicator"; - if (new->virtual) newType= "virtual indicator"; - else newType= "real indicator"; - if (replace) { - using= new->name; - ignoring= old->name; - } - else { - using= old->name; - ignoring= new->name; - } - ACTION4("Using %s %s, ignoring %s %s\n", - oldType,XkbAtomText(NULL,using,XkbMessage), - newType,XkbAtomText(NULL,ignoring,XkbMessage)); - } - } - if (replace) { - old->name= new->name; - old->virtual= new->virtual; - } - return True; - } - old= new; - new= NextIndicatorName(info); - if (!new) { - WSGO1("Couldn't allocate name for indicator %d\n",new->ndx); - ACTION("Ignored\n"); - return False; - } - new->name= old->name; - new->ndx= old->ndx; - new->virtual= old->virtual; + IndicatorNameInfo *old; + Bool replace; + const char *action; + + replace = (new->defs.merge == MergeReplace) || + (new->defs.merge == MergeOverride); + old = FindIndicatorByName(info, new->name); + if (old) + { + if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0)) + || (warningLevel > 9)) + { + WARN1("Multiple indicators named %s\n", + XkbAtomText(NULL, new->name, XkbMessage)); + if (old->ndx == new->ndx) + { + if (old->virtual != new->virtual) + { + if (replace) + old->virtual = new->virtual; + action = "Using %s instead of %s\n"; + } + else + { + action = "Identical definitions ignored\n"; + } + ACTION2(action, (old->virtual ? "virtual" : "real"), + (old->virtual ? "real" : "virtual")); + return True; + } + else + { + if (replace) + action = "Ignoring %d, using %d\n"; + else + action = "Using %d, ignoring %d\n"; + ACTION2(action, old->ndx, new->ndx); + } + if (replace) + { + if (info->leds == old) + info->leds = (IndicatorNameInfo *) old->defs.next; + else + { + IndicatorNameInfo *tmp; + tmp = info->leds; + for (; tmp != NULL; + tmp = (IndicatorNameInfo *) tmp->defs.next) + { + if (tmp->defs.next == (CommonInfo *) old) + { + tmp->defs.next = old->defs.next; + break; + } + } + } + uFree(old); + } + } + } + old = FindIndicatorByIndex(info, new->ndx); + if (old) + { + if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0)) + || (warningLevel > 9)) + { + WARN1("Multiple names for indicator %d\n", new->ndx); + if ((old->name == new->name) && (old->virtual == new->virtual)) + action = "Identical definitions ignored\n"; + else + { + const char *oldType, *newType; + Atom using, ignoring; + if (old->virtual) + oldType = "virtual indicator"; + else + oldType = "real indicator"; + if (new->virtual) + newType = "virtual indicator"; + else + newType = "real indicator"; + if (replace) + { + using = new->name; + ignoring = old->name; + } + else + { + using = old->name; + ignoring = new->name; + } + ACTION4("Using %s %s, ignoring %s %s\n", + oldType, XkbAtomText(NULL, using, XkbMessage), + newType, XkbAtomText(NULL, ignoring, XkbMessage)); + } + } + if (replace) + { + old->name = new->name; + old->virtual = new->virtual; + } + return True; + } + old = new; + new = NextIndicatorName(info); + if (!new) + { + WSGO1("Couldn't allocate name for indicator %d\n", new->ndx); + ACTION("Ignored\n"); + return False; + } + new->name = old->name; + new->ndx = old->ndx; + new->virtual = old->virtual; return True; } static void -ClearKeyNamesInfo(KeyNamesInfo *info) +ClearKeyNamesInfo(KeyNamesInfo * info) { - if (info->name!=NULL) - uFree(info->name); - info->name= NULL; - info->computedMax= info->explicitMax= info->explicitMin= -1; - info->computedMin= 256; - info->effectiveMin= 8; - info->effectiveMax= 255; - bzero((char *)info->names,sizeof(info->names)); - bzero((char *)info->files,sizeof(info->files)); - bzero((char *)info->has_alt_forms,sizeof(info->has_alt_forms)); + if (info->name != NULL) + uFree(info->name); + info->name = NULL; + info->computedMax = info->explicitMax = info->explicitMin = -1; + info->computedMin = 256; + info->effectiveMin = 8; + info->effectiveMax = 255; + bzero((char *) info->names, sizeof(info->names)); + bzero((char *) info->files, sizeof(info->files)); + bzero((char *) info->has_alt_forms, sizeof(info->has_alt_forms)); if (info->leds) - ClearIndicatorNameInfo(info->leds,info); + ClearIndicatorNameInfo(info->leds, info); if (info->aliases) - ClearAliases(&info->aliases); + ClearAliases(&info->aliases); return; } static void -InitKeyNamesInfo(KeyNamesInfo *info) +InitKeyNamesInfo(KeyNamesInfo * info) { - info->name= NULL; - info->leds= NULL; - info->aliases= NULL; + info->name = NULL; + info->leds = NULL; + info->aliases = NULL; ClearKeyNamesInfo(info); - info->errorCount= 0; + info->errorCount = 0; return; } static int -FindKeyByLong(KeyNamesInfo *info,unsigned long name) +FindKeyByLong(KeyNamesInfo * info, unsigned long name) { -register int i; + register int i; - for (i=info->effectiveMin;i<=info->effectiveMax;i++) { - if (info->names[i]==name) - return i; + for (i = info->effectiveMin; i <= info->effectiveMax; i++) + { + if (info->names[i] == name) + return i; } return 0; } +/** + * Store the name of the key as a long in the info struct under the given + * keycode. If the same keys is referred to twice, print a warning. + * Note that the key's name is stored as a long, the keycode is the index. + */ static Bool -AddKeyName( KeyNamesInfo * info, - int kc, - char * name, - unsigned merge, - unsigned fileID, - Bool reportCollisions) +AddKeyName(KeyNamesInfo * info, + int kc, + char *name, unsigned merge, unsigned fileID, Bool reportCollisions) { -int old; -unsigned long lval; - - if ((kc<info->effectiveMin)||(kc>info->effectiveMax)) { - ERROR2("Illegal keycode %d for name <%s>\n",kc,name); - ACTION2("Must be in the range %d-%d inclusive\n",info->effectiveMin, - info->effectiveMax); - return False; - } - if (kc<info->computedMin) info->computedMin= kc; - if (kc>info->computedMax) info->computedMax= kc; - lval= KeyNameToLong(name); - - if (reportCollisions) { - reportCollisions= ((warningLevel>7)|| - ((warningLevel>0)&&(fileID==info->files[kc]))); - } - - if (info->names[kc]!=0) { - char buf[6]; - - LongToKeyName(info->names[kc],buf); - buf[4]= '\0'; - if (info->names[kc]==lval) { - if (info->has_alt_forms[kc] || (merge==MergeAltForm)) { - info->has_alt_forms[kc]= True; - } - else if (reportCollisions) { - WARN("Multiple identical key name definitions\n"); - ACTION2("Later occurences of \"<%s> = %d\" ignored\n",buf,kc); - } - return True; - } - if (merge==MergeAugment) { - if (reportCollisions) { - WARN1("Multiple names for keycode %d\n",kc); - ACTION2("Using <%s>, ignoring <%s>\n",buf,name); - } - return True; - } - else { - if (reportCollisions) { - WARN1("Multiple names for keycode %d\n",kc); - ACTION2("Using <%s>, ignoring <%s>\n",name,buf); - } - info->names[kc]= 0; - info->files[kc]= 0; - } - } - old= FindKeyByLong(info,lval); - if ((old!=0)&&(old!=kc)) { - if (merge==MergeOverride) { - info->names[old]= 0; - info->files[old]= 0; - info->has_alt_forms[old]= True; - if (reportCollisions) { - WARN1("Key name <%s> assigned to multiple keys\n",name); - ACTION2("Using %d, ignoring %d\n",kc,old); - } - } - else if (merge!=MergeAltForm) { - if ((reportCollisions)&&(warningLevel>3)) { - WARN1("Key name <%s> assigned to multiple keys\n",name); - ACTION2("Using %d, ignoring %d\n",old,kc); - ACTION("Use 'alternate' keyword to assign the same name to multiple keys\n"); - } - return True; - } - else { - info->has_alt_forms[old]= True; - } - } - info->names[kc]= lval; - info->files[kc]= fileID; - info->has_alt_forms[kc]= (merge==MergeAltForm); + int old; + unsigned long lval; + + if ((kc < info->effectiveMin) || (kc > info->effectiveMax)) + { + ERROR2("Illegal keycode %d for name <%s>\n", kc, name); + ACTION2("Must be in the range %d-%d inclusive\n", + info->effectiveMin, info->effectiveMax); + return False; + } + if (kc < info->computedMin) + info->computedMin = kc; + if (kc > info->computedMax) + info->computedMax = kc; + lval = KeyNameToLong(name); + + if (reportCollisions) + { + reportCollisions = ((warningLevel > 7) || + ((warningLevel > 0) + && (fileID == info->files[kc]))); + } + + if (info->names[kc] != 0) + { + char buf[6]; + + LongToKeyName(info->names[kc], buf); + buf[4] = '\0'; + if (info->names[kc] == lval) + { + if (info->has_alt_forms[kc] || (merge == MergeAltForm)) + { + info->has_alt_forms[kc] = True; + } + else if (reportCollisions) + { + WARN("Multiple identical key name definitions\n"); + ACTION2("Later occurences of \"<%s> = %d\" ignored\n", + buf, kc); + } + return True; + } + if (merge == MergeAugment) + { + if (reportCollisions) + { + WARN1("Multiple names for keycode %d\n", kc); + ACTION2("Using <%s>, ignoring <%s>\n", buf, name); + } + return True; + } + else + { + if (reportCollisions) + { + WARN1("Multiple names for keycode %d\n", kc); + ACTION2("Using <%s>, ignoring <%s>\n", name, buf); + } + info->names[kc] = 0; + info->files[kc] = 0; + } + } + old = FindKeyByLong(info, lval); + if ((old != 0) && (old != kc)) + { + if (merge == MergeOverride) + { + info->names[old] = 0; + info->files[old] = 0; + info->has_alt_forms[old] = True; + if (reportCollisions) + { + WARN1("Key name <%s> assigned to multiple keys\n", name); + ACTION2("Using %d, ignoring %d\n", kc, old); + } + } + else if (merge != MergeAltForm) + { + if ((reportCollisions) && (warningLevel > 3)) + { + WARN1("Key name <%s> assigned to multiple keys\n", name); + ACTION2("Using %d, ignoring %d\n", old, kc); + ACTION + ("Use 'alternate' keyword to assign the same name to multiple keys\n"); + } + return True; + } + else + { + info->has_alt_forms[old] = True; + } + } + info->names[kc] = lval; + info->files[kc] = fileID; + info->has_alt_forms[kc] = (merge == MergeAltForm); return True; } /***====================================================================***/ static void -MergeIncludedKeycodes(KeyNamesInfo *into,KeyNamesInfo *from,unsigned merge) +MergeIncludedKeycodes(KeyNamesInfo * into, KeyNamesInfo * from, + unsigned merge) { -register int i; -char buf[5]; - - if (from->errorCount>0) { - into->errorCount+= from->errorCount; - return; - } - if (into->name==NULL) { - into->name= from->name; - from->name= NULL; - } - for (i=from->computedMin;i<=from->computedMax;i++) { - unsigned thisMerge; - if (from->names[i]==0) - continue; - LongToKeyName(from->names[i],buf); - buf[4]= '\0'; - if (from->has_alt_forms[i]) - thisMerge= MergeAltForm; - else thisMerge= merge; - if (!AddKeyName(into,i,buf,thisMerge,from->fileID,False)) - into->errorCount++; - } - if (from->leds) { - IndicatorNameInfo *led,*next; - for (led=from->leds;led!=NULL;led=next) { - if (merge!=MergeDefault) - led->defs.merge= merge; - if (!AddIndicatorName(into,led)) - into->errorCount++; - next= (IndicatorNameInfo *)led->defs.next; - } - } - if (!MergeAliases(&into->aliases,&from->aliases,merge)) - into->errorCount++; - if (from->explicitMin>0) { - if ((into->explicitMin<0)||(into->explicitMin>from->explicitMin)) - into->effectiveMin= into->explicitMin= from->explicitMin; - } - if (from->explicitMax>0) { - if ((into->explicitMax<0)||(into->explicitMax<from->explicitMax)) - into->effectiveMax= into->explicitMax= from->explicitMax; + register int i; + char buf[5]; + + if (from->errorCount > 0) + { + into->errorCount += from->errorCount; + return; + } + if (into->name == NULL) + { + into->name = from->name; + from->name = NULL; + } + for (i = from->computedMin; i <= from->computedMax; i++) + { + unsigned thisMerge; + if (from->names[i] == 0) + continue; + LongToKeyName(from->names[i], buf); + buf[4] = '\0'; + if (from->has_alt_forms[i]) + thisMerge = MergeAltForm; + else + thisMerge = merge; + if (!AddKeyName(into, i, buf, thisMerge, from->fileID, False)) + into->errorCount++; + } + if (from->leds) + { + IndicatorNameInfo *led, *next; + for (led = from->leds; led != NULL; led = next) + { + if (merge != MergeDefault) + led->defs.merge = merge; + if (!AddIndicatorName(into, led)) + into->errorCount++; + next = (IndicatorNameInfo *) led->defs.next; + } + } + if (!MergeAliases(&into->aliases, &from->aliases, merge)) + into->errorCount++; + if (from->explicitMin > 0) + { + if ((into->explicitMin < 0) + || (into->explicitMin > from->explicitMin)) + into->effectiveMin = into->explicitMin = from->explicitMin; + } + if (from->explicitMax > 0) + { + if ((into->explicitMax < 0) + || (into->explicitMax < from->explicitMax)) + into->effectiveMax = into->explicitMax = from->explicitMax; } return; } -typedef void (*FileHandler)( - XkbFile * /* rtrn */, - XkbDescPtr /* xkb */, - unsigned /* merge */, - KeyNamesInfo * /* included */ -); - +/** + * Handle the given include statement (e.g. "include "evdev+aliases(qwerty)"). + * + * @param stmt The include statement from the keymap file. + * @param xkb Unused for all but the xkb->flags. + * @param info Struct to store the key info in. + */ static Bool -HandleIncludeKeycodes( IncludeStmt * stmt, - XkbDescPtr xkb, - KeyNamesInfo * info, - FileHandler hndlr) +HandleIncludeKeycodes(IncludeStmt * stmt, XkbDescPtr xkb, KeyNamesInfo * info) { -unsigned newMerge; -XkbFile * rtrn; -KeyNamesInfo included; -Bool haveSelf; - - haveSelf= False; - if ((stmt->file==NULL)&&(stmt->map==NULL)) { - haveSelf= True; - included= *info; - bzero(info,sizeof(KeyNamesInfo)); - } - else if (strcmp(stmt->file,"computed")==0) { - xkb->flags|= AutoKeyNames; - info->explicitMin= XkbMinLegalKeyCode; - info->explicitMax= XkbMaxLegalKeyCode; - return (info->errorCount==0); - } - else if (ProcessIncludeFile(stmt,XkmKeyNamesIndex,&rtrn,&newMerge)) { - InitKeyNamesInfo(&included); - (*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; - KeyNamesInfo next_incl; - - for (next=stmt->next;next!=NULL;next=next->next) { - if ((next->file==NULL)&&(next->map==NULL)) { - haveSelf= True; - MergeIncludedKeycodes(&included,info,next->merge); - ClearKeyNamesInfo(info); - } - else if (ProcessIncludeFile(next,XkmKeyNamesIndex,&rtrn,&op)) { - InitKeyNamesInfo(&next_incl); - (*hndlr)(rtrn,xkb,MergeOverride,&next_incl); - MergeIncludedKeycodes(&included,&next_incl,op); - ClearKeyNamesInfo(&next_incl); - } - else { - info->errorCount+= 10; - return False; - } - } + unsigned newMerge; + XkbFile *rtrn; + KeyNamesInfo included = {NULL}; + Bool haveSelf; + + haveSelf = False; + if ((stmt->file == NULL) && (stmt->map == NULL)) + { + haveSelf = True; + included = *info; + bzero(info, sizeof(KeyNamesInfo)); + } + else if (strcmp(stmt->file, "computed") == 0) + { + xkb->flags |= AutoKeyNames; + info->explicitMin = XkbMinLegalKeyCode; + info->explicitMax = XkbMaxLegalKeyCode; + return (info->errorCount == 0); + } /* parse file, store returned info in the xkb struct */ + else if (ProcessIncludeFile(stmt, XkmKeyNamesIndex, &rtrn, &newMerge)) + { + InitKeyNamesInfo(&included); + HandleKeycodesFile(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; /* XXX: why 10?? */ + return False; + } + /* Do we have more than one include statement? */ + if ((stmt->next != NULL) && (included.errorCount < 1)) + { + IncludeStmt *next; + unsigned op; + KeyNamesInfo next_incl; + + for (next = stmt->next; next != NULL; next = next->next) + { + if ((next->file == NULL) && (next->map == NULL)) + { + haveSelf = True; + MergeIncludedKeycodes(&included, info, next->merge); + ClearKeyNamesInfo(info); + } + else if (ProcessIncludeFile(next, XkmKeyNamesIndex, &rtrn, &op)) + { + InitKeyNamesInfo(&next_incl); + HandleKeycodesFile(rtrn, xkb, MergeOverride, &next_incl); + MergeIncludedKeycodes(&included, &next_incl, op); + ClearKeyNamesInfo(&next_incl); + } + else + { + info->errorCount += 10; /* XXX: Why 10?? */ + return False; + } + } } if (haveSelf) - *info= included; - else { - MergeIncludedKeycodes(info,&included,newMerge); - ClearKeyNamesInfo(&included); + *info = included; + else + { + MergeIncludedKeycodes(info, &included, newMerge); + ClearKeyNamesInfo(&included); } - return (info->errorCount==0); + return (info->errorCount == 0); } +/** + * Parse the given statement and store the output in the info struct. + * e.g. <ESC> = 9 + */ static int -HandleKeycodeDef( KeycodeDef * stmt, - XkbDescPtr xkb, - unsigned merge, - KeyNamesInfo * info) +HandleKeycodeDef(KeycodeDef * stmt, unsigned merge, KeyNamesInfo * info) { -int code; -ExprResult result; - - if (!ExprResolveInteger(stmt->value,&result,NULL,NULL)) { - ACTION1("No value keycode assigned to name <%s>\n",stmt->name); - return 0; - } - code= result.ival; - if ((code<info->effectiveMin)||(code>info->effectiveMax)) { - ERROR2("Illegal keycode %d for name <%s>\n",code,stmt->name); - ACTION2("Must be in the range %d-%d inclusive\n",info->effectiveMin, - info->effectiveMax); - return 0; - } - if (stmt->merge!=MergeDefault) { - if (stmt->merge==MergeReplace) - merge= MergeOverride; - else merge= stmt->merge; - } - return AddKeyName(info,code,stmt->name,merge,info->fileID,True); + int code; + ExprResult result; + + if (!ExprResolveInteger(stmt->value, &result, NULL, NULL)) + { + ACTION1("No value keycode assigned to name <%s>\n", stmt->name); + return 0; + } + code = result.ival; + if ((code < info->effectiveMin) || (code > info->effectiveMax)) + { + ERROR2("Illegal keycode %d for name <%s>\n", code, stmt->name); + ACTION2("Must be in the range %d-%d inclusive\n", + info->effectiveMin, info->effectiveMax); + return 0; + } + if (stmt->merge != MergeDefault) + { + if (stmt->merge == MergeReplace) + merge = MergeOverride; + else + merge = stmt->merge; + } + return AddKeyName(info, code, stmt->name, merge, info->fileID, True); } #define MIN_KEYCODE_DEF 0 #define MAX_KEYCODE_DEF 1 +/** + * Handle the minimum/maximum statement of the xkb file. + * Sets explicitMin/Max and effectiveMin/Max of the info struct. + * + * @return 1 on success, 0 otherwise. + */ static int -HandleKeyNameVar(VarDef *stmt,XkbDescPtr xkb,unsigned merge,KeyNamesInfo *info) +HandleKeyNameVar(VarDef * stmt, KeyNamesInfo * info) { -ExprResult tmp,field; -ExprDef * arrayNdx; -int which; - - if (ExprResolveLhs(stmt->name,&tmp,&field,&arrayNdx)==0) - return 0; /* internal error, already reported */ - - if (tmp.str!=NULL) { - ERROR1("Unknown element %s encountered\n",tmp.str); - ACTION1("Default for field %s ignored\n",field.str); - return 0; - } - if (uStrCaseCmp(field.str,"minimum")==0) which= MIN_KEYCODE_DEF; - else if (uStrCaseCmp(field.str,"maximum")==0) which= MAX_KEYCODE_DEF; - else { - ERROR("Unknown field encountered\n"); - ACTION1("Assigment to field %s ignored\n",field.str); - return 0; - } - if (arrayNdx!=NULL) { - ERROR1("The %s setting is not an array\n",field.str); - ACTION("Illegal array reference ignored\n"); - return 0; - } - - if (ExprResolveInteger(stmt->value,&tmp,NULL,NULL)==0) { - ACTION1("Assignment to field %s ignored\n",field.str); - return 0; - } - if ((tmp.ival<XkbMinLegalKeyCode)||(tmp.ival>XkbMaxLegalKeyCode)) { - ERROR3("Illegal keycode %d (must be in the range %d-%d inclusive)\n", - tmp.ival,XkbMinLegalKeyCode,XkbMaxLegalKeyCode); - ACTION1("Value of \"%s\" not changed\n",field.str); - return 0; - } - if (which==MIN_KEYCODE_DEF) { - if ((info->explicitMax>0)&&(info->explicitMax<tmp.ival)) { - ERROR2("Minimum key code (%d) must be <= maximum key code (%d)\n", - tmp.ival,info->explicitMax); - ACTION("Minimum key code value not changed\n"); - return 0; - } - if ((info->computedMax>0)&&(info->computedMin<tmp.ival)) { - ERROR2("Minimum key code (%d) must be <= lowest defined key (%d)\n", - tmp.ival,info->computedMin); - ACTION("Minimum key code value not changed\n"); - return 0; - } - info->explicitMin= tmp.ival; - info->effectiveMin= tmp.ival; - } - if (which==MAX_KEYCODE_DEF) { - if ((info->explicitMin>0)&&(info->explicitMin>tmp.ival)) { - ERROR2("Maximum code (%d) must be >= minimum key code (%d)\n", - tmp.ival,info->explicitMin); - ACTION("Maximum code value not changed\n"); - return 0; - } - if ((info->computedMax>0)&&(info->computedMax>tmp.ival)) { - ERROR2("Maximum code (%d) must be >= highest defined key (%d)\n", - tmp.ival,info->computedMax); - ACTION("Maximum code value not changed\n"); - return 0; - } - info->explicitMax= tmp.ival; - info->effectiveMax= tmp.ival; + ExprResult tmp, field; + ExprDef *arrayNdx; + int which; + + if (ExprResolveLhs(stmt->name, &tmp, &field, &arrayNdx) == 0) + return 0; /* internal error, already reported */ + + if (tmp.str != NULL) + { + ERROR1("Unknown element %s encountered\n", tmp.str); + ACTION1("Default for field %s ignored\n", field.str); + return 0; + } + if (uStrCaseCmp(field.str, "minimum") == 0) + which = MIN_KEYCODE_DEF; + else if (uStrCaseCmp(field.str, "maximum") == 0) + which = MAX_KEYCODE_DEF; + else + { + ERROR("Unknown field encountered\n"); + ACTION1("Assigment to field %s ignored\n", field.str); + return 0; + } + if (arrayNdx != NULL) + { + ERROR1("The %s setting is not an array\n", field.str); + ACTION("Illegal array reference ignored\n"); + return 0; + } + + if (ExprResolveInteger(stmt->value, &tmp, NULL, NULL) == 0) + { + ACTION1("Assignment to field %s ignored\n", field.str); + return 0; + } + if ((tmp.ival < XkbMinLegalKeyCode) || (tmp.ival > XkbMaxLegalKeyCode)) + { + ERROR3 + ("Illegal keycode %d (must be in the range %d-%d inclusive)\n", + tmp.ival, XkbMinLegalKeyCode, XkbMaxLegalKeyCode); + ACTION1("Value of \"%s\" not changed\n", field.str); + return 0; + } + if (which == MIN_KEYCODE_DEF) + { + if ((info->explicitMax > 0) && (info->explicitMax < tmp.ival)) + { + ERROR2 + ("Minimum key code (%d) must be <= maximum key code (%d)\n", + tmp.ival, info->explicitMax); + ACTION("Minimum key code value not changed\n"); + return 0; + } + if ((info->computedMax > 0) && (info->computedMin < tmp.ival)) + { + ERROR2 + ("Minimum key code (%d) must be <= lowest defined key (%d)\n", + tmp.ival, info->computedMin); + ACTION("Minimum key code value not changed\n"); + return 0; + } + info->explicitMin = tmp.ival; + info->effectiveMin = tmp.ival; + } + if (which == MAX_KEYCODE_DEF) + { + if ((info->explicitMin > 0) && (info->explicitMin > tmp.ival)) + { + ERROR2("Maximum code (%d) must be >= minimum key code (%d)\n", + tmp.ival, info->explicitMin); + ACTION("Maximum code value not changed\n"); + return 0; + } + if ((info->computedMax > 0) && (info->computedMax > tmp.ival)) + { + ERROR2 + ("Maximum code (%d) must be >= highest defined key (%d)\n", + tmp.ival, info->computedMax); + ACTION("Maximum code value not changed\n"); + return 0; + } + info->explicitMax = tmp.ival; + info->effectiveMax = tmp.ival; } return 1; } static int -HandleIndicatorNameDef( IndicatorNameDef * def, - XkbDescPtr xkb, - unsigned merge, - KeyNamesInfo * info) +HandleIndicatorNameDef(IndicatorNameDef * def, + unsigned merge, KeyNamesInfo * info) { -IndicatorNameInfo ii; -ExprResult tmp; - - if ((def->ndx<1)||(def->ndx>XkbNumIndicators)) { - info->errorCount++; - ERROR1("Name specified for illegal indicator index %d\n",def->ndx); - ACTION("Ignored\n"); - return False; - } - InitIndicatorNameInfo(&ii,info); - ii.ndx= def->ndx; - if (!ExprResolveString(def->name,&tmp,NULL,NULL)) { - char buf[20]; - sprintf(buf,"%d",def->ndx); - info->errorCount++; - return ReportBadType("indicator","name",buf,"string"); - } - ii.name= XkbInternAtom(NULL,tmp.str,False); - ii.virtual= def->virtual; - if (!AddIndicatorName(info,&ii)) - return False; + IndicatorNameInfo ii; + ExprResult tmp; + + if ((def->ndx < 1) || (def->ndx > XkbNumIndicators)) + { + info->errorCount++; + ERROR1("Name specified for illegal indicator index %d\n", def->ndx); + ACTION("Ignored\n"); + return False; + } + InitIndicatorNameInfo(&ii, info); + ii.ndx = def->ndx; + if (!ExprResolveString(def->name, &tmp, NULL, NULL)) + { + char buf[20]; + snprintf(buf, sizeof(buf), "%d", def->ndx); + info->errorCount++; + return ReportBadType("indicator", "name", buf, "string"); + } + ii.name = XkbInternAtom(NULL, tmp.str, False); + ii.virtual = def->virtual; + if (!AddIndicatorName(info, &ii)) + return False; return True; } +/** + * Handle the xkb_keycodes section of a xkb file. + * All information about parsed keys is stored in the info struct. + * + * Such a section may have include statements, in which case this function is + * semi-recursive (it calls HandleIncludeKeycodes, which may call + * HandleKeycodesFile again). + * + * @param file The input file (parsed xkb_keycodes section) + * @param xkb Necessary to pass down, may have flags changed. + * @param merge Merge strategy (MergeOverride, etc.) + * @param info Struct to contain the fully parsed key information. + */ static void -HandleKeycodesFile( XkbFile * file, - XkbDescPtr xkb, - unsigned merge, - KeyNamesInfo * info) +HandleKeycodesFile(XkbFile * file, + XkbDescPtr xkb, unsigned merge, KeyNamesInfo * info) { -ParseCommon *stmt; - - info->name= uStringDup(file->name); - stmt= file->defs; - while (stmt) { - switch (stmt->stmtType) { - case StmtInclude: - if (!HandleIncludeKeycodes((IncludeStmt *)stmt,xkb,info, - HandleKeycodesFile)) - info->errorCount++; - break; - case StmtKeycodeDef: - if (!HandleKeycodeDef((KeycodeDef *)stmt,xkb,merge,info)) - info->errorCount++; - break; - case StmtKeyAliasDef: - if (!HandleAliasDef((KeyAliasDef *)stmt, - merge,info->fileID,&info->aliases)) - info->errorCount++; - break; - case StmtVarDef: - if (!HandleKeyNameVar((VarDef *)stmt,xkb,merge,info)) - info->errorCount++; - break; - case StmtIndicatorNameDef: - if (!HandleIndicatorNameDef((IndicatorNameDef *)stmt,xkb, - merge,info)) { - info->errorCount++; - } - break; - case StmtInterpDef: - case StmtVModDef: - ERROR("Keycode files may define key and indicator names only\n"); - ACTION1("Ignoring definition of %s\n", - ((stmt->stmtType==StmtInterpDef)? - "a symbol interpretation": - "virtual modifiers")); - info->errorCount++; - break; - default: - WSGO1("Unexpected statement type %d in HandleKeycodesFile\n", - stmt->stmtType); - break; - } - stmt= stmt->next; - if (info->errorCount>10) { + ParseCommon *stmt; + + info->name = uStringDup(file->name); + stmt = file->defs; + while (stmt) + { + switch (stmt->stmtType) + { + case StmtInclude: /* e.g. include "evdev+aliases(qwerty)" */ + if (!HandleIncludeKeycodes((IncludeStmt *) stmt, xkb, info)) + info->errorCount++; + break; + case StmtKeycodeDef: /* e.g. <ESC> = 9; */ + if (!HandleKeycodeDef((KeycodeDef *) stmt, merge, info)) + info->errorCount++; + break; + case StmtKeyAliasDef: /* e.g. alias <MENU> = <COMP>; */ + if (!HandleAliasDef((KeyAliasDef *) stmt, + merge, info->fileID, &info->aliases)) + info->errorCount++; + break; + case StmtVarDef: /* e.g. minimum, maximum */ + if (!HandleKeyNameVar((VarDef *) stmt, info)) + info->errorCount++; + break; + case StmtIndicatorNameDef: /* e.g. indicator 1 = "Caps Lock"; */ + if (!HandleIndicatorNameDef((IndicatorNameDef *) stmt, + merge, info)) + { + info->errorCount++; + } + break; + case StmtInterpDef: + case StmtVModDef: + ERROR("Keycode files may define key and indicator names only\n"); + ACTION1("Ignoring definition of %s\n", + ((stmt->stmtType == + StmtInterpDef) ? "a symbol interpretation" : + "virtual modifiers")); + info->errorCount++; + break; + default: + WSGO1("Unexpected statement type %d in HandleKeycodesFile\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 keycodes file \"%s\"\n",file->topName); - break; - } + ACTION1("Abandoning keycodes file \"%s\"\n", file->topName); + break; + } } return; } +/** + * Compile the xkb_keycodes section, parse it's output, return the results. + * + * @param file The parsed XKB file (may have include statements requiring + * further parsing) + * @param result The effective keycodes, as gathered from the file. + * @param merge Merge strategy. + * + * @return True on success, False otherwise. + */ Bool -CompileKeycodes(XkbFile *file,XkbFileInfo *result,unsigned merge) +CompileKeycodes(XkbFile * file, XkbFileInfo * result, unsigned merge) { -KeyNamesInfo info; -XkbDescPtr xkb; + KeyNamesInfo info; /* contains all the info after parsing */ + XkbDescPtr xkb; - xkb= result->xkb; + xkb = result->xkb; InitKeyNamesInfo(&info); - HandleKeycodesFile(file,xkb,merge,&info); - - if (info.errorCount==0) { - if (info.explicitMin>0) - xkb->min_key_code= info.effectiveMin; - else xkb->min_key_code= info.computedMin; - if (info.explicitMax>0) - xkb->max_key_code= info.effectiveMax; - else xkb->max_key_code= info.computedMax; - if (XkbAllocNames(xkb,XkbKeyNamesMask|XkbIndicatorNamesMask,0,0)==Success) { - register int i; - xkb->names->keycodes= XkbInternAtom(xkb->dpy,info.name,False); - uDEBUG2(1,"key range: %d..%d\n",xkb->min_key_code,xkb->max_key_code); - for (i=info.computedMin;i<=info.computedMax;i++) { - LongToKeyName(info.names[i],xkb->names->keys[i].name); - uDEBUG2(2,"key %d = %s\n",i, - XkbKeyNameText(xkb->names->keys[i].name,XkbMessage)); - } - } - else { - WSGO("Cannot create XkbNamesRec in CompileKeycodes\n"); - return False; - } - if (info.leds) { - IndicatorNameInfo *ii; - if (XkbAllocIndicatorMaps(xkb)!=Success) { - WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n"); - ACTION("Physical indicators not set\n"); - } - for (ii=info.leds;ii!=NULL;ii=(IndicatorNameInfo *)ii->defs.next){ - xkb->names->indicators[ii->ndx-1]= - XkbInternAtom(xkb->dpy, - XkbAtomGetString(NULL,ii->name),False); - if (xkb->indicators!=NULL) { - register unsigned bit; - bit= 1<<(ii->ndx-1); - if (ii->virtual) - xkb->indicators->phys_indicators&= ~bit; - else xkb->indicators->phys_indicators|= bit; - } - } - } - if (info.aliases) - ApplyAliases(xkb,False,&info.aliases); - return True; + HandleKeycodesFile(file, xkb, merge, &info); + + /* all the keys are now stored in info */ + + if (info.errorCount == 0) + { + if (info.explicitMin > 0) /* if "minimum" statement was present */ + xkb->min_key_code = info.effectiveMin; + else + xkb->min_key_code = info.computedMin; + if (info.explicitMax > 0) /* if "maximum" statement was present */ + xkb->max_key_code = info.effectiveMax; + else + xkb->max_key_code = info.computedMax; + if (XkbAllocNames(xkb, XkbKeyNamesMask | XkbIndicatorNamesMask, 0, 0) + == Success) + { + register int i; + xkb->names->keycodes = XkbInternAtom(xkb->dpy, info.name, False); + uDEBUG2(1, "key range: %d..%d\n", xkb->min_key_code, + xkb->max_key_code); + for (i = info.computedMin; i <= info.computedMax; i++) + { + LongToKeyName(info.names[i], xkb->names->keys[i].name); + uDEBUG2(2, "key %d = %s\n", i, + XkbKeyNameText(xkb->names->keys[i].name, XkbMessage)); + } + } + else + { + WSGO("Cannot create XkbNamesRec in CompileKeycodes\n"); + return False; + } + if (info.leds) + { + IndicatorNameInfo *ii; + if (XkbAllocIndicatorMaps(xkb) != Success) + { + WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n"); + ACTION("Physical indicators not set\n"); + } + for (ii = info.leds; ii != NULL; + ii = (IndicatorNameInfo *) ii->defs.next) + { + xkb->names->indicators[ii->ndx - 1] = + XkbInternAtom(xkb->dpy, + XkbAtomGetString(NULL, ii->name), False); + if (xkb->indicators != NULL) + { + register unsigned bit; + bit = 1 << (ii->ndx - 1); + if (ii->virtual) + xkb->indicators->phys_indicators &= ~bit; + else + xkb->indicators->phys_indicators |= bit; + } + } + } + if (info.aliases) + ApplyAliases(xkb, False, &info.aliases); + return True; } ClearKeyNamesInfo(&info); return False; |