1706f2543Smrg/************************************************************ 2706f2543Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 3706f2543Smrg 4706f2543Smrg Permission to use, copy, modify, and distribute this 5706f2543Smrg software and its documentation for any purpose and without 6706f2543Smrg fee is hereby granted, provided that the above copyright 7706f2543Smrg notice appear in all copies and that both that copyright 8706f2543Smrg notice and this permission notice appear in supporting 9706f2543Smrg documentation, and that the name of Silicon Graphics not be 10706f2543Smrg used in advertising or publicity pertaining to distribution 11706f2543Smrg of the software without specific prior written permission. 12706f2543Smrg Silicon Graphics makes no representation about the suitability 13706f2543Smrg of this software for any purpose. It is provided "as is" 14706f2543Smrg without any express or implied warranty. 15706f2543Smrg 16706f2543Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17706f2543Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18706f2543Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19706f2543Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20706f2543Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21706f2543Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22706f2543Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23706f2543Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 24706f2543Smrg 25706f2543Smrg ********************************************************/ 26706f2543Smrg 27706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 28706f2543Smrg#include <dix-config.h> 29706f2543Smrg#endif 30706f2543Smrg 31706f2543Smrg#include <stdio.h> 32706f2543Smrg 33706f2543Smrg#include <X11/Xos.h> 34706f2543Smrg#include <X11/Xfuncs.h> 35706f2543Smrg 36706f2543Smrg#include <X11/X.h> 37706f2543Smrg#include <X11/Xproto.h> 38706f2543Smrg#include <X11/keysym.h> 39706f2543Smrg#include <X11/extensions/XKMformat.h> 40706f2543Smrg#include "misc.h" 41706f2543Smrg#include "inputstr.h" 42706f2543Smrg#include "xkbstr.h" 43706f2543Smrg#include "xkbsrv.h" 44706f2543Smrg#include "xkbgeom.h" 45706f2543Smrg 46706f2543SmrgAtom 47706f2543SmrgXkbInternAtom(char *str,Bool only_if_exists) 48706f2543Smrg{ 49706f2543Smrg if (str==NULL) 50706f2543Smrg return None; 51706f2543Smrg return MakeAtom(str,strlen(str),!only_if_exists); 52706f2543Smrg} 53706f2543Smrg 54706f2543Smrgchar * 55706f2543Smrg_XkbDupString(const char *str) 56706f2543Smrg{ 57706f2543Smrgchar *new; 58706f2543Smrg 59706f2543Smrg if (str==NULL) 60706f2543Smrg return NULL; 61706f2543Smrg new= calloc(strlen(str)+1,sizeof(char)); 62706f2543Smrg if (new) 63706f2543Smrg strcpy(new,str); 64706f2543Smrg return new; 65706f2543Smrg} 66706f2543Smrg 67706f2543Smrg/***====================================================================***/ 68706f2543Smrg 69706f2543Smrgstatic void * 70706f2543SmrgXkmInsureSize(void *oldPtr,int oldCount,int *newCountRtrn,int elemSize) 71706f2543Smrg{ 72706f2543Smrgint newCount= *newCountRtrn; 73706f2543Smrg 74706f2543Smrg if (oldPtr==NULL) { 75706f2543Smrg if (newCount==0) 76706f2543Smrg return NULL; 77706f2543Smrg oldPtr= calloc(newCount,elemSize); 78706f2543Smrg } 79706f2543Smrg else if (oldCount<newCount) { 80706f2543Smrg oldPtr= realloc(oldPtr,newCount*elemSize); 81706f2543Smrg if (oldPtr!=NULL) { 82706f2543Smrg char *tmp= (char *)oldPtr; 83706f2543Smrg memset(&tmp[oldCount*elemSize], 0, (newCount-oldCount)*elemSize); 84706f2543Smrg } 85706f2543Smrg } 86706f2543Smrg else if (newCount<oldCount) { 87706f2543Smrg *newCountRtrn= oldCount; 88706f2543Smrg } 89706f2543Smrg return oldPtr; 90706f2543Smrg} 91706f2543Smrg 92706f2543Smrg#define XkmInsureTypedSize(p,o,n,t) ((p)=((t *)XkmInsureSize((char *)(p),(o),(n),sizeof(t)))) 93706f2543Smrg 94706f2543Smrgstatic CARD8 95706f2543SmrgXkmGetCARD8(FILE *file,int *pNRead) 96706f2543Smrg{ 97706f2543Smrgint tmp; 98706f2543Smrg tmp= getc(file); 99706f2543Smrg if (pNRead&&(tmp!=EOF)) 100706f2543Smrg (*pNRead)+= 1; 101706f2543Smrg return tmp; 102706f2543Smrg} 103706f2543Smrg 104706f2543Smrgstatic CARD16 105706f2543SmrgXkmGetCARD16(FILE *file,int *pNRead) 106706f2543Smrg{ 107706f2543SmrgCARD16 val; 108706f2543Smrg 109706f2543Smrg if ((fread(&val,2,1,file)==1)&&(pNRead)) 110706f2543Smrg (*pNRead)+= 2; 111706f2543Smrg return val; 112706f2543Smrg} 113706f2543Smrg 114706f2543Smrgstatic CARD32 115706f2543SmrgXkmGetCARD32(FILE *file,int *pNRead) 116706f2543Smrg{ 117706f2543SmrgCARD32 val; 118706f2543Smrg 119706f2543Smrg if ((fread(&val,4,1,file)==1)&&(pNRead)) 120706f2543Smrg (*pNRead)+= 4; 121706f2543Smrg return val; 122706f2543Smrg} 123706f2543Smrg 124706f2543Smrgstatic int 125706f2543SmrgXkmSkipPadding(FILE *file,unsigned pad) 126706f2543Smrg{ 127706f2543Smrgregister int i,nRead=0; 128706f2543Smrg 129706f2543Smrg for (i=0;i<pad;i++) { 130706f2543Smrg if (getc(file)!=EOF) 131706f2543Smrg nRead++; 132706f2543Smrg } 133706f2543Smrg return nRead; 134706f2543Smrg} 135706f2543Smrg 136706f2543Smrgstatic int 137706f2543SmrgXkmGetCountedString(FILE *file,char *str,int max_len) 138706f2543Smrg{ 139706f2543Smrgint count,nRead=0; 140706f2543Smrg 141706f2543Smrg count= XkmGetCARD16(file,&nRead); 142706f2543Smrg if (count>0) { 143706f2543Smrg int tmp; 144706f2543Smrg if (count>max_len) { 145706f2543Smrg tmp= fread(str,1,max_len,file); 146706f2543Smrg while (tmp<count) { 147706f2543Smrg if ((getc(file))!=EOF) 148706f2543Smrg tmp++; 149706f2543Smrg else break; 150706f2543Smrg } 151706f2543Smrg } 152706f2543Smrg else { 153706f2543Smrg tmp= fread(str,1,count,file); 154706f2543Smrg } 155706f2543Smrg nRead+= tmp; 156706f2543Smrg } 157706f2543Smrg if (count>=max_len) str[max_len-1]= '\0'; 158706f2543Smrg else str[count]= '\0'; 159706f2543Smrg count= XkbPaddedSize(nRead)-nRead; 160706f2543Smrg if (count>0) 161706f2543Smrg nRead+= XkmSkipPadding(file,count); 162706f2543Smrg return nRead; 163706f2543Smrg} 164706f2543Smrg 165706f2543Smrg/***====================================================================***/ 166706f2543Smrg 167706f2543Smrgstatic int 168706f2543SmrgReadXkmVirtualMods(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) 169706f2543Smrg{ 170706f2543Smrgregister unsigned int i,bit; 171706f2543Smrgunsigned int bound,named,tmp; 172706f2543Smrgint nRead=0; 173706f2543Smrg 174706f2543Smrg if (XkbAllocServerMap(xkb,XkbVirtualModsMask,0)!=Success) { 175706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0); 176706f2543Smrg return -1; 177706f2543Smrg } 178706f2543Smrg bound= XkmGetCARD16(file,&nRead); 179706f2543Smrg named= XkmGetCARD16(file,&nRead); 180706f2543Smrg for (i=tmp=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 181706f2543Smrg if (bound&bit) { 182706f2543Smrg xkb->server->vmods[i]= XkmGetCARD8(file,&nRead); 183706f2543Smrg if (changes) 184706f2543Smrg changes->map.vmods|= bit; 185706f2543Smrg tmp++; 186706f2543Smrg } 187706f2543Smrg } 188706f2543Smrg if ((i= XkbPaddedSize(tmp)-tmp)>0) 189706f2543Smrg nRead+= XkmSkipPadding(file,i); 190706f2543Smrg if (XkbAllocNames(xkb,XkbVirtualModNamesMask,0,0)!=Success) { 191706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0); 192706f2543Smrg return -1; 193706f2543Smrg } 194706f2543Smrg for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 195706f2543Smrg char name[100]; 196706f2543Smrg if (named&bit) { 197706f2543Smrg if (nRead+=XkmGetCountedString(file,name,100)) { 198706f2543Smrg xkb->names->vmods[i]= XkbInternAtom(name,FALSE); 199706f2543Smrg if (changes) 200706f2543Smrg changes->names.changed_vmods|= bit; 201706f2543Smrg } 202706f2543Smrg } 203706f2543Smrg } 204706f2543Smrg return nRead; 205706f2543Smrg} 206706f2543Smrg 207706f2543Smrg/***====================================================================***/ 208706f2543Smrg 209706f2543Smrgstatic int 210706f2543SmrgReadXkmKeycodes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) 211706f2543Smrg{ 212706f2543Smrgregister int i; 213706f2543Smrgunsigned minKC,maxKC,nAl; 214706f2543Smrgint nRead=0; 215706f2543Smrgchar name[100]; 216706f2543SmrgXkbKeyNamePtr pN; 217706f2543Smrg 218706f2543Smrg name[0]= '\0'; 219706f2543Smrg nRead+= XkmGetCountedString(file,name,100); 220706f2543Smrg minKC= XkmGetCARD8(file,&nRead); 221706f2543Smrg maxKC= XkmGetCARD8(file,&nRead); 222706f2543Smrg if (xkb->min_key_code==0) { 223706f2543Smrg xkb->min_key_code= minKC; 224706f2543Smrg xkb->max_key_code= maxKC; 225706f2543Smrg } 226706f2543Smrg else { 227706f2543Smrg if (minKC<xkb->min_key_code) 228706f2543Smrg xkb->min_key_code= minKC; 229706f2543Smrg if (maxKC>xkb->max_key_code) { 230706f2543Smrg _XkbLibError(_XkbErrBadValue,"ReadXkmKeycodes",maxKC); 231706f2543Smrg return -1; 232706f2543Smrg } 233706f2543Smrg } 234706f2543Smrg nAl= XkmGetCARD8(file,&nRead); 235706f2543Smrg nRead+= XkmSkipPadding(file,1); 236706f2543Smrg 237706f2543Smrg#define WANTED (XkbKeycodesNameMask|XkbKeyNamesMask|XkbKeyAliasesMask) 238706f2543Smrg if (XkbAllocNames(xkb,WANTED,0,nAl)!=Success) { 239706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0); 240706f2543Smrg return -1; 241706f2543Smrg } 242706f2543Smrg if (name[0]!='\0') { 243706f2543Smrg xkb->names->keycodes= XkbInternAtom(name,FALSE); 244706f2543Smrg } 245706f2543Smrg 246706f2543Smrg for (pN=&xkb->names->keys[minKC],i=minKC;i<=(int)maxKC;i++,pN++) { 247706f2543Smrg if (fread(pN,1,XkbKeyNameLength,file)!=XkbKeyNameLength) { 248706f2543Smrg _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0); 249706f2543Smrg return -1; 250706f2543Smrg } 251706f2543Smrg nRead+= XkbKeyNameLength; 252706f2543Smrg } 253706f2543Smrg if (nAl>0) { 254706f2543Smrg XkbKeyAliasPtr pAl; 255706f2543Smrg for (pAl= xkb->names->key_aliases,i=0;i<nAl;i++,pAl++) { 256706f2543Smrg int tmp; 257706f2543Smrg tmp= fread(pAl,1,2*XkbKeyNameLength,file); 258706f2543Smrg if (tmp!=2*XkbKeyNameLength) { 259706f2543Smrg _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0); 260706f2543Smrg return -1; 261706f2543Smrg } 262706f2543Smrg nRead+= 2*XkbKeyNameLength; 263706f2543Smrg } 264706f2543Smrg if (changes) 265706f2543Smrg changes->names.changed|= XkbKeyAliasesMask; 266706f2543Smrg } 267706f2543Smrg if (changes) 268706f2543Smrg changes->names.changed|= XkbKeyNamesMask; 269706f2543Smrg return nRead; 270706f2543Smrg} 271706f2543Smrg 272706f2543Smrg/***====================================================================***/ 273706f2543Smrg 274706f2543Smrgstatic int 275706f2543SmrgReadXkmKeyTypes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) 276706f2543Smrg{ 277706f2543Smrgregister unsigned i,n; 278706f2543Smrgunsigned num_types; 279706f2543Smrgint nRead=0; 280706f2543Smrgint tmp; 281706f2543SmrgXkbKeyTypePtr type; 282706f2543SmrgxkmKeyTypeDesc wire; 283706f2543SmrgXkbKTMapEntryPtr entry; 284706f2543SmrgxkmKTMapEntryDesc wire_entry; 285706f2543Smrgchar buf[100]; 286706f2543Smrg 287706f2543Smrg if ((tmp= XkmGetCountedString(file,buf,100))<1) { 288706f2543Smrg _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0); 289706f2543Smrg return -1; 290706f2543Smrg } 291706f2543Smrg nRead+= tmp; 292706f2543Smrg if (buf[0]!='\0') { 293706f2543Smrg if (XkbAllocNames(xkb,XkbTypesNameMask,0,0)!=Success) { 294706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0); 295706f2543Smrg return -1; 296706f2543Smrg } 297706f2543Smrg xkb->names->types= XkbInternAtom(buf,FALSE); 298706f2543Smrg } 299706f2543Smrg num_types= XkmGetCARD16(file,&nRead); 300706f2543Smrg nRead+= XkmSkipPadding(file,2); 301706f2543Smrg if (num_types<1) 302706f2543Smrg return nRead; 303706f2543Smrg if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_types)!=Success) { 304706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0); 305706f2543Smrg return nRead; 306706f2543Smrg } 307706f2543Smrg xkb->map->num_types= num_types; 308706f2543Smrg if (num_types<XkbNumRequiredTypes) { 309706f2543Smrg _XkbLibError(_XkbErrMissingReqTypes,"ReadXkmKeyTypes",0); 310706f2543Smrg return -1; 311706f2543Smrg } 312706f2543Smrg type= xkb->map->types; 313706f2543Smrg for (i=0;i<num_types;i++,type++) { 314706f2543Smrg if ((int)fread(&wire,SIZEOF(xkmKeyTypeDesc),1,file)<1) { 315706f2543Smrg _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0); 316706f2543Smrg return -1; 317706f2543Smrg } 318706f2543Smrg nRead+= SIZEOF(xkmKeyTypeDesc); 319706f2543Smrg if (((i==XkbOneLevelIndex)&&(wire.numLevels!=1))|| 320706f2543Smrg (((i==XkbTwoLevelIndex)||(i==XkbAlphabeticIndex)|| 321706f2543Smrg ((i)==XkbKeypadIndex))&&(wire.numLevels!=2))) { 322706f2543Smrg _XkbLibError(_XkbErrBadTypeWidth,"ReadXkmKeyTypes",i); 323706f2543Smrg return -1; 324706f2543Smrg } 325706f2543Smrg tmp= wire.nMapEntries; 326706f2543Smrg XkmInsureTypedSize(type->map,type->map_count,&tmp,XkbKTMapEntryRec); 327706f2543Smrg if ((wire.nMapEntries>0)&&(type->map==NULL)) { 328706f2543Smrg _XkbLibError(_XkbErrBadValue,"ReadXkmKeyTypes",wire.nMapEntries); 329706f2543Smrg return -1; 330706f2543Smrg } 331706f2543Smrg for (n=0,entry= type->map;n<wire.nMapEntries;n++,entry++) { 332706f2543Smrg if (fread(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file)<(int)1) { 333706f2543Smrg _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0); 334706f2543Smrg return -1; 335706f2543Smrg } 336706f2543Smrg nRead+= SIZEOF(xkmKTMapEntryDesc); 337706f2543Smrg entry->active= (wire_entry.virtualMods==0); 338706f2543Smrg entry->level= wire_entry.level; 339706f2543Smrg entry->mods.mask= wire_entry.realMods; 340706f2543Smrg entry->mods.real_mods= wire_entry.realMods; 341706f2543Smrg entry->mods.vmods= wire_entry.virtualMods; 342706f2543Smrg } 343706f2543Smrg nRead+= XkmGetCountedString(file,buf,100); 344706f2543Smrg if (((i==XkbOneLevelIndex)&&(strcmp(buf,"ONE_LEVEL")!=0))|| 345706f2543Smrg ((i==XkbTwoLevelIndex)&&(strcmp(buf,"TWO_LEVEL")!=0))|| 346706f2543Smrg ((i==XkbAlphabeticIndex)&&(strcmp(buf,"ALPHABETIC")!=0))|| 347706f2543Smrg ((i==XkbKeypadIndex)&&(strcmp(buf,"KEYPAD")!=0))) { 348706f2543Smrg _XkbLibError(_XkbErrBadTypeName,"ReadXkmKeyTypes",0); 349706f2543Smrg return -1; 350706f2543Smrg } 351706f2543Smrg if (buf[0]!='\0') { 352706f2543Smrg type->name= XkbInternAtom(buf,FALSE); 353706f2543Smrg } 354706f2543Smrg else type->name= None; 355706f2543Smrg 356706f2543Smrg if (wire.preserve) { 357706f2543Smrg xkmModsDesc p_entry; 358706f2543Smrg XkbModsPtr pre; 359706f2543Smrg XkmInsureTypedSize(type->preserve,type->map_count,&tmp, 360706f2543Smrg XkbModsRec); 361706f2543Smrg if (type->preserve==NULL) { 362706f2543Smrg _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0); 363706f2543Smrg return -1; 364706f2543Smrg } 365706f2543Smrg for (n=0,pre=type->preserve;n<wire.nMapEntries;n++,pre++) { 366706f2543Smrg if (fread(&p_entry,SIZEOF(xkmModsDesc),1,file)<1) { 367706f2543Smrg _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0); 368706f2543Smrg return -1; 369706f2543Smrg } 370706f2543Smrg nRead+= SIZEOF(xkmModsDesc); 371706f2543Smrg pre->mask= p_entry.realMods; 372706f2543Smrg pre->real_mods= p_entry.realMods; 373706f2543Smrg pre->vmods= p_entry.virtualMods; 374706f2543Smrg } 375706f2543Smrg } 376706f2543Smrg if (wire.nLevelNames>0) { 377706f2543Smrg int width= wire.numLevels; 378706f2543Smrg if (wire.nLevelNames>(unsigned)width) { 379706f2543Smrg _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0); 380706f2543Smrg return -1; 381706f2543Smrg } 382706f2543Smrg XkmInsureTypedSize(type->level_names,type->num_levels,&width,Atom); 383706f2543Smrg if (type->level_names!=NULL) { 384706f2543Smrg for (n=0;n<wire.nLevelNames;n++) { 385706f2543Smrg if ((tmp=XkmGetCountedString(file,buf,100))<1) 386706f2543Smrg return -1; 387706f2543Smrg nRead+= tmp; 388706f2543Smrg if (strlen(buf)==0) 389706f2543Smrg type->level_names[n]= None; 390706f2543Smrg else type->level_names[n]= XkbInternAtom(buf,0); 391706f2543Smrg } 392706f2543Smrg } 393706f2543Smrg } 394706f2543Smrg type->mods.mask= wire.realMods; 395706f2543Smrg type->mods.real_mods= wire.realMods; 396706f2543Smrg type->mods.vmods= wire.virtualMods; 397706f2543Smrg type->num_levels= wire.numLevels; 398706f2543Smrg type->map_count= wire.nMapEntries; 399706f2543Smrg } 400706f2543Smrg if (changes) { 401706f2543Smrg changes->map.changed|= XkbKeyTypesMask; 402706f2543Smrg changes->map.first_type= 0; 403706f2543Smrg changes->map.num_types= xkb->map->num_types; 404706f2543Smrg } 405706f2543Smrg return nRead; 406706f2543Smrg} 407706f2543Smrg 408706f2543Smrg/***====================================================================***/ 409706f2543Smrg 410706f2543Smrgstatic int 411706f2543SmrgReadXkmCompatMap(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) 412706f2543Smrg{ 413706f2543Smrgregister int i; 414706f2543Smrgunsigned num_si,groups; 415706f2543Smrgchar name[100]; 416706f2543SmrgXkbSymInterpretPtr interp; 417706f2543SmrgxkmSymInterpretDesc wire; 418706f2543Smrgunsigned tmp; 419706f2543Smrgint nRead=0; 420706f2543SmrgXkbCompatMapPtr compat; 421706f2543SmrgXkbAction *act; 422706f2543Smrg 423706f2543Smrg if ((tmp= XkmGetCountedString(file,name,100))<1) { 424706f2543Smrg _XkbLibError(_XkbErrBadLength,"ReadXkmCompatMap",0); 425706f2543Smrg return -1; 426706f2543Smrg } 427706f2543Smrg nRead+= tmp; 428706f2543Smrg if (name[0]!='\0') { 429706f2543Smrg if (XkbAllocNames(xkb,XkbCompatNameMask,0,0)!=Success) { 430706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmCompatMap",0); 431706f2543Smrg return -1; 432706f2543Smrg } 433706f2543Smrg xkb->names->compat= XkbInternAtom(name,FALSE); 434706f2543Smrg } 435706f2543Smrg num_si= XkmGetCARD16(file,&nRead); 436706f2543Smrg groups= XkmGetCARD8(file,&nRead); 437706f2543Smrg nRead+= XkmSkipPadding(file,1); 438706f2543Smrg if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_si)!=Success) 439706f2543Smrg return -1; 440706f2543Smrg compat= xkb->compat; 441706f2543Smrg compat->num_si= num_si; 442706f2543Smrg interp= compat->sym_interpret; 443706f2543Smrg for (i=0;i<num_si;i++,interp++) { 444706f2543Smrg tmp= fread(&wire,SIZEOF(xkmSymInterpretDesc),1,file); 445706f2543Smrg nRead+= tmp*SIZEOF(xkmSymInterpretDesc); 446706f2543Smrg interp->sym= wire.sym; 447706f2543Smrg interp->mods= wire.mods; 448706f2543Smrg interp->match= wire.match; 449706f2543Smrg interp->virtual_mod= wire.virtualMod; 450706f2543Smrg interp->flags= wire.flags; 451706f2543Smrg interp->act.type= wire.actionType; 452706f2543Smrg act = (XkbAction *) &interp->act; 453706f2543Smrg 454706f2543Smrg switch (interp->act.type) { 455706f2543Smrg case XkbSA_SetMods: 456706f2543Smrg case XkbSA_LatchMods: 457706f2543Smrg case XkbSA_LockMods: 458706f2543Smrg act->mods.flags = wire.actionData[0]; 459706f2543Smrg act->mods.mask = wire.actionData[1]; 460706f2543Smrg act->mods.real_mods = wire.actionData[2]; 461706f2543Smrg act->mods.vmods1 = wire.actionData[3]; 462706f2543Smrg act->mods.vmods2 = wire.actionData[4]; 463706f2543Smrg break; 464706f2543Smrg case XkbSA_SetGroup: 465706f2543Smrg case XkbSA_LatchGroup: 466706f2543Smrg case XkbSA_LockGroup: 467706f2543Smrg act->group.flags = wire.actionData[0]; 468706f2543Smrg act->group.group_XXX = wire.actionData[1]; 469706f2543Smrg break; 470706f2543Smrg case XkbSA_MovePtr: 471706f2543Smrg act->ptr.flags = wire.actionData[0]; 472706f2543Smrg act->ptr.high_XXX = wire.actionData[1]; 473706f2543Smrg act->ptr.low_XXX = wire.actionData[2]; 474706f2543Smrg act->ptr.high_YYY = wire.actionData[3]; 475706f2543Smrg act->ptr.low_YYY = wire.actionData[4]; 476706f2543Smrg break; 477706f2543Smrg case XkbSA_PtrBtn: 478706f2543Smrg case XkbSA_LockPtrBtn: 479706f2543Smrg act->btn.flags = wire.actionData[0]; 480706f2543Smrg act->btn.count = wire.actionData[1]; 481706f2543Smrg act->btn.button = wire.actionData[2]; 482706f2543Smrg break; 483706f2543Smrg case XkbSA_DeviceBtn: 484706f2543Smrg case XkbSA_LockDeviceBtn: 485706f2543Smrg act->devbtn.flags = wire.actionData[0]; 486706f2543Smrg act->devbtn.count = wire.actionData[1]; 487706f2543Smrg act->devbtn.button = wire.actionData[2]; 488706f2543Smrg act->devbtn.device = wire.actionData[3]; 489706f2543Smrg break; 490706f2543Smrg case XkbSA_SetPtrDflt: 491706f2543Smrg act->dflt.flags = wire.actionData[0]; 492706f2543Smrg act->dflt.affect = wire.actionData[1]; 493706f2543Smrg act->dflt.valueXXX = wire.actionData[2]; 494706f2543Smrg break; 495706f2543Smrg case XkbSA_ISOLock: 496706f2543Smrg act->iso.flags = wire.actionData[0]; 497706f2543Smrg act->iso.mask = wire.actionData[1]; 498706f2543Smrg act->iso.real_mods = wire.actionData[2]; 499706f2543Smrg act->iso.group_XXX = wire.actionData[3]; 500706f2543Smrg act->iso.affect = wire.actionData[4]; 501706f2543Smrg act->iso.vmods1 = wire.actionData[5]; 502706f2543Smrg act->iso.vmods2 = wire.actionData[6]; 503706f2543Smrg break; 504706f2543Smrg case XkbSA_SwitchScreen: 505706f2543Smrg act->screen.flags = wire.actionData[0]; 506706f2543Smrg act->screen.screenXXX = wire.actionData[1]; 507706f2543Smrg break; 508706f2543Smrg case XkbSA_SetControls: 509706f2543Smrg case XkbSA_LockControls: 510706f2543Smrg act->ctrls.flags = wire.actionData[0]; 511706f2543Smrg act->ctrls.ctrls3 = wire.actionData[1]; 512706f2543Smrg act->ctrls.ctrls2 = wire.actionData[2]; 513706f2543Smrg act->ctrls.ctrls1 = wire.actionData[3]; 514706f2543Smrg act->ctrls.ctrls0 = wire.actionData[4]; 515706f2543Smrg break; 516706f2543Smrg case XkbSA_RedirectKey: 517706f2543Smrg act->redirect.new_key = wire.actionData[0]; 518706f2543Smrg act->redirect.mods_mask = wire.actionData[1]; 519706f2543Smrg act->redirect.mods = wire.actionData[2]; 520706f2543Smrg act->redirect.vmods_mask0 = wire.actionData[3]; 521706f2543Smrg act->redirect.vmods_mask1 = wire.actionData[4]; 522706f2543Smrg act->redirect.vmods0 = wire.actionData[4]; 523706f2543Smrg act->redirect.vmods1 = wire.actionData[5]; 524706f2543Smrg break; 525706f2543Smrg case XkbSA_DeviceValuator: 526706f2543Smrg act->devval.device = wire.actionData[0]; 527706f2543Smrg act->devval.v1_what = wire.actionData[1]; 528706f2543Smrg act->devval.v1_ndx = wire.actionData[2]; 529706f2543Smrg act->devval.v1_value = wire.actionData[3]; 530706f2543Smrg act->devval.v2_what = wire.actionData[4]; 531706f2543Smrg act->devval.v2_ndx = wire.actionData[5]; 532706f2543Smrg act->devval.v2_what = wire.actionData[6]; 533706f2543Smrg break; 534706f2543Smrg 535706f2543Smrg case XkbSA_XFree86Private: 536706f2543Smrg /* copy the kind of action */ 537706f2543Smrg memcpy(act->any.data, wire.actionData, XkbAnyActionDataSize); 538706f2543Smrg break ; 539706f2543Smrg 540706f2543Smrg case XkbSA_Terminate: 541706f2543Smrg /* no args, kinda (note: untrue for xfree86). */ 542706f2543Smrg break; 543706f2543Smrg case XkbSA_ActionMessage: 544706f2543Smrg /* unsupported. */ 545706f2543Smrg break; 546706f2543Smrg } 547706f2543Smrg } 548706f2543Smrg if ((num_si>0)&&(changes)) { 549706f2543Smrg changes->compat.first_si= 0; 550706f2543Smrg changes->compat.num_si= num_si; 551706f2543Smrg } 552706f2543Smrg if (groups) { 553706f2543Smrg register unsigned bit; 554706f2543Smrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 555706f2543Smrg xkmModsDesc md; 556706f2543Smrg if (groups&bit) { 557706f2543Smrg tmp= fread(&md,SIZEOF(xkmModsDesc),1,file); 558706f2543Smrg nRead+= tmp*SIZEOF(xkmModsDesc); 559706f2543Smrg xkb->compat->groups[i].real_mods= md.realMods; 560706f2543Smrg xkb->compat->groups[i].vmods= md.virtualMods; 561706f2543Smrg if (md.virtualMods != 0) { 562706f2543Smrg unsigned mask; 563706f2543Smrg if (XkbVirtualModsToReal(xkb,md.virtualMods,&mask)) 564706f2543Smrg xkb->compat->groups[i].mask= md.realMods|mask; 565706f2543Smrg } 566706f2543Smrg else xkb->compat->groups[i].mask= md.realMods; 567706f2543Smrg } 568706f2543Smrg } 569706f2543Smrg if (changes) 570706f2543Smrg changes->compat.changed_groups|= groups; 571706f2543Smrg } 572706f2543Smrg return nRead; 573706f2543Smrg} 574706f2543Smrg 575706f2543Smrgstatic int 576706f2543SmrgReadXkmIndicators(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) 577706f2543Smrg{ 578706f2543Smrgregister unsigned nLEDs; 579706f2543SmrgxkmIndicatorMapDesc wire; 580706f2543Smrgchar buf[100]; 581706f2543Smrgunsigned tmp; 582706f2543Smrgint nRead=0; 583706f2543Smrg 584706f2543Smrg if ((xkb->indicators==NULL)&&(XkbAllocIndicatorMaps(xkb)!=Success)) { 585706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"indicator rec",0); 586706f2543Smrg return -1; 587706f2543Smrg } 588706f2543Smrg if (XkbAllocNames(xkb,XkbIndicatorNamesMask,0,0)!=Success) { 589706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"indicator names",0); 590706f2543Smrg return -1; 591706f2543Smrg } 592706f2543Smrg nLEDs= XkmGetCARD8(file,&nRead); 593706f2543Smrg nRead+= XkmSkipPadding(file,3); 594706f2543Smrg xkb->indicators->phys_indicators= XkmGetCARD32(file,&nRead); 595706f2543Smrg while (nLEDs-->0) { 596706f2543Smrg Atom name; 597706f2543Smrg XkbIndicatorMapPtr map; 598706f2543Smrg 599706f2543Smrg if ((tmp=XkmGetCountedString(file,buf,100))<1) { 600706f2543Smrg _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0); 601706f2543Smrg return -1; 602706f2543Smrg } 603706f2543Smrg nRead+= tmp; 604706f2543Smrg if (buf[0]!='\0') 605706f2543Smrg name= XkbInternAtom(buf,FALSE); 606706f2543Smrg else name= None; 607706f2543Smrg if ((tmp=fread(&wire,SIZEOF(xkmIndicatorMapDesc),1,file))<1) { 608706f2543Smrg _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0); 609706f2543Smrg return -1; 610706f2543Smrg } 611706f2543Smrg nRead+= tmp*SIZEOF(xkmIndicatorMapDesc); 612706f2543Smrg if (xkb->names) { 613706f2543Smrg xkb->names->indicators[wire.indicator-1]= name; 614706f2543Smrg if (changes) 615706f2543Smrg changes->names.changed_indicators|= (1<<(wire.indicator-1)); 616706f2543Smrg } 617706f2543Smrg map= &xkb->indicators->maps[wire.indicator-1]; 618706f2543Smrg map->flags= wire.flags; 619706f2543Smrg map->which_groups= wire.which_groups; 620706f2543Smrg map->groups= wire.groups; 621706f2543Smrg map->which_mods= wire.which_mods; 622706f2543Smrg map->mods.mask= wire.real_mods; 623706f2543Smrg map->mods.real_mods= wire.real_mods; 624706f2543Smrg map->mods.vmods= wire.vmods; 625706f2543Smrg map->ctrls= wire.ctrls; 626706f2543Smrg } 627706f2543Smrg return nRead; 628706f2543Smrg} 629706f2543Smrg 630706f2543Smrgstatic XkbKeyTypePtr 631706f2543SmrgFindTypeForKey(XkbDescPtr xkb,Atom name,unsigned width,KeySym *syms) 632706f2543Smrg{ 633706f2543Smrg if ((!xkb)||(!xkb->map)) 634706f2543Smrg return NULL; 635706f2543Smrg if (name!=None) { 636706f2543Smrg register unsigned i; 637706f2543Smrg for (i=0;i<xkb->map->num_types;i++) { 638706f2543Smrg if (xkb->map->types[i].name==name) { 639706f2543Smrg if (xkb->map->types[i].num_levels!=width) 640706f2543Smrg DebugF("Group width mismatch between key and type\n"); 641706f2543Smrg return &xkb->map->types[i]; 642706f2543Smrg } 643706f2543Smrg } 644706f2543Smrg } 645706f2543Smrg if ((width<2)||((syms!=NULL)&&(syms[1]==NoSymbol))) 646706f2543Smrg return &xkb->map->types[XkbOneLevelIndex]; 647706f2543Smrg if (syms!=NULL) { 648706f2543Smrg if (XkbKSIsLower(syms[0])&&XkbKSIsUpper(syms[1])) 649706f2543Smrg return &xkb->map->types[XkbAlphabeticIndex]; 650706f2543Smrg else if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1])) 651706f2543Smrg return &xkb->map->types[XkbKeypadIndex]; 652706f2543Smrg } 653706f2543Smrg return &xkb->map->types[XkbTwoLevelIndex]; 654706f2543Smrg} 655706f2543Smrg 656706f2543Smrgstatic int 657706f2543SmrgReadXkmSymbols(FILE *file,XkbDescPtr xkb) 658706f2543Smrg{ 659706f2543Smrgregister int i,g,s,totalVModMaps; 660706f2543SmrgxkmKeySymMapDesc wireMap; 661706f2543Smrgchar buf[100]; 662706f2543Smrgunsigned minKC,maxKC,groupNames,tmp; 663706f2543Smrgint nRead=0; 664706f2543Smrg 665706f2543Smrg if ((tmp=XkmGetCountedString(file,buf,100))<1) 666706f2543Smrg return -1; 667706f2543Smrg nRead+= tmp; 668706f2543Smrg minKC= XkmGetCARD8(file,&nRead); 669706f2543Smrg maxKC= XkmGetCARD8(file,&nRead); 670706f2543Smrg groupNames= XkmGetCARD8(file,&nRead); 671706f2543Smrg totalVModMaps= XkmGetCARD8(file,&nRead); 672706f2543Smrg if (XkbAllocNames(xkb, 673706f2543Smrg XkbSymbolsNameMask|XkbPhysSymbolsNameMask|XkbGroupNamesMask, 674706f2543Smrg 0,0)!=Success) { 675706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"physical names",0); 676706f2543Smrg return -1; 677706f2543Smrg } 678706f2543Smrg if ((buf[0]!='\0')&&(xkb->names)) { 679706f2543Smrg Atom name; 680706f2543Smrg name= XkbInternAtom(buf,0); 681706f2543Smrg xkb->names->symbols= name; 682706f2543Smrg xkb->names->phys_symbols= name; 683706f2543Smrg } 684706f2543Smrg for (i=0,g=1;i<XkbNumKbdGroups;i++,g<<=1) { 685706f2543Smrg if (groupNames&g) { 686706f2543Smrg if ((tmp=XkmGetCountedString(file,buf,100))<1) 687706f2543Smrg return -1; 688706f2543Smrg nRead+= tmp; 689706f2543Smrg 690706f2543Smrg if (!xkb->names) 691706f2543Smrg continue; 692706f2543Smrg 693706f2543Smrg if (buf[0]!='\0') { 694706f2543Smrg Atom name; 695706f2543Smrg name= XkbInternAtom(buf,0); 696706f2543Smrg xkb->names->groups[i]= name; 697706f2543Smrg } 698706f2543Smrg else xkb->names->groups[i]= None; 699706f2543Smrg } 700706f2543Smrg } 701706f2543Smrg if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success) { 702706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"server map",0); 703706f2543Smrg return -1; 704706f2543Smrg } 705706f2543Smrg if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) { 706706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"client map",0); 707706f2543Smrg return -1; 708706f2543Smrg } 709706f2543Smrg if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) { 710706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"controls",0); 711706f2543Smrg return -1; 712706f2543Smrg } 713706f2543Smrg if ((xkb->map==NULL)||(xkb->server==NULL)) 714706f2543Smrg return -1; 715706f2543Smrg if (xkb->min_key_code<8) xkb->min_key_code= minKC; 716706f2543Smrg if (xkb->max_key_code<8) xkb->max_key_code= maxKC; 717706f2543Smrg if ((minKC>=8)&&(minKC<xkb->min_key_code)) 718706f2543Smrg xkb->min_key_code= minKC; 719706f2543Smrg if ((maxKC>=8)&&(maxKC>xkb->max_key_code)) { 720706f2543Smrg _XkbLibError(_XkbErrBadValue,"keys in symbol map",maxKC); 721706f2543Smrg return -1; 722706f2543Smrg } 723706f2543Smrg for (i=minKC;i<=(int)maxKC;i++) { 724706f2543Smrg Atom typeName[XkbNumKbdGroups]; 725706f2543Smrg XkbKeyTypePtr type[XkbNumKbdGroups]; 726706f2543Smrg if ((tmp=fread(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file))<1) { 727706f2543Smrg _XkbLibError(_XkbErrBadLength,"ReadXkmSymbols",0); 728706f2543Smrg return -1; 729706f2543Smrg } 730706f2543Smrg nRead+= tmp*SIZEOF(xkmKeySymMapDesc); 731706f2543Smrg memset((char *)typeName, 0, XkbNumKbdGroups*sizeof(Atom)); 732706f2543Smrg memset((char *)type, 0, XkbNumKbdGroups*sizeof(XkbKeyTypePtr)); 733706f2543Smrg if (wireMap.flags&XkmKeyHasTypes) { 734706f2543Smrg register int g; 735706f2543Smrg for (g=0;g<XkbNumKbdGroups;g++) { 736706f2543Smrg if ((wireMap.flags&(1<<g))&& 737706f2543Smrg ((tmp=XkmGetCountedString(file,buf,100))>0)) { 738706f2543Smrg typeName[g]= XkbInternAtom(buf,1); 739706f2543Smrg nRead+= tmp; 740706f2543Smrg } 741706f2543Smrg type[g]=FindTypeForKey(xkb,typeName[g],wireMap.width,NULL); 742706f2543Smrg if (type[g]==NULL) { 743706f2543Smrg _XkbLibError(_XkbErrMissingTypes,"ReadXkmSymbols",0); 744706f2543Smrg return -1; 745706f2543Smrg } 746706f2543Smrg if (typeName[g]==type[g]->name) 747706f2543Smrg xkb->server->explicit[i]|= (1<<g); 748706f2543Smrg } 749706f2543Smrg } 750706f2543Smrg if (wireMap.flags&XkmRepeatingKey) { 751706f2543Smrg xkb->ctrls->per_key_repeat[i/8]|= (1<<(i%8)); 752706f2543Smrg xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask; 753706f2543Smrg } 754706f2543Smrg else if (wireMap.flags&XkmNonRepeatingKey) { 755706f2543Smrg xkb->ctrls->per_key_repeat[i/8]&= ~(1<<(i%8)); 756706f2543Smrg xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask; 757706f2543Smrg } 758706f2543Smrg xkb->map->modmap[i]= wireMap.modifier_map; 759706f2543Smrg if (XkbNumGroups(wireMap.num_groups)>0) { 760706f2543Smrg KeySym *sym; 761706f2543Smrg int nSyms; 762706f2543Smrg 763706f2543Smrg if (XkbNumGroups(wireMap.num_groups)>xkb->ctrls->num_groups) 764706f2543Smrg xkb->ctrls->num_groups= wireMap.num_groups; 765706f2543Smrg nSyms= XkbNumGroups(wireMap.num_groups)*wireMap.width; 766706f2543Smrg sym= XkbResizeKeySyms(xkb,i,nSyms); 767706f2543Smrg if (!sym) 768706f2543Smrg return -1; 769706f2543Smrg for (s=0;s<nSyms;s++) { 770706f2543Smrg *sym++= XkmGetCARD32(file,&nRead); 771706f2543Smrg } 772706f2543Smrg if (wireMap.flags&XkmKeyHasActions) { 773706f2543Smrg XkbAction * act; 774706f2543Smrg act= XkbResizeKeyActions(xkb,i,nSyms); 775706f2543Smrg for (s=0;s<nSyms;s++,act++) { 776706f2543Smrg tmp=fread(act,SIZEOF(xkmActionDesc),1,file); 777706f2543Smrg nRead+= tmp*SIZEOF(xkmActionDesc); 778706f2543Smrg } 779706f2543Smrg xkb->server->explicit[i]|= XkbExplicitInterpretMask; 780706f2543Smrg } 781706f2543Smrg } 782706f2543Smrg for (g=0;g<XkbNumGroups(wireMap.num_groups);g++) { 783706f2543Smrg if (((xkb->server->explicit[i]&(1<<g))==0)||(type[g]==NULL)) { 784706f2543Smrg KeySym *tmpSyms; 785706f2543Smrg tmpSyms= XkbKeySymsPtr(xkb,i)+(wireMap.width*g); 786706f2543Smrg type[g]= FindTypeForKey(xkb,None,wireMap.width,tmpSyms); 787706f2543Smrg } 788706f2543Smrg xkb->map->key_sym_map[i].kt_index[g]= type[g]-(&xkb->map->types[0]); 789706f2543Smrg } 790706f2543Smrg xkb->map->key_sym_map[i].group_info= wireMap.num_groups; 791706f2543Smrg xkb->map->key_sym_map[i].width= wireMap.width; 792706f2543Smrg if (wireMap.flags&XkmKeyHasBehavior) { 793706f2543Smrg xkmBehaviorDesc b; 794706f2543Smrg tmp= fread(&b,SIZEOF(xkmBehaviorDesc),1,file); 795706f2543Smrg nRead+= tmp*SIZEOF(xkmBehaviorDesc); 796706f2543Smrg xkb->server->behaviors[i].type= b.type; 797706f2543Smrg xkb->server->behaviors[i].data= b.data; 798706f2543Smrg xkb->server->explicit[i]|= XkbExplicitBehaviorMask; 799706f2543Smrg } 800706f2543Smrg } 801706f2543Smrg if (totalVModMaps>0) { 802706f2543Smrg xkmVModMapDesc v; 803706f2543Smrg for (i=0;i<totalVModMaps;i++) { 804706f2543Smrg tmp= fread(&v,SIZEOF(xkmVModMapDesc),1,file); 805706f2543Smrg nRead+= tmp*SIZEOF(xkmVModMapDesc); 806706f2543Smrg if (tmp>0) 807706f2543Smrg xkb->server->vmodmap[v.key]= v.vmods; 808706f2543Smrg } 809706f2543Smrg } 810706f2543Smrg return nRead; 811706f2543Smrg} 812706f2543Smrg 813706f2543Smrgstatic int 814706f2543SmrgReadXkmGeomDoodad( 815706f2543Smrg FILE * file, 816706f2543Smrg XkbGeometryPtr geom, 817706f2543Smrg XkbSectionPtr section) 818706f2543Smrg{ 819706f2543SmrgXkbDoodadPtr doodad; 820706f2543SmrgxkmDoodadDesc doodadWire; 821706f2543Smrgchar buf[100]; 822706f2543Smrgunsigned tmp; 823706f2543Smrgint nRead=0; 824706f2543Smrg 825706f2543Smrg nRead+= XkmGetCountedString(file,buf,100); 826706f2543Smrg tmp= fread(&doodadWire,SIZEOF(xkmDoodadDesc),1,file); 827706f2543Smrg nRead+= SIZEOF(xkmDoodadDesc)*tmp; 828706f2543Smrg doodad= XkbAddGeomDoodad(geom,section,XkbInternAtom(buf,FALSE)); 829706f2543Smrg if (!doodad) 830706f2543Smrg return nRead; 831706f2543Smrg doodad->any.type= doodadWire.any.type; 832706f2543Smrg doodad->any.priority= doodadWire.any.priority; 833706f2543Smrg doodad->any.top= doodadWire.any.top; 834706f2543Smrg doodad->any.left= doodadWire.any.left; 835706f2543Smrg switch (doodadWire.any.type) { 836706f2543Smrg case XkbOutlineDoodad: 837706f2543Smrg case XkbSolidDoodad: 838706f2543Smrg doodad->shape.angle= doodadWire.shape.angle; 839706f2543Smrg doodad->shape.color_ndx= doodadWire.shape.color_ndx; 840706f2543Smrg doodad->shape.shape_ndx= doodadWire.shape.shape_ndx; 841706f2543Smrg break; 842706f2543Smrg case XkbTextDoodad: 843706f2543Smrg doodad->text.angle= doodadWire.text.angle; 844706f2543Smrg doodad->text.width= doodadWire.text.width; 845706f2543Smrg doodad->text.height= doodadWire.text.height; 846706f2543Smrg doodad->text.color_ndx= doodadWire.text.color_ndx; 847706f2543Smrg nRead+= XkmGetCountedString(file,buf,100); 848706f2543Smrg doodad->text.text= _XkbDupString(buf); 849706f2543Smrg nRead+= XkmGetCountedString(file,buf,100); 850706f2543Smrg doodad->text.font= _XkbDupString(buf); 851706f2543Smrg break; 852706f2543Smrg case XkbIndicatorDoodad: 853706f2543Smrg doodad->indicator.shape_ndx= doodadWire.indicator.shape_ndx; 854706f2543Smrg doodad->indicator.on_color_ndx= doodadWire.indicator.on_color_ndx; 855706f2543Smrg doodad->indicator.off_color_ndx= doodadWire.indicator.off_color_ndx; 856706f2543Smrg break; 857706f2543Smrg case XkbLogoDoodad: 858706f2543Smrg doodad->logo.angle= doodadWire.logo.angle; 859706f2543Smrg doodad->logo.color_ndx= doodadWire.logo.color_ndx; 860706f2543Smrg doodad->logo.shape_ndx= doodadWire.logo.shape_ndx; 861706f2543Smrg nRead+= XkmGetCountedString(file,buf,100); 862706f2543Smrg doodad->logo.logo_name= _XkbDupString(buf); 863706f2543Smrg break; 864706f2543Smrg default: 865706f2543Smrg /* report error? */ 866706f2543Smrg return nRead; 867706f2543Smrg } 868706f2543Smrg return nRead; 869706f2543Smrg} 870706f2543Smrg 871706f2543Smrgstatic int 872706f2543SmrgReadXkmGeomOverlay( FILE * file, 873706f2543Smrg XkbGeometryPtr geom, 874706f2543Smrg XkbSectionPtr section) 875706f2543Smrg{ 876706f2543Smrgchar buf[100]; 877706f2543Smrgunsigned tmp; 878706f2543Smrgint nRead=0; 879706f2543SmrgXkbOverlayPtr ol; 880706f2543SmrgXkbOverlayRowPtr row; 881706f2543SmrgxkmOverlayDesc olWire; 882706f2543SmrgxkmOverlayRowDesc rowWire; 883706f2543Smrgregister int r; 884706f2543Smrg 885706f2543Smrg nRead+= XkmGetCountedString(file,buf,100); 886706f2543Smrg tmp= fread(&olWire,SIZEOF(xkmOverlayDesc),1,file); 887706f2543Smrg nRead+= tmp*SIZEOF(xkmOverlayDesc); 888706f2543Smrg ol= XkbAddGeomOverlay(section,XkbInternAtom(buf,FALSE), 889706f2543Smrg olWire.num_rows); 890706f2543Smrg if (!ol) 891706f2543Smrg return nRead; 892706f2543Smrg for (r=0;r<olWire.num_rows;r++) { 893706f2543Smrg int k; 894706f2543Smrg xkmOverlayKeyDesc keyWire; 895706f2543Smrg tmp= fread(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file); 896706f2543Smrg nRead+= tmp*SIZEOF(xkmOverlayRowDesc); 897706f2543Smrg row= XkbAddGeomOverlayRow(ol,rowWire.row_under,rowWire.num_keys); 898706f2543Smrg if (!row) { 899706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomOverlay",0); 900706f2543Smrg return nRead; 901706f2543Smrg } 902706f2543Smrg for (k=0;k<rowWire.num_keys;k++) { 903706f2543Smrg tmp= fread(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file); 904706f2543Smrg nRead+= tmp*SIZEOF(xkmOverlayKeyDesc); 905706f2543Smrg memcpy(row->keys[k].over.name,keyWire.over,XkbKeyNameLength); 906706f2543Smrg memcpy(row->keys[k].under.name,keyWire.under,XkbKeyNameLength); 907706f2543Smrg } 908706f2543Smrg row->num_keys= rowWire.num_keys; 909706f2543Smrg } 910706f2543Smrg return nRead; 911706f2543Smrg} 912706f2543Smrg 913706f2543Smrgstatic int 914706f2543SmrgReadXkmGeomSection( FILE * file, 915706f2543Smrg XkbGeometryPtr geom) 916706f2543Smrg{ 917706f2543Smrgregister int i; 918706f2543SmrgXkbSectionPtr section; 919706f2543SmrgxkmSectionDesc sectionWire; 920706f2543Smrgunsigned tmp; 921706f2543Smrgint nRead= 0; 922706f2543Smrgchar buf[100]; 923706f2543SmrgAtom nameAtom; 924706f2543Smrg 925706f2543Smrg nRead+= XkmGetCountedString(file,buf,100); 926706f2543Smrg nameAtom= XkbInternAtom(buf,FALSE); 927706f2543Smrg tmp= fread(§ionWire,SIZEOF(xkmSectionDesc),1,file); 928706f2543Smrg nRead+= SIZEOF(xkmSectionDesc)*tmp; 929706f2543Smrg section= XkbAddGeomSection(geom,nameAtom,sectionWire.num_rows, 930706f2543Smrg sectionWire.num_doodads, 931706f2543Smrg sectionWire.num_overlays); 932706f2543Smrg if (!section) { 933706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0); 934706f2543Smrg return nRead; 935706f2543Smrg } 936706f2543Smrg section->top= sectionWire.top; 937706f2543Smrg section->left= sectionWire.left; 938706f2543Smrg section->width= sectionWire.width; 939706f2543Smrg section->height= sectionWire.height; 940706f2543Smrg section->angle= sectionWire.angle; 941706f2543Smrg section->priority= sectionWire.priority; 942706f2543Smrg if (sectionWire.num_rows>0) { 943706f2543Smrg register int k; 944706f2543Smrg XkbRowPtr row; 945706f2543Smrg xkmRowDesc rowWire; 946706f2543Smrg XkbKeyPtr key; 947706f2543Smrg xkmKeyDesc keyWire; 948706f2543Smrg 949706f2543Smrg for (i=0;i<sectionWire.num_rows;i++) { 950706f2543Smrg tmp= fread(&rowWire,SIZEOF(xkmRowDesc),1,file); 951706f2543Smrg nRead+= SIZEOF(xkmRowDesc)*tmp; 952706f2543Smrg row= XkbAddGeomRow(section,rowWire.num_keys); 953706f2543Smrg if (!row) { 954706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0); 955706f2543Smrg return nRead; 956706f2543Smrg } 957706f2543Smrg row->top= rowWire.top; 958706f2543Smrg row->left= rowWire.left; 959706f2543Smrg row->vertical= rowWire.vertical; 960706f2543Smrg for (k=0;k<rowWire.num_keys;k++) { 961706f2543Smrg tmp= fread(&keyWire,SIZEOF(xkmKeyDesc),1,file); 962706f2543Smrg nRead+= SIZEOF(xkmKeyDesc)*tmp; 963706f2543Smrg key= XkbAddGeomKey(row); 964706f2543Smrg if (!key) { 965706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0); 966706f2543Smrg return nRead; 967706f2543Smrg } 968706f2543Smrg memcpy(key->name.name,keyWire.name,XkbKeyNameLength); 969706f2543Smrg key->gap= keyWire.gap; 970706f2543Smrg key->shape_ndx= keyWire.shape_ndx; 971706f2543Smrg key->color_ndx= keyWire.color_ndx; 972706f2543Smrg } 973706f2543Smrg } 974706f2543Smrg } 975706f2543Smrg if (sectionWire.num_doodads>0) { 976706f2543Smrg for (i=0;i<sectionWire.num_doodads;i++) { 977706f2543Smrg tmp= ReadXkmGeomDoodad(file,geom,section); 978706f2543Smrg nRead+= tmp; 979706f2543Smrg if (tmp<1) 980706f2543Smrg return nRead; 981706f2543Smrg } 982706f2543Smrg } 983706f2543Smrg if (sectionWire.num_overlays>0) { 984706f2543Smrg for (i=0;i<sectionWire.num_overlays;i++) { 985706f2543Smrg tmp= ReadXkmGeomOverlay(file,geom,section); 986706f2543Smrg nRead+= tmp; 987706f2543Smrg if (tmp<1) 988706f2543Smrg return nRead; 989706f2543Smrg } 990706f2543Smrg } 991706f2543Smrg return nRead; 992706f2543Smrg} 993706f2543Smrg 994706f2543Smrgstatic int 995706f2543SmrgReadXkmGeometry(FILE *file,XkbDescPtr xkb) 996706f2543Smrg{ 997706f2543Smrgregister int i; 998706f2543Smrgchar buf[100]; 999706f2543Smrgunsigned tmp; 1000706f2543Smrgint nRead= 0; 1001706f2543SmrgxkmGeometryDesc wireGeom; 1002706f2543SmrgXkbGeometryPtr geom; 1003706f2543SmrgXkbGeometrySizesRec sizes; 1004706f2543Smrg 1005706f2543Smrg nRead+= XkmGetCountedString(file,buf,100); 1006706f2543Smrg tmp= fread(&wireGeom,SIZEOF(xkmGeometryDesc),1,file); 1007706f2543Smrg nRead+= tmp*SIZEOF(xkmGeometryDesc); 1008706f2543Smrg sizes.which= XkbGeomAllMask; 1009706f2543Smrg sizes.num_properties= wireGeom.num_properties; 1010706f2543Smrg sizes.num_colors= wireGeom.num_colors; 1011706f2543Smrg sizes.num_shapes= wireGeom.num_shapes; 1012706f2543Smrg sizes.num_sections= wireGeom.num_sections; 1013706f2543Smrg sizes.num_doodads= wireGeom.num_doodads; 1014706f2543Smrg sizes.num_key_aliases= wireGeom.num_key_aliases; 1015706f2543Smrg if (XkbAllocGeometry(xkb,&sizes)!=Success) { 1016706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1017706f2543Smrg return nRead; 1018706f2543Smrg } 1019706f2543Smrg geom= xkb->geom; 1020706f2543Smrg geom->name= XkbInternAtom(buf,FALSE); 1021706f2543Smrg geom->width_mm= wireGeom.width_mm; 1022706f2543Smrg geom->height_mm= wireGeom.height_mm; 1023706f2543Smrg nRead+= XkmGetCountedString(file,buf,100); 1024706f2543Smrg geom->label_font= _XkbDupString(buf); 1025706f2543Smrg if (wireGeom.num_properties>0) { 1026706f2543Smrg char val[1024]; 1027706f2543Smrg for (i=0;i<wireGeom.num_properties;i++) { 1028706f2543Smrg nRead+= XkmGetCountedString(file,buf,100); 1029706f2543Smrg nRead+= XkmGetCountedString(file,val,1024); 1030706f2543Smrg if (XkbAddGeomProperty(geom,buf,val)==NULL) { 1031706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1032706f2543Smrg return nRead; 1033706f2543Smrg } 1034706f2543Smrg } 1035706f2543Smrg } 1036706f2543Smrg if (wireGeom.num_colors>0) { 1037706f2543Smrg for (i=0;i<wireGeom.num_colors;i++) { 1038706f2543Smrg nRead+= XkmGetCountedString(file,buf,100); 1039706f2543Smrg if (XkbAddGeomColor(geom,buf,i)==NULL) { 1040706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1041706f2543Smrg return nRead; 1042706f2543Smrg } 1043706f2543Smrg } 1044706f2543Smrg } 1045706f2543Smrg geom->base_color= &geom->colors[wireGeom.base_color_ndx]; 1046706f2543Smrg geom->label_color= &geom->colors[wireGeom.label_color_ndx]; 1047706f2543Smrg if (wireGeom.num_shapes>0) { 1048706f2543Smrg XkbShapePtr shape; 1049706f2543Smrg xkmShapeDesc shapeWire; 1050706f2543Smrg Atom nameAtom; 1051706f2543Smrg for (i=0;i<wireGeom.num_shapes;i++) { 1052706f2543Smrg register int n; 1053706f2543Smrg XkbOutlinePtr ol; 1054706f2543Smrg xkmOutlineDesc olWire; 1055706f2543Smrg nRead+= XkmGetCountedString(file,buf,100); 1056706f2543Smrg nameAtom= XkbInternAtom(buf,FALSE); 1057706f2543Smrg tmp= fread(&shapeWire,SIZEOF(xkmShapeDesc),1,file); 1058706f2543Smrg nRead+= tmp*SIZEOF(xkmShapeDesc); 1059706f2543Smrg shape= XkbAddGeomShape(geom,nameAtom,shapeWire.num_outlines); 1060706f2543Smrg if (!shape) { 1061706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1062706f2543Smrg return nRead; 1063706f2543Smrg } 1064706f2543Smrg for (n=0;n<shapeWire.num_outlines;n++) { 1065706f2543Smrg register int p; 1066706f2543Smrg xkmPointDesc ptWire; 1067706f2543Smrg tmp= fread(&olWire,SIZEOF(xkmOutlineDesc),1,file); 1068706f2543Smrg nRead+= tmp*SIZEOF(xkmOutlineDesc); 1069706f2543Smrg ol= XkbAddGeomOutline(shape,olWire.num_points); 1070706f2543Smrg if (!ol) { 1071706f2543Smrg _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1072706f2543Smrg return nRead; 1073706f2543Smrg } 1074706f2543Smrg ol->num_points= olWire.num_points; 1075706f2543Smrg ol->corner_radius= olWire.corner_radius; 1076706f2543Smrg for (p=0;p<olWire.num_points;p++) { 1077706f2543Smrg tmp= fread(&ptWire,SIZEOF(xkmPointDesc),1,file); 1078706f2543Smrg nRead+= tmp*SIZEOF(xkmPointDesc); 1079706f2543Smrg ol->points[p].x= ptWire.x; 1080706f2543Smrg ol->points[p].y= ptWire.y; 1081706f2543Smrg if (ptWire.x<shape->bounds.x1) shape->bounds.x1= ptWire.x; 1082706f2543Smrg if (ptWire.x>shape->bounds.x2) shape->bounds.x2= ptWire.x; 1083706f2543Smrg if (ptWire.y<shape->bounds.y1) shape->bounds.y1= ptWire.y; 1084706f2543Smrg if (ptWire.y>shape->bounds.y2) shape->bounds.y2= ptWire.y; 1085706f2543Smrg } 1086706f2543Smrg } 1087706f2543Smrg if (shapeWire.primary_ndx!=XkbNoShape) 1088706f2543Smrg shape->primary= &shape->outlines[shapeWire.primary_ndx]; 1089706f2543Smrg if (shapeWire.approx_ndx!=XkbNoShape) 1090706f2543Smrg shape->approx= &shape->outlines[shapeWire.approx_ndx]; 1091706f2543Smrg } 1092706f2543Smrg } 1093706f2543Smrg if (wireGeom.num_sections>0) { 1094706f2543Smrg for (i=0;i<wireGeom.num_sections;i++) { 1095706f2543Smrg tmp= ReadXkmGeomSection(file,geom); 1096706f2543Smrg nRead+= tmp; 1097706f2543Smrg if (tmp==0) 1098706f2543Smrg return nRead; 1099706f2543Smrg } 1100706f2543Smrg } 1101706f2543Smrg if (wireGeom.num_doodads>0) { 1102706f2543Smrg for (i=0;i<wireGeom.num_doodads;i++) { 1103706f2543Smrg tmp= ReadXkmGeomDoodad(file,geom,NULL); 1104706f2543Smrg nRead+= tmp; 1105706f2543Smrg if (tmp==0) 1106706f2543Smrg return nRead; 1107706f2543Smrg } 1108706f2543Smrg } 1109706f2543Smrg if ((wireGeom.num_key_aliases>0)&&(geom->key_aliases)) { 1110706f2543Smrg int sz= XkbKeyNameLength*2; 1111706f2543Smrg int num= wireGeom.num_key_aliases; 1112706f2543Smrg if (fread(geom->key_aliases,sz,num,file)!=num) { 1113706f2543Smrg _XkbLibError(_XkbErrBadLength,"ReadXkmGeometry",0); 1114706f2543Smrg return -1; 1115706f2543Smrg } 1116706f2543Smrg nRead+= (num*sz); 1117706f2543Smrg geom->num_key_aliases= num; 1118706f2543Smrg } 1119706f2543Smrg return nRead; 1120706f2543Smrg} 1121706f2543Smrg 1122706f2543SmrgBool 1123706f2543SmrgXkmProbe(FILE *file) 1124706f2543Smrg{ 1125706f2543Smrgunsigned hdr,tmp; 1126706f2543Smrgint nRead=0; 1127706f2543Smrg 1128706f2543Smrg hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); 1129706f2543Smrg tmp= XkmGetCARD32(file,&nRead); 1130706f2543Smrg if (tmp!=hdr) { 1131706f2543Smrg if ((tmp&(~0xff))==(hdr&(~0xff))) { 1132706f2543Smrg _XkbLibError(_XkbErrBadFileVersion,"XkmProbe",tmp&0xff); 1133706f2543Smrg } 1134706f2543Smrg return 0; 1135706f2543Smrg } 1136706f2543Smrg return 1; 1137706f2543Smrg} 1138706f2543Smrg 1139706f2543Smrgstatic Bool 1140706f2543SmrgXkmReadTOC(FILE *file,xkmFileInfo* file_info,int max_toc,xkmSectionInfo *toc) 1141706f2543Smrg{ 1142706f2543Smrgunsigned hdr,tmp; 1143706f2543Smrgint nRead=0; 1144706f2543Smrgunsigned i,size_toc; 1145706f2543Smrg 1146706f2543Smrg hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); 1147706f2543Smrg tmp= XkmGetCARD32(file,&nRead); 1148706f2543Smrg if (tmp!=hdr) { 1149706f2543Smrg if ((tmp&(~0xff))==(hdr&(~0xff))) { 1150706f2543Smrg _XkbLibError(_XkbErrBadFileVersion,"XkmReadTOC",tmp&0xff); 1151706f2543Smrg } 1152706f2543Smrg else { 1153706f2543Smrg _XkbLibError(_XkbErrBadFileType,"XkmReadTOC",tmp); 1154706f2543Smrg } 1155706f2543Smrg return 0; 1156706f2543Smrg } 1157706f2543Smrg fread(file_info,SIZEOF(xkmFileInfo),1,file); 1158706f2543Smrg size_toc= file_info->num_toc; 1159706f2543Smrg if (size_toc>max_toc) { 1160706f2543Smrg DebugF("Warning! Too many TOC entries; last %d ignored\n", 1161706f2543Smrg size_toc-max_toc); 1162706f2543Smrg size_toc= max_toc; 1163706f2543Smrg } 1164706f2543Smrg for (i=0;i<size_toc;i++) { 1165706f2543Smrg fread(&toc[i],SIZEOF(xkmSectionInfo),1,file); 1166706f2543Smrg } 1167706f2543Smrg return 1; 1168706f2543Smrg} 1169706f2543Smrg 1170706f2543Smrg/***====================================================================***/ 1171706f2543Smrg 1172706f2543Smrg#define MAX_TOC 16 1173706f2543Smrgunsigned 1174706f2543SmrgXkmReadFile(FILE *file,unsigned need,unsigned want,XkbDescPtr *xkb) 1175706f2543Smrg{ 1176706f2543Smrgregister unsigned i; 1177706f2543SmrgxkmSectionInfo toc[MAX_TOC],tmpTOC; 1178706f2543SmrgxkmFileInfo fileInfo; 1179706f2543Smrgunsigned tmp,nRead=0; 1180706f2543Smrgunsigned which= need|want; 1181706f2543Smrg 1182706f2543Smrg if (!XkmReadTOC(file,&fileInfo,MAX_TOC,toc)) 1183706f2543Smrg return which; 1184706f2543Smrg if ((fileInfo.present&need)!=need) { 1185706f2543Smrg _XkbLibError(_XkbErrIllegalContents,"XkmReadFile", 1186706f2543Smrg need&(~fileInfo.present)); 1187706f2543Smrg return which; 1188706f2543Smrg } 1189706f2543Smrg if (*xkb==NULL) 1190706f2543Smrg *xkb= XkbAllocKeyboard(); 1191706f2543Smrg for (i=0;i<fileInfo.num_toc;i++) { 1192706f2543Smrg fseek(file,toc[i].offset,SEEK_SET); 1193706f2543Smrg tmp= fread(&tmpTOC,SIZEOF(xkmSectionInfo),1,file); 1194706f2543Smrg nRead= tmp*SIZEOF(xkmSectionInfo); 1195706f2543Smrg if ((tmpTOC.type!=toc[i].type)||(tmpTOC.format!=toc[i].format)|| 1196706f2543Smrg (tmpTOC.size!=toc[i].size)||(tmpTOC.offset!=toc[i].offset)) { 1197706f2543Smrg return which; 1198706f2543Smrg } 1199706f2543Smrg if ((which&(1<<tmpTOC.type))==0) { 1200706f2543Smrg continue; 1201706f2543Smrg } 1202706f2543Smrg switch (tmpTOC.type) { 1203706f2543Smrg case XkmVirtualModsIndex: 1204706f2543Smrg tmp= ReadXkmVirtualMods(file,*xkb,NULL); 1205706f2543Smrg break; 1206706f2543Smrg case XkmTypesIndex: 1207706f2543Smrg tmp= ReadXkmKeyTypes(file,*xkb,NULL); 1208706f2543Smrg break; 1209706f2543Smrg case XkmCompatMapIndex: 1210706f2543Smrg tmp= ReadXkmCompatMap(file,*xkb,NULL); 1211706f2543Smrg break; 1212706f2543Smrg case XkmKeyNamesIndex: 1213706f2543Smrg tmp= ReadXkmKeycodes(file,*xkb,NULL); 1214706f2543Smrg break; 1215706f2543Smrg case XkmIndicatorsIndex: 1216706f2543Smrg tmp= ReadXkmIndicators(file,*xkb,NULL); 1217706f2543Smrg break; 1218706f2543Smrg case XkmSymbolsIndex: 1219706f2543Smrg tmp= ReadXkmSymbols(file,*xkb); 1220706f2543Smrg break; 1221706f2543Smrg case XkmGeometryIndex: 1222706f2543Smrg tmp= ReadXkmGeometry(file,*xkb); 1223706f2543Smrg break; 1224706f2543Smrg default: 1225706f2543Smrg _XkbLibError(_XkbErrBadImplementation, 1226706f2543Smrg XkbConfigText(tmpTOC.type,XkbMessage),0); 1227706f2543Smrg tmp= 0; 1228706f2543Smrg break; 1229706f2543Smrg } 1230706f2543Smrg if (tmp>0) { 1231706f2543Smrg nRead+= tmp; 1232706f2543Smrg which&= ~(1<<toc[i].type); 1233706f2543Smrg (*xkb)->defined|= (1<<toc[i].type); 1234706f2543Smrg } 1235706f2543Smrg if (nRead!=tmpTOC.size) { 1236706f2543Smrg _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage), 1237706f2543Smrg nRead-tmpTOC.size); 1238706f2543Smrg } 1239706f2543Smrg } 1240706f2543Smrg return which; 1241706f2543Smrg} 1242