xkmread.c revision 6747b715
1/************************************************************ 2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 3 4 Permission to use, copy, modify, and distribute this 5 software and its documentation for any purpose and without 6 fee is hereby granted, provided that the above copyright 7 notice appear in all copies and that both that copyright 8 notice and this permission notice appear in supporting 9 documentation, and that the name of Silicon Graphics not be 10 used in advertising or publicity pertaining to distribution 11 of the software without specific prior written permission. 12 Silicon Graphics makes no representation about the suitability 13 of this software for any purpose. It is provided "as is" 14 without any express or implied warranty. 15 16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23 THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 25 ********************************************************/ 26 27#ifdef HAVE_DIX_CONFIG_H 28#include <dix-config.h> 29#endif 30 31#include <stdio.h> 32 33#include <X11/Xos.h> 34#include <X11/Xfuncs.h> 35 36#include <X11/X.h> 37#include <X11/Xproto.h> 38#include <X11/keysym.h> 39#include <X11/extensions/XKMformat.h> 40#include "misc.h" 41#include "inputstr.h" 42#include "xkbstr.h" 43#include "xkbsrv.h" 44#include "xkbgeom.h" 45 46Atom 47XkbInternAtom(char *str,Bool only_if_exists) 48{ 49 if (str==NULL) 50 return None; 51 return MakeAtom(str,strlen(str),!only_if_exists); 52} 53 54char * 55_XkbDupString(const char *str) 56{ 57char *new; 58 59 if (str==NULL) 60 return NULL; 61 new= calloc(strlen(str)+1,sizeof(char)); 62 if (new) 63 strcpy(new,str); 64 return new; 65} 66 67/***====================================================================***/ 68 69static void * 70XkmInsureSize(void *oldPtr,int oldCount,int *newCountRtrn,int elemSize) 71{ 72int newCount= *newCountRtrn; 73 74 if (oldPtr==NULL) { 75 if (newCount==0) 76 return NULL; 77 oldPtr= calloc(newCount,elemSize); 78 } 79 else if (oldCount<newCount) { 80 oldPtr= realloc(oldPtr,newCount*elemSize); 81 if (oldPtr!=NULL) { 82 char *tmp= (char *)oldPtr; 83 memset(&tmp[oldCount*elemSize], 0, (newCount-oldCount)*elemSize); 84 } 85 } 86 else if (newCount<oldCount) { 87 *newCountRtrn= oldCount; 88 } 89 return oldPtr; 90} 91 92#define XkmInsureTypedSize(p,o,n,t) ((p)=((t *)XkmInsureSize((char *)(p),(o),(n),sizeof(t)))) 93 94static CARD8 95XkmGetCARD8(FILE *file,int *pNRead) 96{ 97int tmp; 98 tmp= getc(file); 99 if (pNRead&&(tmp!=EOF)) 100 (*pNRead)+= 1; 101 return tmp; 102} 103 104static CARD16 105XkmGetCARD16(FILE *file,int *pNRead) 106{ 107CARD16 val; 108 109 if ((fread(&val,2,1,file)==1)&&(pNRead)) 110 (*pNRead)+= 2; 111 return val; 112} 113 114static CARD32 115XkmGetCARD32(FILE *file,int *pNRead) 116{ 117CARD32 val; 118 119 if ((fread(&val,4,1,file)==1)&&(pNRead)) 120 (*pNRead)+= 4; 121 return val; 122} 123 124static int 125XkmSkipPadding(FILE *file,unsigned pad) 126{ 127register int i,nRead=0; 128 129 for (i=0;i<pad;i++) { 130 if (getc(file)!=EOF) 131 nRead++; 132 } 133 return nRead; 134} 135 136static int 137XkmGetCountedString(FILE *file,char *str,int max_len) 138{ 139int count,nRead=0; 140 141 count= XkmGetCARD16(file,&nRead); 142 if (count>0) { 143 int tmp; 144 if (count>max_len) { 145 tmp= fread(str,1,max_len,file); 146 while (tmp<count) { 147 if ((getc(file))!=EOF) 148 tmp++; 149 else break; 150 } 151 } 152 else { 153 tmp= fread(str,1,count,file); 154 } 155 nRead+= tmp; 156 } 157 if (count>=max_len) str[max_len-1]= '\0'; 158 else str[count]= '\0'; 159 count= XkbPaddedSize(nRead)-nRead; 160 if (count>0) 161 nRead+= XkmSkipPadding(file,count); 162 return nRead; 163} 164 165/***====================================================================***/ 166 167static int 168ReadXkmVirtualMods(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) 169{ 170register unsigned int i,bit; 171unsigned int bound,named,tmp; 172int nRead=0; 173 174 if (XkbAllocServerMap(xkb,XkbVirtualModsMask,0)!=Success) { 175 _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0); 176 return -1; 177 } 178 bound= XkmGetCARD16(file,&nRead); 179 named= XkmGetCARD16(file,&nRead); 180 for (i=tmp=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 181 if (bound&bit) { 182 xkb->server->vmods[i]= XkmGetCARD8(file,&nRead); 183 if (changes) 184 changes->map.vmods|= bit; 185 tmp++; 186 } 187 } 188 if ((i= XkbPaddedSize(tmp)-tmp)>0) 189 nRead+= XkmSkipPadding(file,i); 190 if (XkbAllocNames(xkb,XkbVirtualModNamesMask,0,0)!=Success) { 191 _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0); 192 return -1; 193 } 194 for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 195 char name[100]; 196 if (named&bit) { 197 if (nRead+=XkmGetCountedString(file,name,100)) { 198 xkb->names->vmods[i]= XkbInternAtom(name,FALSE); 199 if (changes) 200 changes->names.changed_vmods|= bit; 201 } 202 } 203 } 204 return nRead; 205} 206 207/***====================================================================***/ 208 209static int 210ReadXkmKeycodes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) 211{ 212register int i; 213unsigned minKC,maxKC,nAl; 214int nRead=0; 215char name[100]; 216XkbKeyNamePtr pN; 217 218 name[0]= '\0'; 219 nRead+= XkmGetCountedString(file,name,100); 220 minKC= XkmGetCARD8(file,&nRead); 221 maxKC= XkmGetCARD8(file,&nRead); 222 if (xkb->min_key_code==0) { 223 xkb->min_key_code= minKC; 224 xkb->max_key_code= maxKC; 225 } 226 else { 227 if (minKC<xkb->min_key_code) 228 xkb->min_key_code= minKC; 229 if (maxKC>xkb->max_key_code) { 230 _XkbLibError(_XkbErrBadValue,"ReadXkmKeycodes",maxKC); 231 return -1; 232 } 233 } 234 nAl= XkmGetCARD8(file,&nRead); 235 nRead+= XkmSkipPadding(file,1); 236 237#define WANTED (XkbKeycodesNameMask|XkbKeyNamesMask|XkbKeyAliasesMask) 238 if (XkbAllocNames(xkb,WANTED,0,nAl)!=Success) { 239 _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0); 240 return -1; 241 } 242 if (name[0]!='\0') { 243 xkb->names->keycodes= XkbInternAtom(name,FALSE); 244 } 245 246 for (pN=&xkb->names->keys[minKC],i=minKC;i<=(int)maxKC;i++,pN++) { 247 if (fread(pN,1,XkbKeyNameLength,file)!=XkbKeyNameLength) { 248 _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0); 249 return -1; 250 } 251 nRead+= XkbKeyNameLength; 252 } 253 if (nAl>0) { 254 XkbKeyAliasPtr pAl; 255 for (pAl= xkb->names->key_aliases,i=0;i<nAl;i++,pAl++) { 256 int tmp; 257 tmp= fread(pAl,1,2*XkbKeyNameLength,file); 258 if (tmp!=2*XkbKeyNameLength) { 259 _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0); 260 return -1; 261 } 262 nRead+= 2*XkbKeyNameLength; 263 } 264 if (changes) 265 changes->names.changed|= XkbKeyAliasesMask; 266 } 267 if (changes) 268 changes->names.changed|= XkbKeyNamesMask; 269 return nRead; 270} 271 272/***====================================================================***/ 273 274static int 275ReadXkmKeyTypes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) 276{ 277register unsigned i,n; 278unsigned num_types; 279int nRead=0; 280int tmp; 281XkbKeyTypePtr type; 282xkmKeyTypeDesc wire; 283XkbKTMapEntryPtr entry; 284xkmKTMapEntryDesc wire_entry; 285char buf[100]; 286 287 if ((tmp= XkmGetCountedString(file,buf,100))<1) { 288 _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0); 289 return -1; 290 } 291 nRead+= tmp; 292 if (buf[0]!='\0') { 293 if (XkbAllocNames(xkb,XkbTypesNameMask,0,0)!=Success) { 294 _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0); 295 return -1; 296 } 297 xkb->names->types= XkbInternAtom(buf,FALSE); 298 } 299 num_types= XkmGetCARD16(file,&nRead); 300 nRead+= XkmSkipPadding(file,2); 301 if (num_types<1) 302 return nRead; 303 if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_types)!=Success) { 304 _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0); 305 return nRead; 306 } 307 xkb->map->num_types= num_types; 308 if (num_types<XkbNumRequiredTypes) { 309 _XkbLibError(_XkbErrMissingReqTypes,"ReadXkmKeyTypes",0); 310 return -1; 311 } 312 type= xkb->map->types; 313 for (i=0;i<num_types;i++,type++) { 314 if ((int)fread(&wire,SIZEOF(xkmKeyTypeDesc),1,file)<1) { 315 _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0); 316 return -1; 317 } 318 nRead+= SIZEOF(xkmKeyTypeDesc); 319 if (((i==XkbOneLevelIndex)&&(wire.numLevels!=1))|| 320 (((i==XkbTwoLevelIndex)||(i==XkbAlphabeticIndex)|| 321 ((i)==XkbKeypadIndex))&&(wire.numLevels!=2))) { 322 _XkbLibError(_XkbErrBadTypeWidth,"ReadXkmKeyTypes",i); 323 return -1; 324 } 325 tmp= wire.nMapEntries; 326 XkmInsureTypedSize(type->map,type->map_count,&tmp,XkbKTMapEntryRec); 327 if ((wire.nMapEntries>0)&&(type->map==NULL)) { 328 _XkbLibError(_XkbErrBadValue,"ReadXkmKeyTypes",wire.nMapEntries); 329 return -1; 330 } 331 for (n=0,entry= type->map;n<wire.nMapEntries;n++,entry++) { 332 if (fread(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file)<(int)1) { 333 _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0); 334 return -1; 335 } 336 nRead+= SIZEOF(xkmKTMapEntryDesc); 337 entry->active= (wire_entry.virtualMods==0); 338 entry->level= wire_entry.level; 339 entry->mods.mask= wire_entry.realMods; 340 entry->mods.real_mods= wire_entry.realMods; 341 entry->mods.vmods= wire_entry.virtualMods; 342 } 343 nRead+= XkmGetCountedString(file,buf,100); 344 if (((i==XkbOneLevelIndex)&&(strcmp(buf,"ONE_LEVEL")!=0))|| 345 ((i==XkbTwoLevelIndex)&&(strcmp(buf,"TWO_LEVEL")!=0))|| 346 ((i==XkbAlphabeticIndex)&&(strcmp(buf,"ALPHABETIC")!=0))|| 347 ((i==XkbKeypadIndex)&&(strcmp(buf,"KEYPAD")!=0))) { 348 _XkbLibError(_XkbErrBadTypeName,"ReadXkmKeyTypes",0); 349 return -1; 350 } 351 if (buf[0]!='\0') { 352 type->name= XkbInternAtom(buf,FALSE); 353 } 354 else type->name= None; 355 356 if (wire.preserve) { 357 xkmModsDesc p_entry; 358 XkbModsPtr pre; 359 XkmInsureTypedSize(type->preserve,type->map_count,&tmp, 360 XkbModsRec); 361 if (type->preserve==NULL) { 362 _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0); 363 return -1; 364 } 365 for (n=0,pre=type->preserve;n<wire.nMapEntries;n++,pre++) { 366 if (fread(&p_entry,SIZEOF(xkmModsDesc),1,file)<1) { 367 _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0); 368 return -1; 369 } 370 nRead+= SIZEOF(xkmModsDesc); 371 pre->mask= p_entry.realMods; 372 pre->real_mods= p_entry.realMods; 373 pre->vmods= p_entry.virtualMods; 374 } 375 } 376 if (wire.nLevelNames>0) { 377 int width= wire.numLevels; 378 if (wire.nLevelNames>(unsigned)width) { 379 _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0); 380 return -1; 381 } 382 XkmInsureTypedSize(type->level_names,type->num_levels,&width,Atom); 383 if (type->level_names!=NULL) { 384 for (n=0;n<wire.nLevelNames;n++) { 385 if ((tmp=XkmGetCountedString(file,buf,100))<1) 386 return -1; 387 nRead+= tmp; 388 if (strlen(buf)==0) 389 type->level_names[n]= None; 390 else type->level_names[n]= XkbInternAtom(buf,0); 391 } 392 } 393 } 394 type->mods.mask= wire.realMods; 395 type->mods.real_mods= wire.realMods; 396 type->mods.vmods= wire.virtualMods; 397 type->num_levels= wire.numLevels; 398 type->map_count= wire.nMapEntries; 399 } 400 if (changes) { 401 changes->map.changed|= XkbKeyTypesMask; 402 changes->map.first_type= 0; 403 changes->map.num_types= xkb->map->num_types; 404 } 405 return nRead; 406} 407 408/***====================================================================***/ 409 410static int 411ReadXkmCompatMap(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) 412{ 413register int i; 414unsigned num_si,groups; 415char name[100]; 416XkbSymInterpretPtr interp; 417xkmSymInterpretDesc wire; 418unsigned tmp; 419int nRead=0; 420XkbCompatMapPtr compat; 421XkbAction *act; 422 423 if ((tmp= XkmGetCountedString(file,name,100))<1) { 424 _XkbLibError(_XkbErrBadLength,"ReadXkmCompatMap",0); 425 return -1; 426 } 427 nRead+= tmp; 428 if (name[0]!='\0') { 429 if (XkbAllocNames(xkb,XkbCompatNameMask,0,0)!=Success) { 430 _XkbLibError(_XkbErrBadAlloc,"ReadXkmCompatMap",0); 431 return -1; 432 } 433 xkb->names->compat= XkbInternAtom(name,FALSE); 434 } 435 num_si= XkmGetCARD16(file,&nRead); 436 groups= XkmGetCARD8(file,&nRead); 437 nRead+= XkmSkipPadding(file,1); 438 if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_si)!=Success) 439 return -1; 440 compat= xkb->compat; 441 compat->num_si= num_si; 442 interp= compat->sym_interpret; 443 for (i=0;i<num_si;i++,interp++) { 444 tmp= fread(&wire,SIZEOF(xkmSymInterpretDesc),1,file); 445 nRead+= tmp*SIZEOF(xkmSymInterpretDesc); 446 interp->sym= wire.sym; 447 interp->mods= wire.mods; 448 interp->match= wire.match; 449 interp->virtual_mod= wire.virtualMod; 450 interp->flags= wire.flags; 451 interp->act.type= wire.actionType; 452 act = (XkbAction *) &interp->act; 453 454 switch (interp->act.type) { 455 case XkbSA_SetMods: 456 case XkbSA_LatchMods: 457 case XkbSA_LockMods: 458 act->mods.flags = wire.actionData[0]; 459 act->mods.mask = wire.actionData[1]; 460 act->mods.real_mods = wire.actionData[2]; 461 act->mods.vmods1 = wire.actionData[3]; 462 act->mods.vmods2 = wire.actionData[4]; 463 break; 464 case XkbSA_SetGroup: 465 case XkbSA_LatchGroup: 466 case XkbSA_LockGroup: 467 act->group.flags = wire.actionData[0]; 468 act->group.group_XXX = wire.actionData[1]; 469 break; 470 case XkbSA_MovePtr: 471 act->ptr.flags = wire.actionData[0]; 472 act->ptr.high_XXX = wire.actionData[1]; 473 act->ptr.low_XXX = wire.actionData[2]; 474 act->ptr.high_YYY = wire.actionData[3]; 475 act->ptr.low_YYY = wire.actionData[4]; 476 break; 477 case XkbSA_PtrBtn: 478 case XkbSA_LockPtrBtn: 479 act->btn.flags = wire.actionData[0]; 480 act->btn.count = wire.actionData[1]; 481 act->btn.button = wire.actionData[2]; 482 break; 483 case XkbSA_DeviceBtn: 484 case XkbSA_LockDeviceBtn: 485 act->devbtn.flags = wire.actionData[0]; 486 act->devbtn.count = wire.actionData[1]; 487 act->devbtn.button = wire.actionData[2]; 488 act->devbtn.device = wire.actionData[3]; 489 break; 490 case XkbSA_SetPtrDflt: 491 act->dflt.flags = wire.actionData[0]; 492 act->dflt.affect = wire.actionData[1]; 493 act->dflt.valueXXX = wire.actionData[2]; 494 break; 495 case XkbSA_ISOLock: 496 act->iso.flags = wire.actionData[0]; 497 act->iso.mask = wire.actionData[1]; 498 act->iso.real_mods = wire.actionData[2]; 499 act->iso.group_XXX = wire.actionData[3]; 500 act->iso.affect = wire.actionData[4]; 501 act->iso.vmods1 = wire.actionData[5]; 502 act->iso.vmods2 = wire.actionData[6]; 503 break; 504 case XkbSA_SwitchScreen: 505 act->screen.flags = wire.actionData[0]; 506 act->screen.screenXXX = wire.actionData[1]; 507 break; 508 case XkbSA_SetControls: 509 case XkbSA_LockControls: 510 act->ctrls.flags = wire.actionData[0]; 511 act->ctrls.ctrls3 = wire.actionData[1]; 512 act->ctrls.ctrls2 = wire.actionData[2]; 513 act->ctrls.ctrls1 = wire.actionData[3]; 514 act->ctrls.ctrls0 = wire.actionData[4]; 515 break; 516 case XkbSA_RedirectKey: 517 act->redirect.new_key = wire.actionData[0]; 518 act->redirect.mods_mask = wire.actionData[1]; 519 act->redirect.mods = wire.actionData[2]; 520 act->redirect.vmods_mask0 = wire.actionData[3]; 521 act->redirect.vmods_mask1 = wire.actionData[4]; 522 act->redirect.vmods0 = wire.actionData[4]; 523 act->redirect.vmods1 = wire.actionData[5]; 524 break; 525 case XkbSA_DeviceValuator: 526 act->devval.device = wire.actionData[0]; 527 act->devval.v1_what = wire.actionData[1]; 528 act->devval.v1_ndx = wire.actionData[2]; 529 act->devval.v1_value = wire.actionData[3]; 530 act->devval.v2_what = wire.actionData[4]; 531 act->devval.v2_ndx = wire.actionData[5]; 532 act->devval.v2_what = wire.actionData[6]; 533 break; 534 535 case XkbSA_XFree86Private: 536 /* copy the kind of action */ 537 strncpy((char*)act->any.data, (char*)wire.actionData, 538 XkbAnyActionDataSize); 539 break ; 540 541 case XkbSA_Terminate: 542 /* no args, kinda (note: untrue for xfree86). */ 543 break; 544 case XkbSA_ActionMessage: 545 /* unsupported. */ 546 break; 547 } 548 } 549 if ((num_si>0)&&(changes)) { 550 changes->compat.first_si= 0; 551 changes->compat.num_si= num_si; 552 } 553 if (groups) { 554 register unsigned bit; 555 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 556 xkmModsDesc md; 557 if (groups&bit) { 558 tmp= fread(&md,SIZEOF(xkmModsDesc),1,file); 559 nRead+= tmp*SIZEOF(xkmModsDesc); 560 xkb->compat->groups[i].real_mods= md.realMods; 561 xkb->compat->groups[i].vmods= md.virtualMods; 562 if (md.virtualMods != 0) { 563 unsigned mask; 564 if (XkbVirtualModsToReal(xkb,md.virtualMods,&mask)) 565 xkb->compat->groups[i].mask= md.realMods|mask; 566 } 567 else xkb->compat->groups[i].mask= md.realMods; 568 } 569 } 570 if (changes) 571 changes->compat.changed_groups|= groups; 572 } 573 return nRead; 574} 575 576static int 577ReadXkmIndicators(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) 578{ 579register unsigned nLEDs; 580xkmIndicatorMapDesc wire; 581char buf[100]; 582unsigned tmp; 583int nRead=0; 584 585 if ((xkb->indicators==NULL)&&(XkbAllocIndicatorMaps(xkb)!=Success)) { 586 _XkbLibError(_XkbErrBadAlloc,"indicator rec",0); 587 return -1; 588 } 589 if (XkbAllocNames(xkb,XkbIndicatorNamesMask,0,0)!=Success) { 590 _XkbLibError(_XkbErrBadAlloc,"indicator names",0); 591 return -1; 592 } 593 nLEDs= XkmGetCARD8(file,&nRead); 594 nRead+= XkmSkipPadding(file,3); 595 xkb->indicators->phys_indicators= XkmGetCARD32(file,&nRead); 596 while (nLEDs-->0) { 597 Atom name; 598 XkbIndicatorMapPtr map; 599 600 if ((tmp=XkmGetCountedString(file,buf,100))<1) { 601 _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0); 602 return -1; 603 } 604 nRead+= tmp; 605 if (buf[0]!='\0') 606 name= XkbInternAtom(buf,FALSE); 607 else name= None; 608 if ((tmp=fread(&wire,SIZEOF(xkmIndicatorMapDesc),1,file))<1) { 609 _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0); 610 return -1; 611 } 612 nRead+= tmp*SIZEOF(xkmIndicatorMapDesc); 613 if (xkb->names) { 614 xkb->names->indicators[wire.indicator-1]= name; 615 if (changes) 616 changes->names.changed_indicators|= (1<<(wire.indicator-1)); 617 } 618 map= &xkb->indicators->maps[wire.indicator-1]; 619 map->flags= wire.flags; 620 map->which_groups= wire.which_groups; 621 map->groups= wire.groups; 622 map->which_mods= wire.which_mods; 623 map->mods.mask= wire.real_mods; 624 map->mods.real_mods= wire.real_mods; 625 map->mods.vmods= wire.vmods; 626 map->ctrls= wire.ctrls; 627 } 628 return nRead; 629} 630 631static XkbKeyTypePtr 632FindTypeForKey(XkbDescPtr xkb,Atom name,unsigned width,KeySym *syms) 633{ 634 if ((!xkb)||(!xkb->map)) 635 return NULL; 636 if (name!=None) { 637 register unsigned i; 638 for (i=0;i<xkb->map->num_types;i++) { 639 if (xkb->map->types[i].name==name) { 640 if (xkb->map->types[i].num_levels!=width) 641 DebugF("Group width mismatch between key and type\n"); 642 return &xkb->map->types[i]; 643 } 644 } 645 } 646 if ((width<2)||((syms!=NULL)&&(syms[1]==NoSymbol))) 647 return &xkb->map->types[XkbOneLevelIndex]; 648 if (syms!=NULL) { 649 if (XkbKSIsLower(syms[0])&&XkbKSIsUpper(syms[1])) 650 return &xkb->map->types[XkbAlphabeticIndex]; 651 else if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1])) 652 return &xkb->map->types[XkbKeypadIndex]; 653 } 654 return &xkb->map->types[XkbTwoLevelIndex]; 655} 656 657static int 658ReadXkmSymbols(FILE *file,XkbDescPtr xkb) 659{ 660register int i,g,s,totalVModMaps; 661xkmKeySymMapDesc wireMap; 662char buf[100]; 663unsigned minKC,maxKC,groupNames,tmp; 664int nRead=0; 665 666 if ((tmp=XkmGetCountedString(file,buf,100))<1) 667 return -1; 668 nRead+= tmp; 669 minKC= XkmGetCARD8(file,&nRead); 670 maxKC= XkmGetCARD8(file,&nRead); 671 groupNames= XkmGetCARD8(file,&nRead); 672 totalVModMaps= XkmGetCARD8(file,&nRead); 673 if (XkbAllocNames(xkb, 674 XkbSymbolsNameMask|XkbPhysSymbolsNameMask|XkbGroupNamesMask, 675 0,0)!=Success) { 676 _XkbLibError(_XkbErrBadAlloc,"physical names",0); 677 return -1; 678 } 679 if ((buf[0]!='\0')&&(xkb->names)) { 680 Atom name; 681 name= XkbInternAtom(buf,0); 682 xkb->names->symbols= name; 683 xkb->names->phys_symbols= name; 684 } 685 for (i=0,g=1;i<XkbNumKbdGroups;i++,g<<=1) { 686 if (groupNames&g) { 687 if ((tmp=XkmGetCountedString(file,buf,100))<1) 688 return -1; 689 nRead+= tmp; 690 if ((buf[0]!='\0')&&(xkb->names)) { 691 Atom name; 692 name= XkbInternAtom(buf,0); 693 xkb->names->groups[i]= name; 694 } 695 else xkb->names->groups[i]= None; 696 } 697 } 698 if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success) { 699 _XkbLibError(_XkbErrBadAlloc,"server map",0); 700 return -1; 701 } 702 if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) { 703 _XkbLibError(_XkbErrBadAlloc,"client map",0); 704 return -1; 705 } 706 if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) { 707 _XkbLibError(_XkbErrBadAlloc,"controls",0); 708 return -1; 709 } 710 if ((xkb->map==NULL)||(xkb->server==NULL)) 711 return -1; 712 if (xkb->min_key_code<8) xkb->min_key_code= minKC; 713 if (xkb->max_key_code<8) xkb->max_key_code= maxKC; 714 if ((minKC>=8)&&(minKC<xkb->min_key_code)) 715 xkb->min_key_code= minKC; 716 if ((maxKC>=8)&&(maxKC>xkb->max_key_code)) { 717 _XkbLibError(_XkbErrBadValue,"keys in symbol map",maxKC); 718 return -1; 719 } 720 for (i=minKC;i<=(int)maxKC;i++) { 721 Atom typeName[XkbNumKbdGroups]; 722 XkbKeyTypePtr type[XkbNumKbdGroups]; 723 if ((tmp=fread(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file))<1) { 724 _XkbLibError(_XkbErrBadLength,"ReadXkmSymbols",0); 725 return -1; 726 } 727 nRead+= tmp*SIZEOF(xkmKeySymMapDesc); 728 memset((char *)typeName, 0, XkbNumKbdGroups*sizeof(Atom)); 729 memset((char *)type, 0, XkbNumKbdGroups*sizeof(XkbKeyTypePtr)); 730 if (wireMap.flags&XkmKeyHasTypes) { 731 register int g; 732 for (g=0;g<XkbNumKbdGroups;g++) { 733 if ((wireMap.flags&(1<<g))&& 734 ((tmp=XkmGetCountedString(file,buf,100))>0)) { 735 typeName[g]= XkbInternAtom(buf,1); 736 nRead+= tmp; 737 } 738 type[g]=FindTypeForKey(xkb,typeName[g],wireMap.width,NULL); 739 if (type[g]==NULL) { 740 _XkbLibError(_XkbErrMissingTypes,"ReadXkmSymbols",0); 741 return -1; 742 } 743 if (typeName[g]==type[g]->name) 744 xkb->server->explicit[i]|= (1<<g); 745 } 746 } 747 if (wireMap.flags&XkmRepeatingKey) { 748 xkb->ctrls->per_key_repeat[i/8]|= (1<<(i%8)); 749 xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask; 750 } 751 else if (wireMap.flags&XkmNonRepeatingKey) { 752 xkb->ctrls->per_key_repeat[i/8]&= ~(1<<(i%8)); 753 xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask; 754 } 755 xkb->map->modmap[i]= wireMap.modifier_map; 756 if (XkbNumGroups(wireMap.num_groups)>0) { 757 KeySym *sym; 758 int nSyms; 759 760 if (XkbNumGroups(wireMap.num_groups)>xkb->ctrls->num_groups) 761 xkb->ctrls->num_groups= wireMap.num_groups; 762 nSyms= XkbNumGroups(wireMap.num_groups)*wireMap.width; 763 sym= XkbResizeKeySyms(xkb,i,nSyms); 764 if (!sym) 765 return -1; 766 for (s=0;s<nSyms;s++) { 767 *sym++= XkmGetCARD32(file,&nRead); 768 } 769 if (wireMap.flags&XkmKeyHasActions) { 770 XkbAction * act; 771 act= XkbResizeKeyActions(xkb,i,nSyms); 772 for (s=0;s<nSyms;s++,act++) { 773 tmp=fread(act,SIZEOF(xkmActionDesc),1,file); 774 nRead+= tmp*SIZEOF(xkmActionDesc); 775 } 776 xkb->server->explicit[i]|= XkbExplicitInterpretMask; 777 } 778 } 779 for (g=0;g<XkbNumGroups(wireMap.num_groups);g++) { 780 if (((xkb->server->explicit[i]&(1<<g))==0)||(type[g]==NULL)) { 781 KeySym *tmpSyms; 782 tmpSyms= XkbKeySymsPtr(xkb,i)+(wireMap.width*g); 783 type[g]= FindTypeForKey(xkb,None,wireMap.width,tmpSyms); 784 } 785 xkb->map->key_sym_map[i].kt_index[g]= type[g]-(&xkb->map->types[0]); 786 } 787 xkb->map->key_sym_map[i].group_info= wireMap.num_groups; 788 xkb->map->key_sym_map[i].width= wireMap.width; 789 if (wireMap.flags&XkmKeyHasBehavior) { 790 xkmBehaviorDesc b; 791 tmp= fread(&b,SIZEOF(xkmBehaviorDesc),1,file); 792 nRead+= tmp*SIZEOF(xkmBehaviorDesc); 793 xkb->server->behaviors[i].type= b.type; 794 xkb->server->behaviors[i].data= b.data; 795 xkb->server->explicit[i]|= XkbExplicitBehaviorMask; 796 } 797 } 798 if (totalVModMaps>0) { 799 xkmVModMapDesc v; 800 for (i=0;i<totalVModMaps;i++) { 801 tmp= fread(&v,SIZEOF(xkmVModMapDesc),1,file); 802 nRead+= tmp*SIZEOF(xkmVModMapDesc); 803 if (tmp>0) 804 xkb->server->vmodmap[v.key]= v.vmods; 805 } 806 } 807 return nRead; 808} 809 810static int 811ReadXkmGeomDoodad( 812 FILE * file, 813 XkbGeometryPtr geom, 814 XkbSectionPtr section) 815{ 816XkbDoodadPtr doodad; 817xkmDoodadDesc doodadWire; 818char buf[100]; 819unsigned tmp; 820int nRead=0; 821 822 nRead+= XkmGetCountedString(file,buf,100); 823 tmp= fread(&doodadWire,SIZEOF(xkmDoodadDesc),1,file); 824 nRead+= SIZEOF(xkmDoodadDesc)*tmp; 825 doodad= XkbAddGeomDoodad(geom,section,XkbInternAtom(buf,FALSE)); 826 if (!doodad) 827 return nRead; 828 doodad->any.type= doodadWire.any.type; 829 doodad->any.priority= doodadWire.any.priority; 830 doodad->any.top= doodadWire.any.top; 831 doodad->any.left= doodadWire.any.left; 832 switch (doodadWire.any.type) { 833 case XkbOutlineDoodad: 834 case XkbSolidDoodad: 835 doodad->shape.angle= doodadWire.shape.angle; 836 doodad->shape.color_ndx= doodadWire.shape.color_ndx; 837 doodad->shape.shape_ndx= doodadWire.shape.shape_ndx; 838 break; 839 case XkbTextDoodad: 840 doodad->text.angle= doodadWire.text.angle; 841 doodad->text.width= doodadWire.text.width; 842 doodad->text.height= doodadWire.text.height; 843 doodad->text.color_ndx= doodadWire.text.color_ndx; 844 nRead+= XkmGetCountedString(file,buf,100); 845 doodad->text.text= _XkbDupString(buf); 846 nRead+= XkmGetCountedString(file,buf,100); 847 doodad->text.font= _XkbDupString(buf); 848 break; 849 case XkbIndicatorDoodad: 850 doodad->indicator.shape_ndx= doodadWire.indicator.shape_ndx; 851 doodad->indicator.on_color_ndx= doodadWire.indicator.on_color_ndx; 852 doodad->indicator.off_color_ndx= doodadWire.indicator.off_color_ndx; 853 break; 854 case XkbLogoDoodad: 855 doodad->logo.angle= doodadWire.logo.angle; 856 doodad->logo.color_ndx= doodadWire.logo.color_ndx; 857 doodad->logo.shape_ndx= doodadWire.logo.shape_ndx; 858 nRead+= XkmGetCountedString(file,buf,100); 859 doodad->logo.logo_name= _XkbDupString(buf); 860 break; 861 default: 862 /* report error? */ 863 return nRead; 864 } 865 return nRead; 866} 867 868static int 869ReadXkmGeomOverlay( FILE * file, 870 XkbGeometryPtr geom, 871 XkbSectionPtr section) 872{ 873char buf[100]; 874unsigned tmp; 875int nRead=0; 876XkbOverlayPtr ol; 877XkbOverlayRowPtr row; 878xkmOverlayDesc olWire; 879xkmOverlayRowDesc rowWire; 880register int r; 881 882 nRead+= XkmGetCountedString(file,buf,100); 883 tmp= fread(&olWire,SIZEOF(xkmOverlayDesc),1,file); 884 nRead+= tmp*SIZEOF(xkmOverlayDesc); 885 ol= XkbAddGeomOverlay(section,XkbInternAtom(buf,FALSE), 886 olWire.num_rows); 887 if (!ol) 888 return nRead; 889 for (r=0;r<olWire.num_rows;r++) { 890 int k; 891 xkmOverlayKeyDesc keyWire; 892 tmp= fread(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file); 893 nRead+= tmp*SIZEOF(xkmOverlayRowDesc); 894 row= XkbAddGeomOverlayRow(ol,rowWire.row_under,rowWire.num_keys); 895 if (!row) { 896 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomOverlay",0); 897 return nRead; 898 } 899 for (k=0;k<rowWire.num_keys;k++) { 900 tmp= fread(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file); 901 nRead+= tmp*SIZEOF(xkmOverlayKeyDesc); 902 memcpy(row->keys[k].over.name,keyWire.over,XkbKeyNameLength); 903 memcpy(row->keys[k].under.name,keyWire.under,XkbKeyNameLength); 904 } 905 row->num_keys= rowWire.num_keys; 906 } 907 return nRead; 908} 909 910static int 911ReadXkmGeomSection( FILE * file, 912 XkbGeometryPtr geom) 913{ 914register int i; 915XkbSectionPtr section; 916xkmSectionDesc sectionWire; 917unsigned tmp; 918int nRead= 0; 919char buf[100]; 920Atom nameAtom; 921 922 nRead+= XkmGetCountedString(file,buf,100); 923 nameAtom= XkbInternAtom(buf,FALSE); 924 tmp= fread(§ionWire,SIZEOF(xkmSectionDesc),1,file); 925 nRead+= SIZEOF(xkmSectionDesc)*tmp; 926 section= XkbAddGeomSection(geom,nameAtom,sectionWire.num_rows, 927 sectionWire.num_doodads, 928 sectionWire.num_overlays); 929 if (!section) { 930 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0); 931 return nRead; 932 } 933 section->top= sectionWire.top; 934 section->left= sectionWire.left; 935 section->width= sectionWire.width; 936 section->height= sectionWire.height; 937 section->angle= sectionWire.angle; 938 section->priority= sectionWire.priority; 939 if (sectionWire.num_rows>0) { 940 register int k; 941 XkbRowPtr row; 942 xkmRowDesc rowWire; 943 XkbKeyPtr key; 944 xkmKeyDesc keyWire; 945 946 for (i=0;i<sectionWire.num_rows;i++) { 947 tmp= fread(&rowWire,SIZEOF(xkmRowDesc),1,file); 948 nRead+= SIZEOF(xkmRowDesc)*tmp; 949 row= XkbAddGeomRow(section,rowWire.num_keys); 950 if (!row) { 951 _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0); 952 return nRead; 953 } 954 row->top= rowWire.top; 955 row->left= rowWire.left; 956 row->vertical= rowWire.vertical; 957 for (k=0;k<rowWire.num_keys;k++) { 958 tmp= fread(&keyWire,SIZEOF(xkmKeyDesc),1,file); 959 nRead+= SIZEOF(xkmKeyDesc)*tmp; 960 key= XkbAddGeomKey(row); 961 if (!key) { 962 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0); 963 return nRead; 964 } 965 memcpy(key->name.name,keyWire.name,XkbKeyNameLength); 966 key->gap= keyWire.gap; 967 key->shape_ndx= keyWire.shape_ndx; 968 key->color_ndx= keyWire.color_ndx; 969 } 970 } 971 } 972 if (sectionWire.num_doodads>0) { 973 for (i=0;i<sectionWire.num_doodads;i++) { 974 tmp= ReadXkmGeomDoodad(file,geom,section); 975 nRead+= tmp; 976 if (tmp<1) 977 return nRead; 978 } 979 } 980 if (sectionWire.num_overlays>0) { 981 for (i=0;i<sectionWire.num_overlays;i++) { 982 tmp= ReadXkmGeomOverlay(file,geom,section); 983 nRead+= tmp; 984 if (tmp<1) 985 return nRead; 986 } 987 } 988 return nRead; 989} 990 991static int 992ReadXkmGeometry(FILE *file,XkbDescPtr xkb) 993{ 994register int i; 995char buf[100]; 996unsigned tmp; 997int nRead= 0; 998xkmGeometryDesc wireGeom; 999XkbGeometryPtr geom; 1000XkbGeometrySizesRec sizes; 1001 1002 nRead+= XkmGetCountedString(file,buf,100); 1003 tmp= fread(&wireGeom,SIZEOF(xkmGeometryDesc),1,file); 1004 nRead+= tmp*SIZEOF(xkmGeometryDesc); 1005 sizes.which= XkbGeomAllMask; 1006 sizes.num_properties= wireGeom.num_properties; 1007 sizes.num_colors= wireGeom.num_colors; 1008 sizes.num_shapes= wireGeom.num_shapes; 1009 sizes.num_sections= wireGeom.num_sections; 1010 sizes.num_doodads= wireGeom.num_doodads; 1011 sizes.num_key_aliases= wireGeom.num_key_aliases; 1012 if (XkbAllocGeometry(xkb,&sizes)!=Success) { 1013 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1014 return nRead; 1015 } 1016 geom= xkb->geom; 1017 geom->name= XkbInternAtom(buf,FALSE); 1018 geom->width_mm= wireGeom.width_mm; 1019 geom->height_mm= wireGeom.height_mm; 1020 nRead+= XkmGetCountedString(file,buf,100); 1021 geom->label_font= _XkbDupString(buf); 1022 if (wireGeom.num_properties>0) { 1023 char val[1024]; 1024 for (i=0;i<wireGeom.num_properties;i++) { 1025 nRead+= XkmGetCountedString(file,buf,100); 1026 nRead+= XkmGetCountedString(file,val,1024); 1027 if (XkbAddGeomProperty(geom,buf,val)==NULL) { 1028 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1029 return nRead; 1030 } 1031 } 1032 } 1033 if (wireGeom.num_colors>0) { 1034 for (i=0;i<wireGeom.num_colors;i++) { 1035 nRead+= XkmGetCountedString(file,buf,100); 1036 if (XkbAddGeomColor(geom,buf,i)==NULL) { 1037 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1038 return nRead; 1039 } 1040 } 1041 } 1042 geom->base_color= &geom->colors[wireGeom.base_color_ndx]; 1043 geom->label_color= &geom->colors[wireGeom.label_color_ndx]; 1044 if (wireGeom.num_shapes>0) { 1045 XkbShapePtr shape; 1046 xkmShapeDesc shapeWire; 1047 Atom nameAtom; 1048 for (i=0;i<wireGeom.num_shapes;i++) { 1049 register int n; 1050 XkbOutlinePtr ol; 1051 xkmOutlineDesc olWire; 1052 nRead+= XkmGetCountedString(file,buf,100); 1053 nameAtom= XkbInternAtom(buf,FALSE); 1054 tmp= fread(&shapeWire,SIZEOF(xkmShapeDesc),1,file); 1055 nRead+= tmp*SIZEOF(xkmShapeDesc); 1056 shape= XkbAddGeomShape(geom,nameAtom,shapeWire.num_outlines); 1057 if (!shape) { 1058 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1059 return nRead; 1060 } 1061 for (n=0;n<shapeWire.num_outlines;n++) { 1062 register int p; 1063 xkmPointDesc ptWire; 1064 tmp= fread(&olWire,SIZEOF(xkmOutlineDesc),1,file); 1065 nRead+= tmp*SIZEOF(xkmOutlineDesc); 1066 ol= XkbAddGeomOutline(shape,olWire.num_points); 1067 if (!ol) { 1068 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1069 return nRead; 1070 } 1071 ol->num_points= olWire.num_points; 1072 ol->corner_radius= olWire.corner_radius; 1073 for (p=0;p<olWire.num_points;p++) { 1074 tmp= fread(&ptWire,SIZEOF(xkmPointDesc),1,file); 1075 nRead+= tmp*SIZEOF(xkmPointDesc); 1076 ol->points[p].x= ptWire.x; 1077 ol->points[p].y= ptWire.y; 1078 if (ptWire.x<shape->bounds.x1) shape->bounds.x1= ptWire.x; 1079 if (ptWire.x>shape->bounds.x2) shape->bounds.x2= ptWire.x; 1080 if (ptWire.y<shape->bounds.y1) shape->bounds.y1= ptWire.y; 1081 if (ptWire.y>shape->bounds.y2) shape->bounds.y2= ptWire.y; 1082 } 1083 } 1084 if (shapeWire.primary_ndx!=XkbNoShape) 1085 shape->primary= &shape->outlines[shapeWire.primary_ndx]; 1086 if (shapeWire.approx_ndx!=XkbNoShape) 1087 shape->approx= &shape->outlines[shapeWire.approx_ndx]; 1088 } 1089 } 1090 if (wireGeom.num_sections>0) { 1091 for (i=0;i<wireGeom.num_sections;i++) { 1092 tmp= ReadXkmGeomSection(file,geom); 1093 nRead+= tmp; 1094 if (tmp==0) 1095 return nRead; 1096 } 1097 } 1098 if (wireGeom.num_doodads>0) { 1099 for (i=0;i<wireGeom.num_doodads;i++) { 1100 tmp= ReadXkmGeomDoodad(file,geom,NULL); 1101 nRead+= tmp; 1102 if (tmp==0) 1103 return nRead; 1104 } 1105 } 1106 if ((wireGeom.num_key_aliases>0)&&(geom->key_aliases)) { 1107 int sz= XkbKeyNameLength*2; 1108 int num= wireGeom.num_key_aliases; 1109 if (fread(geom->key_aliases,sz,num,file)!=num) { 1110 _XkbLibError(_XkbErrBadLength,"ReadXkmGeometry",0); 1111 return -1; 1112 } 1113 nRead+= (num*sz); 1114 geom->num_key_aliases= num; 1115 } 1116 return nRead; 1117} 1118 1119Bool 1120XkmProbe(FILE *file) 1121{ 1122unsigned hdr,tmp; 1123int nRead=0; 1124 1125 hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); 1126 tmp= XkmGetCARD32(file,&nRead); 1127 if (tmp!=hdr) { 1128 if ((tmp&(~0xff))==(hdr&(~0xff))) { 1129 _XkbLibError(_XkbErrBadFileVersion,"XkmProbe",tmp&0xff); 1130 } 1131 return 0; 1132 } 1133 return 1; 1134} 1135 1136static Bool 1137XkmReadTOC(FILE *file,xkmFileInfo* file_info,int max_toc,xkmSectionInfo *toc) 1138{ 1139unsigned hdr,tmp; 1140int nRead=0; 1141unsigned i,size_toc; 1142 1143 hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); 1144 tmp= XkmGetCARD32(file,&nRead); 1145 if (tmp!=hdr) { 1146 if ((tmp&(~0xff))==(hdr&(~0xff))) { 1147 _XkbLibError(_XkbErrBadFileVersion,"XkmReadTOC",tmp&0xff); 1148 } 1149 else { 1150 _XkbLibError(_XkbErrBadFileType,"XkmReadTOC",tmp); 1151 } 1152 return 0; 1153 } 1154 fread(file_info,SIZEOF(xkmFileInfo),1,file); 1155 size_toc= file_info->num_toc; 1156 if (size_toc>max_toc) { 1157 DebugF("Warning! Too many TOC entries; last %d ignored\n", 1158 size_toc-max_toc); 1159 size_toc= max_toc; 1160 } 1161 for (i=0;i<size_toc;i++) { 1162 fread(&toc[i],SIZEOF(xkmSectionInfo),1,file); 1163 } 1164 return 1; 1165} 1166 1167/***====================================================================***/ 1168 1169#define MAX_TOC 16 1170unsigned 1171XkmReadFile(FILE *file,unsigned need,unsigned want,XkbDescPtr *xkb) 1172{ 1173register unsigned i; 1174xkmSectionInfo toc[MAX_TOC],tmpTOC; 1175xkmFileInfo fileInfo; 1176unsigned tmp,nRead=0; 1177unsigned which= need|want; 1178 1179 if (!XkmReadTOC(file,&fileInfo,MAX_TOC,toc)) 1180 return which; 1181 if ((fileInfo.present&need)!=need) { 1182 _XkbLibError(_XkbErrIllegalContents,"XkmReadFile", 1183 need&(~fileInfo.present)); 1184 return which; 1185 } 1186 if (*xkb==NULL) 1187 *xkb= XkbAllocKeyboard(); 1188 for (i=0;i<fileInfo.num_toc;i++) { 1189 fseek(file,toc[i].offset,SEEK_SET); 1190 tmp= fread(&tmpTOC,SIZEOF(xkmSectionInfo),1,file); 1191 nRead= tmp*SIZEOF(xkmSectionInfo); 1192 if ((tmpTOC.type!=toc[i].type)||(tmpTOC.format!=toc[i].format)|| 1193 (tmpTOC.size!=toc[i].size)||(tmpTOC.offset!=toc[i].offset)) { 1194 return which; 1195 } 1196 if ((which&(1<<tmpTOC.type))==0) { 1197 continue; 1198 } 1199 switch (tmpTOC.type) { 1200 case XkmVirtualModsIndex: 1201 tmp= ReadXkmVirtualMods(file,*xkb,NULL); 1202 break; 1203 case XkmTypesIndex: 1204 tmp= ReadXkmKeyTypes(file,*xkb,NULL); 1205 break; 1206 case XkmCompatMapIndex: 1207 tmp= ReadXkmCompatMap(file,*xkb,NULL); 1208 break; 1209 case XkmKeyNamesIndex: 1210 tmp= ReadXkmKeycodes(file,*xkb,NULL); 1211 break; 1212 case XkmIndicatorsIndex: 1213 tmp= ReadXkmIndicators(file,*xkb,NULL); 1214 break; 1215 case XkmSymbolsIndex: 1216 tmp= ReadXkmSymbols(file,*xkb); 1217 break; 1218 case XkmGeometryIndex: 1219 tmp= ReadXkmGeometry(file,*xkb); 1220 break; 1221 default: 1222 _XkbLibError(_XkbErrBadImplementation, 1223 XkbConfigText(tmpTOC.type,XkbMessage),0); 1224 tmp= 0; 1225 break; 1226 } 1227 if (tmp>0) { 1228 nRead+= tmp; 1229 which&= ~(1<<toc[i].type); 1230 (*xkb)->defined|= (1<<toc[i].type); 1231 } 1232 if (nRead!=tmpTOC.size) { 1233 _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage), 1234 nRead-tmpTOC.size); 1235 } 1236 } 1237 return which; 1238} 1239