1 /************************************************************
2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
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.
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.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
34 #include <X11/Xfuncs.h>
37 #include <X11/Xproto.h>
38 #include <X11/keysym.h>
39 #include <X11/extensions/XKMformat.h>
47 XkbInternAtom(char *str,Bool only_if_exists)
51 return MakeAtom(str,strlen(str),!only_if_exists);
55 _XkbDupString(const char *str)
61 new= calloc(strlen(str)+1,sizeof(char));
67 /***====================================================================***/
70 XkmInsureSize(void *oldPtr,int oldCount,int *newCountRtrn,int elemSize)
72 int newCount= *newCountRtrn;
77 oldPtr= calloc(newCount,elemSize);
79 else if (oldCount<newCount) {
80 oldPtr= realloc(oldPtr,newCount*elemSize);
82 char *tmp= (char *)oldPtr;
83 memset(&tmp[oldCount*elemSize], 0, (newCount-oldCount)*elemSize);
86 else if (newCount<oldCount) {
87 *newCountRtrn= oldCount;
92 #define XkmInsureTypedSize(p,o,n,t) ((p)=((t *)XkmInsureSize((char *)(p),(o),(n),sizeof(t))))
95 XkmGetCARD8(FILE *file,int *pNRead)
99 if (pNRead&&(tmp!=EOF))
105 XkmGetCARD16(FILE *file,int *pNRead)
109 if ((fread(&val,2,1,file)==1)&&(pNRead))
115 XkmGetCARD32(FILE *file,int *pNRead)
119 if ((fread(&val,4,1,file)==1)&&(pNRead))
125 XkmSkipPadding(FILE *file,unsigned pad)
127 register int i,nRead=0;
129 for (i=0;i<pad;i++) {
137 XkmGetCountedString(FILE *file,char *str,int max_len)
141 count= XkmGetCARD16(file,&nRead);
145 tmp= fread(str,1,max_len,file);
147 if ((getc(file))!=EOF)
153 tmp= fread(str,1,count,file);
157 if (count>=max_len) str[max_len-1]= '\0';
158 else str[count]= '\0';
159 count= XkbPaddedSize(nRead)-nRead;
161 nRead+= XkmSkipPadding(file,count);
165 /***====================================================================***/
168 ReadXkmVirtualMods(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
170 register unsigned int i,bit;
171 unsigned int bound,named,tmp;
174 if (XkbAllocServerMap(xkb,XkbVirtualModsMask,0)!=Success) {
175 _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0);
178 bound= XkmGetCARD16(file,&nRead);
179 named= XkmGetCARD16(file,&nRead);
180 for (i=tmp=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
182 xkb->server->vmods[i]= XkmGetCARD8(file,&nRead);
184 changes->map.vmods|= bit;
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);
194 for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
197 if (nRead+=XkmGetCountedString(file,name,100)) {
198 xkb->names->vmods[i]= XkbInternAtom(name,FALSE);
200 changes->names.changed_vmods|= bit;
207 /***====================================================================***/
210 ReadXkmKeycodes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
213 unsigned minKC,maxKC,nAl;
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;
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);
234 nAl= XkmGetCARD8(file,&nRead);
235 nRead+= XkmSkipPadding(file,1);
237 #define WANTED (XkbKeycodesNameMask|XkbKeyNamesMask|XkbKeyAliasesMask)
238 if (XkbAllocNames(xkb,WANTED,0,nAl)!=Success) {
239 _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0);
243 xkb->names->keycodes= XkbInternAtom(name,FALSE);
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);
251 nRead+= XkbKeyNameLength;
255 for (pAl= xkb->names->key_aliases,i=0;i<nAl;i++,pAl++) {
257 tmp= fread(pAl,1,2*XkbKeyNameLength,file);
258 if (tmp!=2*XkbKeyNameLength) {
259 _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
262 nRead+= 2*XkbKeyNameLength;
265 changes->names.changed|= XkbKeyAliasesMask;
268 changes->names.changed|= XkbKeyNamesMask;
272 /***====================================================================***/
275 ReadXkmKeyTypes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
277 register unsigned i,n;
283 XkbKTMapEntryPtr entry;
284 xkmKTMapEntryDesc wire_entry;
287 if ((tmp= XkmGetCountedString(file,buf,100))<1) {
288 _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
293 if (XkbAllocNames(xkb,XkbTypesNameMask,0,0)!=Success) {
294 _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0);
297 xkb->names->types= XkbInternAtom(buf,FALSE);
299 num_types= XkmGetCARD16(file,&nRead);
300 nRead+= XkmSkipPadding(file,2);
303 if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_types)!=Success) {
304 _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0);
307 xkb->map->num_types= num_types;
308 if (num_types<XkbNumRequiredTypes) {
309 _XkbLibError(_XkbErrMissingReqTypes,"ReadXkmKeyTypes",0);
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);
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);
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);
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);
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;
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);
352 type->name= XkbInternAtom(buf,FALSE);
354 else type->name= None;
359 XkmInsureTypedSize(type->preserve,type->map_count,&tmp,
361 if (type->preserve==NULL) {
362 _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0);
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);
370 nRead+= SIZEOF(xkmModsDesc);
371 pre->mask= p_entry.realMods;
372 pre->real_mods= p_entry.realMods;
373 pre->vmods= p_entry.virtualMods;
376 if (wire.nLevelNames>0) {
377 int width= wire.numLevels;
378 if (wire.nLevelNames>(unsigned)width) {
379 _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0);
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)
389 type->level_names[n]= None;
390 else type->level_names[n]= XkbInternAtom(buf,0);
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;
401 changes->map.changed|= XkbKeyTypesMask;
402 changes->map.first_type= 0;
403 changes->map.num_types= xkb->map->num_types;
408 /***====================================================================***/
411 ReadXkmCompatMap(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
414 unsigned num_si,groups;
416 XkbSymInterpretPtr interp;
417 xkmSymInterpretDesc wire;
420 XkbCompatMapPtr compat;
423 if ((tmp= XkmGetCountedString(file,name,100))<1) {
424 _XkbLibError(_XkbErrBadLength,"ReadXkmCompatMap",0);
429 if (XkbAllocNames(xkb,XkbCompatNameMask,0,0)!=Success) {
430 _XkbLibError(_XkbErrBadAlloc,"ReadXkmCompatMap",0);
433 xkb->names->compat= XkbInternAtom(name,FALSE);
435 num_si= XkmGetCARD16(file,&nRead);
436 groups= XkmGetCARD8(file,&nRead);
437 nRead+= XkmSkipPadding(file,1);
438 if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_si)!=Success)
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;
454 switch (interp->act.type) {
456 case XkbSA_LatchMods:
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];
465 case XkbSA_LatchGroup:
466 case XkbSA_LockGroup:
467 act->group.flags = wire.actionData[0];
468 act->group.group_XXX = wire.actionData[1];
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];
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];
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];
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];
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];
504 case XkbSA_SwitchScreen:
505 act->screen.flags = wire.actionData[0];
506 act->screen.screenXXX = wire.actionData[1];
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];
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];
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];
535 case XkbSA_XFree86Private:
536 /* copy the kind of action */
537 strncpy((char*)act->any.data, (char*)wire.actionData,
538 XkbAnyActionDataSize);
541 case XkbSA_Terminate:
542 /* no args, kinda (note: untrue for xfree86). */
544 case XkbSA_ActionMessage:
549 if ((num_si>0)&&(changes)) {
550 changes->compat.first_si= 0;
551 changes->compat.num_si= num_si;
554 register unsigned bit;
555 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
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) {
564 if (XkbVirtualModsToReal(xkb,md.virtualMods,&mask))
565 xkb->compat->groups[i].mask= md.realMods|mask;
567 else xkb->compat->groups[i].mask= md.realMods;
571 changes->compat.changed_groups|= groups;
577 ReadXkmIndicators(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
579 register unsigned nLEDs;
580 xkmIndicatorMapDesc wire;
585 if ((xkb->indicators==NULL)&&(XkbAllocIndicatorMaps(xkb)!=Success)) {
586 _XkbLibError(_XkbErrBadAlloc,"indicator rec",0);
589 if (XkbAllocNames(xkb,XkbIndicatorNamesMask,0,0)!=Success) {
590 _XkbLibError(_XkbErrBadAlloc,"indicator names",0);
593 nLEDs= XkmGetCARD8(file,&nRead);
594 nRead+= XkmSkipPadding(file,3);
595 xkb->indicators->phys_indicators= XkmGetCARD32(file,&nRead);
598 XkbIndicatorMapPtr map;
600 if ((tmp=XkmGetCountedString(file,buf,100))<1) {
601 _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0);
606 name= XkbInternAtom(buf,FALSE);
608 if ((tmp=fread(&wire,SIZEOF(xkmIndicatorMapDesc),1,file))<1) {
609 _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0);
612 nRead+= tmp*SIZEOF(xkmIndicatorMapDesc);
614 xkb->names->indicators[wire.indicator-1]= name;
616 changes->names.changed_indicators|= (1<<(wire.indicator-1));
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;
632 FindTypeForKey(XkbDescPtr xkb,Atom name,unsigned width,KeySym *syms)
634 if ((!xkb)||(!xkb->map))
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];
646 if ((width<2)||((syms!=NULL)&&(syms[1]==NoSymbol)))
647 return &xkb->map->types[XkbOneLevelIndex];
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];
654 return &xkb->map->types[XkbTwoLevelIndex];
658 ReadXkmSymbols(FILE *file,XkbDescPtr xkb)
660 register int i,g,s,totalVModMaps;
661 xkmKeySymMapDesc wireMap;
663 unsigned minKC,maxKC,groupNames,tmp;
666 if ((tmp=XkmGetCountedString(file,buf,100))<1)
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,
676 _XkbLibError(_XkbErrBadAlloc,"physical names",0);
679 if ((buf[0]!='\0')&&(xkb->names)) {
681 name= XkbInternAtom(buf,0);
682 xkb->names->symbols= name;
683 xkb->names->phys_symbols= name;
685 for (i=0,g=1;i<XkbNumKbdGroups;i++,g<<=1) {
687 if ((tmp=XkmGetCountedString(file,buf,100))<1)
690 if ((buf[0]!='\0')&&(xkb->names)) {
692 name= XkbInternAtom(buf,0);
693 xkb->names->groups[i]= name;
695 else xkb->names->groups[i]= None;
698 if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success) {
699 _XkbLibError(_XkbErrBadAlloc,"server map",0);
702 if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) {
703 _XkbLibError(_XkbErrBadAlloc,"client map",0);
706 if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) {
707 _XkbLibError(_XkbErrBadAlloc,"controls",0);
710 if ((xkb->map==NULL)||(xkb->server==NULL))
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);
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);
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) {
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);
738 type[g]=FindTypeForKey(xkb,typeName[g],wireMap.width,NULL);
740 _XkbLibError(_XkbErrMissingTypes,"ReadXkmSymbols",0);
743 if (typeName[g]==type[g]->name)
744 xkb->server->explicit[i]|= (1<<g);
747 if (wireMap.flags&XkmRepeatingKey) {
748 xkb->ctrls->per_key_repeat[i/8]|= (1<<(i%8));
749 xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask;
751 else if (wireMap.flags&XkmNonRepeatingKey) {
752 xkb->ctrls->per_key_repeat[i/8]&= ~(1<<(i%8));
753 xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask;
755 xkb->map->modmap[i]= wireMap.modifier_map;
756 if (XkbNumGroups(wireMap.num_groups)>0) {
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);
766 for (s=0;s<nSyms;s++) {
767 *sym++= XkmGetCARD32(file,&nRead);
769 if (wireMap.flags&XkmKeyHasActions) {
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);
776 xkb->server->explicit[i]|= XkbExplicitInterpretMask;
779 for (g=0;g<XkbNumGroups(wireMap.num_groups);g++) {
780 if (((xkb->server->explicit[i]&(1<<g))==0)||(type[g]==NULL)) {
782 tmpSyms= XkbKeySymsPtr(xkb,i)+(wireMap.width*g);
783 type[g]= FindTypeForKey(xkb,None,wireMap.width,tmpSyms);
785 xkb->map->key_sym_map[i].kt_index[g]= type[g]-(&xkb->map->types[0]);
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) {
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;
798 if (totalVModMaps>0) {
800 for (i=0;i<totalVModMaps;i++) {
801 tmp= fread(&v,SIZEOF(xkmVModMapDesc),1,file);
802 nRead+= tmp*SIZEOF(xkmVModMapDesc);
804 xkb->server->vmodmap[v.key]= v.vmods;
814 XkbSectionPtr section)
817 xkmDoodadDesc doodadWire;
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));
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:
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;
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);
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;
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);
869 ReadXkmGeomOverlay( FILE * file,
871 XkbSectionPtr section)
877 XkbOverlayRowPtr row;
878 xkmOverlayDesc olWire;
879 xkmOverlayRowDesc rowWire;
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),
889 for (r=0;r<olWire.num_rows;r++) {
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);
896 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomOverlay",0);
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);
905 row->num_keys= rowWire.num_keys;
911 ReadXkmGeomSection( FILE * file,
915 XkbSectionPtr section;
916 xkmSectionDesc sectionWire;
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);
930 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0);
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) {
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);
951 _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0);
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);
962 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0);
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;
972 if (sectionWire.num_doodads>0) {
973 for (i=0;i<sectionWire.num_doodads;i++) {
974 tmp= ReadXkmGeomDoodad(file,geom,section);
980 if (sectionWire.num_overlays>0) {
981 for (i=0;i<sectionWire.num_overlays;i++) {
982 tmp= ReadXkmGeomOverlay(file,geom,section);
992 ReadXkmGeometry(FILE *file,XkbDescPtr xkb)
998 xkmGeometryDesc wireGeom;
1000 XkbGeometrySizesRec sizes;
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);
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) {
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);
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);
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) {
1046 xkmShapeDesc shapeWire;
1048 for (i=0;i<wireGeom.num_shapes;i++) {
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);
1058 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
1061 for (n=0;n<shapeWire.num_outlines;n++) {
1063 xkmPointDesc ptWire;
1064 tmp= fread(&olWire,SIZEOF(xkmOutlineDesc),1,file);
1065 nRead+= tmp*SIZEOF(xkmOutlineDesc);
1066 ol= XkbAddGeomOutline(shape,olWire.num_points);
1068 _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
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;
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];
1090 if (wireGeom.num_sections>0) {
1091 for (i=0;i<wireGeom.num_sections;i++) {
1092 tmp= ReadXkmGeomSection(file,geom);
1098 if (wireGeom.num_doodads>0) {
1099 for (i=0;i<wireGeom.num_doodads;i++) {
1100 tmp= ReadXkmGeomDoodad(file,geom,NULL);
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);
1114 geom->num_key_aliases= num;
1120 XkmProbe(FILE *file)
1125 hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
1126 tmp= XkmGetCARD32(file,&nRead);
1128 if ((tmp&(~0xff))==(hdr&(~0xff))) {
1129 _XkbLibError(_XkbErrBadFileVersion,"XkmProbe",tmp&0xff);
1137 XkmReadTOC(FILE *file,xkmFileInfo* file_info,int max_toc,xkmSectionInfo *toc)
1141 unsigned i,size_toc;
1143 hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
1144 tmp= XkmGetCARD32(file,&nRead);
1146 if ((tmp&(~0xff))==(hdr&(~0xff))) {
1147 _XkbLibError(_XkbErrBadFileVersion,"XkmReadTOC",tmp&0xff);
1150 _XkbLibError(_XkbErrBadFileType,"XkmReadTOC",tmp);
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",
1161 for (i=0;i<size_toc;i++) {
1162 fread(&toc[i],SIZEOF(xkmSectionInfo),1,file);
1167 /***====================================================================***/
1171 XkmReadFile(FILE *file,unsigned need,unsigned want,XkbDescPtr *xkb)
1173 register unsigned i;
1174 xkmSectionInfo toc[MAX_TOC],tmpTOC;
1175 xkmFileInfo fileInfo;
1176 unsigned tmp,nRead=0;
1177 unsigned which= need|want;
1179 if (!XkmReadTOC(file,&fileInfo,MAX_TOC,toc))
1181 if ((fileInfo.present&need)!=need) {
1182 _XkbLibError(_XkbErrIllegalContents,"XkmReadFile",
1183 need&(~fileInfo.present));
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)) {
1196 if ((which&(1<<tmpTOC.type))==0) {
1199 switch (tmpTOC.type) {
1200 case XkmVirtualModsIndex:
1201 tmp= ReadXkmVirtualMods(file,*xkb,NULL);
1204 tmp= ReadXkmKeyTypes(file,*xkb,NULL);
1206 case XkmCompatMapIndex:
1207 tmp= ReadXkmCompatMap(file,*xkb,NULL);
1209 case XkmKeyNamesIndex:
1210 tmp= ReadXkmKeycodes(file,*xkb,NULL);
1212 case XkmIndicatorsIndex:
1213 tmp= ReadXkmIndicators(file,*xkb,NULL);
1215 case XkmSymbolsIndex:
1216 tmp= ReadXkmSymbols(file,*xkb);
1218 case XkmGeometryIndex:
1219 tmp= ReadXkmGeometry(file,*xkb);
1222 _XkbLibError(_XkbErrBadImplementation,
1223 XkbConfigText(tmpTOC.type,XkbMessage),0);
1229 which&= ~(1<<toc[i].type);
1230 (*xkb)->defined|= (1<<toc[i].type);
1232 if (nRead!=tmpTOC.size) {
1233 _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage),