From c38dead3ea7e177728d90cd815cf4eead0c9f534 Mon Sep 17 00:00:00 2001 From: marha Date: Sat, 15 May 2010 16:28:11 +0000 Subject: xserver git update 15/5/2010 --- xorg-server/xkb/xkmread.c | 2476 ++++++++++++++++++++++----------------------- 1 file changed, 1238 insertions(+), 1238 deletions(-) (limited to 'xorg-server/xkb/xkmread.c') diff --git a/xorg-server/xkb/xkmread.c b/xorg-server/xkb/xkmread.c index a201731f3..660884a7f 100644 --- a/xorg-server/xkb/xkmread.c +++ b/xorg-server/xkb/xkmread.c @@ -1,1238 +1,1238 @@ -/************************************************************ - Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - - Permission to use, copy, modify, and distribute this - software and its documentation for any purpose and without - fee is hereby granted, provided that the above copyright - notice appear in all copies and that both that copyright - notice and this permission notice appear in supporting - documentation, and that the name of Silicon Graphics not be - used in advertising or publicity pertaining to distribution - of the software without specific prior written permission. - Silicon Graphics makes no representation about the suitability - of this software for any purpose. It is provided "as is" - without any express or implied warranty. - - SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ********************************************************/ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include - -#include -#include - -#include -#include -#include -#include -#include "misc.h" -#include "inputstr.h" -#include "xkbstr.h" -#include "xkbsrv.h" -#include "xkbgeom.h" - -Atom -XkbInternAtom(char *str,Bool only_if_exists) -{ - if (str==NULL) - return None; - return MakeAtom(str,strlen(str),!only_if_exists); -} - -char * -_XkbDupString(const char *str) -{ -char *new; - - if (str==NULL) - return NULL; - new= xcalloc(strlen(str)+1,sizeof(char)); - if (new) - strcpy(new,str); - return new; -} - -/***====================================================================***/ - -static void * -XkmInsureSize(void *oldPtr,int oldCount,int *newCountRtrn,int elemSize) -{ -int newCount= *newCountRtrn; - - if (oldPtr==NULL) { - if (newCount==0) - return NULL; - oldPtr= xcalloc(newCount,elemSize); - } - else if (oldCount0) { - int tmp; - if (count>max_len) { - tmp= fread(str,1,max_len,file); - while (tmp=max_len) str[max_len-1]= '\0'; - else str[count]= '\0'; - count= XkbPaddedSize(nRead)-nRead; - if (count>0) - nRead+= XkmSkipPadding(file,count); - return nRead; -} - -/***====================================================================***/ - -static int -ReadXkmVirtualMods(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) -{ -register unsigned int i,bit; -unsigned int bound,named,tmp; -int nRead=0; - - if (XkbAllocServerMap(xkb,XkbVirtualModsMask,0)!=Success) { - _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0); - return -1; - } - bound= XkmGetCARD16(file,&nRead); - named= XkmGetCARD16(file,&nRead); - for (i=tmp=0,bit=1;iserver->vmods[i]= XkmGetCARD8(file,&nRead); - if (changes) - changes->map.vmods|= bit; - tmp++; - } - } - if ((i= XkbPaddedSize(tmp)-tmp)>0) - nRead+= XkmSkipPadding(file,i); - if (XkbAllocNames(xkb,XkbVirtualModNamesMask,0,0)!=Success) { - _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0); - return -1; - } - for (i=0,bit=1;inames->vmods[i]= XkbInternAtom(name,FALSE); - if (changes) - changes->names.changed_vmods|= bit; - } - } - } - return nRead; -} - -/***====================================================================***/ - -static int -ReadXkmKeycodes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) -{ -register int i; -unsigned minKC,maxKC,nAl; -int nRead=0; -char name[100]; -XkbKeyNamePtr pN; - - name[0]= '\0'; - nRead+= XkmGetCountedString(file,name,100); - minKC= XkmGetCARD8(file,&nRead); - maxKC= XkmGetCARD8(file,&nRead); - if (xkb->min_key_code==0) { - xkb->min_key_code= minKC; - xkb->max_key_code= maxKC; - } - else { - if (minKCmin_key_code) - xkb->min_key_code= minKC; - if (maxKC>xkb->max_key_code) { - _XkbLibError(_XkbErrBadValue,"ReadXkmKeycodes",maxKC); - return -1; - } - } - nAl= XkmGetCARD8(file,&nRead); - nRead+= XkmSkipPadding(file,1); - -#define WANTED (XkbKeycodesNameMask|XkbKeyNamesMask|XkbKeyAliasesMask) - if (XkbAllocNames(xkb,WANTED,0,nAl)!=Success) { - _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0); - return -1; - } - if (name[0]!='\0') { - xkb->names->keycodes= XkbInternAtom(name,FALSE); - } - - for (pN=&xkb->names->keys[minKC],i=minKC;i<=(int)maxKC;i++,pN++) { - if (fread(pN,1,XkbKeyNameLength,file)!=XkbKeyNameLength) { - _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0); - return -1; - } - nRead+= XkbKeyNameLength; - } - if (nAl>0) { - XkbKeyAliasPtr pAl; - for (pAl= xkb->names->key_aliases,i=0;inames.changed|= XkbKeyAliasesMask; - } - if (changes) - changes->names.changed|= XkbKeyNamesMask; - return nRead; -} - -/***====================================================================***/ - -static int -ReadXkmKeyTypes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) -{ -register unsigned i,n; -unsigned num_types; -int nRead=0; -int tmp; -XkbKeyTypePtr type; -xkmKeyTypeDesc wire; -XkbKTMapEntryPtr entry; -xkmKTMapEntryDesc wire_entry; -char buf[100]; - - if ((tmp= XkmGetCountedString(file,buf,100))<1) { - _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0); - return -1; - } - nRead+= tmp; - if (buf[0]!='\0') { - if (XkbAllocNames(xkb,XkbTypesNameMask,0,0)!=Success) { - _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0); - return -1; - } - xkb->names->types= XkbInternAtom(buf,FALSE); - } - num_types= XkmGetCARD16(file,&nRead); - nRead+= XkmSkipPadding(file,2); - if (num_types<1) - return nRead; - if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_types)!=Success) { - _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0); - return nRead; - } - xkb->map->num_types= num_types; - if (num_typesmap->types; - for (i=0;imap,type->map_count,&tmp,XkbKTMapEntryRec); - if ((wire.nMapEntries>0)&&(type->map==NULL)) { - _XkbLibError(_XkbErrBadValue,"ReadXkmKeyTypes",wire.nMapEntries); - return -1; - } - for (n=0,entry= type->map;nactive= (wire_entry.virtualMods==0); - entry->level= wire_entry.level; - entry->mods.mask= wire_entry.realMods; - entry->mods.real_mods= wire_entry.realMods; - entry->mods.vmods= wire_entry.virtualMods; - } - nRead+= XkmGetCountedString(file,buf,100); - if (((i==XkbOneLevelIndex)&&(strcmp(buf,"ONE_LEVEL")!=0))|| - ((i==XkbTwoLevelIndex)&&(strcmp(buf,"TWO_LEVEL")!=0))|| - ((i==XkbAlphabeticIndex)&&(strcmp(buf,"ALPHABETIC")!=0))|| - ((i==XkbKeypadIndex)&&(strcmp(buf,"KEYPAD")!=0))) { - _XkbLibError(_XkbErrBadTypeName,"ReadXkmKeyTypes",0); - return -1; - } - if (buf[0]!='\0') { - type->name= XkbInternAtom(buf,FALSE); - } - else type->name= None; - - if (wire.preserve) { - xkmModsDesc p_entry; - XkbModsPtr pre; - XkmInsureTypedSize(type->preserve,type->map_count,&tmp, - XkbModsRec); - if (type->preserve==NULL) { - _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0); - return -1; - } - for (n=0,pre=type->preserve;nmask= p_entry.realMods; - pre->real_mods= p_entry.realMods; - pre->vmods= p_entry.virtualMods; - } - } - if (wire.nLevelNames>0) { - int width= wire.numLevels; - if (wire.nLevelNames>(unsigned)width) { - _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0); - return -1; - } - XkmInsureTypedSize(type->level_names,type->num_levels,&width,Atom); - if (type->level_names!=NULL) { - for (n=0;nlevel_names[n]= None; - else type->level_names[n]= XkbInternAtom(buf,0); - } - } - } - type->mods.mask= wire.realMods; - type->mods.real_mods= wire.realMods; - type->mods.vmods= wire.virtualMods; - type->num_levels= wire.numLevels; - type->map_count= wire.nMapEntries; - } - if (changes) { - changes->map.changed|= XkbKeyTypesMask; - changes->map.first_type= 0; - changes->map.num_types= xkb->map->num_types; - } - return nRead; -} - -/***====================================================================***/ - -static int -ReadXkmCompatMap(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) -{ -register int i; -unsigned num_si,groups; -char name[100]; -XkbSymInterpretPtr interp; -xkmSymInterpretDesc wire; -unsigned tmp; -int nRead=0; -XkbCompatMapPtr compat; -XkbAction *act; - - if ((tmp= XkmGetCountedString(file,name,100))<1) { - _XkbLibError(_XkbErrBadLength,"ReadXkmCompatMap",0); - return -1; - } - nRead+= tmp; - if (name[0]!='\0') { - if (XkbAllocNames(xkb,XkbCompatNameMask,0,0)!=Success) { - _XkbLibError(_XkbErrBadAlloc,"ReadXkmCompatMap",0); - return -1; - } - xkb->names->compat= XkbInternAtom(name,FALSE); - } - num_si= XkmGetCARD16(file,&nRead); - groups= XkmGetCARD8(file,&nRead); - nRead+= XkmSkipPadding(file,1); - if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_si)!=Success) - return -1; - compat= xkb->compat; - compat->num_si= num_si; - interp= compat->sym_interpret; - for (i=0;isym= wire.sym; - interp->mods= wire.mods; - interp->match= wire.match; - interp->virtual_mod= wire.virtualMod; - interp->flags= wire.flags; - interp->act.type= wire.actionType; - act = (XkbAction *) &interp->act; - - switch (interp->act.type) { - case XkbSA_SetMods: - case XkbSA_LatchMods: - case XkbSA_LockMods: - act->mods.flags = wire.actionData[0]; - act->mods.mask = wire.actionData[1]; - act->mods.real_mods = wire.actionData[2]; - act->mods.vmods1 = wire.actionData[3]; - act->mods.vmods2 = wire.actionData[4]; - break; - case XkbSA_SetGroup: - case XkbSA_LatchGroup: - case XkbSA_LockGroup: - act->group.flags = wire.actionData[0]; - act->group.group_XXX = wire.actionData[1]; - break; - case XkbSA_MovePtr: - act->ptr.flags = wire.actionData[0]; - act->ptr.high_XXX = wire.actionData[1]; - act->ptr.low_XXX = wire.actionData[2]; - act->ptr.high_YYY = wire.actionData[3]; - act->ptr.low_YYY = wire.actionData[4]; - break; - case XkbSA_PtrBtn: - case XkbSA_LockPtrBtn: - act->btn.flags = wire.actionData[0]; - act->btn.count = wire.actionData[1]; - act->btn.button = wire.actionData[2]; - break; - case XkbSA_DeviceBtn: - case XkbSA_LockDeviceBtn: - act->devbtn.flags = wire.actionData[0]; - act->devbtn.count = wire.actionData[1]; - act->devbtn.button = wire.actionData[2]; - act->devbtn.device = wire.actionData[3]; - break; - case XkbSA_SetPtrDflt: - act->dflt.flags = wire.actionData[0]; - act->dflt.affect = wire.actionData[1]; - act->dflt.valueXXX = wire.actionData[2]; - break; - case XkbSA_ISOLock: - act->iso.flags = wire.actionData[0]; - act->iso.mask = wire.actionData[1]; - act->iso.real_mods = wire.actionData[2]; - act->iso.group_XXX = wire.actionData[3]; - act->iso.affect = wire.actionData[4]; - act->iso.vmods1 = wire.actionData[5]; - act->iso.vmods2 = wire.actionData[6]; - break; - case XkbSA_SwitchScreen: - act->screen.flags = wire.actionData[0]; - act->screen.screenXXX = wire.actionData[1]; - break; - case XkbSA_SetControls: - case XkbSA_LockControls: - act->ctrls.flags = wire.actionData[0]; - act->ctrls.ctrls3 = wire.actionData[1]; - act->ctrls.ctrls2 = wire.actionData[2]; - act->ctrls.ctrls1 = wire.actionData[3]; - act->ctrls.ctrls0 = wire.actionData[4]; - break; - case XkbSA_RedirectKey: - act->redirect.new_key = wire.actionData[0]; - act->redirect.mods_mask = wire.actionData[1]; - act->redirect.mods = wire.actionData[2]; - act->redirect.vmods_mask0 = wire.actionData[3]; - act->redirect.vmods_mask1 = wire.actionData[4]; - act->redirect.vmods0 = wire.actionData[4]; - act->redirect.vmods1 = wire.actionData[5]; - break; - case XkbSA_DeviceValuator: - act->devval.device = wire.actionData[0]; - act->devval.v1_what = wire.actionData[1]; - act->devval.v1_ndx = wire.actionData[2]; - act->devval.v1_value = wire.actionData[3]; - act->devval.v2_what = wire.actionData[4]; - act->devval.v2_ndx = wire.actionData[5]; - act->devval.v2_what = wire.actionData[6]; - break; - - case XkbSA_XFree86Private: - /* copy the kind of action */ - strncpy((char*)act->any.data, (char*)wire.actionData, - XkbAnyActionDataSize); - break ; - - case XkbSA_Terminate: - /* no args, kinda (note: untrue for xfree86). */ - break; - case XkbSA_ActionMessage: - /* unsupported. */ - break; - } - } - if ((num_si>0)&&(changes)) { - changes->compat.first_si= 0; - changes->compat.num_si= num_si; - } - if (groups) { - register unsigned bit; - for (i=0,bit=1;icompat->groups[i].real_mods= md.realMods; - xkb->compat->groups[i].vmods= md.virtualMods; - if (md.virtualMods != 0) { - unsigned mask; - if (XkbVirtualModsToReal(xkb,md.virtualMods,&mask)) - xkb->compat->groups[i].mask= md.realMods|mask; - } - else xkb->compat->groups[i].mask= md.realMods; - } - } - if (changes) - changes->compat.changed_groups|= groups; - } - return nRead; -} - -static int -ReadXkmIndicators(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) -{ -register unsigned nLEDs; -xkmIndicatorMapDesc wire; -char buf[100]; -unsigned tmp; -int nRead=0; - - if ((xkb->indicators==NULL)&&(XkbAllocIndicatorMaps(xkb)!=Success)) { - _XkbLibError(_XkbErrBadAlloc,"indicator rec",0); - return -1; - } - if (XkbAllocNames(xkb,XkbIndicatorNamesMask,0,0)!=Success) { - _XkbLibError(_XkbErrBadAlloc,"indicator names",0); - return -1; - } - nLEDs= XkmGetCARD8(file,&nRead); - nRead+= XkmSkipPadding(file,3); - xkb->indicators->phys_indicators= XkmGetCARD32(file,&nRead); - while (nLEDs-->0) { - Atom name; - XkbIndicatorMapPtr map; - - if ((tmp=XkmGetCountedString(file,buf,100))<1) { - _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0); - return -1; - } - nRead+= tmp; - if (buf[0]!='\0') - name= XkbInternAtom(buf,FALSE); - else name= None; - if ((tmp=fread(&wire,SIZEOF(xkmIndicatorMapDesc),1,file))<1) { - _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0); - return -1; - } - nRead+= tmp*SIZEOF(xkmIndicatorMapDesc); - if (xkb->names) { - xkb->names->indicators[wire.indicator-1]= name; - if (changes) - changes->names.changed_indicators|= (1<<(wire.indicator-1)); - } - map= &xkb->indicators->maps[wire.indicator-1]; - map->flags= wire.flags; - map->which_groups= wire.which_groups; - map->groups= wire.groups; - map->which_mods= wire.which_mods; - map->mods.mask= wire.real_mods; - map->mods.real_mods= wire.real_mods; - map->mods.vmods= wire.vmods; - map->ctrls= wire.ctrls; - } - return nRead; -} - -static XkbKeyTypePtr -FindTypeForKey(XkbDescPtr xkb,Atom name,unsigned width,KeySym *syms) -{ - if ((!xkb)||(!xkb->map)) - return NULL; - if (name!=None) { - register unsigned i; - for (i=0;imap->num_types;i++) { - if (xkb->map->types[i].name==name) { - if (xkb->map->types[i].num_levels!=width) - DebugF("Group width mismatch between key and type\n"); - return &xkb->map->types[i]; - } - } - } - if ((width<2)||((syms!=NULL)&&(syms[1]==NoSymbol))) - return &xkb->map->types[XkbOneLevelIndex]; - if (syms!=NULL) { - if (XkbKSIsLower(syms[0])&&XkbKSIsUpper(syms[1])) - return &xkb->map->types[XkbAlphabeticIndex]; - else if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1])) - return &xkb->map->types[XkbKeypadIndex]; - } - return &xkb->map->types[XkbTwoLevelIndex]; -} - -static int -ReadXkmSymbols(FILE *file,XkbDescPtr xkb) -{ -register int i,g,s,totalVModMaps; -xkmKeySymMapDesc wireMap; -char buf[100]; -unsigned minKC,maxKC,groupNames,tmp; -int nRead=0; - - if ((tmp=XkmGetCountedString(file,buf,100))<1) - return -1; - nRead+= tmp; - minKC= XkmGetCARD8(file,&nRead); - maxKC= XkmGetCARD8(file,&nRead); - groupNames= XkmGetCARD8(file,&nRead); - totalVModMaps= XkmGetCARD8(file,&nRead); - if (XkbAllocNames(xkb, - XkbSymbolsNameMask|XkbPhysSymbolsNameMask|XkbGroupNamesMask, - 0,0)!=Success) { - _XkbLibError(_XkbErrBadAlloc,"physical names",0); - return -1; - } - if ((buf[0]!='\0')&&(xkb->names)) { - Atom name; - name= XkbInternAtom(buf,0); - xkb->names->symbols= name; - xkb->names->phys_symbols= name; - } - for (i=0,g=1;inames)) { - Atom name; - name= XkbInternAtom(buf,0); - xkb->names->groups[i]= name; - } - else xkb->names->groups[i]= None; - } - } - if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success) { - _XkbLibError(_XkbErrBadAlloc,"server map",0); - return -1; - } - if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) { - _XkbLibError(_XkbErrBadAlloc,"client map",0); - return -1; - } - if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) { - _XkbLibError(_XkbErrBadAlloc,"controls",0); - return -1; - } - if ((xkb->map==NULL)||(xkb->server==NULL)) - return -1; - if (xkb->min_key_code<8) xkb->min_key_code= minKC; - if (xkb->max_key_code<8) xkb->max_key_code= maxKC; - if ((minKC>=8)&&(minKCmin_key_code)) - xkb->min_key_code= minKC; - if ((maxKC>=8)&&(maxKC>xkb->max_key_code)) { - _XkbLibError(_XkbErrBadValue,"keys in symbol map",maxKC); - return -1; - } - for (i=minKC;i<=(int)maxKC;i++) { - Atom typeName[XkbNumKbdGroups]; - XkbKeyTypePtr type[XkbNumKbdGroups]; - if ((tmp=fread(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file))<1) { - _XkbLibError(_XkbErrBadLength,"ReadXkmSymbols",0); - return -1; - } - nRead+= tmp*SIZEOF(xkmKeySymMapDesc); - bzero((char *)typeName,XkbNumKbdGroups*sizeof(Atom)); - bzero((char *)type,XkbNumKbdGroups*sizeof(XkbKeyTypePtr)); - if (wireMap.flags&XkmKeyHasTypes) { - register int g; - for (g=0;g0)) { - typeName[g]= XkbInternAtom(buf,1); - nRead+= tmp; - } - type[g]=FindTypeForKey(xkb,typeName[g],wireMap.width,NULL); - if (type[g]==NULL) { - _XkbLibError(_XkbErrMissingTypes,"ReadXkmSymbols",0); - return -1; - } - if (typeName[g]==type[g]->name) - xkb->server->explicit[i]|= (1<ctrls->per_key_repeat[i/8]|= (1<<(i%8)); - xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask; - } - else if (wireMap.flags&XkmNonRepeatingKey) { - xkb->ctrls->per_key_repeat[i/8]&= ~(1<<(i%8)); - xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask; - } - xkb->map->modmap[i]= wireMap.modifier_map; - if (XkbNumGroups(wireMap.num_groups)>0) { - KeySym *sym; - int nSyms; - - if (XkbNumGroups(wireMap.num_groups)>xkb->ctrls->num_groups) - xkb->ctrls->num_groups= wireMap.num_groups; - nSyms= XkbNumGroups(wireMap.num_groups)*wireMap.width; - sym= XkbResizeKeySyms(xkb,i,nSyms); - if (!sym) - return -1; - for (s=0;sserver->explicit[i]|= XkbExplicitInterpretMask; - } - } - for (g=0;gserver->explicit[i]&(1<map->key_sym_map[i].kt_index[g]= type[g]-(&xkb->map->types[0]); - } - xkb->map->key_sym_map[i].group_info= wireMap.num_groups; - xkb->map->key_sym_map[i].width= wireMap.width; - if (wireMap.flags&XkmKeyHasBehavior) { - xkmBehaviorDesc b; - tmp= fread(&b,SIZEOF(xkmBehaviorDesc),1,file); - nRead+= tmp*SIZEOF(xkmBehaviorDesc); - xkb->server->behaviors[i].type= b.type; - xkb->server->behaviors[i].data= b.data; - xkb->server->explicit[i]|= XkbExplicitBehaviorMask; - } - } - if (totalVModMaps>0) { - xkmVModMapDesc v; - for (i=0;i0) - xkb->server->vmodmap[v.key]= v.vmods; - } - } - return nRead; -} - -static int -ReadXkmGeomDoodad( - FILE * file, - XkbGeometryPtr geom, - XkbSectionPtr section) -{ -XkbDoodadPtr doodad; -xkmDoodadDesc doodadWire; -char buf[100]; -unsigned tmp; -int nRead=0; - - nRead+= XkmGetCountedString(file,buf,100); - tmp= fread(&doodadWire,SIZEOF(xkmDoodadDesc),1,file); - nRead+= SIZEOF(xkmDoodadDesc)*tmp; - doodad= XkbAddGeomDoodad(geom,section,XkbInternAtom(buf,FALSE)); - if (!doodad) - return nRead; - doodad->any.type= doodadWire.any.type; - doodad->any.priority= doodadWire.any.priority; - doodad->any.top= doodadWire.any.top; - doodad->any.left= doodadWire.any.left; - switch (doodadWire.any.type) { - case XkbOutlineDoodad: - case XkbSolidDoodad: - doodad->shape.angle= doodadWire.shape.angle; - doodad->shape.color_ndx= doodadWire.shape.color_ndx; - doodad->shape.shape_ndx= doodadWire.shape.shape_ndx; - break; - case XkbTextDoodad: - doodad->text.angle= doodadWire.text.angle; - doodad->text.width= doodadWire.text.width; - doodad->text.height= doodadWire.text.height; - doodad->text.color_ndx= doodadWire.text.color_ndx; - nRead+= XkmGetCountedString(file,buf,100); - doodad->text.text= _XkbDupString(buf); - nRead+= XkmGetCountedString(file,buf,100); - doodad->text.font= _XkbDupString(buf); - break; - case XkbIndicatorDoodad: - doodad->indicator.shape_ndx= doodadWire.indicator.shape_ndx; - doodad->indicator.on_color_ndx= doodadWire.indicator.on_color_ndx; - doodad->indicator.off_color_ndx= doodadWire.indicator.off_color_ndx; - break; - case XkbLogoDoodad: - doodad->logo.angle= doodadWire.logo.angle; - doodad->logo.color_ndx= doodadWire.logo.color_ndx; - doodad->logo.shape_ndx= doodadWire.logo.shape_ndx; - nRead+= XkmGetCountedString(file,buf,100); - doodad->logo.logo_name= _XkbDupString(buf); - break; - default: - /* report error? */ - return nRead; - } - return nRead; -} - -static int -ReadXkmGeomOverlay( FILE * file, - XkbGeometryPtr geom, - XkbSectionPtr section) -{ -char buf[100]; -unsigned tmp; -int nRead=0; -XkbOverlayPtr ol; -XkbOverlayRowPtr row; -xkmOverlayDesc olWire; -xkmOverlayRowDesc rowWire; -register int r; - - nRead+= XkmGetCountedString(file,buf,100); - tmp= fread(&olWire,SIZEOF(xkmOverlayDesc),1,file); - nRead+= tmp*SIZEOF(xkmOverlayDesc); - ol= XkbAddGeomOverlay(section,XkbInternAtom(buf,FALSE), - olWire.num_rows); - if (!ol) - return nRead; - for (r=0;rkeys[k].over.name,keyWire.over,XkbKeyNameLength); - memcpy(row->keys[k].under.name,keyWire.under,XkbKeyNameLength); - } - row->num_keys= rowWire.num_keys; - } - return nRead; -} - -static int -ReadXkmGeomSection( FILE * file, - XkbGeometryPtr geom) -{ -register int i; -XkbSectionPtr section; -xkmSectionDesc sectionWire; -unsigned tmp; -int nRead= 0; -char buf[100]; -Atom nameAtom; - - nRead+= XkmGetCountedString(file,buf,100); - nameAtom= XkbInternAtom(buf,FALSE); - tmp= fread(§ionWire,SIZEOF(xkmSectionDesc),1,file); - nRead+= SIZEOF(xkmSectionDesc)*tmp; - section= XkbAddGeomSection(geom,nameAtom,sectionWire.num_rows, - sectionWire.num_doodads, - sectionWire.num_overlays); - if (!section) { - _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0); - return nRead; - } - section->top= sectionWire.top; - section->left= sectionWire.left; - section->width= sectionWire.width; - section->height= sectionWire.height; - section->angle= sectionWire.angle; - section->priority= sectionWire.priority; - if (sectionWire.num_rows>0) { - register int k; - XkbRowPtr row; - xkmRowDesc rowWire; - XkbKeyPtr key; - xkmKeyDesc keyWire; - - for (i=0;itop= rowWire.top; - row->left= rowWire.left; - row->vertical= rowWire.vertical; - for (k=0;kname.name,keyWire.name,XkbKeyNameLength); - key->gap= keyWire.gap; - key->shape_ndx= keyWire.shape_ndx; - key->color_ndx= keyWire.color_ndx; - } - } - } - if (sectionWire.num_doodads>0) { - for (i=0;i0) { - for (i=0;igeom; - geom->name= XkbInternAtom(buf,FALSE); - geom->width_mm= wireGeom.width_mm; - geom->height_mm= wireGeom.height_mm; - nRead+= XkmGetCountedString(file,buf,100); - geom->label_font= _XkbDupString(buf); - if (wireGeom.num_properties>0) { - char val[1024]; - for (i=0;i0) { - for (i=0;ibase_color= &geom->colors[wireGeom.base_color_ndx]; - geom->label_color= &geom->colors[wireGeom.label_color_ndx]; - if (wireGeom.num_shapes>0) { - XkbShapePtr shape; - xkmShapeDesc shapeWire; - Atom nameAtom; - for (i=0;inum_points= olWire.num_points; - ol->corner_radius= olWire.corner_radius; - for (p=0;ppoints[p].x= ptWire.x; - ol->points[p].y= ptWire.y; - if (ptWire.xbounds.x1) shape->bounds.x1= ptWire.x; - if (ptWire.x>shape->bounds.x2) shape->bounds.x2= ptWire.x; - if (ptWire.ybounds.y1) shape->bounds.y1= ptWire.y; - if (ptWire.y>shape->bounds.y2) shape->bounds.y2= ptWire.y; - } - } - if (shapeWire.primary_ndx!=XkbNoShape) - shape->primary= &shape->outlines[shapeWire.primary_ndx]; - if (shapeWire.approx_ndx!=XkbNoShape) - shape->approx= &shape->outlines[shapeWire.approx_ndx]; - } - } - if (wireGeom.num_sections>0) { - for (i=0;i0) { - for (i=0;i0)&&(geom->key_aliases)) { - int sz= XkbKeyNameLength*2; - int num= wireGeom.num_key_aliases; - if (fread(geom->key_aliases,sz,num,file)!=num) { - _XkbLibError(_XkbErrBadLength,"ReadXkmGeometry",0); - return -1; - } - nRead+= (num*sz); - geom->num_key_aliases= num; - } - return nRead; -} - -Bool -XkmProbe(FILE *file) -{ -unsigned hdr,tmp; -int nRead=0; - - hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); - tmp= XkmGetCARD32(file,&nRead); - if (tmp!=hdr) { - if ((tmp&(~0xff))==(hdr&(~0xff))) { - _XkbLibError(_XkbErrBadFileVersion,"XkmProbe",tmp&0xff); - } - return 0; - } - return 1; -} - -static Bool -XkmReadTOC(FILE *file,xkmFileInfo* file_info,int max_toc,xkmSectionInfo *toc) -{ -unsigned hdr,tmp; -int nRead=0; -unsigned i,size_toc; - - hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); - tmp= XkmGetCARD32(file,&nRead); - if (tmp!=hdr) { - if ((tmp&(~0xff))==(hdr&(~0xff))) { - _XkbLibError(_XkbErrBadFileVersion,"XkmReadTOC",tmp&0xff); - } - else { - _XkbLibError(_XkbErrBadFileType,"XkmReadTOC",tmp); - } - return 0; - } - fread(file_info,SIZEOF(xkmFileInfo),1,file); - size_toc= file_info->num_toc; - if (size_toc>max_toc) { - DebugF("Warning! Too many TOC entries; last %d ignored\n", - size_toc-max_toc); - size_toc= max_toc; - } - for (i=0;i0) { - nRead+= tmp; - which&= ~(1<defined|= (1< +#endif + +#include + +#include +#include + +#include +#include +#include +#include +#include "misc.h" +#include "inputstr.h" +#include "xkbstr.h" +#include "xkbsrv.h" +#include "xkbgeom.h" + +Atom +XkbInternAtom(char *str,Bool only_if_exists) +{ + if (str==NULL) + return None; + return MakeAtom(str,strlen(str),!only_if_exists); +} + +char * +_XkbDupString(const char *str) +{ +char *new; + + if (str==NULL) + return NULL; + new= calloc(strlen(str)+1,sizeof(char)); + if (new) + strcpy(new,str); + return new; +} + +/***====================================================================***/ + +static void * +XkmInsureSize(void *oldPtr,int oldCount,int *newCountRtrn,int elemSize) +{ +int newCount= *newCountRtrn; + + if (oldPtr==NULL) { + if (newCount==0) + return NULL; + oldPtr= calloc(newCount,elemSize); + } + else if (oldCount0) { + int tmp; + if (count>max_len) { + tmp= fread(str,1,max_len,file); + while (tmp=max_len) str[max_len-1]= '\0'; + else str[count]= '\0'; + count= XkbPaddedSize(nRead)-nRead; + if (count>0) + nRead+= XkmSkipPadding(file,count); + return nRead; +} + +/***====================================================================***/ + +static int +ReadXkmVirtualMods(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) +{ +register unsigned int i,bit; +unsigned int bound,named,tmp; +int nRead=0; + + if (XkbAllocServerMap(xkb,XkbVirtualModsMask,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0); + return -1; + } + bound= XkmGetCARD16(file,&nRead); + named= XkmGetCARD16(file,&nRead); + for (i=tmp=0,bit=1;iserver->vmods[i]= XkmGetCARD8(file,&nRead); + if (changes) + changes->map.vmods|= bit; + tmp++; + } + } + if ((i= XkbPaddedSize(tmp)-tmp)>0) + nRead+= XkmSkipPadding(file,i); + if (XkbAllocNames(xkb,XkbVirtualModNamesMask,0,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0); + return -1; + } + for (i=0,bit=1;inames->vmods[i]= XkbInternAtom(name,FALSE); + if (changes) + changes->names.changed_vmods|= bit; + } + } + } + return nRead; +} + +/***====================================================================***/ + +static int +ReadXkmKeycodes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) +{ +register int i; +unsigned minKC,maxKC,nAl; +int nRead=0; +char name[100]; +XkbKeyNamePtr pN; + + name[0]= '\0'; + nRead+= XkmGetCountedString(file,name,100); + minKC= XkmGetCARD8(file,&nRead); + maxKC= XkmGetCARD8(file,&nRead); + if (xkb->min_key_code==0) { + xkb->min_key_code= minKC; + xkb->max_key_code= maxKC; + } + else { + if (minKCmin_key_code) + xkb->min_key_code= minKC; + if (maxKC>xkb->max_key_code) { + _XkbLibError(_XkbErrBadValue,"ReadXkmKeycodes",maxKC); + return -1; + } + } + nAl= XkmGetCARD8(file,&nRead); + nRead+= XkmSkipPadding(file,1); + +#define WANTED (XkbKeycodesNameMask|XkbKeyNamesMask|XkbKeyAliasesMask) + if (XkbAllocNames(xkb,WANTED,0,nAl)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0); + return -1; + } + if (name[0]!='\0') { + xkb->names->keycodes= XkbInternAtom(name,FALSE); + } + + for (pN=&xkb->names->keys[minKC],i=minKC;i<=(int)maxKC;i++,pN++) { + if (fread(pN,1,XkbKeyNameLength,file)!=XkbKeyNameLength) { + _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0); + return -1; + } + nRead+= XkbKeyNameLength; + } + if (nAl>0) { + XkbKeyAliasPtr pAl; + for (pAl= xkb->names->key_aliases,i=0;inames.changed|= XkbKeyAliasesMask; + } + if (changes) + changes->names.changed|= XkbKeyNamesMask; + return nRead; +} + +/***====================================================================***/ + +static int +ReadXkmKeyTypes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) +{ +register unsigned i,n; +unsigned num_types; +int nRead=0; +int tmp; +XkbKeyTypePtr type; +xkmKeyTypeDesc wire; +XkbKTMapEntryPtr entry; +xkmKTMapEntryDesc wire_entry; +char buf[100]; + + if ((tmp= XkmGetCountedString(file,buf,100))<1) { + _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0); + return -1; + } + nRead+= tmp; + if (buf[0]!='\0') { + if (XkbAllocNames(xkb,XkbTypesNameMask,0,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0); + return -1; + } + xkb->names->types= XkbInternAtom(buf,FALSE); + } + num_types= XkmGetCARD16(file,&nRead); + nRead+= XkmSkipPadding(file,2); + if (num_types<1) + return nRead; + if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_types)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0); + return nRead; + } + xkb->map->num_types= num_types; + if (num_typesmap->types; + for (i=0;imap,type->map_count,&tmp,XkbKTMapEntryRec); + if ((wire.nMapEntries>0)&&(type->map==NULL)) { + _XkbLibError(_XkbErrBadValue,"ReadXkmKeyTypes",wire.nMapEntries); + return -1; + } + for (n=0,entry= type->map;nactive= (wire_entry.virtualMods==0); + entry->level= wire_entry.level; + entry->mods.mask= wire_entry.realMods; + entry->mods.real_mods= wire_entry.realMods; + entry->mods.vmods= wire_entry.virtualMods; + } + nRead+= XkmGetCountedString(file,buf,100); + if (((i==XkbOneLevelIndex)&&(strcmp(buf,"ONE_LEVEL")!=0))|| + ((i==XkbTwoLevelIndex)&&(strcmp(buf,"TWO_LEVEL")!=0))|| + ((i==XkbAlphabeticIndex)&&(strcmp(buf,"ALPHABETIC")!=0))|| + ((i==XkbKeypadIndex)&&(strcmp(buf,"KEYPAD")!=0))) { + _XkbLibError(_XkbErrBadTypeName,"ReadXkmKeyTypes",0); + return -1; + } + if (buf[0]!='\0') { + type->name= XkbInternAtom(buf,FALSE); + } + else type->name= None; + + if (wire.preserve) { + xkmModsDesc p_entry; + XkbModsPtr pre; + XkmInsureTypedSize(type->preserve,type->map_count,&tmp, + XkbModsRec); + if (type->preserve==NULL) { + _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0); + return -1; + } + for (n=0,pre=type->preserve;nmask= p_entry.realMods; + pre->real_mods= p_entry.realMods; + pre->vmods= p_entry.virtualMods; + } + } + if (wire.nLevelNames>0) { + int width= wire.numLevels; + if (wire.nLevelNames>(unsigned)width) { + _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0); + return -1; + } + XkmInsureTypedSize(type->level_names,type->num_levels,&width,Atom); + if (type->level_names!=NULL) { + for (n=0;nlevel_names[n]= None; + else type->level_names[n]= XkbInternAtom(buf,0); + } + } + } + type->mods.mask= wire.realMods; + type->mods.real_mods= wire.realMods; + type->mods.vmods= wire.virtualMods; + type->num_levels= wire.numLevels; + type->map_count= wire.nMapEntries; + } + if (changes) { + changes->map.changed|= XkbKeyTypesMask; + changes->map.first_type= 0; + changes->map.num_types= xkb->map->num_types; + } + return nRead; +} + +/***====================================================================***/ + +static int +ReadXkmCompatMap(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) +{ +register int i; +unsigned num_si,groups; +char name[100]; +XkbSymInterpretPtr interp; +xkmSymInterpretDesc wire; +unsigned tmp; +int nRead=0; +XkbCompatMapPtr compat; +XkbAction *act; + + if ((tmp= XkmGetCountedString(file,name,100))<1) { + _XkbLibError(_XkbErrBadLength,"ReadXkmCompatMap",0); + return -1; + } + nRead+= tmp; + if (name[0]!='\0') { + if (XkbAllocNames(xkb,XkbCompatNameMask,0,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmCompatMap",0); + return -1; + } + xkb->names->compat= XkbInternAtom(name,FALSE); + } + num_si= XkmGetCARD16(file,&nRead); + groups= XkmGetCARD8(file,&nRead); + nRead+= XkmSkipPadding(file,1); + if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_si)!=Success) + return -1; + compat= xkb->compat; + compat->num_si= num_si; + interp= compat->sym_interpret; + for (i=0;isym= wire.sym; + interp->mods= wire.mods; + interp->match= wire.match; + interp->virtual_mod= wire.virtualMod; + interp->flags= wire.flags; + interp->act.type= wire.actionType; + act = (XkbAction *) &interp->act; + + switch (interp->act.type) { + case XkbSA_SetMods: + case XkbSA_LatchMods: + case XkbSA_LockMods: + act->mods.flags = wire.actionData[0]; + act->mods.mask = wire.actionData[1]; + act->mods.real_mods = wire.actionData[2]; + act->mods.vmods1 = wire.actionData[3]; + act->mods.vmods2 = wire.actionData[4]; + break; + case XkbSA_SetGroup: + case XkbSA_LatchGroup: + case XkbSA_LockGroup: + act->group.flags = wire.actionData[0]; + act->group.group_XXX = wire.actionData[1]; + break; + case XkbSA_MovePtr: + act->ptr.flags = wire.actionData[0]; + act->ptr.high_XXX = wire.actionData[1]; + act->ptr.low_XXX = wire.actionData[2]; + act->ptr.high_YYY = wire.actionData[3]; + act->ptr.low_YYY = wire.actionData[4]; + break; + case XkbSA_PtrBtn: + case XkbSA_LockPtrBtn: + act->btn.flags = wire.actionData[0]; + act->btn.count = wire.actionData[1]; + act->btn.button = wire.actionData[2]; + break; + case XkbSA_DeviceBtn: + case XkbSA_LockDeviceBtn: + act->devbtn.flags = wire.actionData[0]; + act->devbtn.count = wire.actionData[1]; + act->devbtn.button = wire.actionData[2]; + act->devbtn.device = wire.actionData[3]; + break; + case XkbSA_SetPtrDflt: + act->dflt.flags = wire.actionData[0]; + act->dflt.affect = wire.actionData[1]; + act->dflt.valueXXX = wire.actionData[2]; + break; + case XkbSA_ISOLock: + act->iso.flags = wire.actionData[0]; + act->iso.mask = wire.actionData[1]; + act->iso.real_mods = wire.actionData[2]; + act->iso.group_XXX = wire.actionData[3]; + act->iso.affect = wire.actionData[4]; + act->iso.vmods1 = wire.actionData[5]; + act->iso.vmods2 = wire.actionData[6]; + break; + case XkbSA_SwitchScreen: + act->screen.flags = wire.actionData[0]; + act->screen.screenXXX = wire.actionData[1]; + break; + case XkbSA_SetControls: + case XkbSA_LockControls: + act->ctrls.flags = wire.actionData[0]; + act->ctrls.ctrls3 = wire.actionData[1]; + act->ctrls.ctrls2 = wire.actionData[2]; + act->ctrls.ctrls1 = wire.actionData[3]; + act->ctrls.ctrls0 = wire.actionData[4]; + break; + case XkbSA_RedirectKey: + act->redirect.new_key = wire.actionData[0]; + act->redirect.mods_mask = wire.actionData[1]; + act->redirect.mods = wire.actionData[2]; + act->redirect.vmods_mask0 = wire.actionData[3]; + act->redirect.vmods_mask1 = wire.actionData[4]; + act->redirect.vmods0 = wire.actionData[4]; + act->redirect.vmods1 = wire.actionData[5]; + break; + case XkbSA_DeviceValuator: + act->devval.device = wire.actionData[0]; + act->devval.v1_what = wire.actionData[1]; + act->devval.v1_ndx = wire.actionData[2]; + act->devval.v1_value = wire.actionData[3]; + act->devval.v2_what = wire.actionData[4]; + act->devval.v2_ndx = wire.actionData[5]; + act->devval.v2_what = wire.actionData[6]; + break; + + case XkbSA_XFree86Private: + /* copy the kind of action */ + strncpy((char*)act->any.data, (char*)wire.actionData, + XkbAnyActionDataSize); + break ; + + case XkbSA_Terminate: + /* no args, kinda (note: untrue for xfree86). */ + break; + case XkbSA_ActionMessage: + /* unsupported. */ + break; + } + } + if ((num_si>0)&&(changes)) { + changes->compat.first_si= 0; + changes->compat.num_si= num_si; + } + if (groups) { + register unsigned bit; + for (i=0,bit=1;icompat->groups[i].real_mods= md.realMods; + xkb->compat->groups[i].vmods= md.virtualMods; + if (md.virtualMods != 0) { + unsigned mask; + if (XkbVirtualModsToReal(xkb,md.virtualMods,&mask)) + xkb->compat->groups[i].mask= md.realMods|mask; + } + else xkb->compat->groups[i].mask= md.realMods; + } + } + if (changes) + changes->compat.changed_groups|= groups; + } + return nRead; +} + +static int +ReadXkmIndicators(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) +{ +register unsigned nLEDs; +xkmIndicatorMapDesc wire; +char buf[100]; +unsigned tmp; +int nRead=0; + + if ((xkb->indicators==NULL)&&(XkbAllocIndicatorMaps(xkb)!=Success)) { + _XkbLibError(_XkbErrBadAlloc,"indicator rec",0); + return -1; + } + if (XkbAllocNames(xkb,XkbIndicatorNamesMask,0,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"indicator names",0); + return -1; + } + nLEDs= XkmGetCARD8(file,&nRead); + nRead+= XkmSkipPadding(file,3); + xkb->indicators->phys_indicators= XkmGetCARD32(file,&nRead); + while (nLEDs-->0) { + Atom name; + XkbIndicatorMapPtr map; + + if ((tmp=XkmGetCountedString(file,buf,100))<1) { + _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0); + return -1; + } + nRead+= tmp; + if (buf[0]!='\0') + name= XkbInternAtom(buf,FALSE); + else name= None; + if ((tmp=fread(&wire,SIZEOF(xkmIndicatorMapDesc),1,file))<1) { + _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0); + return -1; + } + nRead+= tmp*SIZEOF(xkmIndicatorMapDesc); + if (xkb->names) { + xkb->names->indicators[wire.indicator-1]= name; + if (changes) + changes->names.changed_indicators|= (1<<(wire.indicator-1)); + } + map= &xkb->indicators->maps[wire.indicator-1]; + map->flags= wire.flags; + map->which_groups= wire.which_groups; + map->groups= wire.groups; + map->which_mods= wire.which_mods; + map->mods.mask= wire.real_mods; + map->mods.real_mods= wire.real_mods; + map->mods.vmods= wire.vmods; + map->ctrls= wire.ctrls; + } + return nRead; +} + +static XkbKeyTypePtr +FindTypeForKey(XkbDescPtr xkb,Atom name,unsigned width,KeySym *syms) +{ + if ((!xkb)||(!xkb->map)) + return NULL; + if (name!=None) { + register unsigned i; + for (i=0;imap->num_types;i++) { + if (xkb->map->types[i].name==name) { + if (xkb->map->types[i].num_levels!=width) + DebugF("Group width mismatch between key and type\n"); + return &xkb->map->types[i]; + } + } + } + if ((width<2)||((syms!=NULL)&&(syms[1]==NoSymbol))) + return &xkb->map->types[XkbOneLevelIndex]; + if (syms!=NULL) { + if (XkbKSIsLower(syms[0])&&XkbKSIsUpper(syms[1])) + return &xkb->map->types[XkbAlphabeticIndex]; + else if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1])) + return &xkb->map->types[XkbKeypadIndex]; + } + return &xkb->map->types[XkbTwoLevelIndex]; +} + +static int +ReadXkmSymbols(FILE *file,XkbDescPtr xkb) +{ +register int i,g,s,totalVModMaps; +xkmKeySymMapDesc wireMap; +char buf[100]; +unsigned minKC,maxKC,groupNames,tmp; +int nRead=0; + + if ((tmp=XkmGetCountedString(file,buf,100))<1) + return -1; + nRead+= tmp; + minKC= XkmGetCARD8(file,&nRead); + maxKC= XkmGetCARD8(file,&nRead); + groupNames= XkmGetCARD8(file,&nRead); + totalVModMaps= XkmGetCARD8(file,&nRead); + if (XkbAllocNames(xkb, + XkbSymbolsNameMask|XkbPhysSymbolsNameMask|XkbGroupNamesMask, + 0,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"physical names",0); + return -1; + } + if ((buf[0]!='\0')&&(xkb->names)) { + Atom name; + name= XkbInternAtom(buf,0); + xkb->names->symbols= name; + xkb->names->phys_symbols= name; + } + for (i=0,g=1;inames)) { + Atom name; + name= XkbInternAtom(buf,0); + xkb->names->groups[i]= name; + } + else xkb->names->groups[i]= None; + } + } + if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"server map",0); + return -1; + } + if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"client map",0); + return -1; + } + if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"controls",0); + return -1; + } + if ((xkb->map==NULL)||(xkb->server==NULL)) + return -1; + if (xkb->min_key_code<8) xkb->min_key_code= minKC; + if (xkb->max_key_code<8) xkb->max_key_code= maxKC; + if ((minKC>=8)&&(minKCmin_key_code)) + xkb->min_key_code= minKC; + if ((maxKC>=8)&&(maxKC>xkb->max_key_code)) { + _XkbLibError(_XkbErrBadValue,"keys in symbol map",maxKC); + return -1; + } + for (i=minKC;i<=(int)maxKC;i++) { + Atom typeName[XkbNumKbdGroups]; + XkbKeyTypePtr type[XkbNumKbdGroups]; + if ((tmp=fread(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file))<1) { + _XkbLibError(_XkbErrBadLength,"ReadXkmSymbols",0); + return -1; + } + nRead+= tmp*SIZEOF(xkmKeySymMapDesc); + bzero((char *)typeName,XkbNumKbdGroups*sizeof(Atom)); + bzero((char *)type,XkbNumKbdGroups*sizeof(XkbKeyTypePtr)); + if (wireMap.flags&XkmKeyHasTypes) { + register int g; + for (g=0;g0)) { + typeName[g]= XkbInternAtom(buf,1); + nRead+= tmp; + } + type[g]=FindTypeForKey(xkb,typeName[g],wireMap.width,NULL); + if (type[g]==NULL) { + _XkbLibError(_XkbErrMissingTypes,"ReadXkmSymbols",0); + return -1; + } + if (typeName[g]==type[g]->name) + xkb->server->explicit[i]|= (1<ctrls->per_key_repeat[i/8]|= (1<<(i%8)); + xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask; + } + else if (wireMap.flags&XkmNonRepeatingKey) { + xkb->ctrls->per_key_repeat[i/8]&= ~(1<<(i%8)); + xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask; + } + xkb->map->modmap[i]= wireMap.modifier_map; + if (XkbNumGroups(wireMap.num_groups)>0) { + KeySym *sym; + int nSyms; + + if (XkbNumGroups(wireMap.num_groups)>xkb->ctrls->num_groups) + xkb->ctrls->num_groups= wireMap.num_groups; + nSyms= XkbNumGroups(wireMap.num_groups)*wireMap.width; + sym= XkbResizeKeySyms(xkb,i,nSyms); + if (!sym) + return -1; + for (s=0;sserver->explicit[i]|= XkbExplicitInterpretMask; + } + } + for (g=0;gserver->explicit[i]&(1<map->key_sym_map[i].kt_index[g]= type[g]-(&xkb->map->types[0]); + } + xkb->map->key_sym_map[i].group_info= wireMap.num_groups; + xkb->map->key_sym_map[i].width= wireMap.width; + if (wireMap.flags&XkmKeyHasBehavior) { + xkmBehaviorDesc b; + tmp= fread(&b,SIZEOF(xkmBehaviorDesc),1,file); + nRead+= tmp*SIZEOF(xkmBehaviorDesc); + xkb->server->behaviors[i].type= b.type; + xkb->server->behaviors[i].data= b.data; + xkb->server->explicit[i]|= XkbExplicitBehaviorMask; + } + } + if (totalVModMaps>0) { + xkmVModMapDesc v; + for (i=0;i0) + xkb->server->vmodmap[v.key]= v.vmods; + } + } + return nRead; +} + +static int +ReadXkmGeomDoodad( + FILE * file, + XkbGeometryPtr geom, + XkbSectionPtr section) +{ +XkbDoodadPtr doodad; +xkmDoodadDesc doodadWire; +char buf[100]; +unsigned tmp; +int nRead=0; + + nRead+= XkmGetCountedString(file,buf,100); + tmp= fread(&doodadWire,SIZEOF(xkmDoodadDesc),1,file); + nRead+= SIZEOF(xkmDoodadDesc)*tmp; + doodad= XkbAddGeomDoodad(geom,section,XkbInternAtom(buf,FALSE)); + if (!doodad) + return nRead; + doodad->any.type= doodadWire.any.type; + doodad->any.priority= doodadWire.any.priority; + doodad->any.top= doodadWire.any.top; + doodad->any.left= doodadWire.any.left; + switch (doodadWire.any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + doodad->shape.angle= doodadWire.shape.angle; + doodad->shape.color_ndx= doodadWire.shape.color_ndx; + doodad->shape.shape_ndx= doodadWire.shape.shape_ndx; + break; + case XkbTextDoodad: + doodad->text.angle= doodadWire.text.angle; + doodad->text.width= doodadWire.text.width; + doodad->text.height= doodadWire.text.height; + doodad->text.color_ndx= doodadWire.text.color_ndx; + nRead+= XkmGetCountedString(file,buf,100); + doodad->text.text= _XkbDupString(buf); + nRead+= XkmGetCountedString(file,buf,100); + doodad->text.font= _XkbDupString(buf); + break; + case XkbIndicatorDoodad: + doodad->indicator.shape_ndx= doodadWire.indicator.shape_ndx; + doodad->indicator.on_color_ndx= doodadWire.indicator.on_color_ndx; + doodad->indicator.off_color_ndx= doodadWire.indicator.off_color_ndx; + break; + case XkbLogoDoodad: + doodad->logo.angle= doodadWire.logo.angle; + doodad->logo.color_ndx= doodadWire.logo.color_ndx; + doodad->logo.shape_ndx= doodadWire.logo.shape_ndx; + nRead+= XkmGetCountedString(file,buf,100); + doodad->logo.logo_name= _XkbDupString(buf); + break; + default: + /* report error? */ + return nRead; + } + return nRead; +} + +static int +ReadXkmGeomOverlay( FILE * file, + XkbGeometryPtr geom, + XkbSectionPtr section) +{ +char buf[100]; +unsigned tmp; +int nRead=0; +XkbOverlayPtr ol; +XkbOverlayRowPtr row; +xkmOverlayDesc olWire; +xkmOverlayRowDesc rowWire; +register int r; + + nRead+= XkmGetCountedString(file,buf,100); + tmp= fread(&olWire,SIZEOF(xkmOverlayDesc),1,file); + nRead+= tmp*SIZEOF(xkmOverlayDesc); + ol= XkbAddGeomOverlay(section,XkbInternAtom(buf,FALSE), + olWire.num_rows); + if (!ol) + return nRead; + for (r=0;rkeys[k].over.name,keyWire.over,XkbKeyNameLength); + memcpy(row->keys[k].under.name,keyWire.under,XkbKeyNameLength); + } + row->num_keys= rowWire.num_keys; + } + return nRead; +} + +static int +ReadXkmGeomSection( FILE * file, + XkbGeometryPtr geom) +{ +register int i; +XkbSectionPtr section; +xkmSectionDesc sectionWire; +unsigned tmp; +int nRead= 0; +char buf[100]; +Atom nameAtom; + + nRead+= XkmGetCountedString(file,buf,100); + nameAtom= XkbInternAtom(buf,FALSE); + tmp= fread(§ionWire,SIZEOF(xkmSectionDesc),1,file); + nRead+= SIZEOF(xkmSectionDesc)*tmp; + section= XkbAddGeomSection(geom,nameAtom,sectionWire.num_rows, + sectionWire.num_doodads, + sectionWire.num_overlays); + if (!section) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0); + return nRead; + } + section->top= sectionWire.top; + section->left= sectionWire.left; + section->width= sectionWire.width; + section->height= sectionWire.height; + section->angle= sectionWire.angle; + section->priority= sectionWire.priority; + if (sectionWire.num_rows>0) { + register int k; + XkbRowPtr row; + xkmRowDesc rowWire; + XkbKeyPtr key; + xkmKeyDesc keyWire; + + for (i=0;itop= rowWire.top; + row->left= rowWire.left; + row->vertical= rowWire.vertical; + for (k=0;kname.name,keyWire.name,XkbKeyNameLength); + key->gap= keyWire.gap; + key->shape_ndx= keyWire.shape_ndx; + key->color_ndx= keyWire.color_ndx; + } + } + } + if (sectionWire.num_doodads>0) { + for (i=0;i0) { + for (i=0;igeom; + geom->name= XkbInternAtom(buf,FALSE); + geom->width_mm= wireGeom.width_mm; + geom->height_mm= wireGeom.height_mm; + nRead+= XkmGetCountedString(file,buf,100); + geom->label_font= _XkbDupString(buf); + if (wireGeom.num_properties>0) { + char val[1024]; + for (i=0;i0) { + for (i=0;ibase_color= &geom->colors[wireGeom.base_color_ndx]; + geom->label_color= &geom->colors[wireGeom.label_color_ndx]; + if (wireGeom.num_shapes>0) { + XkbShapePtr shape; + xkmShapeDesc shapeWire; + Atom nameAtom; + for (i=0;inum_points= olWire.num_points; + ol->corner_radius= olWire.corner_radius; + for (p=0;ppoints[p].x= ptWire.x; + ol->points[p].y= ptWire.y; + if (ptWire.xbounds.x1) shape->bounds.x1= ptWire.x; + if (ptWire.x>shape->bounds.x2) shape->bounds.x2= ptWire.x; + if (ptWire.ybounds.y1) shape->bounds.y1= ptWire.y; + if (ptWire.y>shape->bounds.y2) shape->bounds.y2= ptWire.y; + } + } + if (shapeWire.primary_ndx!=XkbNoShape) + shape->primary= &shape->outlines[shapeWire.primary_ndx]; + if (shapeWire.approx_ndx!=XkbNoShape) + shape->approx= &shape->outlines[shapeWire.approx_ndx]; + } + } + if (wireGeom.num_sections>0) { + for (i=0;i0) { + for (i=0;i0)&&(geom->key_aliases)) { + int sz= XkbKeyNameLength*2; + int num= wireGeom.num_key_aliases; + if (fread(geom->key_aliases,sz,num,file)!=num) { + _XkbLibError(_XkbErrBadLength,"ReadXkmGeometry",0); + return -1; + } + nRead+= (num*sz); + geom->num_key_aliases= num; + } + return nRead; +} + +Bool +XkmProbe(FILE *file) +{ +unsigned hdr,tmp; +int nRead=0; + + hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); + tmp= XkmGetCARD32(file,&nRead); + if (tmp!=hdr) { + if ((tmp&(~0xff))==(hdr&(~0xff))) { + _XkbLibError(_XkbErrBadFileVersion,"XkmProbe",tmp&0xff); + } + return 0; + } + return 1; +} + +static Bool +XkmReadTOC(FILE *file,xkmFileInfo* file_info,int max_toc,xkmSectionInfo *toc) +{ +unsigned hdr,tmp; +int nRead=0; +unsigned i,size_toc; + + hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); + tmp= XkmGetCARD32(file,&nRead); + if (tmp!=hdr) { + if ((tmp&(~0xff))==(hdr&(~0xff))) { + _XkbLibError(_XkbErrBadFileVersion,"XkmReadTOC",tmp&0xff); + } + else { + _XkbLibError(_XkbErrBadFileType,"XkmReadTOC",tmp); + } + return 0; + } + fread(file_info,SIZEOF(xkmFileInfo),1,file); + size_toc= file_info->num_toc; + if (size_toc>max_toc) { + DebugF("Warning! Too many TOC entries; last %d ignored\n", + size_toc-max_toc); + size_toc= max_toc; + } + for (i=0;i0) { + nRead+= tmp; + which&= ~(1<defined|= (1<