xkbtext.c revision f2346221
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
7505b261ecSmrgchar *
7635c4bbdfSmrgXkbAtomText(Atom atm, unsigned format)
7705b261ecSmrg{
7835c4bbdfSmrg    const char *atmstr;
7935c4bbdfSmrg    char *rtrn, *tmp;
8005b261ecSmrg
816747b715Smrg    atmstr = NameForAtom(atm);
826747b715Smrg    if (atmstr != NULL) {
8335c4bbdfSmrg        int len;
8435c4bbdfSmrg
8535c4bbdfSmrg        len = strlen(atmstr) + 1;
8635c4bbdfSmrg        rtrn = tbGetBuffer(len);
8735c4bbdfSmrg        strlcpy(rtrn, atmstr, len);
8805b261ecSmrg    }
8905b261ecSmrg    else {
9035c4bbdfSmrg        rtrn = tbGetBuffer(1);
9135c4bbdfSmrg        rtrn[0] = '\0';
9205b261ecSmrg    }
9335c4bbdfSmrg    if (format == XkbCFile) {
9435c4bbdfSmrg        for (tmp = rtrn; *tmp != '\0'; tmp++) {
9535c4bbdfSmrg            if ((tmp == rtrn) && (!isalpha(*tmp)))
9635c4bbdfSmrg                *tmp = '_';
9735c4bbdfSmrg            else if (!isalnum(*tmp))
9835c4bbdfSmrg                *tmp = '_';
9935c4bbdfSmrg        }
10005b261ecSmrg    }
10135c4bbdfSmrg    return XkbStringText(rtrn, format);
10205b261ecSmrg}
10305b261ecSmrg
10405b261ecSmrg/***====================================================================***/
10505b261ecSmrg
10605b261ecSmrgchar *
10735c4bbdfSmrgXkbVModIndexText(XkbDescPtr xkb, unsigned ndx, unsigned format)
10805b261ecSmrg{
10935c4bbdfSmrg    register int len;
11035c4bbdfSmrg    register Atom *vmodNames;
11135c4bbdfSmrg    char *rtrn;
11235c4bbdfSmrg    const char *tmp;
11335c4bbdfSmrg    char numBuf[20];
11405b261ecSmrg
11505b261ecSmrg    if (xkb && xkb->names)
11635c4bbdfSmrg        vmodNames = xkb->names->vmods;
11735c4bbdfSmrg    else
11835c4bbdfSmrg        vmodNames = NULL;
11935c4bbdfSmrg
12035c4bbdfSmrg    tmp = NULL;
12135c4bbdfSmrg    if (ndx >= XkbNumVirtualMods)
12235c4bbdfSmrg        tmp = "illegal";
12335c4bbdfSmrg    else if (vmodNames && (vmodNames[ndx] != None))
12435c4bbdfSmrg        tmp = NameForAtom(vmodNames[ndx]);
12535c4bbdfSmrg    if (tmp == NULL) {
12635c4bbdfSmrg        snprintf(numBuf, sizeof(numBuf), "%d", ndx);
12735c4bbdfSmrg        tmp = numBuf;
1286747b715Smrg    }
12905b261ecSmrg
13035c4bbdfSmrg    len = strlen(tmp) + 1;
13135c4bbdfSmrg    if (format == XkbCFile)
13235c4bbdfSmrg        len += 4;
13335c4bbdfSmrg    rtrn = tbGetBuffer(len);
13435c4bbdfSmrg    if (format == XkbCFile) {
13535c4bbdfSmrg        strcpy(rtrn, "vmod_");
13635c4bbdfSmrg        strncpy(&rtrn[5], tmp, len - 4);
13705b261ecSmrg    }
13835c4bbdfSmrg    else
13935c4bbdfSmrg        strncpy(rtrn, tmp, len);
14005b261ecSmrg    return rtrn;
14105b261ecSmrg}
14205b261ecSmrg
1431b5d61b8Smrg#define VMOD_BUFFER_SIZE        512
1441b5d61b8Smrg
14505b261ecSmrgchar *
14635c4bbdfSmrgXkbVModMaskText(XkbDescPtr xkb,
14735c4bbdfSmrg                unsigned modMask, unsigned mask, unsigned format)
14805b261ecSmrg{
14935c4bbdfSmrg    register int i, bit;
15035c4bbdfSmrg    int len;
15135c4bbdfSmrg    char *mm, *rtrn;
1521b5d61b8Smrg    char *str, buf[VMOD_BUFFER_SIZE];
15335c4bbdfSmrg
15435c4bbdfSmrg    if ((modMask == 0) && (mask == 0)) {
15535c4bbdfSmrg        rtrn = tbGetBuffer(5);
15635c4bbdfSmrg        if (format == XkbCFile)
15735c4bbdfSmrg            sprintf(rtrn, "0");
15835c4bbdfSmrg        else
15935c4bbdfSmrg            sprintf(rtrn, "none");
16035c4bbdfSmrg        return rtrn;
16105b261ecSmrg    }
16235c4bbdfSmrg    if (modMask != 0)
16335c4bbdfSmrg        mm = XkbModMaskText(modMask, format);
16435c4bbdfSmrg    else
16535c4bbdfSmrg        mm = NULL;
16605b261ecSmrg
16735c4bbdfSmrg    str = buf;
16835c4bbdfSmrg    buf[0] = '\0';
16905b261ecSmrg    if (mask) {
17035c4bbdfSmrg        char *tmp;
17135c4bbdfSmrg
17235c4bbdfSmrg        for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
17335c4bbdfSmrg            if (mask & bit) {
17435c4bbdfSmrg                tmp = XkbVModIndexText(xkb, i, format);
17535c4bbdfSmrg                len = strlen(tmp) + 1 + (str == buf ? 0 : 1);
17635c4bbdfSmrg                if (format == XkbCFile)
17735c4bbdfSmrg                    len += 4;
178f2346221Smrg                if ((str - buf) + len > VMOD_BUFFER_SIZE)
179f2346221Smrg                    continue; /* Skip */
180f2346221Smrg                if (str != buf) {
181f2346221Smrg                    if (format == XkbCFile)
182f2346221Smrg                        *str++ = '|';
183f2346221Smrg                    else
184f2346221Smrg                        *str++ = '+';
185f2346221Smrg                    len--;
18635c4bbdfSmrg                }
18735c4bbdfSmrg                if (format == XkbCFile)
18835c4bbdfSmrg                    sprintf(str, "%sMask", tmp);
18935c4bbdfSmrg                else
19035c4bbdfSmrg                    strcpy(str, tmp);
19135c4bbdfSmrg                str = &str[len - 1];
19235c4bbdfSmrg            }
19335c4bbdfSmrg        }
19435c4bbdfSmrg        str = buf;
19505b261ecSmrg    }
19635c4bbdfSmrg    else
19735c4bbdfSmrg        str = NULL;
19835c4bbdfSmrg    if (mm)
19935c4bbdfSmrg        len = strlen(mm);
20035c4bbdfSmrg    else
20135c4bbdfSmrg        len = 0;
20205b261ecSmrg    if (str)
20335c4bbdfSmrg        len += strlen(str) + (mm == NULL ? 0 : 1);
20435c4bbdfSmrg    rtrn = tbGetBuffer(len + 1);
20535c4bbdfSmrg    rtrn[0] = '\0';
20635c4bbdfSmrg
20735c4bbdfSmrg    if (mm != NULL) {
20835c4bbdfSmrg        i = strlen(mm);
20935c4bbdfSmrg        if (i > len)
21035c4bbdfSmrg            i = len;
21135c4bbdfSmrg        strcpy(rtrn, mm);
21205b261ecSmrg    }
21305b261ecSmrg    else {
21435c4bbdfSmrg        i = 0;
21505b261ecSmrg    }
21635c4bbdfSmrg    if (str != NULL) {
21735c4bbdfSmrg        if (mm != NULL) {
21835c4bbdfSmrg            if (format == XkbCFile)
21935c4bbdfSmrg                strcat(rtrn, "|");
22035c4bbdfSmrg            else
22135c4bbdfSmrg                strcat(rtrn, "+");
22235c4bbdfSmrg        }
22335c4bbdfSmrg        strncat(rtrn, str, len - i);
22405b261ecSmrg    }
22535c4bbdfSmrg    rtrn[len] = '\0';
22605b261ecSmrg    return rtrn;
22705b261ecSmrg}
22805b261ecSmrg
22935c4bbdfSmrgstatic const char *modNames[XkbNumModifiers] = {
23005b261ecSmrg    "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5"
23105b261ecSmrg};
23205b261ecSmrg
23305b261ecSmrgchar *
23435c4bbdfSmrgXkbModIndexText(unsigned ndx, unsigned format)
23505b261ecSmrg{
23635c4bbdfSmrg    char *rtrn;
23735c4bbdfSmrg    char buf[100];
23835c4bbdfSmrg
23935c4bbdfSmrg    if (format == XkbCFile) {
24035c4bbdfSmrg        if (ndx < XkbNumModifiers)
24135c4bbdfSmrg            snprintf(buf, sizeof(buf), "%sMapIndex", modNames[ndx]);
24235c4bbdfSmrg        else if (ndx == XkbNoModifier)
24335c4bbdfSmrg            snprintf(buf, sizeof(buf), "XkbNoModifier");
24435c4bbdfSmrg        else
24535c4bbdfSmrg            snprintf(buf, sizeof(buf), "0x%02x", ndx);
24605b261ecSmrg    }
24705b261ecSmrg    else {
24835c4bbdfSmrg        if (ndx < XkbNumModifiers)
24935c4bbdfSmrg            strcpy(buf, modNames[ndx]);
25035c4bbdfSmrg        else if (ndx == XkbNoModifier)
25135c4bbdfSmrg            strcpy(buf, "none");
25235c4bbdfSmrg        else
25335c4bbdfSmrg            snprintf(buf, sizeof(buf), "ILLEGAL_%02x", ndx);
25405b261ecSmrg    }
25535c4bbdfSmrg    rtrn = tbGetBuffer(strlen(buf) + 1);
25635c4bbdfSmrg    strcpy(rtrn, buf);
25705b261ecSmrg    return rtrn;
25805b261ecSmrg}
25905b261ecSmrg
26005b261ecSmrgchar *
26135c4bbdfSmrgXkbModMaskText(unsigned mask, unsigned format)
26205b261ecSmrg{
26335c4bbdfSmrg    register int i, bit;
26435c4bbdfSmrg    char buf[64], *rtrn;
26535c4bbdfSmrg
26635c4bbdfSmrg    if ((mask & 0xff) == 0xff) {
26735c4bbdfSmrg        if (format == XkbCFile)
26835c4bbdfSmrg            strcpy(buf, "0xff");
26935c4bbdfSmrg        else
27035c4bbdfSmrg            strcpy(buf, "all");
27105b261ecSmrg    }
27235c4bbdfSmrg    else if ((mask & 0xff) == 0) {
27335c4bbdfSmrg        if (format == XkbCFile)
27435c4bbdfSmrg            strcpy(buf, "0");
27535c4bbdfSmrg        else
27635c4bbdfSmrg            strcpy(buf, "none");
27705b261ecSmrg    }
27805b261ecSmrg    else {
27935c4bbdfSmrg        char *str = buf;
28035c4bbdfSmrg
28135c4bbdfSmrg        buf[0] = '\0';
28235c4bbdfSmrg        for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) {
28335c4bbdfSmrg            if (mask & bit) {
28435c4bbdfSmrg                if (str != buf) {
28535c4bbdfSmrg                    if (format == XkbCFile)
28635c4bbdfSmrg                        *str++ = '|';
28735c4bbdfSmrg                    else
28835c4bbdfSmrg                        *str++ = '+';
28935c4bbdfSmrg                }
29035c4bbdfSmrg                strcpy(str, modNames[i]);
29135c4bbdfSmrg                str = &str[strlen(str)];
29235c4bbdfSmrg                if (format == XkbCFile) {
29335c4bbdfSmrg                    strcpy(str, "Mask");
29435c4bbdfSmrg                    str += 4;
29535c4bbdfSmrg                }
29635c4bbdfSmrg            }
29735c4bbdfSmrg        }
29805b261ecSmrg    }
29935c4bbdfSmrg    rtrn = tbGetBuffer(strlen(buf) + 1);
30035c4bbdfSmrg    strcpy(rtrn, buf);
30105b261ecSmrg    return rtrn;
30205b261ecSmrg}
30305b261ecSmrg
30405b261ecSmrg/***====================================================================***/
30505b261ecSmrg
30635c4bbdfSmrg /*ARGSUSED*/ char *
30735c4bbdfSmrgXkbConfigText(unsigned config, unsigned format)
30805b261ecSmrg{
30935c4bbdfSmrg    static char *buf;
31005b261ecSmrg
31135c4bbdfSmrg    buf = tbGetBuffer(32);
31205b261ecSmrg    switch (config) {
31335c4bbdfSmrg    case XkmSemanticsFile:
31435c4bbdfSmrg        strcpy(buf, "Semantics");
31535c4bbdfSmrg        break;
31635c4bbdfSmrg    case XkmLayoutFile:
31735c4bbdfSmrg        strcpy(buf, "Layout");
31835c4bbdfSmrg        break;
31935c4bbdfSmrg    case XkmKeymapFile:
32035c4bbdfSmrg        strcpy(buf, "Keymap");
32135c4bbdfSmrg        break;
32235c4bbdfSmrg    case XkmGeometryFile:
32335c4bbdfSmrg    case XkmGeometryIndex:
32435c4bbdfSmrg        strcpy(buf, "Geometry");
32535c4bbdfSmrg        break;
32635c4bbdfSmrg    case XkmTypesIndex:
32735c4bbdfSmrg        strcpy(buf, "Types");
32835c4bbdfSmrg        break;
32935c4bbdfSmrg    case XkmCompatMapIndex:
33035c4bbdfSmrg        strcpy(buf, "CompatMap");
33135c4bbdfSmrg        break;
33235c4bbdfSmrg    case XkmSymbolsIndex:
33335c4bbdfSmrg        strcpy(buf, "Symbols");
33435c4bbdfSmrg        break;
33535c4bbdfSmrg    case XkmIndicatorsIndex:
33635c4bbdfSmrg        strcpy(buf, "Indicators");
33735c4bbdfSmrg        break;
33835c4bbdfSmrg    case XkmKeyNamesIndex:
33935c4bbdfSmrg        strcpy(buf, "KeyNames");
34035c4bbdfSmrg        break;
34135c4bbdfSmrg    case XkmVirtualModsIndex:
34235c4bbdfSmrg        strcpy(buf, "VirtualMods");
34335c4bbdfSmrg        break;
34435c4bbdfSmrg    default:
34535c4bbdfSmrg        sprintf(buf, "unknown(%d)", config);
34635c4bbdfSmrg        break;
34705b261ecSmrg    }
34805b261ecSmrg    return buf;
34905b261ecSmrg}
35005b261ecSmrg
35105b261ecSmrg/***====================================================================***/
35205b261ecSmrg
35305b261ecSmrgchar *
35435c4bbdfSmrgXkbKeysymText(KeySym sym, unsigned format)
35505b261ecSmrg{
35635c4bbdfSmrg    static char buf[32];
35705b261ecSmrg
35835c4bbdfSmrg    if (sym == NoSymbol)
35935c4bbdfSmrg        strcpy(buf, "NoSymbol");
36035c4bbdfSmrg    else
36135c4bbdfSmrg        snprintf(buf, sizeof(buf), "0x%lx", (long) sym);
36235c4bbdfSmrg    return buf;
36305b261ecSmrg}
36405b261ecSmrg
36505b261ecSmrgchar *
36635c4bbdfSmrgXkbKeyNameText(char *name, unsigned format)
36705b261ecSmrg{
36835c4bbdfSmrg    char *buf;
36905b261ecSmrg
37035c4bbdfSmrg    if (format == XkbCFile) {
37135c4bbdfSmrg        buf = tbGetBuffer(5);
37235c4bbdfSmrg        memcpy(buf, name, 4);
37335c4bbdfSmrg        buf[4] = '\0';
37405b261ecSmrg    }
37505b261ecSmrg    else {
37635c4bbdfSmrg        int len;
37735c4bbdfSmrg
37835c4bbdfSmrg        buf = tbGetBuffer(7);
37935c4bbdfSmrg        buf[0] = '<';
38035c4bbdfSmrg        memcpy(&buf[1], name, 4);
38135c4bbdfSmrg        buf[5] = '\0';
38235c4bbdfSmrg        len = strlen(buf);
38335c4bbdfSmrg        buf[len++] = '>';
38435c4bbdfSmrg        buf[len] = '\0';
38505b261ecSmrg    }
38605b261ecSmrg    return buf;
38705b261ecSmrg}
38805b261ecSmrg
38905b261ecSmrg/***====================================================================***/
39005b261ecSmrg
39135c4bbdfSmrgstatic const char *siMatchText[5] = {
39235c4bbdfSmrg    "NoneOf", "AnyOfOrNone", "AnyOf", "AllOf", "Exactly"
39305b261ecSmrg};
39405b261ecSmrg
39535c4bbdfSmrgconst char *
39635c4bbdfSmrgXkbSIMatchText(unsigned type, unsigned format)
39705b261ecSmrg{
39835c4bbdfSmrg    static char buf[40];
39935c4bbdfSmrg    const char *rtrn;
40035c4bbdfSmrg
40135c4bbdfSmrg    switch (type & XkbSI_OpMask) {
40235c4bbdfSmrg    case XkbSI_NoneOf:
40335c4bbdfSmrg        rtrn = siMatchText[0];
40435c4bbdfSmrg        break;
40535c4bbdfSmrg    case XkbSI_AnyOfOrNone:
40635c4bbdfSmrg        rtrn = siMatchText[1];
40735c4bbdfSmrg        break;
40835c4bbdfSmrg    case XkbSI_AnyOf:
40935c4bbdfSmrg        rtrn = siMatchText[2];
41035c4bbdfSmrg        break;
41135c4bbdfSmrg    case XkbSI_AllOf:
41235c4bbdfSmrg        rtrn = siMatchText[3];
41335c4bbdfSmrg        break;
41435c4bbdfSmrg    case XkbSI_Exactly:
41535c4bbdfSmrg        rtrn = siMatchText[4];
41635c4bbdfSmrg        break;
41735c4bbdfSmrg    default:
41835c4bbdfSmrg        snprintf(buf, sizeof(buf), "0x%x", type & XkbSI_OpMask);
41935c4bbdfSmrg        return buf;
42005b261ecSmrg    }
42135c4bbdfSmrg    if (format == XkbCFile) {
42235c4bbdfSmrg        if (type & XkbSI_LevelOneOnly)
42335c4bbdfSmrg            snprintf(buf, sizeof(buf), "XkbSI_LevelOneOnly|XkbSI_%s", rtrn);
42435c4bbdfSmrg        else
42535c4bbdfSmrg            snprintf(buf, sizeof(buf), "XkbSI_%s", rtrn);
42635c4bbdfSmrg        rtrn = buf;
42705b261ecSmrg    }
42805b261ecSmrg    return rtrn;
42905b261ecSmrg}
43005b261ecSmrg
43105b261ecSmrg/***====================================================================***/
43205b261ecSmrg
43335c4bbdfSmrgstatic const char *imWhichNames[] = {
43435c4bbdfSmrg    "base",
43535c4bbdfSmrg    "latched",
43635c4bbdfSmrg    "locked",
43735c4bbdfSmrg    "effective",
43835c4bbdfSmrg    "compat"
43905b261ecSmrg};
44005b261ecSmrg
44105b261ecSmrgchar *
44235c4bbdfSmrgXkbIMWhichStateMaskText(unsigned use_which, unsigned format)
44305b261ecSmrg{
44435c4bbdfSmrg    int len;
44535c4bbdfSmrg    unsigned i, bit, tmp;
44635c4bbdfSmrg    char *buf;
44735c4bbdfSmrg
44835c4bbdfSmrg    if (use_which == 0) {
44935c4bbdfSmrg        buf = tbGetBuffer(2);
45035c4bbdfSmrg        strcpy(buf, "0");
45135c4bbdfSmrg        return buf;
45205b261ecSmrg    }
45335c4bbdfSmrg    tmp = use_which & XkbIM_UseAnyMods;
45435c4bbdfSmrg    for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
45535c4bbdfSmrg        if (tmp & bit) {
45635c4bbdfSmrg            tmp &= ~bit;
45735c4bbdfSmrg            len += strlen(imWhichNames[i]) + 1;
45835c4bbdfSmrg            if (format == XkbCFile)
45935c4bbdfSmrg                len += 9;
46035c4bbdfSmrg        }
46105b261ecSmrg    }
46235c4bbdfSmrg    buf = tbGetBuffer(len + 1);
46335c4bbdfSmrg    tmp = use_which & XkbIM_UseAnyMods;
46435c4bbdfSmrg    for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
46535c4bbdfSmrg        if (tmp & bit) {
46635c4bbdfSmrg            tmp &= ~bit;
46735c4bbdfSmrg            if (format == XkbCFile) {
46835c4bbdfSmrg                if (len != 0)
46935c4bbdfSmrg                    buf[len++] = '|';
47035c4bbdfSmrg                sprintf(&buf[len], "XkbIM_Use%s", imWhichNames[i]);
47135c4bbdfSmrg                buf[len + 9] = toupper(buf[len + 9]);
47235c4bbdfSmrg            }
47335c4bbdfSmrg            else {
47435c4bbdfSmrg                if (len != 0)
47535c4bbdfSmrg                    buf[len++] = '+';
47635c4bbdfSmrg                sprintf(&buf[len], "%s", imWhichNames[i]);
47735c4bbdfSmrg            }
47835c4bbdfSmrg            len += strlen(&buf[len]);
47935c4bbdfSmrg        }
48005b261ecSmrg    }
48105b261ecSmrg    return buf;
48205b261ecSmrg}
48305b261ecSmrg
48435c4bbdfSmrgstatic const char *ctrlNames[] = {
48535c4bbdfSmrg    "repeatKeys",
48635c4bbdfSmrg    "slowKeys",
48735c4bbdfSmrg    "bounceKeys",
48835c4bbdfSmrg    "stickyKeys",
48935c4bbdfSmrg    "mouseKeys",
49035c4bbdfSmrg    "mouseKeysAccel",
49135c4bbdfSmrg    "accessXKeys",
49235c4bbdfSmrg    "accessXTimeout",
49335c4bbdfSmrg    "accessXFeedback",
49435c4bbdfSmrg    "audibleBell",
49535c4bbdfSmrg    "overlay1",
49635c4bbdfSmrg    "overlay2",
49735c4bbdfSmrg    "ignoreGroupLock"
49805b261ecSmrg};
49905b261ecSmrg
50005b261ecSmrgchar *
50135c4bbdfSmrgXkbControlsMaskText(unsigned ctrls, unsigned format)
50205b261ecSmrg{
50335c4bbdfSmrg    int len;
50435c4bbdfSmrg    unsigned i, bit, tmp;
50535c4bbdfSmrg    char *buf;
50635c4bbdfSmrg
50735c4bbdfSmrg    if (ctrls == 0) {
50835c4bbdfSmrg        buf = tbGetBuffer(5);
50935c4bbdfSmrg        if (format == XkbCFile)
51035c4bbdfSmrg            strcpy(buf, "0");
51135c4bbdfSmrg        else
51235c4bbdfSmrg            strcpy(buf, "none");
51335c4bbdfSmrg        return buf;
51405b261ecSmrg    }
51535c4bbdfSmrg    tmp = ctrls & XkbAllBooleanCtrlsMask;
51635c4bbdfSmrg    for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
51735c4bbdfSmrg        if (tmp & bit) {
51835c4bbdfSmrg            tmp &= ~bit;
51935c4bbdfSmrg            len += strlen(ctrlNames[i]) + 1;
52035c4bbdfSmrg            if (format == XkbCFile)
52135c4bbdfSmrg                len += 7;
52235c4bbdfSmrg        }
52305b261ecSmrg    }
52435c4bbdfSmrg    buf = tbGetBuffer(len + 1);
52535c4bbdfSmrg    tmp = ctrls & XkbAllBooleanCtrlsMask;
52635c4bbdfSmrg    for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
52735c4bbdfSmrg        if (tmp & bit) {
52835c4bbdfSmrg            tmp &= ~bit;
52935c4bbdfSmrg            if (format == XkbCFile) {
53035c4bbdfSmrg                if (len != 0)
53135c4bbdfSmrg                    buf[len++] = '|';
53235c4bbdfSmrg                sprintf(&buf[len], "Xkb%sMask", ctrlNames[i]);
53335c4bbdfSmrg                buf[len + 3] = toupper(buf[len + 3]);
53435c4bbdfSmrg            }
53535c4bbdfSmrg            else {
53635c4bbdfSmrg                if (len != 0)
53735c4bbdfSmrg                    buf[len++] = '+';
53835c4bbdfSmrg                sprintf(&buf[len], "%s", ctrlNames[i]);
53935c4bbdfSmrg            }
54035c4bbdfSmrg            len += strlen(&buf[len]);
54135c4bbdfSmrg        }
54205b261ecSmrg    }
54305b261ecSmrg    return buf;
54405b261ecSmrg}
54505b261ecSmrg
54605b261ecSmrg/***====================================================================***/
54705b261ecSmrg
54805b261ecSmrgchar *
54935c4bbdfSmrgXkbStringText(char *str, unsigned format)
55005b261ecSmrg{
55135c4bbdfSmrg    char *buf;
55235c4bbdfSmrg    register char *in, *out;
55335c4bbdfSmrg    int len;
55435c4bbdfSmrg    Bool ok;
55535c4bbdfSmrg
55635c4bbdfSmrg    if (str == NULL) {
55735c4bbdfSmrg        buf = tbGetBuffer(2);
55835c4bbdfSmrg        buf[0] = '\0';
55935c4bbdfSmrg        return buf;
56005b261ecSmrg    }
56135c4bbdfSmrg    else if (format == XkbXKMFile)
56235c4bbdfSmrg        return str;
56335c4bbdfSmrg    for (ok = TRUE, len = 0, in = str; *in != '\0'; in++, len++) {
56435c4bbdfSmrg        if (!isprint(*in)) {
56535c4bbdfSmrg            ok = FALSE;
56635c4bbdfSmrg            switch (*in) {
56735c4bbdfSmrg            case '\n':
56835c4bbdfSmrg            case '\t':
56935c4bbdfSmrg            case '\v':
57035c4bbdfSmrg            case '\b':
57135c4bbdfSmrg            case '\r':
57235c4bbdfSmrg            case '\f':
57335c4bbdfSmrg                len++;
57435c4bbdfSmrg                break;
57535c4bbdfSmrg            default:
57635c4bbdfSmrg                len += 4;
57735c4bbdfSmrg                break;
57835c4bbdfSmrg            }
57935c4bbdfSmrg        }
58005b261ecSmrg    }
58105b261ecSmrg    if (ok)
58235c4bbdfSmrg        return str;
58335c4bbdfSmrg    buf = tbGetBuffer(len + 1);
58435c4bbdfSmrg    for (in = str, out = buf; *in != '\0'; in++) {
58535c4bbdfSmrg        if (isprint(*in))
58635c4bbdfSmrg            *out++ = *in;
58735c4bbdfSmrg        else {
58835c4bbdfSmrg            *out++ = '\\';
58935c4bbdfSmrg            if (*in == '\n')
59035c4bbdfSmrg                *out++ = 'n';
59135c4bbdfSmrg            else if (*in == '\t')
59235c4bbdfSmrg                *out++ = 't';
59335c4bbdfSmrg            else if (*in == '\v')
59435c4bbdfSmrg                *out++ = 'v';
59535c4bbdfSmrg            else if (*in == '\b')
59635c4bbdfSmrg                *out++ = 'b';
59735c4bbdfSmrg            else if (*in == '\r')
59835c4bbdfSmrg                *out++ = 'r';
59935c4bbdfSmrg            else if (*in == '\f')
60035c4bbdfSmrg                *out++ = 'f';
60135c4bbdfSmrg            else if ((*in == '\033') && (format == XkbXKMFile)) {
60235c4bbdfSmrg                *out++ = 'e';
60335c4bbdfSmrg            }
60435c4bbdfSmrg            else {
60535c4bbdfSmrg                *out++ = '0';
6061b5d61b8Smrg                sprintf(out, "%o", (unsigned char) *in);
60735c4bbdfSmrg                while (*out != '\0')
60835c4bbdfSmrg                    out++;
60935c4bbdfSmrg            }
61035c4bbdfSmrg        }
61105b261ecSmrg    }
61235c4bbdfSmrg    *out++ = '\0';
61305b261ecSmrg    return buf;
61405b261ecSmrg}
61505b261ecSmrg
61605b261ecSmrg/***====================================================================***/
61705b261ecSmrg
61805b261ecSmrgchar *
61935c4bbdfSmrgXkbGeomFPText(int val, unsigned format)
62005b261ecSmrg{
62135c4bbdfSmrg    int whole, frac;
62235c4bbdfSmrg    char *buf;
62305b261ecSmrg
62435c4bbdfSmrg    buf = tbGetBuffer(12);
62535c4bbdfSmrg    if (format == XkbCFile) {
62635c4bbdfSmrg        sprintf(buf, "%d", val);
62705b261ecSmrg    }
62805b261ecSmrg    else {
62935c4bbdfSmrg        whole = val / XkbGeomPtsPerMM;
63035c4bbdfSmrg        frac = val % XkbGeomPtsPerMM;
63135c4bbdfSmrg        if (frac != 0)
63235c4bbdfSmrg            sprintf(buf, "%d.%d", whole, frac);
63335c4bbdfSmrg        else
63435c4bbdfSmrg            sprintf(buf, "%d", whole);
63505b261ecSmrg    }
63605b261ecSmrg    return buf;
63705b261ecSmrg}
63805b261ecSmrg
63905b261ecSmrgchar *
64035c4bbdfSmrgXkbDoodadTypeText(unsigned type, unsigned format)
64105b261ecSmrg{
64235c4bbdfSmrg    char *buf;
64335c4bbdfSmrg
64435c4bbdfSmrg    if (format == XkbCFile) {
64535c4bbdfSmrg        buf = tbGetBuffer(24);
64635c4bbdfSmrg        if (type == XkbOutlineDoodad)
64735c4bbdfSmrg            strcpy(buf, "XkbOutlineDoodad");
64835c4bbdfSmrg        else if (type == XkbSolidDoodad)
64935c4bbdfSmrg            strcpy(buf, "XkbSolidDoodad");
65035c4bbdfSmrg        else if (type == XkbTextDoodad)
65135c4bbdfSmrg            strcpy(buf, "XkbTextDoodad");
65235c4bbdfSmrg        else if (type == XkbIndicatorDoodad)
65335c4bbdfSmrg            strcpy(buf, "XkbIndicatorDoodad");
65435c4bbdfSmrg        else if (type == XkbLogoDoodad)
65535c4bbdfSmrg            strcpy(buf, "XkbLogoDoodad");
65635c4bbdfSmrg        else
65735c4bbdfSmrg            sprintf(buf, "UnknownDoodad%d", type);
65805b261ecSmrg    }
65905b261ecSmrg    else {
66035c4bbdfSmrg        buf = tbGetBuffer(12);
66135c4bbdfSmrg        if (type == XkbOutlineDoodad)
66235c4bbdfSmrg            strcpy(buf, "outline");
66335c4bbdfSmrg        else if (type == XkbSolidDoodad)
66435c4bbdfSmrg            strcpy(buf, "solid");
66535c4bbdfSmrg        else if (type == XkbTextDoodad)
66635c4bbdfSmrg            strcpy(buf, "text");
66735c4bbdfSmrg        else if (type == XkbIndicatorDoodad)
66835c4bbdfSmrg            strcpy(buf, "indicator");
66935c4bbdfSmrg        else if (type == XkbLogoDoodad)
67035c4bbdfSmrg            strcpy(buf, "logo");
67135c4bbdfSmrg        else
67235c4bbdfSmrg            sprintf(buf, "unknown%d", type);
67305b261ecSmrg    }
67405b261ecSmrg    return buf;
67505b261ecSmrg}
67605b261ecSmrg
67735c4bbdfSmrgstatic const char *actionTypeNames[XkbSA_NumActions] = {
67835c4bbdfSmrg    "NoAction",
67935c4bbdfSmrg    "SetMods", "LatchMods", "LockMods",
68035c4bbdfSmrg    "SetGroup", "LatchGroup", "LockGroup",
68105b261ecSmrg    "MovePtr",
68235c4bbdfSmrg    "PtrBtn", "LockPtrBtn",
68305b261ecSmrg    "SetPtrDflt",
68405b261ecSmrg    "ISOLock",
68535c4bbdfSmrg    "Terminate", "SwitchScreen",
68635c4bbdfSmrg    "SetControls", "LockControls",
68705b261ecSmrg    "ActionMessage",
68805b261ecSmrg    "RedirectKey",
68935c4bbdfSmrg    "DeviceBtn", "LockDeviceBtn"
69005b261ecSmrg};
69105b261ecSmrg
69235c4bbdfSmrgconst char *
69335c4bbdfSmrgXkbActionTypeText(unsigned type, unsigned format)
69405b261ecSmrg{
69535c4bbdfSmrg    static char buf[32];
69635c4bbdfSmrg    const char *rtrn;
69735c4bbdfSmrg
69835c4bbdfSmrg    if (type <= XkbSA_LastAction) {
69935c4bbdfSmrg        rtrn = actionTypeNames[type];
70035c4bbdfSmrg        if (format == XkbCFile) {
70135c4bbdfSmrg            snprintf(buf, sizeof(buf), "XkbSA_%s", rtrn);
70235c4bbdfSmrg            return buf;
70335c4bbdfSmrg        }
70435c4bbdfSmrg        return rtrn;
70505b261ecSmrg    }
70635c4bbdfSmrg    snprintf(buf, sizeof(buf), "Private");
70705b261ecSmrg    return buf;
70805b261ecSmrg}
70905b261ecSmrg
71005b261ecSmrg/***====================================================================***/
71105b261ecSmrg
71205b261ecSmrgstatic int
71335c4bbdfSmrgTryCopyStr(char *to, const char *from, int *pLeft)
71405b261ecSmrg{
71535c4bbdfSmrg    register int len;
71635c4bbdfSmrg
71735c4bbdfSmrg    if (*pLeft > 0) {
71835c4bbdfSmrg        len = strlen(from);
71935c4bbdfSmrg        if (len < ((*pLeft) - 3)) {
72035c4bbdfSmrg            strcat(to, from);
72135c4bbdfSmrg            *pLeft -= len;
72235c4bbdfSmrg            return TRUE;
72335c4bbdfSmrg        }
72405b261ecSmrg    }
72535c4bbdfSmrg    *pLeft = -1;
7266747b715Smrg    return FALSE;
72705b261ecSmrg}
72805b261ecSmrg
72935c4bbdfSmrg /*ARGSUSED*/ static Bool
73035c4bbdfSmrgCopyNoActionArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
73105b261ecSmrg{
7326747b715Smrg    return TRUE;
73305b261ecSmrg}
73405b261ecSmrg
73505b261ecSmrgstatic Bool
73635c4bbdfSmrgCopyModActionArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
73705b261ecSmrg{
73835c4bbdfSmrg    XkbModAction *act;
73935c4bbdfSmrg    unsigned tmp;
74035c4bbdfSmrg
74135c4bbdfSmrg    act = &action->mods;
74235c4bbdfSmrg    tmp = XkbModActionVMods(act);
74335c4bbdfSmrg    TryCopyStr(buf, "modifiers=", sz);
74435c4bbdfSmrg    if (act->flags & XkbSA_UseModMapMods)
74535c4bbdfSmrg        TryCopyStr(buf, "modMapMods", sz);
74605b261ecSmrg    else if (act->real_mods || tmp) {
74735c4bbdfSmrg        TryCopyStr(buf,
74835c4bbdfSmrg                   XkbVModMaskText(xkb, act->real_mods, tmp, XkbXKBFile), sz);
74905b261ecSmrg    }
75035c4bbdfSmrg    else
75135c4bbdfSmrg        TryCopyStr(buf, "none", sz);
75235c4bbdfSmrg    if (act->type == XkbSA_LockMods)
75335c4bbdfSmrg        return TRUE;
75435c4bbdfSmrg    if (act->flags & XkbSA_ClearLocks)
75535c4bbdfSmrg        TryCopyStr(buf, ",clearLocks", sz);
75635c4bbdfSmrg    if (act->flags & XkbSA_LatchToLock)
75735c4bbdfSmrg        TryCopyStr(buf, ",latchToLock", sz);
7586747b715Smrg    return TRUE;
75905b261ecSmrg}
76005b261ecSmrg
76135c4bbdfSmrg /*ARGSUSED*/ static Bool
76235c4bbdfSmrgCopyGroupActionArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
76305b261ecSmrg{
76435c4bbdfSmrg    XkbGroupAction *act;
76535c4bbdfSmrg    char tbuf[32];
76635c4bbdfSmrg
76735c4bbdfSmrg    act = &action->group;
76835c4bbdfSmrg    TryCopyStr(buf, "group=", sz);
76935c4bbdfSmrg    if (act->flags & XkbSA_GroupAbsolute)
77035c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act) + 1);
77135c4bbdfSmrg    else if (XkbSAGroup(act) < 0)
77235c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act));
77335c4bbdfSmrg    else
77435c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAGroup(act));
77535c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
77635c4bbdfSmrg    if (act->type == XkbSA_LockGroup)
77735c4bbdfSmrg        return TRUE;
77835c4bbdfSmrg    if (act->flags & XkbSA_ClearLocks)
77935c4bbdfSmrg        TryCopyStr(buf, ",clearLocks", sz);
78035c4bbdfSmrg    if (act->flags & XkbSA_LatchToLock)
78135c4bbdfSmrg        TryCopyStr(buf, ",latchToLock", sz);
7826747b715Smrg    return TRUE;
78305b261ecSmrg}
78405b261ecSmrg
78535c4bbdfSmrg /*ARGSUSED*/ static Bool
78635c4bbdfSmrgCopyMovePtrArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
78705b261ecSmrg{
78835c4bbdfSmrg    XkbPtrAction *act;
78935c4bbdfSmrg    int x, y;
79035c4bbdfSmrg    char tbuf[32];
79135c4bbdfSmrg
79235c4bbdfSmrg    act = &action->ptr;
79335c4bbdfSmrg    x = XkbPtrActionX(act);
79435c4bbdfSmrg    y = XkbPtrActionY(act);
79535c4bbdfSmrg    if ((act->flags & XkbSA_MoveAbsoluteX) || (x < 0))
79635c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "x=%d", x);
79735c4bbdfSmrg    else
79835c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "x=+%d", x);
79935c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
80035c4bbdfSmrg
80135c4bbdfSmrg    if ((act->flags & XkbSA_MoveAbsoluteY) || (y < 0))
80235c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), ",y=%d", y);
80335c4bbdfSmrg    else
80435c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), ",y=+%d", y);
80535c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
80635c4bbdfSmrg    if (act->flags & XkbSA_NoAcceleration)
80735c4bbdfSmrg        TryCopyStr(buf, ",!accel", sz);
8086747b715Smrg    return TRUE;
80905b261ecSmrg}
81005b261ecSmrg
81135c4bbdfSmrg /*ARGSUSED*/ static Bool
81235c4bbdfSmrgCopyPtrBtnArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
81305b261ecSmrg{
81435c4bbdfSmrg    XkbPtrBtnAction *act;
81535c4bbdfSmrg    char tbuf[32];
81635c4bbdfSmrg
81735c4bbdfSmrg    act = &action->btn;
81835c4bbdfSmrg    TryCopyStr(buf, "button=", sz);
81935c4bbdfSmrg    if ((act->button > 0) && (act->button < 6)) {
82035c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "%d", act->button);
82135c4bbdfSmrg        TryCopyStr(buf, tbuf, sz);
82205b261ecSmrg    }
82335c4bbdfSmrg    else
82435c4bbdfSmrg        TryCopyStr(buf, "default", sz);
82535c4bbdfSmrg    if (act->count > 0) {
82635c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), ",count=%d", act->count);
82735c4bbdfSmrg        TryCopyStr(buf, tbuf, sz);
82805b261ecSmrg    }
82935c4bbdfSmrg    if (action->type == XkbSA_LockPtrBtn) {
83035c4bbdfSmrg        switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
83135c4bbdfSmrg        case XkbSA_LockNoLock:
83235c4bbdfSmrg            TryCopyStr(buf, ",affect=unlock", sz);
83335c4bbdfSmrg            break;
83435c4bbdfSmrg        case XkbSA_LockNoUnlock:
83535c4bbdfSmrg            TryCopyStr(buf, ",affect=lock", sz);
83635c4bbdfSmrg            break;
83735c4bbdfSmrg        case XkbSA_LockNoUnlock | XkbSA_LockNoLock:
83835c4bbdfSmrg            TryCopyStr(buf, ",affect=neither", sz);
83935c4bbdfSmrg            break;
84035c4bbdfSmrg        default:
84135c4bbdfSmrg            TryCopyStr(buf, ",affect=both", sz);
84235c4bbdfSmrg            break;
84335c4bbdfSmrg        }
84405b261ecSmrg    }
8456747b715Smrg    return TRUE;
84605b261ecSmrg}
84705b261ecSmrg
84835c4bbdfSmrg /*ARGSUSED*/ static Bool
84935c4bbdfSmrgCopySetPtrDfltArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
85005b261ecSmrg{
85135c4bbdfSmrg    XkbPtrDfltAction *act;
85235c4bbdfSmrg    char tbuf[32];
85335c4bbdfSmrg
85435c4bbdfSmrg    act = &action->dflt;
85535c4bbdfSmrg    if (act->affect == XkbSA_AffectDfltBtn) {
85635c4bbdfSmrg        TryCopyStr(buf, "affect=button,button=", sz);
85735c4bbdfSmrg        if ((act->flags & XkbSA_DfltBtnAbsolute) ||
85835c4bbdfSmrg            (XkbSAPtrDfltValue(act) < 0))
85935c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%d", XkbSAPtrDfltValue(act));
86035c4bbdfSmrg        else
86135c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAPtrDfltValue(act));
86235c4bbdfSmrg        TryCopyStr(buf, tbuf, sz);
86305b261ecSmrg    }
8646747b715Smrg    return TRUE;
86505b261ecSmrg}
86605b261ecSmrg
86705b261ecSmrgstatic Bool
86835c4bbdfSmrgCopyISOLockArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
86905b261ecSmrg{
87035c4bbdfSmrg    XkbISOAction *act;
87135c4bbdfSmrg    char tbuf[64];
87235c4bbdfSmrg
873ed6184dfSmrg    memset(tbuf, 0, sizeof(tbuf));
87435c4bbdfSmrg    act = &action->iso;
87535c4bbdfSmrg    if (act->flags & XkbSA_ISODfltIsGroup) {
87635c4bbdfSmrg        TryCopyStr(tbuf, "group=", sz);
87735c4bbdfSmrg        if (act->flags & XkbSA_GroupAbsolute)
87835c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act) + 1);
87935c4bbdfSmrg        else if (XkbSAGroup(act) < 0)
88035c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act));
88135c4bbdfSmrg        else
88235c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAGroup(act));
88335c4bbdfSmrg        TryCopyStr(buf, tbuf, sz);
88405b261ecSmrg    }
88505b261ecSmrg    else {
88635c4bbdfSmrg        unsigned tmp;
88735c4bbdfSmrg
88835c4bbdfSmrg        tmp = XkbModActionVMods(act);
88935c4bbdfSmrg        TryCopyStr(buf, "modifiers=", sz);
89035c4bbdfSmrg        if (act->flags & XkbSA_UseModMapMods)
89135c4bbdfSmrg            TryCopyStr(buf, "modMapMods", sz);
89235c4bbdfSmrg        else if (act->real_mods || tmp) {
89335c4bbdfSmrg            if (act->real_mods) {
89435c4bbdfSmrg                TryCopyStr(buf, XkbModMaskText(act->real_mods, XkbXKBFile), sz);
89535c4bbdfSmrg                if (tmp)
89635c4bbdfSmrg                    TryCopyStr(buf, "+", sz);
89735c4bbdfSmrg            }
89835c4bbdfSmrg            if (tmp)
89935c4bbdfSmrg                TryCopyStr(buf, XkbVModMaskText(xkb, 0, tmp, XkbXKBFile), sz);
90035c4bbdfSmrg        }
90135c4bbdfSmrg        else
90235c4bbdfSmrg            TryCopyStr(buf, "none", sz);
90305b261ecSmrg    }
90435c4bbdfSmrg    TryCopyStr(buf, ",affect=", sz);
90535c4bbdfSmrg    if ((act->affect & XkbSA_ISOAffectMask) == 0)
90635c4bbdfSmrg        TryCopyStr(buf, "all", sz);
90705b261ecSmrg    else {
90835c4bbdfSmrg        int nOut = 0;
90935c4bbdfSmrg
91035c4bbdfSmrg        if ((act->affect & XkbSA_ISONoAffectMods) == 0) {
91135c4bbdfSmrg            TryCopyStr(buf, "mods", sz);
91235c4bbdfSmrg            nOut++;
91335c4bbdfSmrg        }
91435c4bbdfSmrg        if ((act->affect & XkbSA_ISONoAffectGroup) == 0) {
91535c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sgroups", (nOut > 0 ? "+" : ""));
91635c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
91735c4bbdfSmrg            nOut++;
91835c4bbdfSmrg        }
91935c4bbdfSmrg        if ((act->affect & XkbSA_ISONoAffectPtr) == 0) {
92035c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%spointer", (nOut > 0 ? "+" : ""));
92135c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
92235c4bbdfSmrg            nOut++;
92335c4bbdfSmrg        }
92435c4bbdfSmrg        if ((act->affect & XkbSA_ISONoAffectCtrls) == 0) {
92535c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%scontrols", (nOut > 0 ? "+" : ""));
92635c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
92735c4bbdfSmrg            nOut++;
92835c4bbdfSmrg        }
92905b261ecSmrg    }
9306747b715Smrg    return TRUE;
93105b261ecSmrg}
93205b261ecSmrg
93335c4bbdfSmrg /*ARGSUSED*/ static Bool
93435c4bbdfSmrgCopySwitchScreenArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
93505b261ecSmrg{
93635c4bbdfSmrg    XkbSwitchScreenAction *act;
93735c4bbdfSmrg    char tbuf[32];
93835c4bbdfSmrg
93935c4bbdfSmrg    act = &action->screen;
94035c4bbdfSmrg    if ((act->flags & XkbSA_SwitchAbsolute) || (XkbSAScreen(act) < 0))
94135c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "screen=%d", XkbSAScreen(act));
94235c4bbdfSmrg    else
94335c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "screen=+%d", XkbSAScreen(act));
94435c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
94535c4bbdfSmrg    if (act->flags & XkbSA_SwitchApplication)
94635c4bbdfSmrg        TryCopyStr(buf, ",!same", sz);
94735c4bbdfSmrg    else
94835c4bbdfSmrg        TryCopyStr(buf, ",same", sz);
9496747b715Smrg    return TRUE;
95005b261ecSmrg}
95105b261ecSmrg
95235c4bbdfSmrg /*ARGSUSED*/ static Bool
95335c4bbdfSmrgCopySetLockControlsArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
95405b261ecSmrg{
95535c4bbdfSmrg    XkbCtrlsAction *act;
95635c4bbdfSmrg    unsigned tmp;
95735c4bbdfSmrg    char tbuf[32];
95835c4bbdfSmrg
95935c4bbdfSmrg    act = &action->ctrls;
96035c4bbdfSmrg    tmp = XkbActionCtrls(act);
96135c4bbdfSmrg    TryCopyStr(buf, "controls=", sz);
96235c4bbdfSmrg    if (tmp == 0)
96335c4bbdfSmrg        TryCopyStr(buf, "none", sz);
96435c4bbdfSmrg    else if ((tmp & XkbAllBooleanCtrlsMask) == XkbAllBooleanCtrlsMask)
96535c4bbdfSmrg        TryCopyStr(buf, "all", sz);
96605b261ecSmrg    else {
96735c4bbdfSmrg        int nOut = 0;
96835c4bbdfSmrg
96935c4bbdfSmrg        if (tmp & XkbRepeatKeysMask) {
97035c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sRepeatKeys", (nOut > 0 ? "+" : ""));
97135c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
97235c4bbdfSmrg            nOut++;
97335c4bbdfSmrg        }
97435c4bbdfSmrg        if (tmp & XkbSlowKeysMask) {
97535c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sSlowKeys", (nOut > 0 ? "+" : ""));
97635c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
97735c4bbdfSmrg            nOut++;
97835c4bbdfSmrg        }
97935c4bbdfSmrg        if (tmp & XkbBounceKeysMask) {
98035c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sBounceKeys", (nOut > 0 ? "+" : ""));
98135c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
98235c4bbdfSmrg            nOut++;
98335c4bbdfSmrg        }
98435c4bbdfSmrg        if (tmp & XkbStickyKeysMask) {
98535c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sStickyKeys", (nOut > 0 ? "+" : ""));
98635c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
98735c4bbdfSmrg            nOut++;
98835c4bbdfSmrg        }
98935c4bbdfSmrg        if (tmp & XkbMouseKeysMask) {
99035c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sMouseKeys", (nOut > 0 ? "+" : ""));
99135c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
99235c4bbdfSmrg            nOut++;
99335c4bbdfSmrg        }
99435c4bbdfSmrg        if (tmp & XkbMouseKeysAccelMask) {
99535c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sMouseKeysAccel",
99635c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
99735c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
99835c4bbdfSmrg            nOut++;
99935c4bbdfSmrg        }
100035c4bbdfSmrg        if (tmp & XkbAccessXKeysMask) {
100135c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sAccessXKeys",
100235c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
100335c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
100435c4bbdfSmrg            nOut++;
100535c4bbdfSmrg        }
100635c4bbdfSmrg        if (tmp & XkbAccessXTimeoutMask) {
100735c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sAccessXTimeout",
100835c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
100935c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
101035c4bbdfSmrg            nOut++;
101135c4bbdfSmrg        }
101235c4bbdfSmrg        if (tmp & XkbAccessXFeedbackMask) {
101335c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sAccessXFeedback",
101435c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
101535c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
101635c4bbdfSmrg            nOut++;
101735c4bbdfSmrg        }
101835c4bbdfSmrg        if (tmp & XkbAudibleBellMask) {
101935c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sAudibleBell",
102035c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
102135c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
102235c4bbdfSmrg            nOut++;
102335c4bbdfSmrg        }
102435c4bbdfSmrg        if (tmp & XkbOverlay1Mask) {
102535c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sOverlay1", (nOut > 0 ? "+" : ""));
102635c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
102735c4bbdfSmrg            nOut++;
102835c4bbdfSmrg        }
102935c4bbdfSmrg        if (tmp & XkbOverlay2Mask) {
103035c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sOverlay2", (nOut > 0 ? "+" : ""));
103135c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
103235c4bbdfSmrg            nOut++;
103335c4bbdfSmrg        }
103435c4bbdfSmrg        if (tmp & XkbIgnoreGroupLockMask) {
103535c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sIgnoreGroupLock",
103635c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
103735c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
103835c4bbdfSmrg            nOut++;
103935c4bbdfSmrg        }
104005b261ecSmrg    }
10416747b715Smrg    return TRUE;
104205b261ecSmrg}
104305b261ecSmrg
104435c4bbdfSmrg /*ARGSUSED*/ static Bool
104535c4bbdfSmrgCopyActionMessageArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
104605b261ecSmrg{
104735c4bbdfSmrg    XkbMessageAction *act;
104835c4bbdfSmrg    unsigned all;
104935c4bbdfSmrg    char tbuf[32];
105035c4bbdfSmrg
105135c4bbdfSmrg    act = &action->msg;
105235c4bbdfSmrg    all = XkbSA_MessageOnPress | XkbSA_MessageOnRelease;
105335c4bbdfSmrg    TryCopyStr(buf, "report=", sz);
105435c4bbdfSmrg    if ((act->flags & all) == 0)
105535c4bbdfSmrg        TryCopyStr(buf, "none", sz);
105635c4bbdfSmrg    else if ((act->flags & all) == all)
105735c4bbdfSmrg        TryCopyStr(buf, "all", sz);
105835c4bbdfSmrg    else if (act->flags & XkbSA_MessageOnPress)
105935c4bbdfSmrg        TryCopyStr(buf, "KeyPress", sz);
106035c4bbdfSmrg    else
106135c4bbdfSmrg        TryCopyStr(buf, "KeyRelease", sz);
106235c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->message[0]);
106335c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
106435c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->message[1]);
106535c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
106635c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->message[2]);
106735c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
106835c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->message[3]);
106935c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
107035c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->message[4]);
107135c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
107235c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->message[5]);
107335c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
10746747b715Smrg    return TRUE;
107505b261ecSmrg}
107605b261ecSmrg
107705b261ecSmrgstatic Bool
107835c4bbdfSmrgCopyRedirectKeyArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
107905b261ecSmrg{
108035c4bbdfSmrg    XkbRedirectKeyAction *act;
108135c4bbdfSmrg    char tbuf[32], *tmp;
108235c4bbdfSmrg    unsigned kc;
108335c4bbdfSmrg    unsigned vmods, vmods_mask;
108435c4bbdfSmrg
108535c4bbdfSmrg    act = &action->redirect;
108635c4bbdfSmrg    kc = act->new_key;
108735c4bbdfSmrg    vmods = XkbSARedirectVMods(act);
108835c4bbdfSmrg    vmods_mask = XkbSARedirectVModsMask(act);
108935c4bbdfSmrg    if (xkb && xkb->names && xkb->names->keys && (kc <= xkb->max_key_code) &&
109035c4bbdfSmrg        (xkb->names->keys[kc].name[0] != '\0')) {
109135c4bbdfSmrg        char *kn;
109235c4bbdfSmrg
109335c4bbdfSmrg        kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile);
109435c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "key=%s", kn);
109505b261ecSmrg    }
109635c4bbdfSmrg    else
109735c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "key=%d", kc);
109835c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
109935c4bbdfSmrg    if ((act->mods_mask == 0) && (vmods_mask == 0))
110035c4bbdfSmrg        return TRUE;
110135c4bbdfSmrg    if ((act->mods_mask == XkbAllModifiersMask) &&
110235c4bbdfSmrg        (vmods_mask == XkbAllVirtualModsMask)) {
110335c4bbdfSmrg        tmp = XkbVModMaskText(xkb, act->mods, vmods, XkbXKBFile);
110435c4bbdfSmrg        TryCopyStr(buf, ",mods=", sz);
110535c4bbdfSmrg        TryCopyStr(buf, tmp, sz);
110605b261ecSmrg    }
110705b261ecSmrg    else {
110835c4bbdfSmrg        if ((act->mods_mask & act->mods) || (vmods_mask & vmods)) {
110935c4bbdfSmrg            tmp = XkbVModMaskText(xkb, act->mods_mask & act->mods,
111035c4bbdfSmrg                                  vmods_mask & vmods, XkbXKBFile);
111135c4bbdfSmrg            TryCopyStr(buf, ",mods= ", sz);
111235c4bbdfSmrg            TryCopyStr(buf, tmp, sz);
111335c4bbdfSmrg        }
111435c4bbdfSmrg        if ((act->mods_mask & (~act->mods)) || (vmods_mask & (~vmods))) {
111535c4bbdfSmrg            tmp = XkbVModMaskText(xkb, act->mods_mask & (~act->mods),
111635c4bbdfSmrg                                  vmods_mask & (~vmods), XkbXKBFile);
111735c4bbdfSmrg            TryCopyStr(buf, ",clearMods= ", sz);
111835c4bbdfSmrg            TryCopyStr(buf, tmp, sz);
111935c4bbdfSmrg        }
112005b261ecSmrg    }
11216747b715Smrg    return TRUE;
112205b261ecSmrg}
112305b261ecSmrg
112435c4bbdfSmrg /*ARGSUSED*/ static Bool
112535c4bbdfSmrgCopyDeviceBtnArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
112605b261ecSmrg{
112735c4bbdfSmrg    XkbDeviceBtnAction *act;
112835c4bbdfSmrg    char tbuf[32];
112935c4bbdfSmrg
113035c4bbdfSmrg    act = &action->devbtn;
113135c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), "device= %d", act->device);
113235c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
113335c4bbdfSmrg    TryCopyStr(buf, ",button=", sz);
113435c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), "%d", act->button);
113535c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
113635c4bbdfSmrg    if (act->count > 0) {
113735c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), ",count=%d", act->count);
113835c4bbdfSmrg        TryCopyStr(buf, tbuf, sz);
113905b261ecSmrg    }
114035c4bbdfSmrg    if (action->type == XkbSA_LockDeviceBtn) {
114135c4bbdfSmrg        switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
114235c4bbdfSmrg        case XkbSA_LockNoLock:
114335c4bbdfSmrg            TryCopyStr(buf, ",affect=unlock", sz);
114435c4bbdfSmrg            break;
114535c4bbdfSmrg        case XkbSA_LockNoUnlock:
114635c4bbdfSmrg            TryCopyStr(buf, ",affect=lock", sz);
114735c4bbdfSmrg            break;
114835c4bbdfSmrg        case XkbSA_LockNoUnlock | XkbSA_LockNoLock:
114935c4bbdfSmrg            TryCopyStr(buf, ",affect=neither", sz);
115035c4bbdfSmrg            break;
115135c4bbdfSmrg        default:
115235c4bbdfSmrg            TryCopyStr(buf, ",affect=both", sz);
115335c4bbdfSmrg            break;
115435c4bbdfSmrg        }
115505b261ecSmrg    }
11566747b715Smrg    return TRUE;
115705b261ecSmrg}
115805b261ecSmrg
115935c4bbdfSmrg /*ARGSUSED*/ static Bool
116035c4bbdfSmrgCopyOtherArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
116105b261ecSmrg{
116235c4bbdfSmrg    XkbAnyAction *act;
116335c4bbdfSmrg    char tbuf[32];
116435c4bbdfSmrg
116535c4bbdfSmrg    act = &action->any;
116635c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), "type=0x%02x", act->type);
116735c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
116835c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->data[0]);
116935c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
117035c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->data[1]);
117135c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
117235c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->data[2]);
117335c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
117435c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->data[3]);
117535c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
117635c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->data[4]);
117735c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
117835c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->data[5]);
117935c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
118035c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[6]=0x%02x", act->data[6]);
118135c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
11826747b715Smrg    return TRUE;
118305b261ecSmrg}
118405b261ecSmrg
118535c4bbdfSmrgtypedef Bool (*actionCopy) (XkbDescPtr /* xkb */ ,
118635c4bbdfSmrg                            XkbAction * /* action */ ,
118735c4bbdfSmrg                            char * /* buf */ ,
118835c4bbdfSmrg                            int *       /* sz */
118935c4bbdfSmrg    );
119035c4bbdfSmrg
119135c4bbdfSmrgstatic actionCopy copyActionArgs[XkbSA_NumActions] = {
119235c4bbdfSmrg    CopyNoActionArgs /* NoAction     */ ,
119335c4bbdfSmrg    CopyModActionArgs /* SetMods      */ ,
119435c4bbdfSmrg    CopyModActionArgs /* LatchMods    */ ,
119535c4bbdfSmrg    CopyModActionArgs /* LockMods     */ ,
119635c4bbdfSmrg    CopyGroupActionArgs /* SetGroup     */ ,
119735c4bbdfSmrg    CopyGroupActionArgs /* LatchGroup   */ ,
119835c4bbdfSmrg    CopyGroupActionArgs /* LockGroup    */ ,
119935c4bbdfSmrg    CopyMovePtrArgs /* MovePtr      */ ,
120035c4bbdfSmrg    CopyPtrBtnArgs /* PtrBtn       */ ,
120135c4bbdfSmrg    CopyPtrBtnArgs /* LockPtrBtn   */ ,
120235c4bbdfSmrg    CopySetPtrDfltArgs /* SetPtrDflt   */ ,
120335c4bbdfSmrg    CopyISOLockArgs /* ISOLock      */ ,
120435c4bbdfSmrg    CopyNoActionArgs /* Terminate    */ ,
120535c4bbdfSmrg    CopySwitchScreenArgs /* SwitchScreen */ ,
120635c4bbdfSmrg    CopySetLockControlsArgs /* SetControls  */ ,
120735c4bbdfSmrg    CopySetLockControlsArgs /* LockControls */ ,
120835c4bbdfSmrg    CopyActionMessageArgs /* ActionMessage */ ,
120935c4bbdfSmrg    CopyRedirectKeyArgs /* RedirectKey  */ ,
121035c4bbdfSmrg    CopyDeviceBtnArgs /* DeviceBtn    */ ,
121135c4bbdfSmrg    CopyDeviceBtnArgs           /* LockDeviceBtn */
121205b261ecSmrg};
121305b261ecSmrg
121405b261ecSmrg#define	ACTION_SZ	256
121505b261ecSmrg
121605b261ecSmrgchar *
121735c4bbdfSmrgXkbActionText(XkbDescPtr xkb, XkbAction *action, unsigned format)
121805b261ecSmrg{
121935c4bbdfSmrg    char buf[ACTION_SZ], *tmp;
122035c4bbdfSmrg    int sz;
122135c4bbdfSmrg
122235c4bbdfSmrg    if (format == XkbCFile) {
122335c4bbdfSmrg        snprintf(buf, sizeof(buf),
122435c4bbdfSmrg                 "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }",
122535c4bbdfSmrg                 XkbActionTypeText(action->type, XkbCFile),
122635c4bbdfSmrg                 action->any.data[0], action->any.data[1], action->any.data[2],
122735c4bbdfSmrg                 action->any.data[3], action->any.data[4], action->any.data[5],
122835c4bbdfSmrg                 action->any.data[6]);
122905b261ecSmrg    }
123005b261ecSmrg    else {
123135c4bbdfSmrg        snprintf(buf, sizeof(buf), "%s(",
123235c4bbdfSmrg                 XkbActionTypeText(action->type, XkbXKBFile));
123335c4bbdfSmrg        sz = ACTION_SZ - strlen(buf) + 2;       /* room for close paren and NULL */
123435c4bbdfSmrg        if (action->type < (unsigned) XkbSA_NumActions)
123535c4bbdfSmrg            (*copyActionArgs[action->type]) (xkb, action, buf, &sz);
123635c4bbdfSmrg        else
123735c4bbdfSmrg            CopyOtherArgs(xkb, action, buf, &sz);
123835c4bbdfSmrg        TryCopyStr(buf, ")", &sz);
123905b261ecSmrg    }
124035c4bbdfSmrg    tmp = tbGetBuffer(strlen(buf) + 1);
124135c4bbdfSmrg    if (tmp != NULL)
124235c4bbdfSmrg        strcpy(tmp, buf);
124305b261ecSmrg    return tmp;
124405b261ecSmrg}
124505b261ecSmrg
124605b261ecSmrgchar *
124735c4bbdfSmrgXkbBehaviorText(XkbDescPtr xkb, XkbBehavior * behavior, unsigned format)
124805b261ecSmrg{
124935c4bbdfSmrg    char buf[256], *tmp;
125035c4bbdfSmrg
125135c4bbdfSmrg    if (format == XkbCFile) {
125235c4bbdfSmrg        if (behavior->type == XkbKB_Default)
125335c4bbdfSmrg            snprintf(buf, sizeof(buf), "{   0,    0 }");
125435c4bbdfSmrg        else
125535c4bbdfSmrg            snprintf(buf, sizeof(buf), "{ %3d, 0x%02x }", behavior->type,
125635c4bbdfSmrg                     behavior->data);
125705b261ecSmrg    }
125805b261ecSmrg    else {
125935c4bbdfSmrg        unsigned type, permanent;
126035c4bbdfSmrg
126135c4bbdfSmrg        type = behavior->type & XkbKB_OpMask;
126235c4bbdfSmrg        permanent = ((behavior->type & XkbKB_Permanent) != 0);
126335c4bbdfSmrg
126435c4bbdfSmrg        if (type == XkbKB_Lock) {
126535c4bbdfSmrg            snprintf(buf, sizeof(buf), "lock= %s",
126635c4bbdfSmrg                     (permanent ? "Permanent" : "TRUE"));
126735c4bbdfSmrg        }
126835c4bbdfSmrg        else if (type == XkbKB_RadioGroup) {
126935c4bbdfSmrg            int g;
127035c4bbdfSmrg
127135c4bbdfSmrg            g = ((behavior->data) & (~XkbKB_RGAllowNone)) + 1;
127235c4bbdfSmrg            if (XkbKB_RGAllowNone & behavior->data) {
127335c4bbdfSmrg                snprintf(buf, sizeof(buf), "allowNone,");
127435c4bbdfSmrg                tmp = &buf[strlen(buf)];
127535c4bbdfSmrg            }
127635c4bbdfSmrg            else
127735c4bbdfSmrg                tmp = buf;
127835c4bbdfSmrg            if (permanent)
127935c4bbdfSmrg                sprintf(tmp, "permanentRadioGroup= %d", g);
128035c4bbdfSmrg            else
128135c4bbdfSmrg                sprintf(tmp, "radioGroup= %d", g);
128235c4bbdfSmrg        }
128335c4bbdfSmrg        else if ((type == XkbKB_Overlay1) || (type == XkbKB_Overlay2)) {
128435c4bbdfSmrg            int ndx, kc;
128535c4bbdfSmrg            char *kn;
128635c4bbdfSmrg
128735c4bbdfSmrg            ndx = ((type == XkbKB_Overlay1) ? 1 : 2);
128835c4bbdfSmrg            kc = behavior->data;
128935c4bbdfSmrg            if ((xkb) && (xkb->names) && (xkb->names->keys))
129035c4bbdfSmrg                kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile);
129135c4bbdfSmrg            else {
129235c4bbdfSmrg                static char tbuf[8];
129335c4bbdfSmrg
129435c4bbdfSmrg                snprintf(tbuf, sizeof(tbuf), "%d", kc);
129535c4bbdfSmrg                kn = tbuf;
129635c4bbdfSmrg            }
129735c4bbdfSmrg            if (permanent)
129835c4bbdfSmrg                snprintf(buf, sizeof(buf), "permanentOverlay%d= %s", ndx, kn);
129935c4bbdfSmrg            else
130035c4bbdfSmrg                snprintf(buf, sizeof(buf), "overlay%d= %s", ndx, kn);
130135c4bbdfSmrg        }
130205b261ecSmrg    }
130335c4bbdfSmrg    tmp = tbGetBuffer(strlen(buf) + 1);
130435c4bbdfSmrg    if (tmp != NULL)
130535c4bbdfSmrg        strcpy(tmp, buf);
130605b261ecSmrg    return tmp;
130705b261ecSmrg}
130805b261ecSmrg
130905b261ecSmrg/***====================================================================***/
131005b261ecSmrg
131105b261ecSmrgchar *
131205b261ecSmrgXkbIndentText(unsigned size)
131305b261ecSmrg{
131435c4bbdfSmrg    static char buf[32];
131535c4bbdfSmrg    register int i;
131605b261ecSmrg
131735c4bbdfSmrg    if (size > 31)
131835c4bbdfSmrg        size = 31;
131905b261ecSmrg
132035c4bbdfSmrg    for (i = 0; i < size; i++) {
132135c4bbdfSmrg        buf[i] = ' ';
132205b261ecSmrg    }
132335c4bbdfSmrg    buf[size] = '\0';
132405b261ecSmrg    return buf;
132505b261ecSmrg}
1326