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 memcpy(act->any.data, wire.actionData, XkbAnyActionDataSize); 538 break ; 539 540 case XkbSA_Terminate: 541 /* no args, kinda (note: untrue for xfree86). */ 542 break; 543 case XkbSA_ActionMessage: 544 /* unsupported. */ 545 break; 546 } 547 } 548 if ((num_si>0)&&(changes)) { 549 changes->compat.first_si= 0; 550 changes->compat.num_si= num_si; 551 } 552 if (groups) { 553 register unsigned bit; 554 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 555 xkmModsDesc md; 556 if (groups&bit) { 557 tmp= fread(&md,SIZEOF(xkmModsDesc),1,file); 558 nRead+= tmp*SIZEOF(xkmModsDesc); 559 xkb->compat->groups[i].real_mods= md.realMods; 560 xkb->compat->groups[i].vmods= md.virtualMods; 561 if (md.virtualMods != 0) { 562 unsigned mask; 563 if (XkbVirtualModsToReal(xkb,md.virtualMods,&mask)) 564 xkb->compat->groups[i].mask= md.realMods|mask; 565 } 566 else xkb->compat->groups[i].mask= md.realMods; 567 } 568 } 569 if (changes) 570 changes->compat.changed_groups|= groups; 571 } 572 return nRead; 573} 574 575static int 576ReadXkmIndicators(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes) 577{ 578register unsigned nLEDs; 579xkmIndicatorMapDesc wire; 580char buf[100]; 581unsigned tmp; 582int nRead=0; 583 584 if ((xkb->indicators==NULL)&&(XkbAllocIndicatorMaps(xkb)!=Success)) { 585 _XkbLibError(_XkbErrBadAlloc,"indicator rec",0); 586 return -1; 587 } 588 if (XkbAllocNames(xkb,XkbIndicatorNamesMask,0,0)!=Success) { 589 _XkbLibError(_XkbErrBadAlloc,"indicator names",0); 590 return -1; 591 } 592 nLEDs= XkmGetCARD8(file,&nRead); 593 nRead+= XkmSkipPadding(file,3); 594 xkb->indicators->phys_indicators= XkmGetCARD32(file,&nRead); 595 while (nLEDs-->0) { 596 Atom name; 597 XkbIndicatorMapPtr map; 598 599 if ((tmp=XkmGetCountedString(file,buf,100))<1) { 600 _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0); 601 return -1; 602 } 603 nRead+= tmp; 604 if (buf[0]!='\0') 605 name= XkbInternAtom(buf,FALSE); 606 else name= None; 607 if ((tmp=fread(&wire,SIZEOF(xkmIndicatorMapDesc),1,file))<1) { 608 _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0); 609 return -1; 610 } 611 nRead+= tmp*SIZEOF(xkmIndicatorMapDesc); 612 if (xkb->names) { 613 xkb->names->indicators[wire.indicator-1]= name; 614 if (changes) 615 changes->names.changed_indicators|= (1<<(wire.indicator-1)); 616 } 617 map= &xkb->indicators->maps[wire.indicator-1]; 618 map->flags= wire.flags; 619 map->which_groups= wire.which_groups; 620 map->groups= wire.groups; 621 map->which_mods= wire.which_mods; 622 map->mods.mask= wire.real_mods; 623 map->mods.real_mods= wire.real_mods; 624 map->mods.vmods= wire.vmods; 625 map->ctrls= wire.ctrls; 626 } 627 return nRead; 628} 629 630static XkbKeyTypePtr 631FindTypeForKey(XkbDescPtr xkb,Atom name,unsigned width,KeySym *syms) 632{ 633 if ((!xkb)||(!xkb->map)) 634 return NULL; 635 if (name!=None) { 636 register unsigned i; 637 for (i=0;i<xkb->map->num_types;i++) { 638 if (xkb->map->types[i].name==name) { 639 if (xkb->map->types[i].num_levels!=width) 640 DebugF("Group width mismatch between key and type\n"); 641 return &xkb->map->types[i]; 642 } 643 } 644 } 645 if ((width<2)||((syms!=NULL)&&(syms[1]==NoSymbol))) 646 return &xkb->map->types[XkbOneLevelIndex]; 647 if (syms!=NULL) { 648 if (XkbKSIsLower(syms[0])&&XkbKSIsUpper(syms[1])) 649 return &xkb->map->types[XkbAlphabeticIndex]; 650 else if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1])) 651 return &xkb->map->types[XkbKeypadIndex]; 652 } 653 return &xkb->map->types[XkbTwoLevelIndex]; 654} 655 656static int 657ReadXkmSymbols(FILE *file,XkbDescPtr xkb) 658{ 659register int i,g,s,totalVModMaps; 660xkmKeySymMapDesc wireMap; 661char buf[100]; 662unsigned minKC,maxKC,groupNames,tmp; 663int nRead=0; 664 665 if ((tmp=XkmGetCountedString(file,buf,100))<1) 666 return -1; 667 nRead+= tmp; 668 minKC= XkmGetCARD8(file,&nRead); 669 maxKC= XkmGetCARD8(file,&nRead); 670 groupNames= XkmGetCARD8(file,&nRead); 671 totalVModMaps= XkmGetCARD8(file,&nRead); 672 if (XkbAllocNames(xkb, 673 XkbSymbolsNameMask|XkbPhysSymbolsNameMask|XkbGroupNamesMask, 674 0,0)!=Success) { 675 _XkbLibError(_XkbErrBadAlloc,"physical names",0); 676 return -1; 677 } 678 if ((buf[0]!='\0')&&(xkb->names)) { 679 Atom name; 680 name= XkbInternAtom(buf,0); 681 xkb->names->symbols= name; 682 xkb->names->phys_symbols= name; 683 } 684 for (i=0,g=1;i<XkbNumKbdGroups;i++,g<<=1) { 685 if (groupNames&g) { 686 if ((tmp=XkmGetCountedString(file,buf,100))<1) 687 return -1; 688 nRead+= tmp; 689 690 if (!xkb->names) 691 continue; 692 693 if (buf[0]!='\0') { 694 Atom name; 695 name= XkbInternAtom(buf,0); 696 xkb->names->groups[i]= name; 697 } 698 else xkb->names->groups[i]= None; 699 } 700 } 701 if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success) { 702 _XkbLibError(_XkbErrBadAlloc,"server map",0); 703 return -1; 704 } 705 if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) { 706 _XkbLibError(_XkbErrBadAlloc,"client map",0); 707 return -1; 708 } 709 if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) { 710 _XkbLibError(_XkbErrBadAlloc,"controls",0); 711 return -1; 712 } 713 if ((xkb->map==NULL)||(xkb->server==NULL)) 714 return -1; 715 if (xkb->min_key_code<8) xkb->min_key_code= minKC; 716 if (xkb->max_key_code<8) xkb->max_key_code= maxKC; 717 if ((minKC>=8)&&(minKC<xkb->min_key_code)) 718 xkb->min_key_code= minKC; 719 if ((maxKC>=8)&&(maxKC>xkb->max_key_code)) { 720 _XkbLibError(_XkbErrBadValue,"keys in symbol map",maxKC); 721 return -1; 722 } 723 for (i=minKC;i<=(int)maxKC;i++) { 724 Atom typeName[XkbNumKbdGroups]; 725 XkbKeyTypePtr type[XkbNumKbdGroups]; 726 if ((tmp=fread(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file))<1) { 727 _XkbLibError(_XkbErrBadLength,"ReadXkmSymbols",0); 728 return -1; 729 } 730 nRead+= tmp*SIZEOF(xkmKeySymMapDesc); 731 memset((char *)typeName, 0, XkbNumKbdGroups*sizeof(Atom)); 732 memset((char *)type, 0, XkbNumKbdGroups*sizeof(XkbKeyTypePtr)); 733 if (wireMap.flags&XkmKeyHasTypes) { 734 register int g; 735 for (g=0;g<XkbNumKbdGroups;g++) { 736 if ((wireMap.flags&(1<<g))&& 737 ((tmp=XkmGetCountedString(file,buf,100))>0)) { 738 typeName[g]= XkbInternAtom(buf,1); 739 nRead+= tmp; 740 } 741 type[g]=FindTypeForKey(xkb,typeName[g],wireMap.width,NULL); 742 if (type[g]==NULL) { 743 _XkbLibError(_XkbErrMissingTypes,"ReadXkmSymbols",0); 744 return -1; 745 } 746 if (typeName[g]==type[g]->name) 747 xkb->server->explicit[i]|= (1<<g); 748 } 749 } 750 if (wireMap.flags&XkmRepeatingKey) { 751 xkb->ctrls->per_key_repeat[i/8]|= (1<<(i%8)); 752 xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask; 753 } 754 else if (wireMap.flags&XkmNonRepeatingKey) { 755 xkb->ctrls->per_key_repeat[i/8]&= ~(1<<(i%8)); 756 xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask; 757 } 758 xkb->map->modmap[i]= wireMap.modifier_map; 759 if (XkbNumGroups(wireMap.num_groups)>0) { 760 KeySym *sym; 761 int nSyms; 762 763 if (XkbNumGroups(wireMap.num_groups)>xkb->ctrls->num_groups) 764 xkb->ctrls->num_groups= wireMap.num_groups; 765 nSyms= XkbNumGroups(wireMap.num_groups)*wireMap.width; 766 sym= XkbResizeKeySyms(xkb,i,nSyms); 767 if (!sym) 768 return -1; 769 for (s=0;s<nSyms;s++) { 770 *sym++= XkmGetCARD32(file,&nRead); 771 } 772 if (wireMap.flags&XkmKeyHasActions) { 773 XkbAction * act; 774 act= XkbResizeKeyActions(xkb,i,nSyms); 775 for (s=0;s<nSyms;s++,act++) { 776 tmp=fread(act,SIZEOF(xkmActionDesc),1,file); 777 nRead+= tmp*SIZEOF(xkmActionDesc); 778 } 779 xkb->server->explicit[i]|= XkbExplicitInterpretMask; 780 } 781 } 782 for (g=0;g<XkbNumGroups(wireMap.num_groups);g++) { 783 if (((xkb->server->explicit[i]&(1<<g))==0)||(type[g]==NULL)) { 784 KeySym *tmpSyms; 785 tmpSyms= XkbKeySymsPtr(xkb,i)+(wireMap.width*g); 786 type[g]= FindTypeForKey(xkb,None,wireMap.width,tmpSyms); 787 } 788 xkb->map->key_sym_map[i].kt_index[g]= type[g]-(&xkb->map->types[0]); 789 } 790 xkb->map->key_sym_map[i].group_info= wireMap.num_groups; 791 xkb->map->key_sym_map[i].width= wireMap.width; 792 if (wireMap.flags&XkmKeyHasBehavior) { 793 xkmBehaviorDesc b; 794 tmp= fread(&b,SIZEOF(xkmBehaviorDesc),1,file); 795 nRead+= tmp*SIZEOF(xkmBehaviorDesc); 796 xkb->server->behaviors[i].type= b.type; 797 xkb->server->behaviors[i].data= b.data; 798 xkb->server->explicit[i]|= XkbExplicitBehaviorMask; 799 } 800 } 801 if (totalVModMaps>0) { 802 xkmVModMapDesc v; 803 for (i=0;i<totalVModMaps;i++) { 804 tmp= fread(&v,SIZEOF(xkmVModMapDesc),1,file); 805 nRead+= tmp*SIZEOF(xkmVModMapDesc); 806 if (tmp>0) 807 xkb->server->vmodmap[v.key]= v.vmods; 808 } 809 } 810 return nRead; 811} 812 813static int 814ReadXkmGeomDoodad( 815 FILE * file, 816 XkbGeometryPtr geom, 817 XkbSectionPtr section) 818{ 819XkbDoodadPtr doodad; 820xkmDoodadDesc doodadWire; 821char buf[100]; 822unsigned tmp; 823int nRead=0; 824 825 nRead+= XkmGetCountedString(file,buf,100); 826 tmp= fread(&doodadWire,SIZEOF(xkmDoodadDesc),1,file); 827 nRead+= SIZEOF(xkmDoodadDesc)*tmp; 828 doodad= XkbAddGeomDoodad(geom,section,XkbInternAtom(buf,FALSE)); 829 if (!doodad) 830 return nRead; 831 doodad->any.type= doodadWire.any.type; 832 doodad->any.priority= doodadWire.any.priority; 833 doodad->any.top= doodadWire.any.top; 834 doodad->any.left= doodadWire.any.left; 835 switch (doodadWire.any.type) { 836 case XkbOutlineDoodad: 837 case XkbSolidDoodad: 838 doodad->shape.angle= doodadWire.shape.angle; 839 doodad->shape.color_ndx= doodadWire.shape.color_ndx; 840 doodad->shape.shape_ndx= doodadWire.shape.shape_ndx; 841 break; 842 case XkbTextDoodad: 843 doodad->text.angle= doodadWire.text.angle; 844 doodad->text.width= doodadWire.text.width; 845 doodad->text.height= doodadWire.text.height; 846 doodad->text.color_ndx= doodadWire.text.color_ndx; 847 nRead+= XkmGetCountedString(file,buf,100); 848 doodad->text.text= _XkbDupString(buf); 849 nRead+= XkmGetCountedString(file,buf,100); 850 doodad->text.font= _XkbDupString(buf); 851 break; 852 case XkbIndicatorDoodad: 853 doodad->indicator.shape_ndx= doodadWire.indicator.shape_ndx; 854 doodad->indicator.on_color_ndx= doodadWire.indicator.on_color_ndx; 855 doodad->indicator.off_color_ndx= doodadWire.indicator.off_color_ndx; 856 break; 857 case XkbLogoDoodad: 858 doodad->logo.angle= doodadWire.logo.angle; 859 doodad->logo.color_ndx= doodadWire.logo.color_ndx; 860 doodad->logo.shape_ndx= doodadWire.logo.shape_ndx; 861 nRead+= XkmGetCountedString(file,buf,100); 862 doodad->logo.logo_name= _XkbDupString(buf); 863 break; 864 default: 865 /* report error? */ 866 return nRead; 867 } 868 return nRead; 869} 870 871static int 872ReadXkmGeomOverlay( FILE * file, 873 XkbGeometryPtr geom, 874 XkbSectionPtr section) 875{ 876char buf[100]; 877unsigned tmp; 878int nRead=0; 879XkbOverlayPtr ol; 880XkbOverlayRowPtr row; 881xkmOverlayDesc olWire; 882xkmOverlayRowDesc rowWire; 883register int r; 884 885 nRead+= XkmGetCountedString(file,buf,100); 886 tmp= fread(&olWire,SIZEOF(xkmOverlayDesc),1,file); 887 nRead+= tmp*SIZEOF(xkmOverlayDesc); 888 ol= XkbAddGeomOverlay(section,XkbInternAtom(buf,FALSE), 889 olWire.num_rows); 890 if (!ol) 891 return nRead; 892 for (r=0;r<olWire.num_rows;r++) { 893 int k; 894 xkmOverlayKeyDesc keyWire; 895 tmp= fread(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file); 896 nRead+= tmp*SIZEOF(xkmOverlayRowDesc); 897 row= XkbAddGeomOverlayRow(ol,rowWire.row_under,rowWire.num_keys); 898 if (!row) { 899 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomOverlay",0); 900 return nRead; 901 } 902 for (k=0;k<rowWire.num_keys;k++) { 903 tmp= fread(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file); 904 nRead+= tmp*SIZEOF(xkmOverlayKeyDesc); 905 memcpy(row->keys[k].over.name,keyWire.over,XkbKeyNameLength); 906 memcpy(row->keys[k].under.name,keyWire.under,XkbKeyNameLength); 907 } 908 row->num_keys= rowWire.num_keys; 909 } 910 return nRead; 911} 912 913static int 914ReadXkmGeomSection( FILE * file, 915 XkbGeometryPtr geom) 916{ 917register int i; 918XkbSectionPtr section; 919xkmSectionDesc sectionWire; 920unsigned tmp; 921int nRead= 0; 922char buf[100]; 923Atom nameAtom; 924 925 nRead+= XkmGetCountedString(file,buf,100); 926 nameAtom= XkbInternAtom(buf,FALSE); 927 tmp= fread(§ionWire,SIZEOF(xkmSectionDesc),1,file); 928 nRead+= SIZEOF(xkmSectionDesc)*tmp; 929 section= XkbAddGeomSection(geom,nameAtom,sectionWire.num_rows, 930 sectionWire.num_doodads, 931 sectionWire.num_overlays); 932 if (!section) { 933 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0); 934 return nRead; 935 } 936 section->top= sectionWire.top; 937 section->left= sectionWire.left; 938 section->width= sectionWire.width; 939 section->height= sectionWire.height; 940 section->angle= sectionWire.angle; 941 section->priority= sectionWire.priority; 942 if (sectionWire.num_rows>0) { 943 register int k; 944 XkbRowPtr row; 945 xkmRowDesc rowWire; 946 XkbKeyPtr key; 947 xkmKeyDesc keyWire; 948 949 for (i=0;i<sectionWire.num_rows;i++) { 950 tmp= fread(&rowWire,SIZEOF(xkmRowDesc),1,file); 951 nRead+= SIZEOF(xkmRowDesc)*tmp; 952 row= XkbAddGeomRow(section,rowWire.num_keys); 953 if (!row) { 954 _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0); 955 return nRead; 956 } 957 row->top= rowWire.top; 958 row->left= rowWire.left; 959 row->vertical= rowWire.vertical; 960 for (k=0;k<rowWire.num_keys;k++) { 961 tmp= fread(&keyWire,SIZEOF(xkmKeyDesc),1,file); 962 nRead+= SIZEOF(xkmKeyDesc)*tmp; 963 key= XkbAddGeomKey(row); 964 if (!key) { 965 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0); 966 return nRead; 967 } 968 memcpy(key->name.name,keyWire.name,XkbKeyNameLength); 969 key->gap= keyWire.gap; 970 key->shape_ndx= keyWire.shape_ndx; 971 key->color_ndx= keyWire.color_ndx; 972 } 973 } 974 } 975 if (sectionWire.num_doodads>0) { 976 for (i=0;i<sectionWire.num_doodads;i++) { 977 tmp= ReadXkmGeomDoodad(file,geom,section); 978 nRead+= tmp; 979 if (tmp<1) 980 return nRead; 981 } 982 } 983 if (sectionWire.num_overlays>0) { 984 for (i=0;i<sectionWire.num_overlays;i++) { 985 tmp= ReadXkmGeomOverlay(file,geom,section); 986 nRead+= tmp; 987 if (tmp<1) 988 return nRead; 989 } 990 } 991 return nRead; 992} 993 994static int 995ReadXkmGeometry(FILE *file,XkbDescPtr xkb) 996{ 997register int i; 998char buf[100]; 999unsigned tmp; 1000int nRead= 0; 1001xkmGeometryDesc wireGeom; 1002XkbGeometryPtr geom; 1003XkbGeometrySizesRec sizes; 1004 1005 nRead+= XkmGetCountedString(file,buf,100); 1006 tmp= fread(&wireGeom,SIZEOF(xkmGeometryDesc),1,file); 1007 nRead+= tmp*SIZEOF(xkmGeometryDesc); 1008 sizes.which= XkbGeomAllMask; 1009 sizes.num_properties= wireGeom.num_properties; 1010 sizes.num_colors= wireGeom.num_colors; 1011 sizes.num_shapes= wireGeom.num_shapes; 1012 sizes.num_sections= wireGeom.num_sections; 1013 sizes.num_doodads= wireGeom.num_doodads; 1014 sizes.num_key_aliases= wireGeom.num_key_aliases; 1015 if (XkbAllocGeometry(xkb,&sizes)!=Success) { 1016 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1017 return nRead; 1018 } 1019 geom= xkb->geom; 1020 geom->name= XkbInternAtom(buf,FALSE); 1021 geom->width_mm= wireGeom.width_mm; 1022 geom->height_mm= wireGeom.height_mm; 1023 nRead+= XkmGetCountedString(file,buf,100); 1024 geom->label_font= _XkbDupString(buf); 1025 if (wireGeom.num_properties>0) { 1026 char val[1024]; 1027 for (i=0;i<wireGeom.num_properties;i++) { 1028 nRead+= XkmGetCountedString(file,buf,100); 1029 nRead+= XkmGetCountedString(file,val,1024); 1030 if (XkbAddGeomProperty(geom,buf,val)==NULL) { 1031 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1032 return nRead; 1033 } 1034 } 1035 } 1036 if (wireGeom.num_colors>0) { 1037 for (i=0;i<wireGeom.num_colors;i++) { 1038 nRead+= XkmGetCountedString(file,buf,100); 1039 if (XkbAddGeomColor(geom,buf,i)==NULL) { 1040 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1041 return nRead; 1042 } 1043 } 1044 } 1045 geom->base_color= &geom->colors[wireGeom.base_color_ndx]; 1046 geom->label_color= &geom->colors[wireGeom.label_color_ndx]; 1047 if (wireGeom.num_shapes>0) { 1048 XkbShapePtr shape; 1049 xkmShapeDesc shapeWire; 1050 Atom nameAtom; 1051 for (i=0;i<wireGeom.num_shapes;i++) { 1052 register int n; 1053 XkbOutlinePtr ol; 1054 xkmOutlineDesc olWire; 1055 nRead+= XkmGetCountedString(file,buf,100); 1056 nameAtom= XkbInternAtom(buf,FALSE); 1057 tmp= fread(&shapeWire,SIZEOF(xkmShapeDesc),1,file); 1058 nRead+= tmp*SIZEOF(xkmShapeDesc); 1059 shape= XkbAddGeomShape(geom,nameAtom,shapeWire.num_outlines); 1060 if (!shape) { 1061 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1062 return nRead; 1063 } 1064 for (n=0;n<shapeWire.num_outlines;n++) { 1065 register int p; 1066 xkmPointDesc ptWire; 1067 tmp= fread(&olWire,SIZEOF(xkmOutlineDesc),1,file); 1068 nRead+= tmp*SIZEOF(xkmOutlineDesc); 1069 ol= XkbAddGeomOutline(shape,olWire.num_points); 1070 if (!ol) { 1071 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); 1072 return nRead; 1073 } 1074 ol->num_points= olWire.num_points; 1075 ol->corner_radius= olWire.corner_radius; 1076 for (p=0;p<olWire.num_points;p++) { 1077 tmp= fread(&ptWire,SIZEOF(xkmPointDesc),1,file); 1078 nRead+= tmp*SIZEOF(xkmPointDesc); 1079 ol->points[p].x= ptWire.x; 1080 ol->points[p].y= ptWire.y; 1081 if (ptWire.x<shape->bounds.x1) shape->bounds.x1= ptWire.x; 1082 if (ptWire.x>shape->bounds.x2) shape->bounds.x2= ptWire.x; 1083 if (ptWire.y<shape->bounds.y1) shape->bounds.y1= ptWire.y; 1084 if (ptWire.y>shape->bounds.y2) shape->bounds.y2= ptWire.y; 1085 } 1086 } 1087 if (shapeWire.primary_ndx!=XkbNoShape) 1088 shape->primary= &shape->outlines[shapeWire.primary_ndx]; 1089 if (shapeWire.approx_ndx!=XkbNoShape) 1090 shape->approx= &shape->outlines[shapeWire.approx_ndx]; 1091 } 1092 } 1093 if (wireGeom.num_sections>0) { 1094 for (i=0;i<wireGeom.num_sections;i++) { 1095 tmp= ReadXkmGeomSection(file,geom); 1096 nRead+= tmp; 1097 if (tmp==0) 1098 return nRead; 1099 } 1100 } 1101 if (wireGeom.num_doodads>0) { 1102 for (i=0;i<wireGeom.num_doodads;i++) { 1103 tmp= ReadXkmGeomDoodad(file,geom,NULL); 1104 nRead+= tmp; 1105 if (tmp==0) 1106 return nRead; 1107 } 1108 } 1109 if ((wireGeom.num_key_aliases>0)&&(geom->key_aliases)) { 1110 int sz= XkbKeyNameLength*2; 1111 int num= wireGeom.num_key_aliases; 1112 if (fread(geom->key_aliases,sz,num,file)!=num) { 1113 _XkbLibError(_XkbErrBadLength,"ReadXkmGeometry",0); 1114 return -1; 1115 } 1116 nRead+= (num*sz); 1117 geom->num_key_aliases= num; 1118 } 1119 return nRead; 1120} 1121 1122Bool 1123XkmProbe(FILE *file) 1124{ 1125unsigned hdr,tmp; 1126int nRead=0; 1127 1128 hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); 1129 tmp= XkmGetCARD32(file,&nRead); 1130 if (tmp!=hdr) { 1131 if ((tmp&(~0xff))==(hdr&(~0xff))) { 1132 _XkbLibError(_XkbErrBadFileVersion,"XkmProbe",tmp&0xff); 1133 } 1134 return 0; 1135 } 1136 return 1; 1137} 1138 1139static Bool 1140XkmReadTOC(FILE *file,xkmFileInfo* file_info,int max_toc,xkmSectionInfo *toc) 1141{ 1142unsigned hdr,tmp; 1143int nRead=0; 1144unsigned i,size_toc; 1145 1146 hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); 1147 tmp= XkmGetCARD32(file,&nRead); 1148 if (tmp!=hdr) { 1149 if ((tmp&(~0xff))==(hdr&(~0xff))) { 1150 _XkbLibError(_XkbErrBadFileVersion,"XkmReadTOC",tmp&0xff); 1151 } 1152 else { 1153 _XkbLibError(_XkbErrBadFileType,"XkmReadTOC",tmp); 1154 } 1155 return 0; 1156 } 1157 fread(file_info,SIZEOF(xkmFileInfo),1,file); 1158 size_toc= file_info->num_toc; 1159 if (size_toc>max_toc) { 1160 DebugF("Warning! Too many TOC entries; last %d ignored\n", 1161 size_toc-max_toc); 1162 size_toc= max_toc; 1163 } 1164 for (i=0;i<size_toc;i++) { 1165 fread(&toc[i],SIZEOF(xkmSectionInfo),1,file); 1166 } 1167 return 1; 1168} 1169 1170/***====================================================================***/ 1171 1172#define MAX_TOC 16 1173unsigned 1174XkmReadFile(FILE *file,unsigned need,unsigned want,XkbDescPtr *xkb) 1175{ 1176register unsigned i; 1177xkmSectionInfo toc[MAX_TOC],tmpTOC; 1178xkmFileInfo fileInfo; 1179unsigned tmp,nRead=0; 1180unsigned which= need|want; 1181 1182 if (!XkmReadTOC(file,&fileInfo,MAX_TOC,toc)) 1183 return which; 1184 if ((fileInfo.present&need)!=need) { 1185 _XkbLibError(_XkbErrIllegalContents,"XkmReadFile", 1186 need&(~fileInfo.present)); 1187 return which; 1188 } 1189 if (*xkb==NULL) 1190 *xkb= XkbAllocKeyboard(); 1191 for (i=0;i<fileInfo.num_toc;i++) { 1192 fseek(file,toc[i].offset,SEEK_SET); 1193 tmp= fread(&tmpTOC,SIZEOF(xkmSectionInfo),1,file); 1194 nRead= tmp*SIZEOF(xkmSectionInfo); 1195 if ((tmpTOC.type!=toc[i].type)||(tmpTOC.format!=toc[i].format)|| 1196 (tmpTOC.size!=toc[i].size)||(tmpTOC.offset!=toc[i].offset)) { 1197 return which; 1198 } 1199 if ((which&(1<<tmpTOC.type))==0) { 1200 continue; 1201 } 1202 switch (tmpTOC.type) { 1203 case XkmVirtualModsIndex: 1204 tmp= ReadXkmVirtualMods(file,*xkb,NULL); 1205 break; 1206 case XkmTypesIndex: 1207 tmp= ReadXkmKeyTypes(file,*xkb,NULL); 1208 break; 1209 case XkmCompatMapIndex: 1210 tmp= ReadXkmCompatMap(file,*xkb,NULL); 1211 break; 1212 case XkmKeyNamesIndex: 1213 tmp= ReadXkmKeycodes(file,*xkb,NULL); 1214 break; 1215 case XkmIndicatorsIndex: 1216 tmp= ReadXkmIndicators(file,*xkb,NULL); 1217 break; 1218 case XkmSymbolsIndex: 1219 tmp= ReadXkmSymbols(file,*xkb); 1220 break; 1221 case XkmGeometryIndex: 1222 tmp= ReadXkmGeometry(file,*xkb); 1223 break; 1224 default: 1225 _XkbLibError(_XkbErrBadImplementation, 1226 XkbConfigText(tmpTOC.type,XkbMessage),0); 1227 tmp= 0; 1228 break; 1229 } 1230 if (tmp>0) { 1231 nRead+= tmp; 1232 which&= ~(1<<toc[i].type); 1233 (*xkb)->defined|= (1<<toc[i].type); 1234 } 1235 if (nRead!=tmpTOC.size) { 1236 _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage), 1237 nRead-tmpTOC.size); 1238 } 1239 } 1240 return which; 1241} 1242