First import
[xorg_rtime.git] / xorg-server-1.4 / xkb / xkbtext.c
blob4983e2b9ef940582fbd383d9957b6d7377fe75c6
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>
29 #endif
31 #include <stdio.h>
32 #include <ctype.h>
33 #include <stdlib.h>
35 #include <X11/Xos.h>
37 #include <X11/X.h>
38 #define NEED_EVENTS
39 #include <X11/Xproto.h>
40 #include "misc.h"
41 #include "inputstr.h"
42 #include "dix.h"
43 #include <X11/extensions/XKBstr.h>
44 #define XKBSRV_NEED_FILE_FUNCS 1
45 #include <xkbsrv.h>
46 #include <X11/extensions/XKBgeom.h>
48 /***====================================================================***/
50 #define BUFFER_SIZE 512
52 static char textBuffer[BUFFER_SIZE];
53 static int tbNext= 0;
55 static char *
56 tbGetBuffer(unsigned size)
58 char *rtrn;
60 if (size>=BUFFER_SIZE)
61 return NULL;
62 if ((BUFFER_SIZE-tbNext)<=size)
63 tbNext= 0;
64 rtrn= &textBuffer[tbNext];
65 tbNext+= size;
66 return rtrn;
69 /***====================================================================***/
71 char *
72 XkbAtomText(Display *dpy,Atom atm,unsigned format)
74 char *rtrn,*tmp;
76 tmp= XkbAtomGetString(dpy,atm);
77 if (tmp!=NULL) {
78 int len;
79 len= strlen(tmp)+1;
80 if (len>BUFFER_SIZE)
81 len= BUFFER_SIZE-2;
82 rtrn= tbGetBuffer(len);
83 strncpy(rtrn,tmp,len);
84 rtrn[len]= '\0';
86 else {
87 rtrn= tbGetBuffer(1);
88 rtrn[0]= '\0';
90 if (format==XkbCFile) {
91 for (tmp=rtrn;*tmp!='\0';tmp++) {
92 if ((tmp==rtrn)&&(!isalpha(*tmp)))
93 *tmp= '_';
94 else if (!isalnum(*tmp))
95 *tmp= '_';
98 return XkbStringText(rtrn,format);
101 /***====================================================================***/
103 char *
104 XkbVModIndexText(Display *dpy,XkbDescPtr xkb,unsigned ndx,unsigned format)
106 register int len;
107 register Atom *vmodNames;
108 char *rtrn,*tmp;
109 char numBuf[20];
111 if (xkb && xkb->names)
112 vmodNames= xkb->names->vmods;
113 else vmodNames= NULL;
115 tmp= NULL;
116 if (ndx>=XkbNumVirtualMods)
117 tmp= "illegal";
118 else if (vmodNames&&(vmodNames[ndx]!=None))
119 tmp= XkbAtomGetString(dpy,vmodNames[ndx]);
120 if (tmp==NULL)
121 sprintf(tmp=numBuf,"%d",ndx);
123 len= strlen(tmp)+1;
124 if (format==XkbCFile)
125 len+= 4;
126 if (len>=BUFFER_SIZE)
127 len= BUFFER_SIZE-1;
128 rtrn= tbGetBuffer(len);
129 if (format==XkbCFile) {
130 strcpy(rtrn,"vmod_");
131 strncpy(&rtrn[5],tmp,len-4);
133 else strncpy(rtrn,tmp,len);
134 return rtrn;
137 char *
138 XkbVModMaskText( Display * dpy,
139 XkbDescPtr xkb,
140 unsigned modMask,
141 unsigned mask,
142 unsigned format)
144 register int i,bit;
145 int len;
146 char *mm,*rtrn;
147 char *str,buf[BUFFER_SIZE];
149 if ((modMask==0)&&(mask==0)) {
150 rtrn= tbGetBuffer(5);
151 if (format==XkbCFile)
152 sprintf(rtrn,"0");
153 else sprintf(rtrn,"none");
154 return rtrn;
156 if (modMask!=0)
157 mm= XkbModMaskText(modMask,format);
158 else mm= NULL;
160 str= buf;
161 buf[0]= '\0';
162 if (mask) {
163 char *tmp;
164 for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
165 if (mask&bit) {
166 tmp= XkbVModIndexText(dpy,xkb,i,format);
167 len= strlen(tmp)+1+(str==buf?0:1);
168 if (format==XkbCFile)
169 len+= 4;
170 if ((str-(buf+len))<=BUFFER_SIZE) {
171 if (str!=buf) {
172 if (format==XkbCFile) *str++= '|';
173 else *str++= '+';
174 len--;
177 if (format==XkbCFile)
178 sprintf(str,"%sMask",tmp);
179 else strcpy(str,tmp);
180 str= &str[len-1];
183 str= buf;
185 else str= NULL;
186 if (mm)
187 len= strlen(mm);
188 else len= 0;
189 if (str)
190 len+= strlen(str)+(mm==NULL?0:1);
191 if (len>=BUFFER_SIZE)
192 len= BUFFER_SIZE-1;
193 rtrn= tbGetBuffer(len+1);
194 rtrn[0]= '\0';
196 if (mm!=NULL) {
197 i= strlen(mm);
198 if (i>len)
199 i= len;
200 strcpy(rtrn,mm);
202 else {
203 i=0;
205 if (str!=NULL) {
206 if (mm!=NULL) {
207 if (format==XkbCFile) strcat(rtrn,"|");
208 else strcat(rtrn,"+");
210 strncat(rtrn,str,len-i);
212 rtrn[len]= '\0';
213 return rtrn;
216 static char *modNames[XkbNumModifiers] = {
217 "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5"
220 char *
221 XkbModIndexText(unsigned ndx,unsigned format)
223 char * rtrn;
224 char buf[100];
226 if (format==XkbCFile) {
227 if (ndx<XkbNumModifiers)
228 sprintf(buf,"%sMapIndex",modNames[ndx]);
229 else if (ndx==XkbNoModifier)
230 sprintf(buf,"XkbNoModifier");
231 else sprintf(buf,"0x%02x",ndx);
233 else {
234 if (ndx<XkbNumModifiers)
235 strcpy(buf,modNames[ndx]);
236 else if (ndx==XkbNoModifier)
237 strcpy(buf,"none");
238 else sprintf(buf,"ILLEGAL_%02x",ndx);
240 rtrn= tbGetBuffer(strlen(buf)+1);
241 strcpy(rtrn,buf);
242 return rtrn;
245 char *
246 XkbModMaskText(unsigned mask,unsigned format)
248 register int i,bit;
249 char buf[64],*rtrn;
251 if ((mask&0xff)==0xff) {
252 if (format==XkbCFile) strcpy(buf,"0xff");
253 else strcpy(buf,"all");
255 else if ((mask&0xff)==0) {
256 if (format==XkbCFile) strcpy(buf,"0");
257 else strcpy(buf,"none");
259 else {
260 char *str= buf;
261 buf[0]= '\0';
262 for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
263 if (mask&bit) {
264 if (str!=buf) {
265 if (format==XkbCFile) *str++= '|';
266 else *str++= '+';
268 strcpy(str,modNames[i]);
269 str= &str[strlen(str)];
270 if (format==XkbCFile) {
271 strcpy(str,"Mask");
272 str+= 4;
277 rtrn= tbGetBuffer(strlen(buf)+1);
278 strcpy(rtrn,buf);
279 return rtrn;
282 /***====================================================================***/
284 /*ARGSUSED*/
285 char *
286 XkbConfigText(unsigned config,unsigned format)
288 static char *buf;
290 buf= tbGetBuffer(32);
291 switch (config) {
292 case XkmSemanticsFile:
293 strcpy(buf,"Semantics");
294 break;
295 case XkmLayoutFile:
296 strcpy(buf,"Layout");
297 break;
298 case XkmKeymapFile:
299 strcpy(buf,"Keymap");
300 break;
301 case XkmGeometryFile:
302 case XkmGeometryIndex:
303 strcpy(buf,"Geometry");
304 break;
305 case XkmTypesIndex:
306 strcpy(buf,"Types");
307 break;
308 case XkmCompatMapIndex:
309 strcpy(buf,"CompatMap");
310 break;
311 case XkmSymbolsIndex:
312 strcpy(buf,"Symbols");
313 break;
314 case XkmIndicatorsIndex:
315 strcpy(buf,"Indicators");
316 break;
317 case XkmKeyNamesIndex:
318 strcpy(buf,"KeyNames");
319 break;
320 case XkmVirtualModsIndex:
321 strcpy(buf,"VirtualMods");
322 break;
323 default:
324 sprintf(buf,"unknown(%d)",config);
325 break;
327 return buf;
330 /***====================================================================***/
332 char *
333 XkbKeysymText(KeySym sym,unsigned format)
335 static char buf[32],*rtrn;
337 if (sym==NoSymbol)
338 strcpy(rtrn=buf,"NoSymbol");
339 else sprintf(rtrn=buf, "0x%lx", (long)sym);
340 return rtrn;
343 char *
344 XkbKeyNameText(char *name,unsigned format)
346 char *buf;
348 if (format==XkbCFile) {
349 buf= tbGetBuffer(5);
350 memcpy(buf,name,4);
351 buf[4]= '\0';
353 else {
354 int len;
355 buf= tbGetBuffer(7);
356 buf[0]= '<';
357 memcpy(&buf[1],name,4);
358 buf[5]= '\0';
359 len= strlen(buf);
360 buf[len++]= '>';
361 buf[len]= '\0';
363 return buf;
366 /***====================================================================***/
368 static char *siMatchText[5] = {
369 "NoneOf", "AnyOfOrNone", "AnyOf", "AllOf", "Exactly"
372 char *
373 XkbSIMatchText(unsigned type,unsigned format)
375 static char buf[40];
376 char *rtrn;
378 switch (type&XkbSI_OpMask) {
379 case XkbSI_NoneOf: rtrn= siMatchText[0]; break;
380 case XkbSI_AnyOfOrNone: rtrn= siMatchText[1]; break;
381 case XkbSI_AnyOf: rtrn= siMatchText[2]; break;
382 case XkbSI_AllOf: rtrn= siMatchText[3]; break;
383 case XkbSI_Exactly: rtrn= siMatchText[4]; break;
384 default: sprintf(buf,"0x%x",type&XkbSI_OpMask);
385 return buf;
387 if (format==XkbCFile) {
388 if (type&XkbSI_LevelOneOnly)
389 sprintf(buf,"XkbSI_LevelOneOnly|XkbSI_%s",rtrn);
390 else sprintf(buf,"XkbSI_%s",rtrn);
391 rtrn= buf;
393 return rtrn;
396 /***====================================================================***/
398 static char *imWhichNames[]= {
399 "base",
400 "latched",
401 "locked",
402 "effective",
403 "compat"
406 char *
407 XkbIMWhichStateMaskText(unsigned use_which,unsigned format)
409 int len;
410 unsigned i,bit,tmp;
411 char * buf;
413 if (use_which==0) {
414 buf= tbGetBuffer(2);
415 strcpy(buf,"0");
416 return buf;
418 tmp= use_which&XkbIM_UseAnyMods;
419 for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
420 if (tmp&bit) {
421 tmp&= ~bit;
422 len+= strlen(imWhichNames[i])+1;
423 if (format==XkbCFile)
424 len+= 9;
427 buf= tbGetBuffer(len+1);
428 tmp= use_which&XkbIM_UseAnyMods;
429 for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
430 if (tmp&bit) {
431 tmp&= ~bit;
432 if (format==XkbCFile) {
433 if (len!=0)
434 buf[len++]= '|';
435 sprintf(&buf[len],"XkbIM_Use%s",imWhichNames[i]);
436 buf[len+9]= toupper(buf[len+9]);
438 else {
439 if (len!=0)
440 buf[len++]= '+';
441 sprintf(&buf[len],"%s",imWhichNames[i]);
443 len+= strlen(&buf[len]);
446 return buf;
449 static char *ctrlNames[] = {
450 "repeatKeys",
451 "slowKeys",
452 "bounceKeys",
453 "stickyKeys",
454 "mouseKeys",
455 "mouseKeysAccel",
456 "accessXKeys",
457 "accessXTimeout",
458 "accessXFeedback",
459 "audibleBell",
460 "overlay1",
461 "overlay2",
462 "ignoreGroupLock"
465 char *
466 XkbControlsMaskText(unsigned ctrls,unsigned format)
468 int len;
469 unsigned i,bit,tmp;
470 char * buf;
472 if (ctrls==0) {
473 buf= tbGetBuffer(5);
474 if (format==XkbCFile)
475 strcpy(buf,"0");
476 else strcpy(buf,"none");
477 return buf;
479 tmp= ctrls&XkbAllBooleanCtrlsMask;
480 for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
481 if (tmp&bit) {
482 tmp&= ~bit;
483 len+= strlen(ctrlNames[i])+1;
484 if (format==XkbCFile)
485 len+= 7;
488 buf= tbGetBuffer(len+1);
489 tmp= ctrls&XkbAllBooleanCtrlsMask;
490 for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
491 if (tmp&bit) {
492 tmp&= ~bit;
493 if (format==XkbCFile) {
494 if (len!=0)
495 buf[len++]= '|';
496 sprintf(&buf[len],"Xkb%sMask",ctrlNames[i]);
497 buf[len+3]= toupper(buf[len+3]);
499 else {
500 if (len!=0)
501 buf[len++]= '+';
502 sprintf(&buf[len],"%s",ctrlNames[i]);
504 len+= strlen(&buf[len]);
507 return buf;
510 /***====================================================================***/
512 char *
513 XkbStringText(char *str,unsigned format)
515 char * buf;
516 register char *in,*out;
517 int len;
518 Bool ok;
520 if (str==NULL) {
521 buf= tbGetBuffer(2);
522 buf[0]='\0';
523 return buf;
525 else if (format==XkbXKMFile)
526 return str;
527 for (ok= True,len=0,in=str;*in!='\0';in++,len++) {
528 if (!isprint(*in)) {
529 ok= False;
530 switch (*in) {
531 case '\n': case '\t': case '\v':
532 case '\b': case '\r': case '\f':
533 len++;
534 break;
535 default:
536 len+= 4;
537 break;
541 if (ok)
542 return str;
543 buf= tbGetBuffer(len+1);
544 for (in=str,out=buf;*in!='\0';in++) {
545 if (isprint(*in))
546 *out++= *in;
547 else {
548 *out++= '\\';
549 if (*in=='\n') *out++= 'n';
550 else if (*in=='\t') *out++= 't';
551 else if (*in=='\v') *out++= 'v';
552 else if (*in=='\b') *out++= 'b';
553 else if (*in=='\r') *out++= 'r';
554 else if (*in=='\f') *out++= 'f';
555 else if ((*in=='\033')&&(format==XkbXKMFile)) {
556 *out++= 'e';
558 else {
559 *out++= '0';
560 sprintf(out,"%o",*in);
561 while (*out!='\0')
562 out++;
566 *out++= '\0';
567 return buf;
570 /***====================================================================***/
572 char *
573 XkbGeomFPText(int val,unsigned format)
575 int whole,frac;
576 char * buf;
578 buf= tbGetBuffer(12);
579 if (format==XkbCFile) {
580 sprintf(buf,"%d",val);
582 else {
583 whole= val/XkbGeomPtsPerMM;
584 frac= val%XkbGeomPtsPerMM;
585 if (frac!=0)
586 sprintf(buf,"%d.%d",whole,frac);
587 else sprintf(buf,"%d",whole);
589 return buf;
592 char *
593 XkbDoodadTypeText(unsigned type,unsigned format)
595 char * buf;
596 if (format==XkbCFile) {
597 buf= tbGetBuffer(24);
598 if (type==XkbOutlineDoodad) strcpy(buf,"XkbOutlineDoodad");
599 else if (type==XkbSolidDoodad) strcpy(buf,"XkbSolidDoodad");
600 else if (type==XkbTextDoodad) strcpy(buf,"XkbTextDoodad");
601 else if (type==XkbIndicatorDoodad) strcpy(buf,"XkbIndicatorDoodad");
602 else if (type==XkbLogoDoodad) strcpy(buf,"XkbLogoDoodad");
603 else sprintf(buf,"UnknownDoodad%d",type);
605 else {
606 buf= tbGetBuffer(12);
607 if (type==XkbOutlineDoodad) strcpy(buf,"outline");
608 else if (type==XkbSolidDoodad) strcpy(buf,"solid");
609 else if (type==XkbTextDoodad) strcpy(buf,"text");
610 else if (type==XkbIndicatorDoodad) strcpy(buf,"indicator");
611 else if (type==XkbLogoDoodad) strcpy(buf,"logo");
612 else sprintf(buf,"unknown%d",type);
614 return buf;
617 static char *actionTypeNames[XkbSA_NumActions]= {
618 "NoAction",
619 "SetMods", "LatchMods", "LockMods",
620 "SetGroup", "LatchGroup", "LockGroup",
621 "MovePtr",
622 "PtrBtn", "LockPtrBtn",
623 "SetPtrDflt",
624 "ISOLock",
625 "Terminate", "SwitchScreen",
626 "SetControls", "LockControls",
627 "ActionMessage",
628 "RedirectKey",
629 "DeviceBtn", "LockDeviceBtn"
632 char *
633 XkbActionTypeText(unsigned type,unsigned format)
635 static char buf[32];
636 char *rtrn;
638 if (type<=XkbSA_LastAction) {
639 rtrn= actionTypeNames[type];
640 if (format==XkbCFile) {
641 sprintf(buf,"XkbSA_%s",rtrn);
642 return buf;
644 return rtrn;
646 sprintf(buf,"Private");
647 return buf;
650 /***====================================================================***/
652 static int
653 TryCopyStr(char *to,char *from,int *pLeft)
655 register int len;
656 if (*pLeft>0) {
657 len= strlen(from);
658 if (len<((*pLeft)-3)) {
659 strcat(to,from);
660 *pLeft-= len;
661 return True;
664 *pLeft= -1;
665 return False;
668 /*ARGSUSED*/
669 static Bool
670 CopyNoActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int*sz)
672 return True;
675 static Bool
676 CopyModActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
677 int* sz)
679 XkbModAction * act;
680 unsigned tmp;
682 act= &action->mods;
683 tmp= XkbModActionVMods(act);
684 TryCopyStr(buf,"modifiers=",sz);
685 if (act->flags&XkbSA_UseModMapMods)
686 TryCopyStr(buf,"modMapMods",sz);
687 else if (act->real_mods || tmp) {
688 TryCopyStr(buf,
689 XkbVModMaskText(dpy,xkb,act->real_mods,tmp,XkbXKBFile),
690 sz);
692 else TryCopyStr(buf,"none",sz);
693 if (act->type==XkbSA_LockMods)
694 return True;
695 if (act->flags&XkbSA_ClearLocks)
696 TryCopyStr(buf,",clearLocks",sz);
697 if (act->flags&XkbSA_LatchToLock)
698 TryCopyStr(buf,",latchToLock",sz);
699 return True;
702 /*ARGSUSED*/
703 static Bool
704 CopyGroupActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
705 int *sz)
707 XkbGroupAction * act;
708 char tbuf[32];
710 act= &action->group;
711 TryCopyStr(buf,"group=",sz);
712 if (act->flags&XkbSA_GroupAbsolute)
713 sprintf(tbuf,"%d",XkbSAGroup(act)+1);
714 else if (XkbSAGroup(act)<0)
715 sprintf(tbuf,"%d",XkbSAGroup(act));
716 else sprintf(tbuf,"+%d",XkbSAGroup(act));
717 TryCopyStr(buf,tbuf,sz);
718 if (act->type==XkbSA_LockGroup)
719 return True;
720 if (act->flags&XkbSA_ClearLocks)
721 TryCopyStr(buf,",clearLocks",sz);
722 if (act->flags&XkbSA_LatchToLock)
723 TryCopyStr(buf,",latchToLock",sz);
724 return True;
727 /*ARGSUSED*/
728 static Bool
729 CopyMovePtrArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
731 XkbPtrAction * act;
732 int x,y;
733 char tbuf[32];
735 act= &action->ptr;
736 x= XkbPtrActionX(act);
737 y= XkbPtrActionY(act);
738 if ((act->flags&XkbSA_MoveAbsoluteX)||(x<0))
739 sprintf(tbuf,"x=%d",x);
740 else sprintf(tbuf,"x=+%d",x);
741 TryCopyStr(buf,tbuf,sz);
743 if ((act->flags&XkbSA_MoveAbsoluteY)||(y<0))
744 sprintf(tbuf,",y=%d",y);
745 else sprintf(tbuf,",y=+%d",y);
746 TryCopyStr(buf,tbuf,sz);
747 if (act->flags&XkbSA_NoAcceleration)
748 TryCopyStr(buf,",!accel",sz);
749 return True;
752 /*ARGSUSED*/
753 static Bool
754 CopyPtrBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
756 XkbPtrBtnAction * act;
757 char tbuf[32];
759 act= &action->btn;
760 TryCopyStr(buf,"button=",sz);
761 if ((act->button>0)&&(act->button<6)) {
762 sprintf(tbuf,"%d",act->button);
763 TryCopyStr(buf,tbuf,sz);
765 else TryCopyStr(buf,"default",sz);
766 if (act->count>0) {
767 sprintf(tbuf,",count=%d",act->count);
768 TryCopyStr(buf,tbuf,sz);
770 if (action->type==XkbSA_LockPtrBtn) {
771 switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) {
772 case XkbSA_LockNoLock:
773 sprintf(tbuf,",affect=unlock"); break;
774 case XkbSA_LockNoUnlock:
775 sprintf(tbuf,",affect=lock"); break;
776 case XkbSA_LockNoUnlock|XkbSA_LockNoLock:
777 sprintf(tbuf,",affect=neither"); break;
778 default:
779 sprintf(tbuf,",affect=both"); break;
781 TryCopyStr(buf,tbuf,sz);
783 return True;
786 /*ARGSUSED*/
787 static Bool
788 CopySetPtrDfltArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
789 int *sz)
791 XkbPtrDfltAction * act;
792 char tbuf[32];
794 act= &action->dflt;
795 if (act->affect==XkbSA_AffectDfltBtn) {
796 TryCopyStr(buf,"affect=button,button=",sz);
797 if ((act->flags&XkbSA_DfltBtnAbsolute)||(XkbSAPtrDfltValue(act)<0))
798 sprintf(tbuf,"%d",XkbSAPtrDfltValue(act));
799 else sprintf(tbuf,"+%d",XkbSAPtrDfltValue(act));
800 TryCopyStr(buf,tbuf,sz);
802 return True;
805 static Bool
806 CopyISOLockArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
808 XkbISOAction * act;
809 char tbuf[64];
811 act= &action->iso;
812 if (act->flags&XkbSA_ISODfltIsGroup) {
813 TryCopyStr(tbuf,"group=",sz);
814 if (act->flags&XkbSA_GroupAbsolute)
815 sprintf(tbuf,"%d",XkbSAGroup(act)+1);
816 else if (XkbSAGroup(act)<0)
817 sprintf(tbuf,"%d",XkbSAGroup(act));
818 else sprintf(tbuf,"+%d",XkbSAGroup(act));
819 TryCopyStr(buf,tbuf,sz);
821 else {
822 unsigned tmp;
823 tmp= XkbModActionVMods(act);
824 TryCopyStr(buf,"modifiers=",sz);
825 if (act->flags&XkbSA_UseModMapMods)
826 TryCopyStr(buf,"modMapMods",sz);
827 else if (act->real_mods || tmp) {
828 if (act->real_mods) {
829 TryCopyStr(buf,XkbModMaskText(act->real_mods,XkbXKBFile),sz);
830 if (tmp)
831 TryCopyStr(buf,"+",sz);
833 if (tmp)
834 TryCopyStr(buf,XkbVModMaskText(dpy,xkb,0,tmp,XkbXKBFile),sz);
836 else TryCopyStr(buf,"none",sz);
838 TryCopyStr(buf,",affect=",sz);
839 if ((act->affect&XkbSA_ISOAffectMask)==0)
840 TryCopyStr(buf,"all",sz);
841 else {
842 int nOut= 0;
843 if ((act->affect&XkbSA_ISONoAffectMods)==0) {
844 TryCopyStr(buf,"mods",sz);
845 nOut++;
847 if ((act->affect&XkbSA_ISONoAffectGroup)==0) {
848 sprintf(tbuf,"%sgroups",(nOut>0?"+":""));
849 TryCopyStr(buf,tbuf,sz);
850 nOut++;
852 if ((act->affect&XkbSA_ISONoAffectPtr)==0) {
853 sprintf(tbuf,"%spointer",(nOut>0?"+":""));
854 TryCopyStr(buf,tbuf,sz);
855 nOut++;
857 if ((act->affect&XkbSA_ISONoAffectCtrls)==0) {
858 sprintf(tbuf,"%scontrols",(nOut>0?"+":""));
859 TryCopyStr(buf,tbuf,sz);
860 nOut++;
863 return True;
866 /*ARGSUSED*/
867 static Bool
868 CopySwitchScreenArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
869 int *sz)
871 XkbSwitchScreenAction * act;
872 char tbuf[32];
874 act= &action->screen;
875 if ((act->flags&XkbSA_SwitchAbsolute)||(XkbSAScreen(act)<0))
876 sprintf(tbuf,"screen=%d",XkbSAScreen(act));
877 else sprintf(tbuf,"screen=+%d",XkbSAScreen(act));
878 TryCopyStr(buf,tbuf,sz);
879 if (act->flags&XkbSA_SwitchApplication)
880 TryCopyStr(buf,",!same",sz);
881 else TryCopyStr(buf,",same",sz);
882 return True;
885 /*ARGSUSED*/
886 static Bool
887 CopySetLockControlsArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,
888 char *buf,int *sz)
890 XkbCtrlsAction * act;
891 unsigned tmp;
892 char tbuf[32];
894 act= &action->ctrls;
895 tmp= XkbActionCtrls(act);
896 TryCopyStr(buf,"controls=",sz);
897 if (tmp==0)
898 TryCopyStr(buf,"none",sz);
899 else if ((tmp&XkbAllBooleanCtrlsMask)==XkbAllBooleanCtrlsMask)
900 TryCopyStr(buf,"all",sz);
901 else {
902 int nOut= 0;
903 if (tmp&XkbRepeatKeysMask) {
904 sprintf(tbuf,"%sRepeatKeys",(nOut>0?"+":""));
905 TryCopyStr(buf,tbuf,sz);
906 nOut++;
908 if (tmp&XkbSlowKeysMask) {
909 sprintf(tbuf,"%sSlowKeys",(nOut>0?"+":""));
910 TryCopyStr(buf,tbuf,sz);
911 nOut++;
913 if (tmp&XkbBounceKeysMask) {
914 sprintf(tbuf,"%sBounceKeys",(nOut>0?"+":""));
915 TryCopyStr(buf,tbuf,sz);
916 nOut++;
918 if (tmp&XkbStickyKeysMask) {
919 sprintf(tbuf,"%sStickyKeys",(nOut>0?"+":""));
920 TryCopyStr(buf,tbuf,sz);
921 nOut++;
923 if (tmp&XkbMouseKeysMask) {
924 sprintf(tbuf,"%sMouseKeys",(nOut>0?"+":""));
925 TryCopyStr(buf,tbuf,sz);
926 nOut++;
928 if (tmp&XkbMouseKeysAccelMask) {
929 sprintf(tbuf,"%sMouseKeysAccel",(nOut>0?"+":""));
930 TryCopyStr(buf,tbuf,sz);
931 nOut++;
933 if (tmp&XkbAccessXKeysMask) {
934 sprintf(tbuf,"%sAccessXKeys",(nOut>0?"+":""));
935 TryCopyStr(buf,tbuf,sz);
936 nOut++;
938 if (tmp&XkbAccessXTimeoutMask) {
939 sprintf(tbuf,"%sAccessXTimeout",(nOut>0?"+":""));
940 TryCopyStr(buf,tbuf,sz);
941 nOut++;
943 if (tmp&XkbAccessXFeedbackMask) {
944 sprintf(tbuf,"%sAccessXFeedback",(nOut>0?"+":""));
945 TryCopyStr(buf,tbuf,sz);
946 nOut++;
948 if (tmp&XkbAudibleBellMask) {
949 sprintf(tbuf,"%sAudibleBell",(nOut>0?"+":""));
950 TryCopyStr(buf,tbuf,sz);
951 nOut++;
953 if (tmp&XkbOverlay1Mask) {
954 sprintf(tbuf,"%sOverlay1",(nOut>0?"+":""));
955 TryCopyStr(buf,tbuf,sz);
956 nOut++;
958 if (tmp&XkbOverlay2Mask) {
959 sprintf(tbuf,"%sOverlay2",(nOut>0?"+":""));
960 TryCopyStr(buf,tbuf,sz);
961 nOut++;
963 if (tmp&XkbIgnoreGroupLockMask) {
964 sprintf(tbuf,"%sIgnoreGroupLock",(nOut>0?"+":""));
965 TryCopyStr(buf,tbuf,sz);
966 nOut++;
969 return True;
972 /*ARGSUSED*/
973 static Bool
974 CopyActionMessageArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
975 int *sz)
977 XkbMessageAction * act;
978 unsigned all;
979 char tbuf[32];
981 act= &action->msg;
982 all= XkbSA_MessageOnPress|XkbSA_MessageOnRelease;
983 TryCopyStr(buf,"report=",sz);
984 if ((act->flags&all)==0)
985 TryCopyStr(buf,"none",sz);
986 else if ((act->flags&all)==all)
987 TryCopyStr(buf,"all",sz);
988 else if (act->flags&XkbSA_MessageOnPress)
989 TryCopyStr(buf,"KeyPress",sz);
990 else TryCopyStr(buf,"KeyRelease",sz);
991 sprintf(tbuf,",data[0]=0x%02x",act->message[0]); TryCopyStr(buf,tbuf,sz);
992 sprintf(tbuf,",data[1]=0x%02x",act->message[1]); TryCopyStr(buf,tbuf,sz);
993 sprintf(tbuf,",data[2]=0x%02x",act->message[2]); TryCopyStr(buf,tbuf,sz);
994 sprintf(tbuf,",data[3]=0x%02x",act->message[3]); TryCopyStr(buf,tbuf,sz);
995 sprintf(tbuf,",data[4]=0x%02x",act->message[4]); TryCopyStr(buf,tbuf,sz);
996 sprintf(tbuf,",data[5]=0x%02x",act->message[5]); TryCopyStr(buf,tbuf,sz);
997 return True;
1000 static Bool
1001 CopyRedirectKeyArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
1002 int *sz)
1004 XkbRedirectKeyAction * act;
1005 char tbuf[32],*tmp;
1006 unsigned kc;
1007 unsigned vmods,vmods_mask;
1009 act= &action->redirect;
1010 kc= act->new_key;
1011 vmods= XkbSARedirectVMods(act);
1012 vmods_mask= XkbSARedirectVModsMask(act);
1013 if (xkb && xkb->names && xkb->names->keys && (kc<=xkb->max_key_code) &&
1014 (xkb->names->keys[kc].name[0]!='\0')) {
1015 char *kn;
1016 kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile);
1017 sprintf(tbuf,"key=%s",kn);
1019 else sprintf(tbuf,"key=%d",kc);
1020 TryCopyStr(buf,tbuf,sz);
1021 if ((act->mods_mask==0)&&(vmods_mask==0))
1022 return True;
1023 if ((act->mods_mask==XkbAllModifiersMask)&&
1024 (vmods_mask==XkbAllVirtualModsMask)) {
1025 tmp= XkbVModMaskText(dpy,xkb,act->mods,vmods,XkbXKBFile);
1026 TryCopyStr(buf,",mods=",sz);
1027 TryCopyStr(buf,tmp,sz);
1029 else {
1030 if ((act->mods_mask&act->mods)||(vmods_mask&vmods)) {
1031 tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&act->mods,
1032 vmods_mask&vmods,XkbXKBFile);
1033 TryCopyStr(buf,",mods= ",sz);
1034 TryCopyStr(buf,tmp,sz);
1036 if ((act->mods_mask&(~act->mods))||(vmods_mask&(~vmods))) {
1037 tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&(~act->mods),
1038 vmods_mask&(~vmods),XkbXKBFile);
1039 TryCopyStr(buf,",clearMods= ",sz);
1040 TryCopyStr(buf,tmp,sz);
1043 return True;
1046 /*ARGSUSED*/
1047 static Bool
1048 CopyDeviceBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
1049 int *sz)
1051 XkbDeviceBtnAction * act;
1052 char tbuf[32];
1054 act= &action->devbtn;
1055 sprintf(tbuf,"device= %d",act->device); TryCopyStr(buf,tbuf,sz);
1056 TryCopyStr(buf,",button=",sz);
1057 sprintf(tbuf,"%d",act->button);
1058 TryCopyStr(buf,tbuf,sz);
1059 if (act->count>0) {
1060 sprintf(tbuf,",count=%d",act->count);
1061 TryCopyStr(buf,tbuf,sz);
1063 if (action->type==XkbSA_LockDeviceBtn) {
1064 switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) {
1065 case XkbSA_LockNoLock:
1066 sprintf(tbuf,",affect=unlock"); break;
1067 case XkbSA_LockNoUnlock:
1068 sprintf(tbuf,",affect=lock"); break;
1069 case XkbSA_LockNoUnlock|XkbSA_LockNoLock:
1070 sprintf(tbuf,",affect=neither"); break;
1071 default:
1072 sprintf(tbuf,",affect=both"); break;
1074 TryCopyStr(buf,tbuf,sz);
1076 return True;
1079 /*ARGSUSED*/
1080 static Bool
1081 CopyOtherArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
1083 XkbAnyAction * act;
1084 char tbuf[32];
1086 act= &action->any;
1087 sprintf(tbuf,"type=0x%02x",act->type); TryCopyStr(buf,tbuf,sz);
1088 sprintf(tbuf,",data[0]=0x%02x",act->data[0]); TryCopyStr(buf,tbuf,sz);
1089 sprintf(tbuf,",data[1]=0x%02x",act->data[1]); TryCopyStr(buf,tbuf,sz);
1090 sprintf(tbuf,",data[2]=0x%02x",act->data[2]); TryCopyStr(buf,tbuf,sz);
1091 sprintf(tbuf,",data[3]=0x%02x",act->data[3]); TryCopyStr(buf,tbuf,sz);
1092 sprintf(tbuf,",data[4]=0x%02x",act->data[4]); TryCopyStr(buf,tbuf,sz);
1093 sprintf(tbuf,",data[5]=0x%02x",act->data[5]); TryCopyStr(buf,tbuf,sz);
1094 sprintf(tbuf,",data[6]=0x%02x",act->data[6]); TryCopyStr(buf,tbuf,sz);
1095 return True;
1098 typedef Bool (*actionCopy)(
1099 Display * /* dpy */,
1100 XkbDescPtr /* xkb */,
1101 XkbAction * /* action */,
1102 char * /* buf */,
1103 int* /* sz */
1105 static actionCopy copyActionArgs[XkbSA_NumActions] = {
1106 CopyNoActionArgs /* NoAction */,
1107 CopyModActionArgs /* SetMods */,
1108 CopyModActionArgs /* LatchMods */,
1109 CopyModActionArgs /* LockMods */,
1110 CopyGroupActionArgs /* SetGroup */,
1111 CopyGroupActionArgs /* LatchGroup */,
1112 CopyGroupActionArgs /* LockGroup */,
1113 CopyMovePtrArgs /* MovePtr */,
1114 CopyPtrBtnArgs /* PtrBtn */,
1115 CopyPtrBtnArgs /* LockPtrBtn */,
1116 CopySetPtrDfltArgs /* SetPtrDflt */,
1117 CopyISOLockArgs /* ISOLock */,
1118 CopyNoActionArgs /* Terminate */,
1119 CopySwitchScreenArgs /* SwitchScreen */,
1120 CopySetLockControlsArgs /* SetControls */,
1121 CopySetLockControlsArgs /* LockControls */,
1122 CopyActionMessageArgs /* ActionMessage*/,
1123 CopyRedirectKeyArgs /* RedirectKey */,
1124 CopyDeviceBtnArgs /* DeviceBtn */,
1125 CopyDeviceBtnArgs /* LockDeviceBtn*/
1128 #define ACTION_SZ 256
1130 char *
1131 XkbActionText(Display *dpy,XkbDescPtr xkb,XkbAction *action,unsigned format)
1133 char buf[ACTION_SZ],*tmp;
1134 int sz;
1136 if (format==XkbCFile) {
1137 sprintf(buf,
1138 "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }",
1139 XkbActionTypeText(action->type,XkbCFile),
1140 action->any.data[0],action->any.data[1],action->any.data[2],
1141 action->any.data[3],action->any.data[4],action->any.data[5],
1142 action->any.data[6]);
1144 else {
1145 sprintf(buf,"%s(",XkbActionTypeText(action->type,XkbXKBFile));
1146 sz= ACTION_SZ-strlen(buf)+2; /* room for close paren and NULL */
1147 if (action->type<(unsigned)XkbSA_NumActions)
1148 (*copyActionArgs[action->type])(dpy,xkb,action,buf,&sz);
1149 else CopyOtherArgs(dpy,xkb,action,buf,&sz);
1150 TryCopyStr(buf,")",&sz);
1152 tmp= tbGetBuffer(strlen(buf)+1);
1153 if (tmp!=NULL)
1154 strcpy(tmp,buf);
1155 return tmp;
1158 char *
1159 XkbBehaviorText(XkbDescPtr xkb,XkbBehavior *behavior,unsigned format)
1161 char buf[256],*tmp;
1163 if (format==XkbCFile) {
1164 if (behavior->type==XkbKB_Default)
1165 sprintf(buf,"{ 0, 0 }");
1166 else sprintf(buf,"{ %3d, 0x%02x }",behavior->type,behavior->data);
1168 else {
1169 unsigned type,permanent;
1170 type= behavior->type&XkbKB_OpMask;
1171 permanent=((behavior->type&XkbKB_Permanent)!=0);
1173 if (type==XkbKB_Lock) {
1174 sprintf(buf,"lock= %s",(permanent?"Permanent":"True"));
1176 else if (type==XkbKB_RadioGroup) {
1177 int g;
1178 char *tmp;
1179 g= ((behavior->data)&(~XkbKB_RGAllowNone))+1;
1180 if (XkbKB_RGAllowNone&behavior->data) {
1181 sprintf(buf,"allowNone,");
1182 tmp= &buf[strlen(buf)];
1184 else tmp= buf;
1185 if (permanent)
1186 sprintf(tmp,"permanentRadioGroup= %d",g);
1187 else sprintf(tmp,"radioGroup= %d",g);
1189 else if ((type==XkbKB_Overlay1)||(type==XkbKB_Overlay2)) {
1190 int ndx,kc;
1191 char *kn;
1193 ndx= ((type==XkbKB_Overlay1)?1:2);
1194 kc= behavior->data;
1195 if ((xkb)&&(xkb->names)&&(xkb->names->keys))
1196 kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile);
1197 else {
1198 static char tbuf[8];
1199 sprintf(tbuf,"%d",kc);
1200 kn= tbuf;
1202 if (permanent)
1203 sprintf(buf,"permanentOverlay%d= %s",ndx,kn);
1204 else sprintf(buf,"overlay%d= %s",ndx,kn);
1207 tmp= tbGetBuffer(strlen(buf)+1);
1208 if (tmp!=NULL)
1209 strcpy(tmp,buf);
1210 return tmp;
1213 /***====================================================================***/
1215 char *
1216 XkbIndentText(unsigned size)
1218 static char buf[32];
1219 register int i;
1221 if (size>31)
1222 size= 31;
1224 for (i=0;i<size;i++) {
1225 buf[i]= ' ';
1227 buf[size]= '\0';
1228 return buf;