105b261ecSmrg/************************************************************
205b261ecSmrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
305b261ecSmrg
405b261ecSmrg Permission to use, copy, modify, and distribute this
505b261ecSmrg software and its documentation for any purpose and without
605b261ecSmrg fee is hereby granted, provided that the above copyright
705b261ecSmrg notice appear in all copies and that both that copyright
805b261ecSmrg notice and this permission notice appear in supporting
935c4bbdfSmrg documentation, and that the name of Silicon Graphics not be
1035c4bbdfSmrg used in advertising or publicity pertaining to distribution
1105b261ecSmrg of the software without specific prior written permission.
1235c4bbdfSmrg Silicon Graphics makes no representation about the suitability
1305b261ecSmrg of this software for any purpose. It is provided "as is"
1405b261ecSmrg without any express or implied warranty.
1535c4bbdfSmrg
1635c4bbdfSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
1735c4bbdfSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1805b261ecSmrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
1935c4bbdfSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
2035c4bbdfSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2135c4bbdfSmrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2205b261ecSmrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
2305b261ecSmrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
2405b261ecSmrg
2505b261ecSmrg ********************************************************/
2605b261ecSmrg
2705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
2805b261ecSmrg#include <dix-config.h>
2905b261ecSmrg#endif
3005b261ecSmrg
3105b261ecSmrg#include <stdio.h>
3205b261ecSmrg#include <ctype.h>
3305b261ecSmrg#include <stdlib.h>
3405b261ecSmrg
3505b261ecSmrg#include <X11/Xos.h>
3605b261ecSmrg
3705b261ecSmrg#include <X11/X.h>
3805b261ecSmrg#include <X11/Xproto.h>
396747b715Smrg#include <X11/extensions/XKMformat.h>
4005b261ecSmrg#include "misc.h"
4105b261ecSmrg#include "inputstr.h"
4205b261ecSmrg#include "dix.h"
434642e01fSmrg#include "xkbstr.h"
4405b261ecSmrg#define XKBSRV_NEED_FILE_FUNCS	1
4505b261ecSmrg#include <xkbsrv.h>
464642e01fSmrg#include "xkbgeom.h"
4705b261ecSmrg
4805b261ecSmrg/***====================================================================***/
4905b261ecSmrg
501b5d61b8Smrg#define NUM_BUFFER      8
511b5d61b8Smrgstatic struct textBuffer {
521b5d61b8Smrg    int size;
531b5d61b8Smrg    char *buffer;
541b5d61b8Smrg} textBuffer[NUM_BUFFER];
551b5d61b8Smrgstatic int textBufferIndex;
5605b261ecSmrg
5705b261ecSmrgstatic char *
5805b261ecSmrgtbGetBuffer(unsigned size)
5905b261ecSmrg{
601b5d61b8Smrg    struct textBuffer *tb;
6135c4bbdfSmrg
621b5d61b8Smrg    tb = &textBuffer[textBufferIndex];
631b5d61b8Smrg    textBufferIndex = (textBufferIndex + 1) % NUM_BUFFER;
641b5d61b8Smrg
651b5d61b8Smrg    if (size > tb->size) {
661b5d61b8Smrg        free(tb->buffer);
671b5d61b8Smrg        tb->buffer = xnfalloc(size);
681b5d61b8Smrg        tb->size = size;
691b5d61b8Smrg    }
701b5d61b8Smrg    return tb->buffer;
7105b261ecSmrg}
7205b261ecSmrg
7305b261ecSmrg/***====================================================================***/
7405b261ecSmrg
7554b5899cSmrgstatic inline char *
7654b5899cSmrgtbGetBufferString(const char *str)
7754b5899cSmrg{
7854b5899cSmrg    size_t size = strlen(str) + 1;
7954b5899cSmrg    char *rtrn = tbGetBuffer((unsigned) size);
8054b5899cSmrg
8154b5899cSmrg    if (rtrn != NULL)
8254b5899cSmrg        memcpy(rtrn, str, size);
8354b5899cSmrg
8454b5899cSmrg    return rtrn;
8554b5899cSmrg}
8654b5899cSmrg
8754b5899cSmrg/***====================================================================***/
8854b5899cSmrg
8905b261ecSmrgchar *
9035c4bbdfSmrgXkbAtomText(Atom atm, unsigned format)
9105b261ecSmrg{
9235c4bbdfSmrg    const char *atmstr;
9335c4bbdfSmrg    char *rtrn, *tmp;
9405b261ecSmrg
956747b715Smrg    atmstr = NameForAtom(atm);
966747b715Smrg    if (atmstr != NULL) {
9754b5899cSmrg        rtrn = tbGetBufferString(atmstr);
9805b261ecSmrg    }
9905b261ecSmrg    else {
10035c4bbdfSmrg        rtrn = tbGetBuffer(1);
10135c4bbdfSmrg        rtrn[0] = '\0';
10205b261ecSmrg    }
10335c4bbdfSmrg    if (format == XkbCFile) {
10435c4bbdfSmrg        for (tmp = rtrn; *tmp != '\0'; tmp++) {
10535c4bbdfSmrg            if ((tmp == rtrn) && (!isalpha(*tmp)))
10635c4bbdfSmrg                *tmp = '_';
10735c4bbdfSmrg            else if (!isalnum(*tmp))
10835c4bbdfSmrg                *tmp = '_';
10935c4bbdfSmrg        }
11005b261ecSmrg    }
11135c4bbdfSmrg    return XkbStringText(rtrn, format);
11205b261ecSmrg}
11305b261ecSmrg
11405b261ecSmrg/***====================================================================***/
11505b261ecSmrg
11605b261ecSmrgchar *
11735c4bbdfSmrgXkbVModIndexText(XkbDescPtr xkb, unsigned ndx, unsigned format)
11805b261ecSmrg{
11935c4bbdfSmrg    register int len;
12035c4bbdfSmrg    register Atom *vmodNames;
12135c4bbdfSmrg    char *rtrn;
12235c4bbdfSmrg    const char *tmp;
12335c4bbdfSmrg    char numBuf[20];
12405b261ecSmrg
12505b261ecSmrg    if (xkb && xkb->names)
12635c4bbdfSmrg        vmodNames = xkb->names->vmods;
12735c4bbdfSmrg    else
12835c4bbdfSmrg        vmodNames = NULL;
12935c4bbdfSmrg
13035c4bbdfSmrg    tmp = NULL;
13135c4bbdfSmrg    if (ndx >= XkbNumVirtualMods)
13235c4bbdfSmrg        tmp = "illegal";
13335c4bbdfSmrg    else if (vmodNames && (vmodNames[ndx] != None))
13435c4bbdfSmrg        tmp = NameForAtom(vmodNames[ndx]);
13535c4bbdfSmrg    if (tmp == NULL) {
13635c4bbdfSmrg        snprintf(numBuf, sizeof(numBuf), "%d", ndx);
13735c4bbdfSmrg        tmp = numBuf;
1386747b715Smrg    }
13905b261ecSmrg
14035c4bbdfSmrg    len = strlen(tmp) + 1;
14135c4bbdfSmrg    if (format == XkbCFile)
14235c4bbdfSmrg        len += 4;
14335c4bbdfSmrg    rtrn = tbGetBuffer(len);
14435c4bbdfSmrg    if (format == XkbCFile) {
14535c4bbdfSmrg        strcpy(rtrn, "vmod_");
14635c4bbdfSmrg        strncpy(&rtrn[5], tmp, len - 4);
14705b261ecSmrg    }
14835c4bbdfSmrg    else
14935c4bbdfSmrg        strncpy(rtrn, tmp, len);
15005b261ecSmrg    return rtrn;
15105b261ecSmrg}
15205b261ecSmrg
1531b5d61b8Smrg#define VMOD_BUFFER_SIZE        512
1541b5d61b8Smrg
15505b261ecSmrgchar *
15635c4bbdfSmrgXkbVModMaskText(XkbDescPtr xkb,
15735c4bbdfSmrg                unsigned modMask, unsigned mask, unsigned format)
15805b261ecSmrg{
15935c4bbdfSmrg    register int i, bit;
16035c4bbdfSmrg    int len;
16135c4bbdfSmrg    char *mm, *rtrn;
1621b5d61b8Smrg    char *str, buf[VMOD_BUFFER_SIZE];
16335c4bbdfSmrg
16435c4bbdfSmrg    if ((modMask == 0) && (mask == 0)) {
16554b5899cSmrg        const int rtrnsize = 5;
16654b5899cSmrg        rtrn = tbGetBuffer(rtrnsize);
16735c4bbdfSmrg        if (format == XkbCFile)
16854b5899cSmrg            snprintf(rtrn, rtrnsize, "0");
16935c4bbdfSmrg        else
17054b5899cSmrg            snprintf(rtrn, rtrnsize, "none");
17135c4bbdfSmrg        return rtrn;
17205b261ecSmrg    }
17335c4bbdfSmrg    if (modMask != 0)
17435c4bbdfSmrg        mm = XkbModMaskText(modMask, format);
17535c4bbdfSmrg    else
17635c4bbdfSmrg        mm = NULL;
17705b261ecSmrg
17835c4bbdfSmrg    str = buf;
17935c4bbdfSmrg    buf[0] = '\0';
18005b261ecSmrg    if (mask) {
18135c4bbdfSmrg        char *tmp;
18235c4bbdfSmrg
18335c4bbdfSmrg        for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
18435c4bbdfSmrg            if (mask & bit) {
18535c4bbdfSmrg                tmp = XkbVModIndexText(xkb, i, format);
18635c4bbdfSmrg                len = strlen(tmp) + 1 + (str == buf ? 0 : 1);
18735c4bbdfSmrg                if (format == XkbCFile)
18835c4bbdfSmrg                    len += 4;
189f2346221Smrg                if ((str - buf) + len > VMOD_BUFFER_SIZE)
190f2346221Smrg                    continue; /* Skip */
191f2346221Smrg                if (str != buf) {
192f2346221Smrg                    if (format == XkbCFile)
193f2346221Smrg                        *str++ = '|';
194f2346221Smrg                    else
195f2346221Smrg                        *str++ = '+';
196f2346221Smrg                    len--;
19735c4bbdfSmrg                }
19835c4bbdfSmrg                if (format == XkbCFile)
19935c4bbdfSmrg                    sprintf(str, "%sMask", tmp);
20035c4bbdfSmrg                else
20135c4bbdfSmrg                    strcpy(str, tmp);
20235c4bbdfSmrg                str = &str[len - 1];
20335c4bbdfSmrg            }
20435c4bbdfSmrg        }
20535c4bbdfSmrg        str = buf;
20605b261ecSmrg    }
20735c4bbdfSmrg    else
20835c4bbdfSmrg        str = NULL;
20935c4bbdfSmrg    if (mm)
21035c4bbdfSmrg        len = strlen(mm);
21135c4bbdfSmrg    else
21235c4bbdfSmrg        len = 0;
21305b261ecSmrg    if (str)
21435c4bbdfSmrg        len += strlen(str) + (mm == NULL ? 0 : 1);
21535c4bbdfSmrg    rtrn = tbGetBuffer(len + 1);
21635c4bbdfSmrg    rtrn[0] = '\0';
21735c4bbdfSmrg
21835c4bbdfSmrg    if (mm != NULL) {
21935c4bbdfSmrg        i = strlen(mm);
22035c4bbdfSmrg        if (i > len)
22135c4bbdfSmrg            i = len;
22235c4bbdfSmrg        strcpy(rtrn, mm);
22305b261ecSmrg    }
22405b261ecSmrg    else {
22535c4bbdfSmrg        i = 0;
22605b261ecSmrg    }
22735c4bbdfSmrg    if (str != NULL) {
22835c4bbdfSmrg        if (mm != NULL) {
22935c4bbdfSmrg            if (format == XkbCFile)
23035c4bbdfSmrg                strcat(rtrn, "|");
23135c4bbdfSmrg            else
23235c4bbdfSmrg                strcat(rtrn, "+");
23335c4bbdfSmrg        }
23435c4bbdfSmrg        strncat(rtrn, str, len - i);
23505b261ecSmrg    }
23635c4bbdfSmrg    rtrn[len] = '\0';
23705b261ecSmrg    return rtrn;
23805b261ecSmrg}
23905b261ecSmrg
24035c4bbdfSmrgstatic const char *modNames[XkbNumModifiers] = {
24105b261ecSmrg    "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5"
24205b261ecSmrg};
24305b261ecSmrg
24405b261ecSmrgchar *
24535c4bbdfSmrgXkbModIndexText(unsigned ndx, unsigned format)
24605b261ecSmrg{
24735c4bbdfSmrg    char buf[100];
24835c4bbdfSmrg
24935c4bbdfSmrg    if (format == XkbCFile) {
25035c4bbdfSmrg        if (ndx < XkbNumModifiers)
25135c4bbdfSmrg            snprintf(buf, sizeof(buf), "%sMapIndex", modNames[ndx]);
25235c4bbdfSmrg        else if (ndx == XkbNoModifier)
25335c4bbdfSmrg            snprintf(buf, sizeof(buf), "XkbNoModifier");
25435c4bbdfSmrg        else
25535c4bbdfSmrg            snprintf(buf, sizeof(buf), "0x%02x", ndx);
25605b261ecSmrg    }
25705b261ecSmrg    else {
25835c4bbdfSmrg        if (ndx < XkbNumModifiers)
25935c4bbdfSmrg            strcpy(buf, modNames[ndx]);
26035c4bbdfSmrg        else if (ndx == XkbNoModifier)
26135c4bbdfSmrg            strcpy(buf, "none");
26235c4bbdfSmrg        else
26335c4bbdfSmrg            snprintf(buf, sizeof(buf), "ILLEGAL_%02x", ndx);
26405b261ecSmrg    }
26554b5899cSmrg    return tbGetBufferString(buf);
26605b261ecSmrg}
26705b261ecSmrg
26805b261ecSmrgchar *
26935c4bbdfSmrgXkbModMaskText(unsigned mask, unsigned format)
27005b261ecSmrg{
27135c4bbdfSmrg    register int i, bit;
27235c4bbdfSmrg    char buf[64], *rtrn;
27335c4bbdfSmrg
27435c4bbdfSmrg    if ((mask & 0xff) == 0xff) {
27535c4bbdfSmrg        if (format == XkbCFile)
27635c4bbdfSmrg            strcpy(buf, "0xff");
27735c4bbdfSmrg        else
27835c4bbdfSmrg            strcpy(buf, "all");
27905b261ecSmrg    }
28035c4bbdfSmrg    else if ((mask & 0xff) == 0) {
28135c4bbdfSmrg        if (format == XkbCFile)
28235c4bbdfSmrg            strcpy(buf, "0");
28335c4bbdfSmrg        else
28435c4bbdfSmrg            strcpy(buf, "none");
28505b261ecSmrg    }
28605b261ecSmrg    else {
28735c4bbdfSmrg        char *str = buf;
28835c4bbdfSmrg
28935c4bbdfSmrg        buf[0] = '\0';
29035c4bbdfSmrg        for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) {
29135c4bbdfSmrg            if (mask & bit) {
29235c4bbdfSmrg                if (str != buf) {
29335c4bbdfSmrg                    if (format == XkbCFile)
29435c4bbdfSmrg                        *str++ = '|';
29535c4bbdfSmrg                    else
29635c4bbdfSmrg                        *str++ = '+';
29735c4bbdfSmrg                }
29835c4bbdfSmrg                strcpy(str, modNames[i]);
29935c4bbdfSmrg                str = &str[strlen(str)];
30035c4bbdfSmrg                if (format == XkbCFile) {
30135c4bbdfSmrg                    strcpy(str, "Mask");
30235c4bbdfSmrg                    str += 4;
30335c4bbdfSmrg                }
30435c4bbdfSmrg            }
30535c4bbdfSmrg        }
30605b261ecSmrg    }
30754b5899cSmrg    rtrn = tbGetBufferString(buf);
30805b261ecSmrg    return rtrn;
30905b261ecSmrg}
31005b261ecSmrg
31105b261ecSmrg/***====================================================================***/
31205b261ecSmrg
31335c4bbdfSmrg /*ARGSUSED*/ char *
31435c4bbdfSmrgXkbConfigText(unsigned config, unsigned format)
31505b261ecSmrg{
31635c4bbdfSmrg    static char *buf;
31754b5899cSmrg    const int bufsize = 32;
31805b261ecSmrg
31954b5899cSmrg    buf = tbGetBuffer(bufsize);
32005b261ecSmrg    switch (config) {
32135c4bbdfSmrg    case XkmSemanticsFile:
32235c4bbdfSmrg        strcpy(buf, "Semantics");
32335c4bbdfSmrg        break;
32435c4bbdfSmrg    case XkmLayoutFile:
32535c4bbdfSmrg        strcpy(buf, "Layout");
32635c4bbdfSmrg        break;
32735c4bbdfSmrg    case XkmKeymapFile:
32835c4bbdfSmrg        strcpy(buf, "Keymap");
32935c4bbdfSmrg        break;
33035c4bbdfSmrg    case XkmGeometryFile:
33135c4bbdfSmrg    case XkmGeometryIndex:
33235c4bbdfSmrg        strcpy(buf, "Geometry");
33335c4bbdfSmrg        break;
33435c4bbdfSmrg    case XkmTypesIndex:
33535c4bbdfSmrg        strcpy(buf, "Types");
33635c4bbdfSmrg        break;
33735c4bbdfSmrg    case XkmCompatMapIndex:
33835c4bbdfSmrg        strcpy(buf, "CompatMap");
33935c4bbdfSmrg        break;
34035c4bbdfSmrg    case XkmSymbolsIndex:
34135c4bbdfSmrg        strcpy(buf, "Symbols");
34235c4bbdfSmrg        break;
34335c4bbdfSmrg    case XkmIndicatorsIndex:
34435c4bbdfSmrg        strcpy(buf, "Indicators");
34535c4bbdfSmrg        break;
34635c4bbdfSmrg    case XkmKeyNamesIndex:
34735c4bbdfSmrg        strcpy(buf, "KeyNames");
34835c4bbdfSmrg        break;
34935c4bbdfSmrg    case XkmVirtualModsIndex:
35035c4bbdfSmrg        strcpy(buf, "VirtualMods");
35135c4bbdfSmrg        break;
35235c4bbdfSmrg    default:
35354b5899cSmrg        snprintf(buf, bufsize, "unknown(%d)", config);
35435c4bbdfSmrg        break;
35505b261ecSmrg    }
35605b261ecSmrg    return buf;
35705b261ecSmrg}
35805b261ecSmrg
35905b261ecSmrg/***====================================================================***/
36005b261ecSmrg
36105b261ecSmrgchar *
36235c4bbdfSmrgXkbKeysymText(KeySym sym, unsigned format)
36305b261ecSmrg{
36435c4bbdfSmrg    static char buf[32];
36505b261ecSmrg
36635c4bbdfSmrg    if (sym == NoSymbol)
36735c4bbdfSmrg        strcpy(buf, "NoSymbol");
36835c4bbdfSmrg    else
36935c4bbdfSmrg        snprintf(buf, sizeof(buf), "0x%lx", (long) sym);
37035c4bbdfSmrg    return buf;
37105b261ecSmrg}
37205b261ecSmrg
37305b261ecSmrgchar *
37435c4bbdfSmrgXkbKeyNameText(char *name, unsigned format)
37505b261ecSmrg{
37635c4bbdfSmrg    char *buf;
37705b261ecSmrg
37835c4bbdfSmrg    if (format == XkbCFile) {
37935c4bbdfSmrg        buf = tbGetBuffer(5);
38035c4bbdfSmrg        memcpy(buf, name, 4);
38135c4bbdfSmrg        buf[4] = '\0';
38205b261ecSmrg    }
38305b261ecSmrg    else {
38435c4bbdfSmrg        int len;
38535c4bbdfSmrg
38635c4bbdfSmrg        buf = tbGetBuffer(7);
38735c4bbdfSmrg        buf[0] = '<';
38835c4bbdfSmrg        memcpy(&buf[1], name, 4);
38935c4bbdfSmrg        buf[5] = '\0';
39035c4bbdfSmrg        len = strlen(buf);
39135c4bbdfSmrg        buf[len++] = '>';
39235c4bbdfSmrg        buf[len] = '\0';
39305b261ecSmrg    }
39405b261ecSmrg    return buf;
39505b261ecSmrg}
39605b261ecSmrg
39705b261ecSmrg/***====================================================================***/
39805b261ecSmrg
39935c4bbdfSmrgstatic const char *siMatchText[5] = {
40035c4bbdfSmrg    "NoneOf", "AnyOfOrNone", "AnyOf", "AllOf", "Exactly"
40105b261ecSmrg};
40205b261ecSmrg
40335c4bbdfSmrgconst char *
40435c4bbdfSmrgXkbSIMatchText(unsigned type, unsigned format)
40505b261ecSmrg{
40635c4bbdfSmrg    static char buf[40];
40735c4bbdfSmrg    const char *rtrn;
40835c4bbdfSmrg
40935c4bbdfSmrg    switch (type & XkbSI_OpMask) {
41035c4bbdfSmrg    case XkbSI_NoneOf:
41135c4bbdfSmrg        rtrn = siMatchText[0];
41235c4bbdfSmrg        break;
41335c4bbdfSmrg    case XkbSI_AnyOfOrNone:
41435c4bbdfSmrg        rtrn = siMatchText[1];
41535c4bbdfSmrg        break;
41635c4bbdfSmrg    case XkbSI_AnyOf:
41735c4bbdfSmrg        rtrn = siMatchText[2];
41835c4bbdfSmrg        break;
41935c4bbdfSmrg    case XkbSI_AllOf:
42035c4bbdfSmrg        rtrn = siMatchText[3];
42135c4bbdfSmrg        break;
42235c4bbdfSmrg    case XkbSI_Exactly:
42335c4bbdfSmrg        rtrn = siMatchText[4];
42435c4bbdfSmrg        break;
42535c4bbdfSmrg    default:
42635c4bbdfSmrg        snprintf(buf, sizeof(buf), "0x%x", type & XkbSI_OpMask);
42735c4bbdfSmrg        return buf;
42805b261ecSmrg    }
42935c4bbdfSmrg    if (format == XkbCFile) {
43035c4bbdfSmrg        if (type & XkbSI_LevelOneOnly)
43135c4bbdfSmrg            snprintf(buf, sizeof(buf), "XkbSI_LevelOneOnly|XkbSI_%s", rtrn);
43235c4bbdfSmrg        else
43335c4bbdfSmrg            snprintf(buf, sizeof(buf), "XkbSI_%s", rtrn);
43435c4bbdfSmrg        rtrn = buf;
43505b261ecSmrg    }
43605b261ecSmrg    return rtrn;
43705b261ecSmrg}
43805b261ecSmrg
43905b261ecSmrg/***====================================================================***/
44005b261ecSmrg
44135c4bbdfSmrgstatic const char *imWhichNames[] = {
44235c4bbdfSmrg    "base",
44335c4bbdfSmrg    "latched",
44435c4bbdfSmrg    "locked",
44535c4bbdfSmrg    "effective",
44635c4bbdfSmrg    "compat"
44705b261ecSmrg};
44805b261ecSmrg
44905b261ecSmrgchar *
45035c4bbdfSmrgXkbIMWhichStateMaskText(unsigned use_which, unsigned format)
45105b261ecSmrg{
45254b5899cSmrg    int len, bufsize;
45335c4bbdfSmrg    unsigned i, bit, tmp;
45435c4bbdfSmrg    char *buf;
45535c4bbdfSmrg
45635c4bbdfSmrg    if (use_which == 0) {
45735c4bbdfSmrg        buf = tbGetBuffer(2);
45835c4bbdfSmrg        strcpy(buf, "0");
45935c4bbdfSmrg        return buf;
46005b261ecSmrg    }
46135c4bbdfSmrg    tmp = use_which & XkbIM_UseAnyMods;
46235c4bbdfSmrg    for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
46335c4bbdfSmrg        if (tmp & bit) {
46435c4bbdfSmrg            tmp &= ~bit;
46535c4bbdfSmrg            len += strlen(imWhichNames[i]) + 1;
46635c4bbdfSmrg            if (format == XkbCFile)
46735c4bbdfSmrg                len += 9;
46835c4bbdfSmrg        }
46905b261ecSmrg    }
47054b5899cSmrg    bufsize = len + 1;
47154b5899cSmrg    buf = tbGetBuffer(bufsize);
47235c4bbdfSmrg    tmp = use_which & XkbIM_UseAnyMods;
47335c4bbdfSmrg    for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
47435c4bbdfSmrg        if (tmp & bit) {
47535c4bbdfSmrg            tmp &= ~bit;
47635c4bbdfSmrg            if (format == XkbCFile) {
47735c4bbdfSmrg                if (len != 0)
47835c4bbdfSmrg                    buf[len++] = '|';
47954b5899cSmrg                snprintf(&buf[len], bufsize - len,
48054b5899cSmrg                         "XkbIM_Use%s", imWhichNames[i]);
48154b5899cSmrg                buf[len + 9] = toupper((unsigned char)buf[len + 9]);
48235c4bbdfSmrg            }
48335c4bbdfSmrg            else {
48435c4bbdfSmrg                if (len != 0)
48535c4bbdfSmrg                    buf[len++] = '+';
48654b5899cSmrg                snprintf(&buf[len], bufsize - len, "%s", imWhichNames[i]);
48735c4bbdfSmrg            }
48835c4bbdfSmrg            len += strlen(&buf[len]);
48935c4bbdfSmrg        }
49005b261ecSmrg    }
49105b261ecSmrg    return buf;
49205b261ecSmrg}
49305b261ecSmrg
49435c4bbdfSmrgstatic const char *ctrlNames[] = {
49535c4bbdfSmrg    "repeatKeys",
49635c4bbdfSmrg    "slowKeys",
49735c4bbdfSmrg    "bounceKeys",
49835c4bbdfSmrg    "stickyKeys",
49935c4bbdfSmrg    "mouseKeys",
50035c4bbdfSmrg    "mouseKeysAccel",
50135c4bbdfSmrg    "accessXKeys",
50235c4bbdfSmrg    "accessXTimeout",
50335c4bbdfSmrg    "accessXFeedback",
50435c4bbdfSmrg    "audibleBell",
50535c4bbdfSmrg    "overlay1",
50635c4bbdfSmrg    "overlay2",
50735c4bbdfSmrg    "ignoreGroupLock"
50805b261ecSmrg};
50905b261ecSmrg
51005b261ecSmrgchar *
51135c4bbdfSmrgXkbControlsMaskText(unsigned ctrls, unsigned format)
51205b261ecSmrg{
51335c4bbdfSmrg    int len;
51435c4bbdfSmrg    unsigned i, bit, tmp;
51535c4bbdfSmrg    char *buf;
51635c4bbdfSmrg
51735c4bbdfSmrg    if (ctrls == 0) {
51835c4bbdfSmrg        buf = tbGetBuffer(5);
51935c4bbdfSmrg        if (format == XkbCFile)
52035c4bbdfSmrg            strcpy(buf, "0");
52135c4bbdfSmrg        else
52235c4bbdfSmrg            strcpy(buf, "none");
52335c4bbdfSmrg        return buf;
52405b261ecSmrg    }
52535c4bbdfSmrg    tmp = ctrls & XkbAllBooleanCtrlsMask;
52635c4bbdfSmrg    for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
52735c4bbdfSmrg        if (tmp & bit) {
52835c4bbdfSmrg            tmp &= ~bit;
52935c4bbdfSmrg            len += strlen(ctrlNames[i]) + 1;
53035c4bbdfSmrg            if (format == XkbCFile)
53135c4bbdfSmrg                len += 7;
53235c4bbdfSmrg        }
53305b261ecSmrg    }
53435c4bbdfSmrg    buf = tbGetBuffer(len + 1);
53535c4bbdfSmrg    tmp = ctrls & XkbAllBooleanCtrlsMask;
53635c4bbdfSmrg    for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
53735c4bbdfSmrg        if (tmp & bit) {
53835c4bbdfSmrg            tmp &= ~bit;
53935c4bbdfSmrg            if (format == XkbCFile) {
54035c4bbdfSmrg                if (len != 0)
54135c4bbdfSmrg                    buf[len++] = '|';
54235c4bbdfSmrg                sprintf(&buf[len], "Xkb%sMask", ctrlNames[i]);
54335c4bbdfSmrg                buf[len + 3] = toupper(buf[len + 3]);
54435c4bbdfSmrg            }
54535c4bbdfSmrg            else {
54635c4bbdfSmrg                if (len != 0)
54735c4bbdfSmrg                    buf[len++] = '+';
54835c4bbdfSmrg                sprintf(&buf[len], "%s", ctrlNames[i]);
54935c4bbdfSmrg            }
55035c4bbdfSmrg            len += strlen(&buf[len]);
55135c4bbdfSmrg        }
55205b261ecSmrg    }
55305b261ecSmrg    return buf;
55405b261ecSmrg}
55505b261ecSmrg
55605b261ecSmrg/***====================================================================***/
55705b261ecSmrg
55805b261ecSmrgchar *
55935c4bbdfSmrgXkbStringText(char *str, unsigned format)
56005b261ecSmrg{
56135c4bbdfSmrg    char *buf;
56235c4bbdfSmrg    register char *in, *out;
56335c4bbdfSmrg    int len;
56435c4bbdfSmrg    Bool ok;
56535c4bbdfSmrg
56635c4bbdfSmrg    if (str == NULL) {
56735c4bbdfSmrg        buf = tbGetBuffer(2);
56835c4bbdfSmrg        buf[0] = '\0';
56935c4bbdfSmrg        return buf;
57005b261ecSmrg    }
57135c4bbdfSmrg    else if (format == XkbXKMFile)
57235c4bbdfSmrg        return str;
57335c4bbdfSmrg    for (ok = TRUE, len = 0, in = str; *in != '\0'; in++, len++) {
57435c4bbdfSmrg        if (!isprint(*in)) {
57535c4bbdfSmrg            ok = FALSE;
57635c4bbdfSmrg            switch (*in) {
57735c4bbdfSmrg            case '\n':
57835c4bbdfSmrg            case '\t':
57935c4bbdfSmrg            case '\v':
58035c4bbdfSmrg            case '\b':
58135c4bbdfSmrg            case '\r':
58235c4bbdfSmrg            case '\f':
58335c4bbdfSmrg                len++;
58435c4bbdfSmrg                break;
58535c4bbdfSmrg            default:
58635c4bbdfSmrg                len += 4;
58735c4bbdfSmrg                break;
58835c4bbdfSmrg            }
58935c4bbdfSmrg        }
59005b261ecSmrg    }
59105b261ecSmrg    if (ok)
59235c4bbdfSmrg        return str;
59335c4bbdfSmrg    buf = tbGetBuffer(len + 1);
59435c4bbdfSmrg    for (in = str, out = buf; *in != '\0'; in++) {
59535c4bbdfSmrg        if (isprint(*in))
59635c4bbdfSmrg            *out++ = *in;
59735c4bbdfSmrg        else {
59835c4bbdfSmrg            *out++ = '\\';
59935c4bbdfSmrg            if (*in == '\n')
60035c4bbdfSmrg                *out++ = 'n';
60135c4bbdfSmrg            else if (*in == '\t')
60235c4bbdfSmrg                *out++ = 't';
60335c4bbdfSmrg            else if (*in == '\v')
60435c4bbdfSmrg                *out++ = 'v';
60535c4bbdfSmrg            else if (*in == '\b')
60635c4bbdfSmrg                *out++ = 'b';
60735c4bbdfSmrg            else if (*in == '\r')
60835c4bbdfSmrg                *out++ = 'r';
60935c4bbdfSmrg            else if (*in == '\f')
61035c4bbdfSmrg                *out++ = 'f';
61135c4bbdfSmrg            else if ((*in == '\033') && (format == XkbXKMFile)) {
61235c4bbdfSmrg                *out++ = 'e';
61335c4bbdfSmrg            }
61435c4bbdfSmrg            else {
61535c4bbdfSmrg                *out++ = '0';
6161b5d61b8Smrg                sprintf(out, "%o", (unsigned char) *in);
61735c4bbdfSmrg                while (*out != '\0')
61835c4bbdfSmrg                    out++;
61935c4bbdfSmrg            }
62035c4bbdfSmrg        }
62105b261ecSmrg    }
62235c4bbdfSmrg    *out++ = '\0';
62305b261ecSmrg    return buf;
62405b261ecSmrg}
62505b261ecSmrg
62605b261ecSmrg/***====================================================================***/
62705b261ecSmrg
62805b261ecSmrgchar *
62935c4bbdfSmrgXkbGeomFPText(int val, unsigned format)
63005b261ecSmrg{
63135c4bbdfSmrg    int whole, frac;
63235c4bbdfSmrg    char *buf;
63354b5899cSmrg    const int bufsize = 13;
63405b261ecSmrg
63554b5899cSmrg    buf = tbGetBuffer(bufsize);
63635c4bbdfSmrg    if (format == XkbCFile) {
63754b5899cSmrg        snprintf(buf, bufsize, "%d", val);
63805b261ecSmrg    }
63905b261ecSmrg    else {
64035c4bbdfSmrg        whole = val / XkbGeomPtsPerMM;
64154b5899cSmrg        frac = abs(val % XkbGeomPtsPerMM);
64254b5899cSmrg        if (frac != 0) {
64354b5899cSmrg            if (val < 0)
64454b5899cSmrg            {
64554b5899cSmrg                int wholeabs;
64654b5899cSmrg                wholeabs = abs(whole);
64754b5899cSmrg                snprintf(buf, bufsize, "-%d.%d", wholeabs, frac);
64854b5899cSmrg            }
64954b5899cSmrg            else
65054b5899cSmrg                snprintf(buf, bufsize, "%d.%d", whole, frac);
65154b5899cSmrg        }
65235c4bbdfSmrg        else
65354b5899cSmrg            snprintf(buf, bufsize, "%d", whole);
65405b261ecSmrg    }
65505b261ecSmrg    return buf;
65605b261ecSmrg}
65705b261ecSmrg
65805b261ecSmrgchar *
65935c4bbdfSmrgXkbDoodadTypeText(unsigned type, unsigned format)
66005b261ecSmrg{
66135c4bbdfSmrg    char *buf;
66235c4bbdfSmrg
66335c4bbdfSmrg    if (format == XkbCFile) {
66454b5899cSmrg        const int bufsize = 24;
66554b5899cSmrg        buf = tbGetBuffer(bufsize);
66635c4bbdfSmrg        if (type == XkbOutlineDoodad)
66735c4bbdfSmrg            strcpy(buf, "XkbOutlineDoodad");
66835c4bbdfSmrg        else if (type == XkbSolidDoodad)
66935c4bbdfSmrg            strcpy(buf, "XkbSolidDoodad");
67035c4bbdfSmrg        else if (type == XkbTextDoodad)
67135c4bbdfSmrg            strcpy(buf, "XkbTextDoodad");
67235c4bbdfSmrg        else if (type == XkbIndicatorDoodad)
67335c4bbdfSmrg            strcpy(buf, "XkbIndicatorDoodad");
67435c4bbdfSmrg        else if (type == XkbLogoDoodad)
67535c4bbdfSmrg            strcpy(buf, "XkbLogoDoodad");
67635c4bbdfSmrg        else
67754b5899cSmrg            snprintf(buf, bufsize, "UnknownDoodad%d", type);
67805b261ecSmrg    }
67905b261ecSmrg    else {
68054b5899cSmrg        const int bufsize = 12;
68154b5899cSmrg        buf = tbGetBuffer(bufsize);
68235c4bbdfSmrg        if (type == XkbOutlineDoodad)
68335c4bbdfSmrg            strcpy(buf, "outline");
68435c4bbdfSmrg        else if (type == XkbSolidDoodad)
68535c4bbdfSmrg            strcpy(buf, "solid");
68635c4bbdfSmrg        else if (type == XkbTextDoodad)
68735c4bbdfSmrg            strcpy(buf, "text");
68835c4bbdfSmrg        else if (type == XkbIndicatorDoodad)
68935c4bbdfSmrg            strcpy(buf, "indicator");
69035c4bbdfSmrg        else if (type == XkbLogoDoodad)
69135c4bbdfSmrg            strcpy(buf, "logo");
69235c4bbdfSmrg        else
69354b5899cSmrg            snprintf(buf, bufsize, "unknown%d", type);
69405b261ecSmrg    }
69505b261ecSmrg    return buf;
69605b261ecSmrg}
69705b261ecSmrg
69835c4bbdfSmrgstatic const char *actionTypeNames[XkbSA_NumActions] = {
69935c4bbdfSmrg    "NoAction",
70035c4bbdfSmrg    "SetMods", "LatchMods", "LockMods",
70135c4bbdfSmrg    "SetGroup", "LatchGroup", "LockGroup",
70205b261ecSmrg    "MovePtr",
70335c4bbdfSmrg    "PtrBtn", "LockPtrBtn",
70405b261ecSmrg    "SetPtrDflt",
70505b261ecSmrg    "ISOLock",
70635c4bbdfSmrg    "Terminate", "SwitchScreen",
70735c4bbdfSmrg    "SetControls", "LockControls",
70805b261ecSmrg    "ActionMessage",
70905b261ecSmrg    "RedirectKey",
71035c4bbdfSmrg    "DeviceBtn", "LockDeviceBtn"
71105b261ecSmrg};
71205b261ecSmrg
71335c4bbdfSmrgconst char *
71435c4bbdfSmrgXkbActionTypeText(unsigned type, unsigned format)
71505b261ecSmrg{
71635c4bbdfSmrg    static char buf[32];
71735c4bbdfSmrg    const char *rtrn;
71835c4bbdfSmrg
71935c4bbdfSmrg    if (type <= XkbSA_LastAction) {
72035c4bbdfSmrg        rtrn = actionTypeNames[type];
72135c4bbdfSmrg        if (format == XkbCFile) {
72235c4bbdfSmrg            snprintf(buf, sizeof(buf), "XkbSA_%s", rtrn);
72335c4bbdfSmrg            return buf;
72435c4bbdfSmrg        }
72535c4bbdfSmrg        return rtrn;
72605b261ecSmrg    }
72735c4bbdfSmrg    snprintf(buf, sizeof(buf), "Private");
72805b261ecSmrg    return buf;
72905b261ecSmrg}
73005b261ecSmrg
73105b261ecSmrg/***====================================================================***/
73205b261ecSmrg
73305b261ecSmrgstatic int
73435c4bbdfSmrgTryCopyStr(char *to, const char *from, int *pLeft)
73505b261ecSmrg{
73635c4bbdfSmrg    register int len;
73735c4bbdfSmrg
73835c4bbdfSmrg    if (*pLeft > 0) {
73935c4bbdfSmrg        len = strlen(from);
74035c4bbdfSmrg        if (len < ((*pLeft) - 3)) {
74135c4bbdfSmrg            strcat(to, from);
74235c4bbdfSmrg            *pLeft -= len;
74335c4bbdfSmrg            return TRUE;
74435c4bbdfSmrg        }
74505b261ecSmrg    }
74635c4bbdfSmrg    *pLeft = -1;
7476747b715Smrg    return FALSE;
74805b261ecSmrg}
74905b261ecSmrg
75035c4bbdfSmrg /*ARGSUSED*/ static Bool
75135c4bbdfSmrgCopyNoActionArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
75205b261ecSmrg{
7536747b715Smrg    return TRUE;
75405b261ecSmrg}
75505b261ecSmrg
75605b261ecSmrgstatic Bool
75735c4bbdfSmrgCopyModActionArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
75805b261ecSmrg{
75935c4bbdfSmrg    XkbModAction *act;
76035c4bbdfSmrg    unsigned tmp;
76135c4bbdfSmrg
76235c4bbdfSmrg    act = &action->mods;
76335c4bbdfSmrg    tmp = XkbModActionVMods(act);
76435c4bbdfSmrg    TryCopyStr(buf, "modifiers=", sz);
76535c4bbdfSmrg    if (act->flags & XkbSA_UseModMapMods)
76635c4bbdfSmrg        TryCopyStr(buf, "modMapMods", sz);
76705b261ecSmrg    else if (act->real_mods || tmp) {
76835c4bbdfSmrg        TryCopyStr(buf,
76935c4bbdfSmrg                   XkbVModMaskText(xkb, act->real_mods, tmp, XkbXKBFile), sz);
77005b261ecSmrg    }
77135c4bbdfSmrg    else
77235c4bbdfSmrg        TryCopyStr(buf, "none", sz);
77335c4bbdfSmrg    if (act->type == XkbSA_LockMods)
77435c4bbdfSmrg        return TRUE;
77535c4bbdfSmrg    if (act->flags & XkbSA_ClearLocks)
77635c4bbdfSmrg        TryCopyStr(buf, ",clearLocks", sz);
77735c4bbdfSmrg    if (act->flags & XkbSA_LatchToLock)
77835c4bbdfSmrg        TryCopyStr(buf, ",latchToLock", sz);
7796747b715Smrg    return TRUE;
78005b261ecSmrg}
78105b261ecSmrg
78235c4bbdfSmrg /*ARGSUSED*/ static Bool
78335c4bbdfSmrgCopyGroupActionArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
78405b261ecSmrg{
78535c4bbdfSmrg    XkbGroupAction *act;
78635c4bbdfSmrg    char tbuf[32];
78735c4bbdfSmrg
78835c4bbdfSmrg    act = &action->group;
78935c4bbdfSmrg    TryCopyStr(buf, "group=", sz);
79035c4bbdfSmrg    if (act->flags & XkbSA_GroupAbsolute)
79135c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act) + 1);
79235c4bbdfSmrg    else if (XkbSAGroup(act) < 0)
79335c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act));
79435c4bbdfSmrg    else
79535c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAGroup(act));
79635c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
79735c4bbdfSmrg    if (act->type == XkbSA_LockGroup)
79835c4bbdfSmrg        return TRUE;
79935c4bbdfSmrg    if (act->flags & XkbSA_ClearLocks)
80035c4bbdfSmrg        TryCopyStr(buf, ",clearLocks", sz);
80135c4bbdfSmrg    if (act->flags & XkbSA_LatchToLock)
80235c4bbdfSmrg        TryCopyStr(buf, ",latchToLock", sz);
8036747b715Smrg    return TRUE;
80405b261ecSmrg}
80505b261ecSmrg
80635c4bbdfSmrg /*ARGSUSED*/ static Bool
80735c4bbdfSmrgCopyMovePtrArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
80805b261ecSmrg{
80935c4bbdfSmrg    XkbPtrAction *act;
81035c4bbdfSmrg    int x, y;
81135c4bbdfSmrg    char tbuf[32];
81235c4bbdfSmrg
81335c4bbdfSmrg    act = &action->ptr;
81435c4bbdfSmrg    x = XkbPtrActionX(act);
81535c4bbdfSmrg    y = XkbPtrActionY(act);
81635c4bbdfSmrg    if ((act->flags & XkbSA_MoveAbsoluteX) || (x < 0))
81735c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "x=%d", x);
81835c4bbdfSmrg    else
81935c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "x=+%d", x);
82035c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
82135c4bbdfSmrg
82235c4bbdfSmrg    if ((act->flags & XkbSA_MoveAbsoluteY) || (y < 0))
82335c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), ",y=%d", y);
82435c4bbdfSmrg    else
82535c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), ",y=+%d", y);
82635c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
82735c4bbdfSmrg    if (act->flags & XkbSA_NoAcceleration)
82835c4bbdfSmrg        TryCopyStr(buf, ",!accel", sz);
8296747b715Smrg    return TRUE;
83005b261ecSmrg}
83105b261ecSmrg
83235c4bbdfSmrg /*ARGSUSED*/ static Bool
83335c4bbdfSmrgCopyPtrBtnArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
83405b261ecSmrg{
83535c4bbdfSmrg    XkbPtrBtnAction *act;
83635c4bbdfSmrg    char tbuf[32];
83735c4bbdfSmrg
83835c4bbdfSmrg    act = &action->btn;
83935c4bbdfSmrg    TryCopyStr(buf, "button=", sz);
84035c4bbdfSmrg    if ((act->button > 0) && (act->button < 6)) {
84135c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "%d", act->button);
84235c4bbdfSmrg        TryCopyStr(buf, tbuf, sz);
84305b261ecSmrg    }
84435c4bbdfSmrg    else
84535c4bbdfSmrg        TryCopyStr(buf, "default", sz);
84635c4bbdfSmrg    if (act->count > 0) {
84735c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), ",count=%d", act->count);
84835c4bbdfSmrg        TryCopyStr(buf, tbuf, sz);
84905b261ecSmrg    }
85035c4bbdfSmrg    if (action->type == XkbSA_LockPtrBtn) {
85135c4bbdfSmrg        switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
85235c4bbdfSmrg        case XkbSA_LockNoLock:
85335c4bbdfSmrg            TryCopyStr(buf, ",affect=unlock", sz);
85435c4bbdfSmrg            break;
85535c4bbdfSmrg        case XkbSA_LockNoUnlock:
85635c4bbdfSmrg            TryCopyStr(buf, ",affect=lock", sz);
85735c4bbdfSmrg            break;
85835c4bbdfSmrg        case XkbSA_LockNoUnlock | XkbSA_LockNoLock:
85935c4bbdfSmrg            TryCopyStr(buf, ",affect=neither", sz);
86035c4bbdfSmrg            break;
86135c4bbdfSmrg        default:
86235c4bbdfSmrg            TryCopyStr(buf, ",affect=both", sz);
86335c4bbdfSmrg            break;
86435c4bbdfSmrg        }
86505b261ecSmrg    }
8666747b715Smrg    return TRUE;
86705b261ecSmrg}
86805b261ecSmrg
86935c4bbdfSmrg /*ARGSUSED*/ static Bool
87035c4bbdfSmrgCopySetPtrDfltArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
87105b261ecSmrg{
87235c4bbdfSmrg    XkbPtrDfltAction *act;
87335c4bbdfSmrg    char tbuf[32];
87435c4bbdfSmrg
87535c4bbdfSmrg    act = &action->dflt;
87635c4bbdfSmrg    if (act->affect == XkbSA_AffectDfltBtn) {
87735c4bbdfSmrg        TryCopyStr(buf, "affect=button,button=", sz);
87835c4bbdfSmrg        if ((act->flags & XkbSA_DfltBtnAbsolute) ||
87935c4bbdfSmrg            (XkbSAPtrDfltValue(act) < 0))
88035c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%d", XkbSAPtrDfltValue(act));
88135c4bbdfSmrg        else
88235c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAPtrDfltValue(act));
88335c4bbdfSmrg        TryCopyStr(buf, tbuf, sz);
88405b261ecSmrg    }
8856747b715Smrg    return TRUE;
88605b261ecSmrg}
88705b261ecSmrg
88805b261ecSmrgstatic Bool
88935c4bbdfSmrgCopyISOLockArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
89005b261ecSmrg{
89135c4bbdfSmrg    XkbISOAction *act;
89235c4bbdfSmrg    char tbuf[64];
89335c4bbdfSmrg
894ed6184dfSmrg    memset(tbuf, 0, sizeof(tbuf));
89535c4bbdfSmrg    act = &action->iso;
89635c4bbdfSmrg    if (act->flags & XkbSA_ISODfltIsGroup) {
89735c4bbdfSmrg        TryCopyStr(tbuf, "group=", sz);
89835c4bbdfSmrg        if (act->flags & XkbSA_GroupAbsolute)
89935c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act) + 1);
90035c4bbdfSmrg        else if (XkbSAGroup(act) < 0)
90135c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act));
90235c4bbdfSmrg        else
90335c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAGroup(act));
90435c4bbdfSmrg        TryCopyStr(buf, tbuf, sz);
90505b261ecSmrg    }
90605b261ecSmrg    else {
90735c4bbdfSmrg        unsigned tmp;
90835c4bbdfSmrg
90935c4bbdfSmrg        tmp = XkbModActionVMods(act);
91035c4bbdfSmrg        TryCopyStr(buf, "modifiers=", sz);
91135c4bbdfSmrg        if (act->flags & XkbSA_UseModMapMods)
91235c4bbdfSmrg            TryCopyStr(buf, "modMapMods", sz);
91335c4bbdfSmrg        else if (act->real_mods || tmp) {
91435c4bbdfSmrg            if (act->real_mods) {
91535c4bbdfSmrg                TryCopyStr(buf, XkbModMaskText(act->real_mods, XkbXKBFile), sz);
91635c4bbdfSmrg                if (tmp)
91735c4bbdfSmrg                    TryCopyStr(buf, "+", sz);
91835c4bbdfSmrg            }
91935c4bbdfSmrg            if (tmp)
92035c4bbdfSmrg                TryCopyStr(buf, XkbVModMaskText(xkb, 0, tmp, XkbXKBFile), sz);
92135c4bbdfSmrg        }
92235c4bbdfSmrg        else
92335c4bbdfSmrg            TryCopyStr(buf, "none", sz);
92405b261ecSmrg    }
92535c4bbdfSmrg    TryCopyStr(buf, ",affect=", sz);
92635c4bbdfSmrg    if ((act->affect & XkbSA_ISOAffectMask) == 0)
92735c4bbdfSmrg        TryCopyStr(buf, "all", sz);
92805b261ecSmrg    else {
92935c4bbdfSmrg        int nOut = 0;
93035c4bbdfSmrg
93135c4bbdfSmrg        if ((act->affect & XkbSA_ISONoAffectMods) == 0) {
93235c4bbdfSmrg            TryCopyStr(buf, "mods", sz);
93335c4bbdfSmrg            nOut++;
93435c4bbdfSmrg        }
93535c4bbdfSmrg        if ((act->affect & XkbSA_ISONoAffectGroup) == 0) {
93635c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sgroups", (nOut > 0 ? "+" : ""));
93735c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
93835c4bbdfSmrg            nOut++;
93935c4bbdfSmrg        }
94035c4bbdfSmrg        if ((act->affect & XkbSA_ISONoAffectPtr) == 0) {
94135c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%spointer", (nOut > 0 ? "+" : ""));
94235c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
94335c4bbdfSmrg            nOut++;
94435c4bbdfSmrg        }
94535c4bbdfSmrg        if ((act->affect & XkbSA_ISONoAffectCtrls) == 0) {
94635c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%scontrols", (nOut > 0 ? "+" : ""));
94735c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
94835c4bbdfSmrg            nOut++;
94935c4bbdfSmrg        }
95005b261ecSmrg    }
9516747b715Smrg    return TRUE;
95205b261ecSmrg}
95305b261ecSmrg
95435c4bbdfSmrg /*ARGSUSED*/ static Bool
95535c4bbdfSmrgCopySwitchScreenArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
95605b261ecSmrg{
95735c4bbdfSmrg    XkbSwitchScreenAction *act;
95835c4bbdfSmrg    char tbuf[32];
95935c4bbdfSmrg
96035c4bbdfSmrg    act = &action->screen;
96135c4bbdfSmrg    if ((act->flags & XkbSA_SwitchAbsolute) || (XkbSAScreen(act) < 0))
96235c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "screen=%d", XkbSAScreen(act));
96335c4bbdfSmrg    else
96435c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "screen=+%d", XkbSAScreen(act));
96535c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
96635c4bbdfSmrg    if (act->flags & XkbSA_SwitchApplication)
96735c4bbdfSmrg        TryCopyStr(buf, ",!same", sz);
96835c4bbdfSmrg    else
96935c4bbdfSmrg        TryCopyStr(buf, ",same", sz);
9706747b715Smrg    return TRUE;
97105b261ecSmrg}
97205b261ecSmrg
97335c4bbdfSmrg /*ARGSUSED*/ static Bool
97435c4bbdfSmrgCopySetLockControlsArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
97505b261ecSmrg{
97635c4bbdfSmrg    XkbCtrlsAction *act;
97735c4bbdfSmrg    unsigned tmp;
97835c4bbdfSmrg    char tbuf[32];
97935c4bbdfSmrg
98035c4bbdfSmrg    act = &action->ctrls;
98135c4bbdfSmrg    tmp = XkbActionCtrls(act);
98235c4bbdfSmrg    TryCopyStr(buf, "controls=", sz);
98335c4bbdfSmrg    if (tmp == 0)
98435c4bbdfSmrg        TryCopyStr(buf, "none", sz);
98535c4bbdfSmrg    else if ((tmp & XkbAllBooleanCtrlsMask) == XkbAllBooleanCtrlsMask)
98635c4bbdfSmrg        TryCopyStr(buf, "all", sz);
98705b261ecSmrg    else {
98835c4bbdfSmrg        int nOut = 0;
98935c4bbdfSmrg
99035c4bbdfSmrg        if (tmp & XkbRepeatKeysMask) {
99135c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sRepeatKeys", (nOut > 0 ? "+" : ""));
99235c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
99335c4bbdfSmrg            nOut++;
99435c4bbdfSmrg        }
99535c4bbdfSmrg        if (tmp & XkbSlowKeysMask) {
99635c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sSlowKeys", (nOut > 0 ? "+" : ""));
99735c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
99835c4bbdfSmrg            nOut++;
99935c4bbdfSmrg        }
100035c4bbdfSmrg        if (tmp & XkbBounceKeysMask) {
100135c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sBounceKeys", (nOut > 0 ? "+" : ""));
100235c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
100335c4bbdfSmrg            nOut++;
100435c4bbdfSmrg        }
100535c4bbdfSmrg        if (tmp & XkbStickyKeysMask) {
100635c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sStickyKeys", (nOut > 0 ? "+" : ""));
100735c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
100835c4bbdfSmrg            nOut++;
100935c4bbdfSmrg        }
101035c4bbdfSmrg        if (tmp & XkbMouseKeysMask) {
101135c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sMouseKeys", (nOut > 0 ? "+" : ""));
101235c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
101335c4bbdfSmrg            nOut++;
101435c4bbdfSmrg        }
101535c4bbdfSmrg        if (tmp & XkbMouseKeysAccelMask) {
101635c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sMouseKeysAccel",
101735c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
101835c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
101935c4bbdfSmrg            nOut++;
102035c4bbdfSmrg        }
102135c4bbdfSmrg        if (tmp & XkbAccessXKeysMask) {
102235c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sAccessXKeys",
102335c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
102435c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
102535c4bbdfSmrg            nOut++;
102635c4bbdfSmrg        }
102735c4bbdfSmrg        if (tmp & XkbAccessXTimeoutMask) {
102835c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sAccessXTimeout",
102935c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
103035c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
103135c4bbdfSmrg            nOut++;
103235c4bbdfSmrg        }
103335c4bbdfSmrg        if (tmp & XkbAccessXFeedbackMask) {
103435c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sAccessXFeedback",
103535c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
103635c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
103735c4bbdfSmrg            nOut++;
103835c4bbdfSmrg        }
103935c4bbdfSmrg        if (tmp & XkbAudibleBellMask) {
104035c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sAudibleBell",
104135c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
104235c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
104335c4bbdfSmrg            nOut++;
104435c4bbdfSmrg        }
104535c4bbdfSmrg        if (tmp & XkbOverlay1Mask) {
104635c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sOverlay1", (nOut > 0 ? "+" : ""));
104735c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
104835c4bbdfSmrg            nOut++;
104935c4bbdfSmrg        }
105035c4bbdfSmrg        if (tmp & XkbOverlay2Mask) {
105135c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sOverlay2", (nOut > 0 ? "+" : ""));
105235c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
105335c4bbdfSmrg            nOut++;
105435c4bbdfSmrg        }
105535c4bbdfSmrg        if (tmp & XkbIgnoreGroupLockMask) {
105635c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sIgnoreGroupLock",
105735c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
105835c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
105935c4bbdfSmrg            nOut++;
106035c4bbdfSmrg        }
106105b261ecSmrg    }
10626747b715Smrg    return TRUE;
106305b261ecSmrg}
106405b261ecSmrg
106535c4bbdfSmrg /*ARGSUSED*/ static Bool
106635c4bbdfSmrgCopyActionMessageArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
106705b261ecSmrg{
106835c4bbdfSmrg    XkbMessageAction *act;
106935c4bbdfSmrg    unsigned all;
107035c4bbdfSmrg    char tbuf[32];
107135c4bbdfSmrg
107235c4bbdfSmrg    act = &action->msg;
107335c4bbdfSmrg    all = XkbSA_MessageOnPress | XkbSA_MessageOnRelease;
107435c4bbdfSmrg    TryCopyStr(buf, "report=", sz);
107535c4bbdfSmrg    if ((act->flags & all) == 0)
107635c4bbdfSmrg        TryCopyStr(buf, "none", sz);
107735c4bbdfSmrg    else if ((act->flags & all) == all)
107835c4bbdfSmrg        TryCopyStr(buf, "all", sz);
107935c4bbdfSmrg    else if (act->flags & XkbSA_MessageOnPress)
108035c4bbdfSmrg        TryCopyStr(buf, "KeyPress", sz);
108135c4bbdfSmrg    else
108235c4bbdfSmrg        TryCopyStr(buf, "KeyRelease", sz);
108335c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->message[0]);
108435c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
108535c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->message[1]);
108635c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
108735c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->message[2]);
108835c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
108935c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->message[3]);
109035c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
109135c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->message[4]);
109235c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
109335c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->message[5]);
109435c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
10956747b715Smrg    return TRUE;
109605b261ecSmrg}
109705b261ecSmrg
109805b261ecSmrgstatic Bool
109935c4bbdfSmrgCopyRedirectKeyArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
110005b261ecSmrg{
110135c4bbdfSmrg    XkbRedirectKeyAction *act;
110235c4bbdfSmrg    char tbuf[32], *tmp;
110335c4bbdfSmrg    unsigned kc;
110435c4bbdfSmrg    unsigned vmods, vmods_mask;
110535c4bbdfSmrg
110635c4bbdfSmrg    act = &action->redirect;
110735c4bbdfSmrg    kc = act->new_key;
110835c4bbdfSmrg    vmods = XkbSARedirectVMods(act);
110935c4bbdfSmrg    vmods_mask = XkbSARedirectVModsMask(act);
111035c4bbdfSmrg    if (xkb && xkb->names && xkb->names->keys && (kc <= xkb->max_key_code) &&
111135c4bbdfSmrg        (xkb->names->keys[kc].name[0] != '\0')) {
111235c4bbdfSmrg        char *kn;
111335c4bbdfSmrg
111435c4bbdfSmrg        kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile);
111535c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "key=%s", kn);
111605b261ecSmrg    }
111735c4bbdfSmrg    else
111835c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "key=%d", kc);
111935c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
112035c4bbdfSmrg    if ((act->mods_mask == 0) && (vmods_mask == 0))
112135c4bbdfSmrg        return TRUE;
112235c4bbdfSmrg    if ((act->mods_mask == XkbAllModifiersMask) &&
112335c4bbdfSmrg        (vmods_mask == XkbAllVirtualModsMask)) {
112435c4bbdfSmrg        tmp = XkbVModMaskText(xkb, act->mods, vmods, XkbXKBFile);
112535c4bbdfSmrg        TryCopyStr(buf, ",mods=", sz);
112635c4bbdfSmrg        TryCopyStr(buf, tmp, sz);
112705b261ecSmrg    }
112805b261ecSmrg    else {
112935c4bbdfSmrg        if ((act->mods_mask & act->mods) || (vmods_mask & vmods)) {
113035c4bbdfSmrg            tmp = XkbVModMaskText(xkb, act->mods_mask & act->mods,
113135c4bbdfSmrg                                  vmods_mask & vmods, XkbXKBFile);
113235c4bbdfSmrg            TryCopyStr(buf, ",mods= ", sz);
113335c4bbdfSmrg            TryCopyStr(buf, tmp, sz);
113435c4bbdfSmrg        }
113535c4bbdfSmrg        if ((act->mods_mask & (~act->mods)) || (vmods_mask & (~vmods))) {
113635c4bbdfSmrg            tmp = XkbVModMaskText(xkb, act->mods_mask & (~act->mods),
113735c4bbdfSmrg                                  vmods_mask & (~vmods), XkbXKBFile);
113835c4bbdfSmrg            TryCopyStr(buf, ",clearMods= ", sz);
113935c4bbdfSmrg            TryCopyStr(buf, tmp, sz);
114035c4bbdfSmrg        }
114105b261ecSmrg    }
11426747b715Smrg    return TRUE;
114305b261ecSmrg}
114405b261ecSmrg
114535c4bbdfSmrg /*ARGSUSED*/ static Bool
114635c4bbdfSmrgCopyDeviceBtnArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
114705b261ecSmrg{
114835c4bbdfSmrg    XkbDeviceBtnAction *act;
114935c4bbdfSmrg    char tbuf[32];
115035c4bbdfSmrg
115135c4bbdfSmrg    act = &action->devbtn;
115235c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), "device= %d", act->device);
115335c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
115435c4bbdfSmrg    TryCopyStr(buf, ",button=", sz);
115535c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), "%d", act->button);
115635c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
115735c4bbdfSmrg    if (act->count > 0) {
115835c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), ",count=%d", act->count);
115935c4bbdfSmrg        TryCopyStr(buf, tbuf, sz);
116005b261ecSmrg    }
116135c4bbdfSmrg    if (action->type == XkbSA_LockDeviceBtn) {
116235c4bbdfSmrg        switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
116335c4bbdfSmrg        case XkbSA_LockNoLock:
116435c4bbdfSmrg            TryCopyStr(buf, ",affect=unlock", sz);
116535c4bbdfSmrg            break;
116635c4bbdfSmrg        case XkbSA_LockNoUnlock:
116735c4bbdfSmrg            TryCopyStr(buf, ",affect=lock", sz);
116835c4bbdfSmrg            break;
116935c4bbdfSmrg        case XkbSA_LockNoUnlock | XkbSA_LockNoLock:
117035c4bbdfSmrg            TryCopyStr(buf, ",affect=neither", sz);
117135c4bbdfSmrg            break;
117235c4bbdfSmrg        default:
117335c4bbdfSmrg            TryCopyStr(buf, ",affect=both", sz);
117435c4bbdfSmrg            break;
117535c4bbdfSmrg        }
117605b261ecSmrg    }
11776747b715Smrg    return TRUE;
117805b261ecSmrg}
117905b261ecSmrg
118035c4bbdfSmrg /*ARGSUSED*/ static Bool
118135c4bbdfSmrgCopyOtherArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
118205b261ecSmrg{
118335c4bbdfSmrg    XkbAnyAction *act;
118435c4bbdfSmrg    char tbuf[32];
118535c4bbdfSmrg
118635c4bbdfSmrg    act = &action->any;
118735c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), "type=0x%02x", act->type);
118835c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
118935c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->data[0]);
119035c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
119135c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->data[1]);
119235c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
119335c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->data[2]);
119435c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
119535c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->data[3]);
119635c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
119735c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->data[4]);
119835c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
119935c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->data[5]);
120035c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
120135c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[6]=0x%02x", act->data[6]);
120235c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
12036747b715Smrg    return TRUE;
120405b261ecSmrg}
120505b261ecSmrg
120635c4bbdfSmrgtypedef Bool (*actionCopy) (XkbDescPtr /* xkb */ ,
120735c4bbdfSmrg                            XkbAction * /* action */ ,
120835c4bbdfSmrg                            char * /* buf */ ,
120935c4bbdfSmrg                            int *       /* sz */
121035c4bbdfSmrg    );
121135c4bbdfSmrg
121235c4bbdfSmrgstatic actionCopy copyActionArgs[XkbSA_NumActions] = {
121335c4bbdfSmrg    CopyNoActionArgs /* NoAction     */ ,
121435c4bbdfSmrg    CopyModActionArgs /* SetMods      */ ,
121535c4bbdfSmrg    CopyModActionArgs /* LatchMods    */ ,
121635c4bbdfSmrg    CopyModActionArgs /* LockMods     */ ,
121735c4bbdfSmrg    CopyGroupActionArgs /* SetGroup     */ ,
121835c4bbdfSmrg    CopyGroupActionArgs /* LatchGroup   */ ,
121935c4bbdfSmrg    CopyGroupActionArgs /* LockGroup    */ ,
122035c4bbdfSmrg    CopyMovePtrArgs /* MovePtr      */ ,
122135c4bbdfSmrg    CopyPtrBtnArgs /* PtrBtn       */ ,
122235c4bbdfSmrg    CopyPtrBtnArgs /* LockPtrBtn   */ ,
122335c4bbdfSmrg    CopySetPtrDfltArgs /* SetPtrDflt   */ ,
122435c4bbdfSmrg    CopyISOLockArgs /* ISOLock      */ ,
122535c4bbdfSmrg    CopyNoActionArgs /* Terminate    */ ,
122635c4bbdfSmrg    CopySwitchScreenArgs /* SwitchScreen */ ,
122735c4bbdfSmrg    CopySetLockControlsArgs /* SetControls  */ ,
122835c4bbdfSmrg    CopySetLockControlsArgs /* LockControls */ ,
122935c4bbdfSmrg    CopyActionMessageArgs /* ActionMessage */ ,
123035c4bbdfSmrg    CopyRedirectKeyArgs /* RedirectKey  */ ,
123135c4bbdfSmrg    CopyDeviceBtnArgs /* DeviceBtn    */ ,
123235c4bbdfSmrg    CopyDeviceBtnArgs           /* LockDeviceBtn */
123305b261ecSmrg};
123405b261ecSmrg
123505b261ecSmrg#define	ACTION_SZ	256
123605b261ecSmrg
123705b261ecSmrgchar *
123835c4bbdfSmrgXkbActionText(XkbDescPtr xkb, XkbAction *action, unsigned format)
123905b261ecSmrg{
124054b5899cSmrg    char buf[ACTION_SZ];
124135c4bbdfSmrg    int sz;
124235c4bbdfSmrg
124335c4bbdfSmrg    if (format == XkbCFile) {
124435c4bbdfSmrg        snprintf(buf, sizeof(buf),
124535c4bbdfSmrg                 "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }",
124635c4bbdfSmrg                 XkbActionTypeText(action->type, XkbCFile),
124735c4bbdfSmrg                 action->any.data[0], action->any.data[1], action->any.data[2],
124835c4bbdfSmrg                 action->any.data[3], action->any.data[4], action->any.data[5],
124935c4bbdfSmrg                 action->any.data[6]);
125005b261ecSmrg    }
125105b261ecSmrg    else {
125235c4bbdfSmrg        snprintf(buf, sizeof(buf), "%s(",
125335c4bbdfSmrg                 XkbActionTypeText(action->type, XkbXKBFile));
125435c4bbdfSmrg        sz = ACTION_SZ - strlen(buf) + 2;       /* room for close paren and NULL */
125535c4bbdfSmrg        if (action->type < (unsigned) XkbSA_NumActions)
125635c4bbdfSmrg            (*copyActionArgs[action->type]) (xkb, action, buf, &sz);
125735c4bbdfSmrg        else
125835c4bbdfSmrg            CopyOtherArgs(xkb, action, buf, &sz);
125935c4bbdfSmrg        TryCopyStr(buf, ")", &sz);
126005b261ecSmrg    }
126154b5899cSmrg    return tbGetBufferString(buf);
126205b261ecSmrg}
126305b261ecSmrg
126405b261ecSmrgchar *
126535c4bbdfSmrgXkbBehaviorText(XkbDescPtr xkb, XkbBehavior * behavior, unsigned format)
126605b261ecSmrg{
126754b5899cSmrg    char buf[256];
126835c4bbdfSmrg
126935c4bbdfSmrg    if (format == XkbCFile) {
127035c4bbdfSmrg        if (behavior->type == XkbKB_Default)
127135c4bbdfSmrg            snprintf(buf, sizeof(buf), "{   0,    0 }");
127235c4bbdfSmrg        else
127335c4bbdfSmrg            snprintf(buf, sizeof(buf), "{ %3d, 0x%02x }", behavior->type,
127435c4bbdfSmrg                     behavior->data);
127505b261ecSmrg    }
127605b261ecSmrg    else {
127735c4bbdfSmrg        unsigned type, permanent;
127835c4bbdfSmrg
127935c4bbdfSmrg        type = behavior->type & XkbKB_OpMask;
128035c4bbdfSmrg        permanent = ((behavior->type & XkbKB_Permanent) != 0);
128135c4bbdfSmrg
128235c4bbdfSmrg        if (type == XkbKB_Lock) {
128335c4bbdfSmrg            snprintf(buf, sizeof(buf), "lock= %s",
128435c4bbdfSmrg                     (permanent ? "Permanent" : "TRUE"));
128535c4bbdfSmrg        }
128635c4bbdfSmrg        else if (type == XkbKB_RadioGroup) {
128735c4bbdfSmrg            int g;
128854b5899cSmrg            char *tmp;
128954b5899cSmrg            size_t tmpsize;
129035c4bbdfSmrg
129135c4bbdfSmrg            g = ((behavior->data) & (~XkbKB_RGAllowNone)) + 1;
129235c4bbdfSmrg            if (XkbKB_RGAllowNone & behavior->data) {
129335c4bbdfSmrg                snprintf(buf, sizeof(buf), "allowNone,");
129435c4bbdfSmrg                tmp = &buf[strlen(buf)];
129535c4bbdfSmrg            }
129635c4bbdfSmrg            else
129735c4bbdfSmrg                tmp = buf;
129854b5899cSmrg            tmpsize = sizeof(buf) - (tmp - buf);
129935c4bbdfSmrg            if (permanent)
130054b5899cSmrg                snprintf(tmp, tmpsize, "permanentRadioGroup= %d", g);
130135c4bbdfSmrg            else
130254b5899cSmrg                snprintf(tmp, tmpsize, "radioGroup= %d", g);
130335c4bbdfSmrg        }
130435c4bbdfSmrg        else if ((type == XkbKB_Overlay1) || (type == XkbKB_Overlay2)) {
130535c4bbdfSmrg            int ndx, kc;
130635c4bbdfSmrg            char *kn;
130735c4bbdfSmrg
130835c4bbdfSmrg            ndx = ((type == XkbKB_Overlay1) ? 1 : 2);
130935c4bbdfSmrg            kc = behavior->data;
131035c4bbdfSmrg            if ((xkb) && (xkb->names) && (xkb->names->keys))
131135c4bbdfSmrg                kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile);
131235c4bbdfSmrg            else {
131335c4bbdfSmrg                static char tbuf[8];
131435c4bbdfSmrg
131535c4bbdfSmrg                snprintf(tbuf, sizeof(tbuf), "%d", kc);
131635c4bbdfSmrg                kn = tbuf;
131735c4bbdfSmrg            }
131835c4bbdfSmrg            if (permanent)
131935c4bbdfSmrg                snprintf(buf, sizeof(buf), "permanentOverlay%d= %s", ndx, kn);
132035c4bbdfSmrg            else
132135c4bbdfSmrg                snprintf(buf, sizeof(buf), "overlay%d= %s", ndx, kn);
132235c4bbdfSmrg        }
132305b261ecSmrg    }
132454b5899cSmrg    return tbGetBufferString(buf);
132505b261ecSmrg}
132605b261ecSmrg
132705b261ecSmrg/***====================================================================***/
132805b261ecSmrg
132905b261ecSmrgchar *
133005b261ecSmrgXkbIndentText(unsigned size)
133105b261ecSmrg{
133235c4bbdfSmrg    static char buf[32];
133335c4bbdfSmrg    register int i;
133405b261ecSmrg
133535c4bbdfSmrg    if (size > 31)
133635c4bbdfSmrg        size = 31;
133705b261ecSmrg
133835c4bbdfSmrg    for (i = 0; i < size; i++) {
133935c4bbdfSmrg        buf[i] = ' ';
134005b261ecSmrg    }
134135c4bbdfSmrg    buf[size] = '\0';
134205b261ecSmrg    return buf;
134305b261ecSmrg}
1344