xref: /OK3568_Linux_fs/external/xserver/xkb/xkbtext.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /************************************************************
2*4882a593Smuzhiyun  Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun  Permission to use, copy, modify, and distribute this
5*4882a593Smuzhiyun  software and its documentation for any purpose and without
6*4882a593Smuzhiyun  fee is hereby granted, provided that the above copyright
7*4882a593Smuzhiyun  notice appear in all copies and that both that copyright
8*4882a593Smuzhiyun  notice and this permission notice appear in supporting
9*4882a593Smuzhiyun  documentation, and that the name of Silicon Graphics not be
10*4882a593Smuzhiyun  used in advertising or publicity pertaining to distribution
11*4882a593Smuzhiyun  of the software without specific prior written permission.
12*4882a593Smuzhiyun  Silicon Graphics makes no representation about the suitability
13*4882a593Smuzhiyun  of this software for any purpose. It is provided "as is"
14*4882a593Smuzhiyun  without any express or implied warranty.
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun  SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17*4882a593Smuzhiyun  SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18*4882a593Smuzhiyun  AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19*4882a593Smuzhiyun  GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20*4882a593Smuzhiyun  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21*4882a593Smuzhiyun  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22*4882a593Smuzhiyun  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23*4882a593Smuzhiyun  THE USE OR PERFORMANCE OF THIS SOFTWARE.
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun  ********************************************************/
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
28*4882a593Smuzhiyun #include <dix-config.h>
29*4882a593Smuzhiyun #endif
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #include <stdio.h>
32*4882a593Smuzhiyun #include <ctype.h>
33*4882a593Smuzhiyun #include <stdlib.h>
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #include <X11/Xos.h>
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun #include <X11/X.h>
38*4882a593Smuzhiyun #include <X11/Xproto.h>
39*4882a593Smuzhiyun #include <X11/extensions/XKMformat.h>
40*4882a593Smuzhiyun #include "misc.h"
41*4882a593Smuzhiyun #include "inputstr.h"
42*4882a593Smuzhiyun #include "dix.h"
43*4882a593Smuzhiyun #include "xkbstr.h"
44*4882a593Smuzhiyun #define XKBSRV_NEED_FILE_FUNCS	1
45*4882a593Smuzhiyun #include <xkbsrv.h>
46*4882a593Smuzhiyun #include "xkbgeom.h"
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun /***====================================================================***/
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun #define NUM_BUFFER      8
51*4882a593Smuzhiyun static struct textBuffer {
52*4882a593Smuzhiyun     int size;
53*4882a593Smuzhiyun     char *buffer;
54*4882a593Smuzhiyun } textBuffer[NUM_BUFFER];
55*4882a593Smuzhiyun static int textBufferIndex;
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun static char *
tbGetBuffer(unsigned size)58*4882a593Smuzhiyun tbGetBuffer(unsigned size)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun     struct textBuffer *tb;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun     tb = &textBuffer[textBufferIndex];
63*4882a593Smuzhiyun     textBufferIndex = (textBufferIndex + 1) % NUM_BUFFER;
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun     if (size > tb->size) {
66*4882a593Smuzhiyun         free(tb->buffer);
67*4882a593Smuzhiyun         tb->buffer = xnfalloc(size);
68*4882a593Smuzhiyun         tb->size = size;
69*4882a593Smuzhiyun     }
70*4882a593Smuzhiyun     return tb->buffer;
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun /***====================================================================***/
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun char *
XkbAtomText(Atom atm,unsigned format)76*4882a593Smuzhiyun XkbAtomText(Atom atm, unsigned format)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun     const char *atmstr;
79*4882a593Smuzhiyun     char *rtrn, *tmp;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun     atmstr = NameForAtom(atm);
82*4882a593Smuzhiyun     if (atmstr != NULL) {
83*4882a593Smuzhiyun         int len;
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun         len = strlen(atmstr) + 1;
86*4882a593Smuzhiyun         rtrn = tbGetBuffer(len);
87*4882a593Smuzhiyun         strlcpy(rtrn, atmstr, len);
88*4882a593Smuzhiyun     }
89*4882a593Smuzhiyun     else {
90*4882a593Smuzhiyun         rtrn = tbGetBuffer(1);
91*4882a593Smuzhiyun         rtrn[0] = '\0';
92*4882a593Smuzhiyun     }
93*4882a593Smuzhiyun     if (format == XkbCFile) {
94*4882a593Smuzhiyun         for (tmp = rtrn; *tmp != '\0'; tmp++) {
95*4882a593Smuzhiyun             if ((tmp == rtrn) && (!isalpha(*tmp)))
96*4882a593Smuzhiyun                 *tmp = '_';
97*4882a593Smuzhiyun             else if (!isalnum(*tmp))
98*4882a593Smuzhiyun                 *tmp = '_';
99*4882a593Smuzhiyun         }
100*4882a593Smuzhiyun     }
101*4882a593Smuzhiyun     return XkbStringText(rtrn, format);
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun /***====================================================================***/
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun char *
XkbVModIndexText(XkbDescPtr xkb,unsigned ndx,unsigned format)107*4882a593Smuzhiyun XkbVModIndexText(XkbDescPtr xkb, unsigned ndx, unsigned format)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun     register int len;
110*4882a593Smuzhiyun     register Atom *vmodNames;
111*4882a593Smuzhiyun     char *rtrn;
112*4882a593Smuzhiyun     const char *tmp;
113*4882a593Smuzhiyun     char numBuf[20];
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun     if (xkb && xkb->names)
116*4882a593Smuzhiyun         vmodNames = xkb->names->vmods;
117*4882a593Smuzhiyun     else
118*4882a593Smuzhiyun         vmodNames = NULL;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun     tmp = NULL;
121*4882a593Smuzhiyun     if (ndx >= XkbNumVirtualMods)
122*4882a593Smuzhiyun         tmp = "illegal";
123*4882a593Smuzhiyun     else if (vmodNames && (vmodNames[ndx] != None))
124*4882a593Smuzhiyun         tmp = NameForAtom(vmodNames[ndx]);
125*4882a593Smuzhiyun     if (tmp == NULL) {
126*4882a593Smuzhiyun         snprintf(numBuf, sizeof(numBuf), "%d", ndx);
127*4882a593Smuzhiyun         tmp = numBuf;
128*4882a593Smuzhiyun     }
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun     len = strlen(tmp) + 1;
131*4882a593Smuzhiyun     if (format == XkbCFile)
132*4882a593Smuzhiyun         len += 4;
133*4882a593Smuzhiyun     rtrn = tbGetBuffer(len);
134*4882a593Smuzhiyun     if (format == XkbCFile) {
135*4882a593Smuzhiyun         strcpy(rtrn, "vmod_");
136*4882a593Smuzhiyun         strncpy(&rtrn[5], tmp, len - 4);
137*4882a593Smuzhiyun     }
138*4882a593Smuzhiyun     else
139*4882a593Smuzhiyun         strncpy(rtrn, tmp, len);
140*4882a593Smuzhiyun     return rtrn;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun #define VMOD_BUFFER_SIZE        512
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun char *
XkbVModMaskText(XkbDescPtr xkb,unsigned modMask,unsigned mask,unsigned format)146*4882a593Smuzhiyun XkbVModMaskText(XkbDescPtr xkb,
147*4882a593Smuzhiyun                 unsigned modMask, unsigned mask, unsigned format)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun     register int i, bit;
150*4882a593Smuzhiyun     int len;
151*4882a593Smuzhiyun     char *mm, *rtrn;
152*4882a593Smuzhiyun     char *str, buf[VMOD_BUFFER_SIZE];
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun     if ((modMask == 0) && (mask == 0)) {
155*4882a593Smuzhiyun         rtrn = tbGetBuffer(5);
156*4882a593Smuzhiyun         if (format == XkbCFile)
157*4882a593Smuzhiyun             sprintf(rtrn, "0");
158*4882a593Smuzhiyun         else
159*4882a593Smuzhiyun             sprintf(rtrn, "none");
160*4882a593Smuzhiyun         return rtrn;
161*4882a593Smuzhiyun     }
162*4882a593Smuzhiyun     if (modMask != 0)
163*4882a593Smuzhiyun         mm = XkbModMaskText(modMask, format);
164*4882a593Smuzhiyun     else
165*4882a593Smuzhiyun         mm = NULL;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun     str = buf;
168*4882a593Smuzhiyun     buf[0] = '\0';
169*4882a593Smuzhiyun     if (mask) {
170*4882a593Smuzhiyun         char *tmp;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun         for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
173*4882a593Smuzhiyun             if (mask & bit) {
174*4882a593Smuzhiyun                 tmp = XkbVModIndexText(xkb, i, format);
175*4882a593Smuzhiyun                 len = strlen(tmp) + 1 + (str == buf ? 0 : 1);
176*4882a593Smuzhiyun                 if (format == XkbCFile)
177*4882a593Smuzhiyun                     len += 4;
178*4882a593Smuzhiyun                 if ((str - (buf + len)) <= VMOD_BUFFER_SIZE) {
179*4882a593Smuzhiyun                     if (str != buf) {
180*4882a593Smuzhiyun                         if (format == XkbCFile)
181*4882a593Smuzhiyun                             *str++ = '|';
182*4882a593Smuzhiyun                         else
183*4882a593Smuzhiyun                             *str++ = '+';
184*4882a593Smuzhiyun                         len--;
185*4882a593Smuzhiyun                     }
186*4882a593Smuzhiyun                 }
187*4882a593Smuzhiyun                 if (format == XkbCFile)
188*4882a593Smuzhiyun                     sprintf(str, "%sMask", tmp);
189*4882a593Smuzhiyun                 else
190*4882a593Smuzhiyun                     strcpy(str, tmp);
191*4882a593Smuzhiyun                 str = &str[len - 1];
192*4882a593Smuzhiyun             }
193*4882a593Smuzhiyun         }
194*4882a593Smuzhiyun         str = buf;
195*4882a593Smuzhiyun     }
196*4882a593Smuzhiyun     else
197*4882a593Smuzhiyun         str = NULL;
198*4882a593Smuzhiyun     if (mm)
199*4882a593Smuzhiyun         len = strlen(mm);
200*4882a593Smuzhiyun     else
201*4882a593Smuzhiyun         len = 0;
202*4882a593Smuzhiyun     if (str)
203*4882a593Smuzhiyun         len += strlen(str) + (mm == NULL ? 0 : 1);
204*4882a593Smuzhiyun     rtrn = tbGetBuffer(len + 1);
205*4882a593Smuzhiyun     rtrn[0] = '\0';
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun     if (mm != NULL) {
208*4882a593Smuzhiyun         i = strlen(mm);
209*4882a593Smuzhiyun         if (i > len)
210*4882a593Smuzhiyun             i = len;
211*4882a593Smuzhiyun         strcpy(rtrn, mm);
212*4882a593Smuzhiyun     }
213*4882a593Smuzhiyun     else {
214*4882a593Smuzhiyun         i = 0;
215*4882a593Smuzhiyun     }
216*4882a593Smuzhiyun     if (str != NULL) {
217*4882a593Smuzhiyun         if (mm != NULL) {
218*4882a593Smuzhiyun             if (format == XkbCFile)
219*4882a593Smuzhiyun                 strcat(rtrn, "|");
220*4882a593Smuzhiyun             else
221*4882a593Smuzhiyun                 strcat(rtrn, "+");
222*4882a593Smuzhiyun         }
223*4882a593Smuzhiyun         strncat(rtrn, str, len - i);
224*4882a593Smuzhiyun     }
225*4882a593Smuzhiyun     rtrn[len] = '\0';
226*4882a593Smuzhiyun     return rtrn;
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun static const char *modNames[XkbNumModifiers] = {
230*4882a593Smuzhiyun     "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5"
231*4882a593Smuzhiyun };
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun char *
XkbModIndexText(unsigned ndx,unsigned format)234*4882a593Smuzhiyun XkbModIndexText(unsigned ndx, unsigned format)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun     char *rtrn;
237*4882a593Smuzhiyun     char buf[100];
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun     if (format == XkbCFile) {
240*4882a593Smuzhiyun         if (ndx < XkbNumModifiers)
241*4882a593Smuzhiyun             snprintf(buf, sizeof(buf), "%sMapIndex", modNames[ndx]);
242*4882a593Smuzhiyun         else if (ndx == XkbNoModifier)
243*4882a593Smuzhiyun             snprintf(buf, sizeof(buf), "XkbNoModifier");
244*4882a593Smuzhiyun         else
245*4882a593Smuzhiyun             snprintf(buf, sizeof(buf), "0x%02x", ndx);
246*4882a593Smuzhiyun     }
247*4882a593Smuzhiyun     else {
248*4882a593Smuzhiyun         if (ndx < XkbNumModifiers)
249*4882a593Smuzhiyun             strcpy(buf, modNames[ndx]);
250*4882a593Smuzhiyun         else if (ndx == XkbNoModifier)
251*4882a593Smuzhiyun             strcpy(buf, "none");
252*4882a593Smuzhiyun         else
253*4882a593Smuzhiyun             snprintf(buf, sizeof(buf), "ILLEGAL_%02x", ndx);
254*4882a593Smuzhiyun     }
255*4882a593Smuzhiyun     rtrn = tbGetBuffer(strlen(buf) + 1);
256*4882a593Smuzhiyun     strcpy(rtrn, buf);
257*4882a593Smuzhiyun     return rtrn;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun char *
XkbModMaskText(unsigned mask,unsigned format)261*4882a593Smuzhiyun XkbModMaskText(unsigned mask, unsigned format)
262*4882a593Smuzhiyun {
263*4882a593Smuzhiyun     register int i, bit;
264*4882a593Smuzhiyun     char buf[64], *rtrn;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun     if ((mask & 0xff) == 0xff) {
267*4882a593Smuzhiyun         if (format == XkbCFile)
268*4882a593Smuzhiyun             strcpy(buf, "0xff");
269*4882a593Smuzhiyun         else
270*4882a593Smuzhiyun             strcpy(buf, "all");
271*4882a593Smuzhiyun     }
272*4882a593Smuzhiyun     else if ((mask & 0xff) == 0) {
273*4882a593Smuzhiyun         if (format == XkbCFile)
274*4882a593Smuzhiyun             strcpy(buf, "0");
275*4882a593Smuzhiyun         else
276*4882a593Smuzhiyun             strcpy(buf, "none");
277*4882a593Smuzhiyun     }
278*4882a593Smuzhiyun     else {
279*4882a593Smuzhiyun         char *str = buf;
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun         buf[0] = '\0';
282*4882a593Smuzhiyun         for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) {
283*4882a593Smuzhiyun             if (mask & bit) {
284*4882a593Smuzhiyun                 if (str != buf) {
285*4882a593Smuzhiyun                     if (format == XkbCFile)
286*4882a593Smuzhiyun                         *str++ = '|';
287*4882a593Smuzhiyun                     else
288*4882a593Smuzhiyun                         *str++ = '+';
289*4882a593Smuzhiyun                 }
290*4882a593Smuzhiyun                 strcpy(str, modNames[i]);
291*4882a593Smuzhiyun                 str = &str[strlen(str)];
292*4882a593Smuzhiyun                 if (format == XkbCFile) {
293*4882a593Smuzhiyun                     strcpy(str, "Mask");
294*4882a593Smuzhiyun                     str += 4;
295*4882a593Smuzhiyun                 }
296*4882a593Smuzhiyun             }
297*4882a593Smuzhiyun         }
298*4882a593Smuzhiyun     }
299*4882a593Smuzhiyun     rtrn = tbGetBuffer(strlen(buf) + 1);
300*4882a593Smuzhiyun     strcpy(rtrn, buf);
301*4882a593Smuzhiyun     return rtrn;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun /***====================================================================***/
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun  /*ARGSUSED*/ char *
XkbConfigText(unsigned config,unsigned format)307*4882a593Smuzhiyun XkbConfigText(unsigned config, unsigned format)
308*4882a593Smuzhiyun {
309*4882a593Smuzhiyun     static char *buf;
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun     buf = tbGetBuffer(32);
312*4882a593Smuzhiyun     switch (config) {
313*4882a593Smuzhiyun     case XkmSemanticsFile:
314*4882a593Smuzhiyun         strcpy(buf, "Semantics");
315*4882a593Smuzhiyun         break;
316*4882a593Smuzhiyun     case XkmLayoutFile:
317*4882a593Smuzhiyun         strcpy(buf, "Layout");
318*4882a593Smuzhiyun         break;
319*4882a593Smuzhiyun     case XkmKeymapFile:
320*4882a593Smuzhiyun         strcpy(buf, "Keymap");
321*4882a593Smuzhiyun         break;
322*4882a593Smuzhiyun     case XkmGeometryFile:
323*4882a593Smuzhiyun     case XkmGeometryIndex:
324*4882a593Smuzhiyun         strcpy(buf, "Geometry");
325*4882a593Smuzhiyun         break;
326*4882a593Smuzhiyun     case XkmTypesIndex:
327*4882a593Smuzhiyun         strcpy(buf, "Types");
328*4882a593Smuzhiyun         break;
329*4882a593Smuzhiyun     case XkmCompatMapIndex:
330*4882a593Smuzhiyun         strcpy(buf, "CompatMap");
331*4882a593Smuzhiyun         break;
332*4882a593Smuzhiyun     case XkmSymbolsIndex:
333*4882a593Smuzhiyun         strcpy(buf, "Symbols");
334*4882a593Smuzhiyun         break;
335*4882a593Smuzhiyun     case XkmIndicatorsIndex:
336*4882a593Smuzhiyun         strcpy(buf, "Indicators");
337*4882a593Smuzhiyun         break;
338*4882a593Smuzhiyun     case XkmKeyNamesIndex:
339*4882a593Smuzhiyun         strcpy(buf, "KeyNames");
340*4882a593Smuzhiyun         break;
341*4882a593Smuzhiyun     case XkmVirtualModsIndex:
342*4882a593Smuzhiyun         strcpy(buf, "VirtualMods");
343*4882a593Smuzhiyun         break;
344*4882a593Smuzhiyun     default:
345*4882a593Smuzhiyun         sprintf(buf, "unknown(%d)", config);
346*4882a593Smuzhiyun         break;
347*4882a593Smuzhiyun     }
348*4882a593Smuzhiyun     return buf;
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun /***====================================================================***/
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun char *
XkbKeysymText(KeySym sym,unsigned format)354*4882a593Smuzhiyun XkbKeysymText(KeySym sym, unsigned format)
355*4882a593Smuzhiyun {
356*4882a593Smuzhiyun     static char buf[32];
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun     if (sym == NoSymbol)
359*4882a593Smuzhiyun         strcpy(buf, "NoSymbol");
360*4882a593Smuzhiyun     else
361*4882a593Smuzhiyun         snprintf(buf, sizeof(buf), "0x%lx", (long) sym);
362*4882a593Smuzhiyun     return buf;
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun char *
XkbKeyNameText(char * name,unsigned format)366*4882a593Smuzhiyun XkbKeyNameText(char *name, unsigned format)
367*4882a593Smuzhiyun {
368*4882a593Smuzhiyun     char *buf;
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun     if (format == XkbCFile) {
371*4882a593Smuzhiyun         buf = tbGetBuffer(5);
372*4882a593Smuzhiyun         memcpy(buf, name, 4);
373*4882a593Smuzhiyun         buf[4] = '\0';
374*4882a593Smuzhiyun     }
375*4882a593Smuzhiyun     else {
376*4882a593Smuzhiyun         int len;
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun         buf = tbGetBuffer(7);
379*4882a593Smuzhiyun         buf[0] = '<';
380*4882a593Smuzhiyun         memcpy(&buf[1], name, 4);
381*4882a593Smuzhiyun         buf[5] = '\0';
382*4882a593Smuzhiyun         len = strlen(buf);
383*4882a593Smuzhiyun         buf[len++] = '>';
384*4882a593Smuzhiyun         buf[len] = '\0';
385*4882a593Smuzhiyun     }
386*4882a593Smuzhiyun     return buf;
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun /***====================================================================***/
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun static const char *siMatchText[5] = {
392*4882a593Smuzhiyun     "NoneOf", "AnyOfOrNone", "AnyOf", "AllOf", "Exactly"
393*4882a593Smuzhiyun };
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun const char *
XkbSIMatchText(unsigned type,unsigned format)396*4882a593Smuzhiyun XkbSIMatchText(unsigned type, unsigned format)
397*4882a593Smuzhiyun {
398*4882a593Smuzhiyun     static char buf[40];
399*4882a593Smuzhiyun     const char *rtrn;
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun     switch (type & XkbSI_OpMask) {
402*4882a593Smuzhiyun     case XkbSI_NoneOf:
403*4882a593Smuzhiyun         rtrn = siMatchText[0];
404*4882a593Smuzhiyun         break;
405*4882a593Smuzhiyun     case XkbSI_AnyOfOrNone:
406*4882a593Smuzhiyun         rtrn = siMatchText[1];
407*4882a593Smuzhiyun         break;
408*4882a593Smuzhiyun     case XkbSI_AnyOf:
409*4882a593Smuzhiyun         rtrn = siMatchText[2];
410*4882a593Smuzhiyun         break;
411*4882a593Smuzhiyun     case XkbSI_AllOf:
412*4882a593Smuzhiyun         rtrn = siMatchText[3];
413*4882a593Smuzhiyun         break;
414*4882a593Smuzhiyun     case XkbSI_Exactly:
415*4882a593Smuzhiyun         rtrn = siMatchText[4];
416*4882a593Smuzhiyun         break;
417*4882a593Smuzhiyun     default:
418*4882a593Smuzhiyun         snprintf(buf, sizeof(buf), "0x%x", type & XkbSI_OpMask);
419*4882a593Smuzhiyun         return buf;
420*4882a593Smuzhiyun     }
421*4882a593Smuzhiyun     if (format == XkbCFile) {
422*4882a593Smuzhiyun         if (type & XkbSI_LevelOneOnly)
423*4882a593Smuzhiyun             snprintf(buf, sizeof(buf), "XkbSI_LevelOneOnly|XkbSI_%s", rtrn);
424*4882a593Smuzhiyun         else
425*4882a593Smuzhiyun             snprintf(buf, sizeof(buf), "XkbSI_%s", rtrn);
426*4882a593Smuzhiyun         rtrn = buf;
427*4882a593Smuzhiyun     }
428*4882a593Smuzhiyun     return rtrn;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun /***====================================================================***/
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun static const char *imWhichNames[] = {
434*4882a593Smuzhiyun     "base",
435*4882a593Smuzhiyun     "latched",
436*4882a593Smuzhiyun     "locked",
437*4882a593Smuzhiyun     "effective",
438*4882a593Smuzhiyun     "compat"
439*4882a593Smuzhiyun };
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun char *
XkbIMWhichStateMaskText(unsigned use_which,unsigned format)442*4882a593Smuzhiyun XkbIMWhichStateMaskText(unsigned use_which, unsigned format)
443*4882a593Smuzhiyun {
444*4882a593Smuzhiyun     int len;
445*4882a593Smuzhiyun     unsigned i, bit, tmp;
446*4882a593Smuzhiyun     char *buf;
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun     if (use_which == 0) {
449*4882a593Smuzhiyun         buf = tbGetBuffer(2);
450*4882a593Smuzhiyun         strcpy(buf, "0");
451*4882a593Smuzhiyun         return buf;
452*4882a593Smuzhiyun     }
453*4882a593Smuzhiyun     tmp = use_which & XkbIM_UseAnyMods;
454*4882a593Smuzhiyun     for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
455*4882a593Smuzhiyun         if (tmp & bit) {
456*4882a593Smuzhiyun             tmp &= ~bit;
457*4882a593Smuzhiyun             len += strlen(imWhichNames[i]) + 1;
458*4882a593Smuzhiyun             if (format == XkbCFile)
459*4882a593Smuzhiyun                 len += 9;
460*4882a593Smuzhiyun         }
461*4882a593Smuzhiyun     }
462*4882a593Smuzhiyun     buf = tbGetBuffer(len + 1);
463*4882a593Smuzhiyun     tmp = use_which & XkbIM_UseAnyMods;
464*4882a593Smuzhiyun     for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
465*4882a593Smuzhiyun         if (tmp & bit) {
466*4882a593Smuzhiyun             tmp &= ~bit;
467*4882a593Smuzhiyun             if (format == XkbCFile) {
468*4882a593Smuzhiyun                 if (len != 0)
469*4882a593Smuzhiyun                     buf[len++] = '|';
470*4882a593Smuzhiyun                 sprintf(&buf[len], "XkbIM_Use%s", imWhichNames[i]);
471*4882a593Smuzhiyun                 buf[len + 9] = toupper(buf[len + 9]);
472*4882a593Smuzhiyun             }
473*4882a593Smuzhiyun             else {
474*4882a593Smuzhiyun                 if (len != 0)
475*4882a593Smuzhiyun                     buf[len++] = '+';
476*4882a593Smuzhiyun                 sprintf(&buf[len], "%s", imWhichNames[i]);
477*4882a593Smuzhiyun             }
478*4882a593Smuzhiyun             len += strlen(&buf[len]);
479*4882a593Smuzhiyun         }
480*4882a593Smuzhiyun     }
481*4882a593Smuzhiyun     return buf;
482*4882a593Smuzhiyun }
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun static const char *ctrlNames[] = {
485*4882a593Smuzhiyun     "repeatKeys",
486*4882a593Smuzhiyun     "slowKeys",
487*4882a593Smuzhiyun     "bounceKeys",
488*4882a593Smuzhiyun     "stickyKeys",
489*4882a593Smuzhiyun     "mouseKeys",
490*4882a593Smuzhiyun     "mouseKeysAccel",
491*4882a593Smuzhiyun     "accessXKeys",
492*4882a593Smuzhiyun     "accessXTimeout",
493*4882a593Smuzhiyun     "accessXFeedback",
494*4882a593Smuzhiyun     "audibleBell",
495*4882a593Smuzhiyun     "overlay1",
496*4882a593Smuzhiyun     "overlay2",
497*4882a593Smuzhiyun     "ignoreGroupLock"
498*4882a593Smuzhiyun };
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun char *
XkbControlsMaskText(unsigned ctrls,unsigned format)501*4882a593Smuzhiyun XkbControlsMaskText(unsigned ctrls, unsigned format)
502*4882a593Smuzhiyun {
503*4882a593Smuzhiyun     int len;
504*4882a593Smuzhiyun     unsigned i, bit, tmp;
505*4882a593Smuzhiyun     char *buf;
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun     if (ctrls == 0) {
508*4882a593Smuzhiyun         buf = tbGetBuffer(5);
509*4882a593Smuzhiyun         if (format == XkbCFile)
510*4882a593Smuzhiyun             strcpy(buf, "0");
511*4882a593Smuzhiyun         else
512*4882a593Smuzhiyun             strcpy(buf, "none");
513*4882a593Smuzhiyun         return buf;
514*4882a593Smuzhiyun     }
515*4882a593Smuzhiyun     tmp = ctrls & XkbAllBooleanCtrlsMask;
516*4882a593Smuzhiyun     for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
517*4882a593Smuzhiyun         if (tmp & bit) {
518*4882a593Smuzhiyun             tmp &= ~bit;
519*4882a593Smuzhiyun             len += strlen(ctrlNames[i]) + 1;
520*4882a593Smuzhiyun             if (format == XkbCFile)
521*4882a593Smuzhiyun                 len += 7;
522*4882a593Smuzhiyun         }
523*4882a593Smuzhiyun     }
524*4882a593Smuzhiyun     buf = tbGetBuffer(len + 1);
525*4882a593Smuzhiyun     tmp = ctrls & XkbAllBooleanCtrlsMask;
526*4882a593Smuzhiyun     for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
527*4882a593Smuzhiyun         if (tmp & bit) {
528*4882a593Smuzhiyun             tmp &= ~bit;
529*4882a593Smuzhiyun             if (format == XkbCFile) {
530*4882a593Smuzhiyun                 if (len != 0)
531*4882a593Smuzhiyun                     buf[len++] = '|';
532*4882a593Smuzhiyun                 sprintf(&buf[len], "Xkb%sMask", ctrlNames[i]);
533*4882a593Smuzhiyun                 buf[len + 3] = toupper(buf[len + 3]);
534*4882a593Smuzhiyun             }
535*4882a593Smuzhiyun             else {
536*4882a593Smuzhiyun                 if (len != 0)
537*4882a593Smuzhiyun                     buf[len++] = '+';
538*4882a593Smuzhiyun                 sprintf(&buf[len], "%s", ctrlNames[i]);
539*4882a593Smuzhiyun             }
540*4882a593Smuzhiyun             len += strlen(&buf[len]);
541*4882a593Smuzhiyun         }
542*4882a593Smuzhiyun     }
543*4882a593Smuzhiyun     return buf;
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun /***====================================================================***/
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun char *
XkbStringText(char * str,unsigned format)549*4882a593Smuzhiyun XkbStringText(char *str, unsigned format)
550*4882a593Smuzhiyun {
551*4882a593Smuzhiyun     char *buf;
552*4882a593Smuzhiyun     register char *in, *out;
553*4882a593Smuzhiyun     int len;
554*4882a593Smuzhiyun     Bool ok;
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun     if (str == NULL) {
557*4882a593Smuzhiyun         buf = tbGetBuffer(2);
558*4882a593Smuzhiyun         buf[0] = '\0';
559*4882a593Smuzhiyun         return buf;
560*4882a593Smuzhiyun     }
561*4882a593Smuzhiyun     else if (format == XkbXKMFile)
562*4882a593Smuzhiyun         return str;
563*4882a593Smuzhiyun     for (ok = TRUE, len = 0, in = str; *in != '\0'; in++, len++) {
564*4882a593Smuzhiyun         if (!isprint(*in)) {
565*4882a593Smuzhiyun             ok = FALSE;
566*4882a593Smuzhiyun             switch (*in) {
567*4882a593Smuzhiyun             case '\n':
568*4882a593Smuzhiyun             case '\t':
569*4882a593Smuzhiyun             case '\v':
570*4882a593Smuzhiyun             case '\b':
571*4882a593Smuzhiyun             case '\r':
572*4882a593Smuzhiyun             case '\f':
573*4882a593Smuzhiyun                 len++;
574*4882a593Smuzhiyun                 break;
575*4882a593Smuzhiyun             default:
576*4882a593Smuzhiyun                 len += 4;
577*4882a593Smuzhiyun                 break;
578*4882a593Smuzhiyun             }
579*4882a593Smuzhiyun         }
580*4882a593Smuzhiyun     }
581*4882a593Smuzhiyun     if (ok)
582*4882a593Smuzhiyun         return str;
583*4882a593Smuzhiyun     buf = tbGetBuffer(len + 1);
584*4882a593Smuzhiyun     for (in = str, out = buf; *in != '\0'; in++) {
585*4882a593Smuzhiyun         if (isprint(*in))
586*4882a593Smuzhiyun             *out++ = *in;
587*4882a593Smuzhiyun         else {
588*4882a593Smuzhiyun             *out++ = '\\';
589*4882a593Smuzhiyun             if (*in == '\n')
590*4882a593Smuzhiyun                 *out++ = 'n';
591*4882a593Smuzhiyun             else if (*in == '\t')
592*4882a593Smuzhiyun                 *out++ = 't';
593*4882a593Smuzhiyun             else if (*in == '\v')
594*4882a593Smuzhiyun                 *out++ = 'v';
595*4882a593Smuzhiyun             else if (*in == '\b')
596*4882a593Smuzhiyun                 *out++ = 'b';
597*4882a593Smuzhiyun             else if (*in == '\r')
598*4882a593Smuzhiyun                 *out++ = 'r';
599*4882a593Smuzhiyun             else if (*in == '\f')
600*4882a593Smuzhiyun                 *out++ = 'f';
601*4882a593Smuzhiyun             else if ((*in == '\033') && (format == XkbXKMFile)) {
602*4882a593Smuzhiyun                 *out++ = 'e';
603*4882a593Smuzhiyun             }
604*4882a593Smuzhiyun             else {
605*4882a593Smuzhiyun                 *out++ = '0';
606*4882a593Smuzhiyun                 sprintf(out, "%o", (unsigned char) *in);
607*4882a593Smuzhiyun                 while (*out != '\0')
608*4882a593Smuzhiyun                     out++;
609*4882a593Smuzhiyun             }
610*4882a593Smuzhiyun         }
611*4882a593Smuzhiyun     }
612*4882a593Smuzhiyun     *out++ = '\0';
613*4882a593Smuzhiyun     return buf;
614*4882a593Smuzhiyun }
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun /***====================================================================***/
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun char *
XkbGeomFPText(int val,unsigned format)619*4882a593Smuzhiyun XkbGeomFPText(int val, unsigned format)
620*4882a593Smuzhiyun {
621*4882a593Smuzhiyun     int whole, frac;
622*4882a593Smuzhiyun     char *buf;
623*4882a593Smuzhiyun 
624*4882a593Smuzhiyun     buf = tbGetBuffer(12);
625*4882a593Smuzhiyun     if (format == XkbCFile) {
626*4882a593Smuzhiyun         sprintf(buf, "%d", val);
627*4882a593Smuzhiyun     }
628*4882a593Smuzhiyun     else {
629*4882a593Smuzhiyun         whole = val / XkbGeomPtsPerMM;
630*4882a593Smuzhiyun         frac = val % XkbGeomPtsPerMM;
631*4882a593Smuzhiyun         if (frac != 0)
632*4882a593Smuzhiyun             sprintf(buf, "%d.%d", whole, frac);
633*4882a593Smuzhiyun         else
634*4882a593Smuzhiyun             sprintf(buf, "%d", whole);
635*4882a593Smuzhiyun     }
636*4882a593Smuzhiyun     return buf;
637*4882a593Smuzhiyun }
638*4882a593Smuzhiyun 
639*4882a593Smuzhiyun char *
XkbDoodadTypeText(unsigned type,unsigned format)640*4882a593Smuzhiyun XkbDoodadTypeText(unsigned type, unsigned format)
641*4882a593Smuzhiyun {
642*4882a593Smuzhiyun     char *buf;
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun     if (format == XkbCFile) {
645*4882a593Smuzhiyun         buf = tbGetBuffer(24);
646*4882a593Smuzhiyun         if (type == XkbOutlineDoodad)
647*4882a593Smuzhiyun             strcpy(buf, "XkbOutlineDoodad");
648*4882a593Smuzhiyun         else if (type == XkbSolidDoodad)
649*4882a593Smuzhiyun             strcpy(buf, "XkbSolidDoodad");
650*4882a593Smuzhiyun         else if (type == XkbTextDoodad)
651*4882a593Smuzhiyun             strcpy(buf, "XkbTextDoodad");
652*4882a593Smuzhiyun         else if (type == XkbIndicatorDoodad)
653*4882a593Smuzhiyun             strcpy(buf, "XkbIndicatorDoodad");
654*4882a593Smuzhiyun         else if (type == XkbLogoDoodad)
655*4882a593Smuzhiyun             strcpy(buf, "XkbLogoDoodad");
656*4882a593Smuzhiyun         else
657*4882a593Smuzhiyun             sprintf(buf, "UnknownDoodad%d", type);
658*4882a593Smuzhiyun     }
659*4882a593Smuzhiyun     else {
660*4882a593Smuzhiyun         buf = tbGetBuffer(12);
661*4882a593Smuzhiyun         if (type == XkbOutlineDoodad)
662*4882a593Smuzhiyun             strcpy(buf, "outline");
663*4882a593Smuzhiyun         else if (type == XkbSolidDoodad)
664*4882a593Smuzhiyun             strcpy(buf, "solid");
665*4882a593Smuzhiyun         else if (type == XkbTextDoodad)
666*4882a593Smuzhiyun             strcpy(buf, "text");
667*4882a593Smuzhiyun         else if (type == XkbIndicatorDoodad)
668*4882a593Smuzhiyun             strcpy(buf, "indicator");
669*4882a593Smuzhiyun         else if (type == XkbLogoDoodad)
670*4882a593Smuzhiyun             strcpy(buf, "logo");
671*4882a593Smuzhiyun         else
672*4882a593Smuzhiyun             sprintf(buf, "unknown%d", type);
673*4882a593Smuzhiyun     }
674*4882a593Smuzhiyun     return buf;
675*4882a593Smuzhiyun }
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun static const char *actionTypeNames[XkbSA_NumActions] = {
678*4882a593Smuzhiyun     "NoAction",
679*4882a593Smuzhiyun     "SetMods", "LatchMods", "LockMods",
680*4882a593Smuzhiyun     "SetGroup", "LatchGroup", "LockGroup",
681*4882a593Smuzhiyun     "MovePtr",
682*4882a593Smuzhiyun     "PtrBtn", "LockPtrBtn",
683*4882a593Smuzhiyun     "SetPtrDflt",
684*4882a593Smuzhiyun     "ISOLock",
685*4882a593Smuzhiyun     "Terminate", "SwitchScreen",
686*4882a593Smuzhiyun     "SetControls", "LockControls",
687*4882a593Smuzhiyun     "ActionMessage",
688*4882a593Smuzhiyun     "RedirectKey",
689*4882a593Smuzhiyun     "DeviceBtn", "LockDeviceBtn"
690*4882a593Smuzhiyun };
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun const char *
XkbActionTypeText(unsigned type,unsigned format)693*4882a593Smuzhiyun XkbActionTypeText(unsigned type, unsigned format)
694*4882a593Smuzhiyun {
695*4882a593Smuzhiyun     static char buf[32];
696*4882a593Smuzhiyun     const char *rtrn;
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun     if (type <= XkbSA_LastAction) {
699*4882a593Smuzhiyun         rtrn = actionTypeNames[type];
700*4882a593Smuzhiyun         if (format == XkbCFile) {
701*4882a593Smuzhiyun             snprintf(buf, sizeof(buf), "XkbSA_%s", rtrn);
702*4882a593Smuzhiyun             return buf;
703*4882a593Smuzhiyun         }
704*4882a593Smuzhiyun         return rtrn;
705*4882a593Smuzhiyun     }
706*4882a593Smuzhiyun     snprintf(buf, sizeof(buf), "Private");
707*4882a593Smuzhiyun     return buf;
708*4882a593Smuzhiyun }
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun /***====================================================================***/
711*4882a593Smuzhiyun 
712*4882a593Smuzhiyun static int
TryCopyStr(char * to,const char * from,int * pLeft)713*4882a593Smuzhiyun TryCopyStr(char *to, const char *from, int *pLeft)
714*4882a593Smuzhiyun {
715*4882a593Smuzhiyun     register int len;
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun     if (*pLeft > 0) {
718*4882a593Smuzhiyun         len = strlen(from);
719*4882a593Smuzhiyun         if (len < ((*pLeft) - 3)) {
720*4882a593Smuzhiyun             strcat(to, from);
721*4882a593Smuzhiyun             *pLeft -= len;
722*4882a593Smuzhiyun             return TRUE;
723*4882a593Smuzhiyun         }
724*4882a593Smuzhiyun     }
725*4882a593Smuzhiyun     *pLeft = -1;
726*4882a593Smuzhiyun     return FALSE;
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun  /*ARGSUSED*/ static Bool
CopyNoActionArgs(XkbDescPtr xkb,XkbAction * action,char * buf,int * sz)730*4882a593Smuzhiyun CopyNoActionArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
731*4882a593Smuzhiyun {
732*4882a593Smuzhiyun     return TRUE;
733*4882a593Smuzhiyun }
734*4882a593Smuzhiyun 
735*4882a593Smuzhiyun static Bool
CopyModActionArgs(XkbDescPtr xkb,XkbAction * action,char * buf,int * sz)736*4882a593Smuzhiyun CopyModActionArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
737*4882a593Smuzhiyun {
738*4882a593Smuzhiyun     XkbModAction *act;
739*4882a593Smuzhiyun     unsigned tmp;
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun     act = &action->mods;
742*4882a593Smuzhiyun     tmp = XkbModActionVMods(act);
743*4882a593Smuzhiyun     TryCopyStr(buf, "modifiers=", sz);
744*4882a593Smuzhiyun     if (act->flags & XkbSA_UseModMapMods)
745*4882a593Smuzhiyun         TryCopyStr(buf, "modMapMods", sz);
746*4882a593Smuzhiyun     else if (act->real_mods || tmp) {
747*4882a593Smuzhiyun         TryCopyStr(buf,
748*4882a593Smuzhiyun                    XkbVModMaskText(xkb, act->real_mods, tmp, XkbXKBFile), sz);
749*4882a593Smuzhiyun     }
750*4882a593Smuzhiyun     else
751*4882a593Smuzhiyun         TryCopyStr(buf, "none", sz);
752*4882a593Smuzhiyun     if (act->type == XkbSA_LockMods)
753*4882a593Smuzhiyun         return TRUE;
754*4882a593Smuzhiyun     if (act->flags & XkbSA_ClearLocks)
755*4882a593Smuzhiyun         TryCopyStr(buf, ",clearLocks", sz);
756*4882a593Smuzhiyun     if (act->flags & XkbSA_LatchToLock)
757*4882a593Smuzhiyun         TryCopyStr(buf, ",latchToLock", sz);
758*4882a593Smuzhiyun     return TRUE;
759*4882a593Smuzhiyun }
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun  /*ARGSUSED*/ static Bool
CopyGroupActionArgs(XkbDescPtr xkb,XkbAction * action,char * buf,int * sz)762*4882a593Smuzhiyun CopyGroupActionArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
763*4882a593Smuzhiyun {
764*4882a593Smuzhiyun     XkbGroupAction *act;
765*4882a593Smuzhiyun     char tbuf[32];
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun     act = &action->group;
768*4882a593Smuzhiyun     TryCopyStr(buf, "group=", sz);
769*4882a593Smuzhiyun     if (act->flags & XkbSA_GroupAbsolute)
770*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act) + 1);
771*4882a593Smuzhiyun     else if (XkbSAGroup(act) < 0)
772*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act));
773*4882a593Smuzhiyun     else
774*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAGroup(act));
775*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
776*4882a593Smuzhiyun     if (act->type == XkbSA_LockGroup)
777*4882a593Smuzhiyun         return TRUE;
778*4882a593Smuzhiyun     if (act->flags & XkbSA_ClearLocks)
779*4882a593Smuzhiyun         TryCopyStr(buf, ",clearLocks", sz);
780*4882a593Smuzhiyun     if (act->flags & XkbSA_LatchToLock)
781*4882a593Smuzhiyun         TryCopyStr(buf, ",latchToLock", sz);
782*4882a593Smuzhiyun     return TRUE;
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun  /*ARGSUSED*/ static Bool
CopyMovePtrArgs(XkbDescPtr xkb,XkbAction * action,char * buf,int * sz)786*4882a593Smuzhiyun CopyMovePtrArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
787*4882a593Smuzhiyun {
788*4882a593Smuzhiyun     XkbPtrAction *act;
789*4882a593Smuzhiyun     int x, y;
790*4882a593Smuzhiyun     char tbuf[32];
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun     act = &action->ptr;
793*4882a593Smuzhiyun     x = XkbPtrActionX(act);
794*4882a593Smuzhiyun     y = XkbPtrActionY(act);
795*4882a593Smuzhiyun     if ((act->flags & XkbSA_MoveAbsoluteX) || (x < 0))
796*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), "x=%d", x);
797*4882a593Smuzhiyun     else
798*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), "x=+%d", x);
799*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun     if ((act->flags & XkbSA_MoveAbsoluteY) || (y < 0))
802*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), ",y=%d", y);
803*4882a593Smuzhiyun     else
804*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), ",y=+%d", y);
805*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
806*4882a593Smuzhiyun     if (act->flags & XkbSA_NoAcceleration)
807*4882a593Smuzhiyun         TryCopyStr(buf, ",!accel", sz);
808*4882a593Smuzhiyun     return TRUE;
809*4882a593Smuzhiyun }
810*4882a593Smuzhiyun 
811*4882a593Smuzhiyun  /*ARGSUSED*/ static Bool
CopyPtrBtnArgs(XkbDescPtr xkb,XkbAction * action,char * buf,int * sz)812*4882a593Smuzhiyun CopyPtrBtnArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
813*4882a593Smuzhiyun {
814*4882a593Smuzhiyun     XkbPtrBtnAction *act;
815*4882a593Smuzhiyun     char tbuf[32];
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun     act = &action->btn;
818*4882a593Smuzhiyun     TryCopyStr(buf, "button=", sz);
819*4882a593Smuzhiyun     if ((act->button > 0) && (act->button < 6)) {
820*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), "%d", act->button);
821*4882a593Smuzhiyun         TryCopyStr(buf, tbuf, sz);
822*4882a593Smuzhiyun     }
823*4882a593Smuzhiyun     else
824*4882a593Smuzhiyun         TryCopyStr(buf, "default", sz);
825*4882a593Smuzhiyun     if (act->count > 0) {
826*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), ",count=%d", act->count);
827*4882a593Smuzhiyun         TryCopyStr(buf, tbuf, sz);
828*4882a593Smuzhiyun     }
829*4882a593Smuzhiyun     if (action->type == XkbSA_LockPtrBtn) {
830*4882a593Smuzhiyun         switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
831*4882a593Smuzhiyun         case XkbSA_LockNoLock:
832*4882a593Smuzhiyun             TryCopyStr(buf, ",affect=unlock", sz);
833*4882a593Smuzhiyun             break;
834*4882a593Smuzhiyun         case XkbSA_LockNoUnlock:
835*4882a593Smuzhiyun             TryCopyStr(buf, ",affect=lock", sz);
836*4882a593Smuzhiyun             break;
837*4882a593Smuzhiyun         case XkbSA_LockNoUnlock | XkbSA_LockNoLock:
838*4882a593Smuzhiyun             TryCopyStr(buf, ",affect=neither", sz);
839*4882a593Smuzhiyun             break;
840*4882a593Smuzhiyun         default:
841*4882a593Smuzhiyun             TryCopyStr(buf, ",affect=both", sz);
842*4882a593Smuzhiyun             break;
843*4882a593Smuzhiyun         }
844*4882a593Smuzhiyun     }
845*4882a593Smuzhiyun     return TRUE;
846*4882a593Smuzhiyun }
847*4882a593Smuzhiyun 
848*4882a593Smuzhiyun  /*ARGSUSED*/ static Bool
CopySetPtrDfltArgs(XkbDescPtr xkb,XkbAction * action,char * buf,int * sz)849*4882a593Smuzhiyun CopySetPtrDfltArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
850*4882a593Smuzhiyun {
851*4882a593Smuzhiyun     XkbPtrDfltAction *act;
852*4882a593Smuzhiyun     char tbuf[32];
853*4882a593Smuzhiyun 
854*4882a593Smuzhiyun     act = &action->dflt;
855*4882a593Smuzhiyun     if (act->affect == XkbSA_AffectDfltBtn) {
856*4882a593Smuzhiyun         TryCopyStr(buf, "affect=button,button=", sz);
857*4882a593Smuzhiyun         if ((act->flags & XkbSA_DfltBtnAbsolute) ||
858*4882a593Smuzhiyun             (XkbSAPtrDfltValue(act) < 0))
859*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%d", XkbSAPtrDfltValue(act));
860*4882a593Smuzhiyun         else
861*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAPtrDfltValue(act));
862*4882a593Smuzhiyun         TryCopyStr(buf, tbuf, sz);
863*4882a593Smuzhiyun     }
864*4882a593Smuzhiyun     return TRUE;
865*4882a593Smuzhiyun }
866*4882a593Smuzhiyun 
867*4882a593Smuzhiyun static Bool
CopyISOLockArgs(XkbDescPtr xkb,XkbAction * action,char * buf,int * sz)868*4882a593Smuzhiyun CopyISOLockArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
869*4882a593Smuzhiyun {
870*4882a593Smuzhiyun     XkbISOAction *act;
871*4882a593Smuzhiyun     char tbuf[64];
872*4882a593Smuzhiyun 
873*4882a593Smuzhiyun     act = &action->iso;
874*4882a593Smuzhiyun     if (act->flags & XkbSA_ISODfltIsGroup) {
875*4882a593Smuzhiyun         TryCopyStr(tbuf, "group=", sz);
876*4882a593Smuzhiyun         if (act->flags & XkbSA_GroupAbsolute)
877*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act) + 1);
878*4882a593Smuzhiyun         else if (XkbSAGroup(act) < 0)
879*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act));
880*4882a593Smuzhiyun         else
881*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAGroup(act));
882*4882a593Smuzhiyun         TryCopyStr(buf, tbuf, sz);
883*4882a593Smuzhiyun     }
884*4882a593Smuzhiyun     else {
885*4882a593Smuzhiyun         unsigned tmp;
886*4882a593Smuzhiyun 
887*4882a593Smuzhiyun         tmp = XkbModActionVMods(act);
888*4882a593Smuzhiyun         TryCopyStr(buf, "modifiers=", sz);
889*4882a593Smuzhiyun         if (act->flags & XkbSA_UseModMapMods)
890*4882a593Smuzhiyun             TryCopyStr(buf, "modMapMods", sz);
891*4882a593Smuzhiyun         else if (act->real_mods || tmp) {
892*4882a593Smuzhiyun             if (act->real_mods) {
893*4882a593Smuzhiyun                 TryCopyStr(buf, XkbModMaskText(act->real_mods, XkbXKBFile), sz);
894*4882a593Smuzhiyun                 if (tmp)
895*4882a593Smuzhiyun                     TryCopyStr(buf, "+", sz);
896*4882a593Smuzhiyun             }
897*4882a593Smuzhiyun             if (tmp)
898*4882a593Smuzhiyun                 TryCopyStr(buf, XkbVModMaskText(xkb, 0, tmp, XkbXKBFile), sz);
899*4882a593Smuzhiyun         }
900*4882a593Smuzhiyun         else
901*4882a593Smuzhiyun             TryCopyStr(buf, "none", sz);
902*4882a593Smuzhiyun     }
903*4882a593Smuzhiyun     TryCopyStr(buf, ",affect=", sz);
904*4882a593Smuzhiyun     if ((act->affect & XkbSA_ISOAffectMask) == 0)
905*4882a593Smuzhiyun         TryCopyStr(buf, "all", sz);
906*4882a593Smuzhiyun     else {
907*4882a593Smuzhiyun         int nOut = 0;
908*4882a593Smuzhiyun 
909*4882a593Smuzhiyun         if ((act->affect & XkbSA_ISONoAffectMods) == 0) {
910*4882a593Smuzhiyun             TryCopyStr(buf, "mods", sz);
911*4882a593Smuzhiyun             nOut++;
912*4882a593Smuzhiyun         }
913*4882a593Smuzhiyun         if ((act->affect & XkbSA_ISONoAffectGroup) == 0) {
914*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sgroups", (nOut > 0 ? "+" : ""));
915*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
916*4882a593Smuzhiyun             nOut++;
917*4882a593Smuzhiyun         }
918*4882a593Smuzhiyun         if ((act->affect & XkbSA_ISONoAffectPtr) == 0) {
919*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%spointer", (nOut > 0 ? "+" : ""));
920*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
921*4882a593Smuzhiyun             nOut++;
922*4882a593Smuzhiyun         }
923*4882a593Smuzhiyun         if ((act->affect & XkbSA_ISONoAffectCtrls) == 0) {
924*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%scontrols", (nOut > 0 ? "+" : ""));
925*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
926*4882a593Smuzhiyun             nOut++;
927*4882a593Smuzhiyun         }
928*4882a593Smuzhiyun     }
929*4882a593Smuzhiyun     return TRUE;
930*4882a593Smuzhiyun }
931*4882a593Smuzhiyun 
932*4882a593Smuzhiyun  /*ARGSUSED*/ static Bool
CopySwitchScreenArgs(XkbDescPtr xkb,XkbAction * action,char * buf,int * sz)933*4882a593Smuzhiyun CopySwitchScreenArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
934*4882a593Smuzhiyun {
935*4882a593Smuzhiyun     XkbSwitchScreenAction *act;
936*4882a593Smuzhiyun     char tbuf[32];
937*4882a593Smuzhiyun 
938*4882a593Smuzhiyun     act = &action->screen;
939*4882a593Smuzhiyun     if ((act->flags & XkbSA_SwitchAbsolute) || (XkbSAScreen(act) < 0))
940*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), "screen=%d", XkbSAScreen(act));
941*4882a593Smuzhiyun     else
942*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), "screen=+%d", XkbSAScreen(act));
943*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
944*4882a593Smuzhiyun     if (act->flags & XkbSA_SwitchApplication)
945*4882a593Smuzhiyun         TryCopyStr(buf, ",!same", sz);
946*4882a593Smuzhiyun     else
947*4882a593Smuzhiyun         TryCopyStr(buf, ",same", sz);
948*4882a593Smuzhiyun     return TRUE;
949*4882a593Smuzhiyun }
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun  /*ARGSUSED*/ static Bool
CopySetLockControlsArgs(XkbDescPtr xkb,XkbAction * action,char * buf,int * sz)952*4882a593Smuzhiyun CopySetLockControlsArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
953*4882a593Smuzhiyun {
954*4882a593Smuzhiyun     XkbCtrlsAction *act;
955*4882a593Smuzhiyun     unsigned tmp;
956*4882a593Smuzhiyun     char tbuf[32];
957*4882a593Smuzhiyun 
958*4882a593Smuzhiyun     act = &action->ctrls;
959*4882a593Smuzhiyun     tmp = XkbActionCtrls(act);
960*4882a593Smuzhiyun     TryCopyStr(buf, "controls=", sz);
961*4882a593Smuzhiyun     if (tmp == 0)
962*4882a593Smuzhiyun         TryCopyStr(buf, "none", sz);
963*4882a593Smuzhiyun     else if ((tmp & XkbAllBooleanCtrlsMask) == XkbAllBooleanCtrlsMask)
964*4882a593Smuzhiyun         TryCopyStr(buf, "all", sz);
965*4882a593Smuzhiyun     else {
966*4882a593Smuzhiyun         int nOut = 0;
967*4882a593Smuzhiyun 
968*4882a593Smuzhiyun         if (tmp & XkbRepeatKeysMask) {
969*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sRepeatKeys", (nOut > 0 ? "+" : ""));
970*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
971*4882a593Smuzhiyun             nOut++;
972*4882a593Smuzhiyun         }
973*4882a593Smuzhiyun         if (tmp & XkbSlowKeysMask) {
974*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sSlowKeys", (nOut > 0 ? "+" : ""));
975*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
976*4882a593Smuzhiyun             nOut++;
977*4882a593Smuzhiyun         }
978*4882a593Smuzhiyun         if (tmp & XkbBounceKeysMask) {
979*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sBounceKeys", (nOut > 0 ? "+" : ""));
980*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
981*4882a593Smuzhiyun             nOut++;
982*4882a593Smuzhiyun         }
983*4882a593Smuzhiyun         if (tmp & XkbStickyKeysMask) {
984*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sStickyKeys", (nOut > 0 ? "+" : ""));
985*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
986*4882a593Smuzhiyun             nOut++;
987*4882a593Smuzhiyun         }
988*4882a593Smuzhiyun         if (tmp & XkbMouseKeysMask) {
989*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sMouseKeys", (nOut > 0 ? "+" : ""));
990*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
991*4882a593Smuzhiyun             nOut++;
992*4882a593Smuzhiyun         }
993*4882a593Smuzhiyun         if (tmp & XkbMouseKeysAccelMask) {
994*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sMouseKeysAccel",
995*4882a593Smuzhiyun                      (nOut > 0 ? "+" : ""));
996*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
997*4882a593Smuzhiyun             nOut++;
998*4882a593Smuzhiyun         }
999*4882a593Smuzhiyun         if (tmp & XkbAccessXKeysMask) {
1000*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sAccessXKeys",
1001*4882a593Smuzhiyun                      (nOut > 0 ? "+" : ""));
1002*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
1003*4882a593Smuzhiyun             nOut++;
1004*4882a593Smuzhiyun         }
1005*4882a593Smuzhiyun         if (tmp & XkbAccessXTimeoutMask) {
1006*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sAccessXTimeout",
1007*4882a593Smuzhiyun                      (nOut > 0 ? "+" : ""));
1008*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
1009*4882a593Smuzhiyun             nOut++;
1010*4882a593Smuzhiyun         }
1011*4882a593Smuzhiyun         if (tmp & XkbAccessXFeedbackMask) {
1012*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sAccessXFeedback",
1013*4882a593Smuzhiyun                      (nOut > 0 ? "+" : ""));
1014*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
1015*4882a593Smuzhiyun             nOut++;
1016*4882a593Smuzhiyun         }
1017*4882a593Smuzhiyun         if (tmp & XkbAudibleBellMask) {
1018*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sAudibleBell",
1019*4882a593Smuzhiyun                      (nOut > 0 ? "+" : ""));
1020*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
1021*4882a593Smuzhiyun             nOut++;
1022*4882a593Smuzhiyun         }
1023*4882a593Smuzhiyun         if (tmp & XkbOverlay1Mask) {
1024*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sOverlay1", (nOut > 0 ? "+" : ""));
1025*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
1026*4882a593Smuzhiyun             nOut++;
1027*4882a593Smuzhiyun         }
1028*4882a593Smuzhiyun         if (tmp & XkbOverlay2Mask) {
1029*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sOverlay2", (nOut > 0 ? "+" : ""));
1030*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
1031*4882a593Smuzhiyun             nOut++;
1032*4882a593Smuzhiyun         }
1033*4882a593Smuzhiyun         if (tmp & XkbIgnoreGroupLockMask) {
1034*4882a593Smuzhiyun             snprintf(tbuf, sizeof(tbuf), "%sIgnoreGroupLock",
1035*4882a593Smuzhiyun                      (nOut > 0 ? "+" : ""));
1036*4882a593Smuzhiyun             TryCopyStr(buf, tbuf, sz);
1037*4882a593Smuzhiyun             nOut++;
1038*4882a593Smuzhiyun         }
1039*4882a593Smuzhiyun     }
1040*4882a593Smuzhiyun     return TRUE;
1041*4882a593Smuzhiyun }
1042*4882a593Smuzhiyun 
1043*4882a593Smuzhiyun  /*ARGSUSED*/ static Bool
CopyActionMessageArgs(XkbDescPtr xkb,XkbAction * action,char * buf,int * sz)1044*4882a593Smuzhiyun CopyActionMessageArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
1045*4882a593Smuzhiyun {
1046*4882a593Smuzhiyun     XkbMessageAction *act;
1047*4882a593Smuzhiyun     unsigned all;
1048*4882a593Smuzhiyun     char tbuf[32];
1049*4882a593Smuzhiyun 
1050*4882a593Smuzhiyun     act = &action->msg;
1051*4882a593Smuzhiyun     all = XkbSA_MessageOnPress | XkbSA_MessageOnRelease;
1052*4882a593Smuzhiyun     TryCopyStr(buf, "report=", sz);
1053*4882a593Smuzhiyun     if ((act->flags & all) == 0)
1054*4882a593Smuzhiyun         TryCopyStr(buf, "none", sz);
1055*4882a593Smuzhiyun     else if ((act->flags & all) == all)
1056*4882a593Smuzhiyun         TryCopyStr(buf, "all", sz);
1057*4882a593Smuzhiyun     else if (act->flags & XkbSA_MessageOnPress)
1058*4882a593Smuzhiyun         TryCopyStr(buf, "KeyPress", sz);
1059*4882a593Smuzhiyun     else
1060*4882a593Smuzhiyun         TryCopyStr(buf, "KeyRelease", sz);
1061*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->message[0]);
1062*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1063*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->message[1]);
1064*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1065*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->message[2]);
1066*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1067*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->message[3]);
1068*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1069*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->message[4]);
1070*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1071*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->message[5]);
1072*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1073*4882a593Smuzhiyun     return TRUE;
1074*4882a593Smuzhiyun }
1075*4882a593Smuzhiyun 
1076*4882a593Smuzhiyun static Bool
CopyRedirectKeyArgs(XkbDescPtr xkb,XkbAction * action,char * buf,int * sz)1077*4882a593Smuzhiyun CopyRedirectKeyArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
1078*4882a593Smuzhiyun {
1079*4882a593Smuzhiyun     XkbRedirectKeyAction *act;
1080*4882a593Smuzhiyun     char tbuf[32], *tmp;
1081*4882a593Smuzhiyun     unsigned kc;
1082*4882a593Smuzhiyun     unsigned vmods, vmods_mask;
1083*4882a593Smuzhiyun 
1084*4882a593Smuzhiyun     act = &action->redirect;
1085*4882a593Smuzhiyun     kc = act->new_key;
1086*4882a593Smuzhiyun     vmods = XkbSARedirectVMods(act);
1087*4882a593Smuzhiyun     vmods_mask = XkbSARedirectVModsMask(act);
1088*4882a593Smuzhiyun     if (xkb && xkb->names && xkb->names->keys && (kc <= xkb->max_key_code) &&
1089*4882a593Smuzhiyun         (xkb->names->keys[kc].name[0] != '\0')) {
1090*4882a593Smuzhiyun         char *kn;
1091*4882a593Smuzhiyun 
1092*4882a593Smuzhiyun         kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile);
1093*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), "key=%s", kn);
1094*4882a593Smuzhiyun     }
1095*4882a593Smuzhiyun     else
1096*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), "key=%d", kc);
1097*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1098*4882a593Smuzhiyun     if ((act->mods_mask == 0) && (vmods_mask == 0))
1099*4882a593Smuzhiyun         return TRUE;
1100*4882a593Smuzhiyun     if ((act->mods_mask == XkbAllModifiersMask) &&
1101*4882a593Smuzhiyun         (vmods_mask == XkbAllVirtualModsMask)) {
1102*4882a593Smuzhiyun         tmp = XkbVModMaskText(xkb, act->mods, vmods, XkbXKBFile);
1103*4882a593Smuzhiyun         TryCopyStr(buf, ",mods=", sz);
1104*4882a593Smuzhiyun         TryCopyStr(buf, tmp, sz);
1105*4882a593Smuzhiyun     }
1106*4882a593Smuzhiyun     else {
1107*4882a593Smuzhiyun         if ((act->mods_mask & act->mods) || (vmods_mask & vmods)) {
1108*4882a593Smuzhiyun             tmp = XkbVModMaskText(xkb, act->mods_mask & act->mods,
1109*4882a593Smuzhiyun                                   vmods_mask & vmods, XkbXKBFile);
1110*4882a593Smuzhiyun             TryCopyStr(buf, ",mods= ", sz);
1111*4882a593Smuzhiyun             TryCopyStr(buf, tmp, sz);
1112*4882a593Smuzhiyun         }
1113*4882a593Smuzhiyun         if ((act->mods_mask & (~act->mods)) || (vmods_mask & (~vmods))) {
1114*4882a593Smuzhiyun             tmp = XkbVModMaskText(xkb, act->mods_mask & (~act->mods),
1115*4882a593Smuzhiyun                                   vmods_mask & (~vmods), XkbXKBFile);
1116*4882a593Smuzhiyun             TryCopyStr(buf, ",clearMods= ", sz);
1117*4882a593Smuzhiyun             TryCopyStr(buf, tmp, sz);
1118*4882a593Smuzhiyun         }
1119*4882a593Smuzhiyun     }
1120*4882a593Smuzhiyun     return TRUE;
1121*4882a593Smuzhiyun }
1122*4882a593Smuzhiyun 
1123*4882a593Smuzhiyun  /*ARGSUSED*/ static Bool
CopyDeviceBtnArgs(XkbDescPtr xkb,XkbAction * action,char * buf,int * sz)1124*4882a593Smuzhiyun CopyDeviceBtnArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
1125*4882a593Smuzhiyun {
1126*4882a593Smuzhiyun     XkbDeviceBtnAction *act;
1127*4882a593Smuzhiyun     char tbuf[32];
1128*4882a593Smuzhiyun 
1129*4882a593Smuzhiyun     act = &action->devbtn;
1130*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), "device= %d", act->device);
1131*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1132*4882a593Smuzhiyun     TryCopyStr(buf, ",button=", sz);
1133*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), "%d", act->button);
1134*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1135*4882a593Smuzhiyun     if (act->count > 0) {
1136*4882a593Smuzhiyun         snprintf(tbuf, sizeof(tbuf), ",count=%d", act->count);
1137*4882a593Smuzhiyun         TryCopyStr(buf, tbuf, sz);
1138*4882a593Smuzhiyun     }
1139*4882a593Smuzhiyun     if (action->type == XkbSA_LockDeviceBtn) {
1140*4882a593Smuzhiyun         switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
1141*4882a593Smuzhiyun         case XkbSA_LockNoLock:
1142*4882a593Smuzhiyun             TryCopyStr(buf, ",affect=unlock", sz);
1143*4882a593Smuzhiyun             break;
1144*4882a593Smuzhiyun         case XkbSA_LockNoUnlock:
1145*4882a593Smuzhiyun             TryCopyStr(buf, ",affect=lock", sz);
1146*4882a593Smuzhiyun             break;
1147*4882a593Smuzhiyun         case XkbSA_LockNoUnlock | XkbSA_LockNoLock:
1148*4882a593Smuzhiyun             TryCopyStr(buf, ",affect=neither", sz);
1149*4882a593Smuzhiyun             break;
1150*4882a593Smuzhiyun         default:
1151*4882a593Smuzhiyun             TryCopyStr(buf, ",affect=both", sz);
1152*4882a593Smuzhiyun             break;
1153*4882a593Smuzhiyun         }
1154*4882a593Smuzhiyun     }
1155*4882a593Smuzhiyun     return TRUE;
1156*4882a593Smuzhiyun }
1157*4882a593Smuzhiyun 
1158*4882a593Smuzhiyun  /*ARGSUSED*/ static Bool
CopyOtherArgs(XkbDescPtr xkb,XkbAction * action,char * buf,int * sz)1159*4882a593Smuzhiyun CopyOtherArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
1160*4882a593Smuzhiyun {
1161*4882a593Smuzhiyun     XkbAnyAction *act;
1162*4882a593Smuzhiyun     char tbuf[32];
1163*4882a593Smuzhiyun 
1164*4882a593Smuzhiyun     act = &action->any;
1165*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), "type=0x%02x", act->type);
1166*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1167*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->data[0]);
1168*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1169*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->data[1]);
1170*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1171*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->data[2]);
1172*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1173*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->data[3]);
1174*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1175*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->data[4]);
1176*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1177*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->data[5]);
1178*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1179*4882a593Smuzhiyun     snprintf(tbuf, sizeof(tbuf), ",data[6]=0x%02x", act->data[6]);
1180*4882a593Smuzhiyun     TryCopyStr(buf, tbuf, sz);
1181*4882a593Smuzhiyun     return TRUE;
1182*4882a593Smuzhiyun }
1183*4882a593Smuzhiyun 
1184*4882a593Smuzhiyun typedef Bool (*actionCopy) (XkbDescPtr /* xkb */ ,
1185*4882a593Smuzhiyun                             XkbAction * /* action */ ,
1186*4882a593Smuzhiyun                             char * /* buf */ ,
1187*4882a593Smuzhiyun                             int *       /* sz */
1188*4882a593Smuzhiyun     );
1189*4882a593Smuzhiyun 
1190*4882a593Smuzhiyun static actionCopy copyActionArgs[XkbSA_NumActions] = {
1191*4882a593Smuzhiyun     CopyNoActionArgs /* NoAction     */ ,
1192*4882a593Smuzhiyun     CopyModActionArgs /* SetMods      */ ,
1193*4882a593Smuzhiyun     CopyModActionArgs /* LatchMods    */ ,
1194*4882a593Smuzhiyun     CopyModActionArgs /* LockMods     */ ,
1195*4882a593Smuzhiyun     CopyGroupActionArgs /* SetGroup     */ ,
1196*4882a593Smuzhiyun     CopyGroupActionArgs /* LatchGroup   */ ,
1197*4882a593Smuzhiyun     CopyGroupActionArgs /* LockGroup    */ ,
1198*4882a593Smuzhiyun     CopyMovePtrArgs /* MovePtr      */ ,
1199*4882a593Smuzhiyun     CopyPtrBtnArgs /* PtrBtn       */ ,
1200*4882a593Smuzhiyun     CopyPtrBtnArgs /* LockPtrBtn   */ ,
1201*4882a593Smuzhiyun     CopySetPtrDfltArgs /* SetPtrDflt   */ ,
1202*4882a593Smuzhiyun     CopyISOLockArgs /* ISOLock      */ ,
1203*4882a593Smuzhiyun     CopyNoActionArgs /* Terminate    */ ,
1204*4882a593Smuzhiyun     CopySwitchScreenArgs /* SwitchScreen */ ,
1205*4882a593Smuzhiyun     CopySetLockControlsArgs /* SetControls  */ ,
1206*4882a593Smuzhiyun     CopySetLockControlsArgs /* LockControls */ ,
1207*4882a593Smuzhiyun     CopyActionMessageArgs /* ActionMessage */ ,
1208*4882a593Smuzhiyun     CopyRedirectKeyArgs /* RedirectKey  */ ,
1209*4882a593Smuzhiyun     CopyDeviceBtnArgs /* DeviceBtn    */ ,
1210*4882a593Smuzhiyun     CopyDeviceBtnArgs           /* LockDeviceBtn */
1211*4882a593Smuzhiyun };
1212*4882a593Smuzhiyun 
1213*4882a593Smuzhiyun #define	ACTION_SZ	256
1214*4882a593Smuzhiyun 
1215*4882a593Smuzhiyun char *
XkbActionText(XkbDescPtr xkb,XkbAction * action,unsigned format)1216*4882a593Smuzhiyun XkbActionText(XkbDescPtr xkb, XkbAction *action, unsigned format)
1217*4882a593Smuzhiyun {
1218*4882a593Smuzhiyun     char buf[ACTION_SZ], *tmp;
1219*4882a593Smuzhiyun     int sz;
1220*4882a593Smuzhiyun 
1221*4882a593Smuzhiyun     if (format == XkbCFile) {
1222*4882a593Smuzhiyun         snprintf(buf, sizeof(buf),
1223*4882a593Smuzhiyun                  "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }",
1224*4882a593Smuzhiyun                  XkbActionTypeText(action->type, XkbCFile),
1225*4882a593Smuzhiyun                  action->any.data[0], action->any.data[1], action->any.data[2],
1226*4882a593Smuzhiyun                  action->any.data[3], action->any.data[4], action->any.data[5],
1227*4882a593Smuzhiyun                  action->any.data[6]);
1228*4882a593Smuzhiyun     }
1229*4882a593Smuzhiyun     else {
1230*4882a593Smuzhiyun         snprintf(buf, sizeof(buf), "%s(",
1231*4882a593Smuzhiyun                  XkbActionTypeText(action->type, XkbXKBFile));
1232*4882a593Smuzhiyun         sz = ACTION_SZ - strlen(buf) + 2;       /* room for close paren and NULL */
1233*4882a593Smuzhiyun         if (action->type < (unsigned) XkbSA_NumActions)
1234*4882a593Smuzhiyun             (*copyActionArgs[action->type]) (xkb, action, buf, &sz);
1235*4882a593Smuzhiyun         else
1236*4882a593Smuzhiyun             CopyOtherArgs(xkb, action, buf, &sz);
1237*4882a593Smuzhiyun         TryCopyStr(buf, ")", &sz);
1238*4882a593Smuzhiyun     }
1239*4882a593Smuzhiyun     tmp = tbGetBuffer(strlen(buf) + 1);
1240*4882a593Smuzhiyun     if (tmp != NULL)
1241*4882a593Smuzhiyun         strcpy(tmp, buf);
1242*4882a593Smuzhiyun     return tmp;
1243*4882a593Smuzhiyun }
1244*4882a593Smuzhiyun 
1245*4882a593Smuzhiyun char *
XkbBehaviorText(XkbDescPtr xkb,XkbBehavior * behavior,unsigned format)1246*4882a593Smuzhiyun XkbBehaviorText(XkbDescPtr xkb, XkbBehavior * behavior, unsigned format)
1247*4882a593Smuzhiyun {
1248*4882a593Smuzhiyun     char buf[256], *tmp;
1249*4882a593Smuzhiyun 
1250*4882a593Smuzhiyun     if (format == XkbCFile) {
1251*4882a593Smuzhiyun         if (behavior->type == XkbKB_Default)
1252*4882a593Smuzhiyun             snprintf(buf, sizeof(buf), "{   0,    0 }");
1253*4882a593Smuzhiyun         else
1254*4882a593Smuzhiyun             snprintf(buf, sizeof(buf), "{ %3d, 0x%02x }", behavior->type,
1255*4882a593Smuzhiyun                      behavior->data);
1256*4882a593Smuzhiyun     }
1257*4882a593Smuzhiyun     else {
1258*4882a593Smuzhiyun         unsigned type, permanent;
1259*4882a593Smuzhiyun 
1260*4882a593Smuzhiyun         type = behavior->type & XkbKB_OpMask;
1261*4882a593Smuzhiyun         permanent = ((behavior->type & XkbKB_Permanent) != 0);
1262*4882a593Smuzhiyun 
1263*4882a593Smuzhiyun         if (type == XkbKB_Lock) {
1264*4882a593Smuzhiyun             snprintf(buf, sizeof(buf), "lock= %s",
1265*4882a593Smuzhiyun                      (permanent ? "Permanent" : "TRUE"));
1266*4882a593Smuzhiyun         }
1267*4882a593Smuzhiyun         else if (type == XkbKB_RadioGroup) {
1268*4882a593Smuzhiyun             int g;
1269*4882a593Smuzhiyun 
1270*4882a593Smuzhiyun             g = ((behavior->data) & (~XkbKB_RGAllowNone)) + 1;
1271*4882a593Smuzhiyun             if (XkbKB_RGAllowNone & behavior->data) {
1272*4882a593Smuzhiyun                 snprintf(buf, sizeof(buf), "allowNone,");
1273*4882a593Smuzhiyun                 tmp = &buf[strlen(buf)];
1274*4882a593Smuzhiyun             }
1275*4882a593Smuzhiyun             else
1276*4882a593Smuzhiyun                 tmp = buf;
1277*4882a593Smuzhiyun             if (permanent)
1278*4882a593Smuzhiyun                 sprintf(tmp, "permanentRadioGroup= %d", g);
1279*4882a593Smuzhiyun             else
1280*4882a593Smuzhiyun                 sprintf(tmp, "radioGroup= %d", g);
1281*4882a593Smuzhiyun         }
1282*4882a593Smuzhiyun         else if ((type == XkbKB_Overlay1) || (type == XkbKB_Overlay2)) {
1283*4882a593Smuzhiyun             int ndx, kc;
1284*4882a593Smuzhiyun             char *kn;
1285*4882a593Smuzhiyun 
1286*4882a593Smuzhiyun             ndx = ((type == XkbKB_Overlay1) ? 1 : 2);
1287*4882a593Smuzhiyun             kc = behavior->data;
1288*4882a593Smuzhiyun             if ((xkb) && (xkb->names) && (xkb->names->keys))
1289*4882a593Smuzhiyun                 kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile);
1290*4882a593Smuzhiyun             else {
1291*4882a593Smuzhiyun                 static char tbuf[8];
1292*4882a593Smuzhiyun 
1293*4882a593Smuzhiyun                 snprintf(tbuf, sizeof(tbuf), "%d", kc);
1294*4882a593Smuzhiyun                 kn = tbuf;
1295*4882a593Smuzhiyun             }
1296*4882a593Smuzhiyun             if (permanent)
1297*4882a593Smuzhiyun                 snprintf(buf, sizeof(buf), "permanentOverlay%d= %s", ndx, kn);
1298*4882a593Smuzhiyun             else
1299*4882a593Smuzhiyun                 snprintf(buf, sizeof(buf), "overlay%d= %s", ndx, kn);
1300*4882a593Smuzhiyun         }
1301*4882a593Smuzhiyun     }
1302*4882a593Smuzhiyun     tmp = tbGetBuffer(strlen(buf) + 1);
1303*4882a593Smuzhiyun     if (tmp != NULL)
1304*4882a593Smuzhiyun         strcpy(tmp, buf);
1305*4882a593Smuzhiyun     return tmp;
1306*4882a593Smuzhiyun }
1307*4882a593Smuzhiyun 
1308*4882a593Smuzhiyun /***====================================================================***/
1309*4882a593Smuzhiyun 
1310*4882a593Smuzhiyun char *
XkbIndentText(unsigned size)1311*4882a593Smuzhiyun XkbIndentText(unsigned size)
1312*4882a593Smuzhiyun {
1313*4882a593Smuzhiyun     static char buf[32];
1314*4882a593Smuzhiyun     register int i;
1315*4882a593Smuzhiyun 
1316*4882a593Smuzhiyun     if (size > 31)
1317*4882a593Smuzhiyun         size = 31;
1318*4882a593Smuzhiyun 
1319*4882a593Smuzhiyun     for (i = 0; i < size; i++) {
1320*4882a593Smuzhiyun         buf[i] = ' ';
1321*4882a593Smuzhiyun     }
1322*4882a593Smuzhiyun     buf[size] = '\0';
1323*4882a593Smuzhiyun     return buf;
1324*4882a593Smuzhiyun }
1325