xkbtext.c revision 35c4bbdf
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
5005b261ecSmrg#define	BUFFER_SIZE	512
5105b261ecSmrg
5205b261ecSmrgstatic char textBuffer[BUFFER_SIZE];
5335c4bbdfSmrgstatic int tbNext = 0;
5405b261ecSmrg
5505b261ecSmrgstatic char *
5605b261ecSmrgtbGetBuffer(unsigned size)
5705b261ecSmrg{
5835c4bbdfSmrg    char *rtrn;
5935c4bbdfSmrg
6035c4bbdfSmrg    if (size >= BUFFER_SIZE)
6135c4bbdfSmrg        return NULL;
6235c4bbdfSmrg    if ((BUFFER_SIZE - tbNext) <= size)
6335c4bbdfSmrg        tbNext = 0;
6435c4bbdfSmrg    rtrn = &textBuffer[tbNext];
6535c4bbdfSmrg    tbNext += size;
6605b261ecSmrg    return rtrn;
6705b261ecSmrg}
6805b261ecSmrg
6905b261ecSmrg/***====================================================================***/
7005b261ecSmrg
7105b261ecSmrgchar *
7235c4bbdfSmrgXkbAtomText(Atom atm, unsigned format)
7305b261ecSmrg{
7435c4bbdfSmrg    const char *atmstr;
7535c4bbdfSmrg    char *rtrn, *tmp;
7605b261ecSmrg
776747b715Smrg    atmstr = NameForAtom(atm);
786747b715Smrg    if (atmstr != NULL) {
7935c4bbdfSmrg        int len;
8035c4bbdfSmrg
8135c4bbdfSmrg        len = strlen(atmstr) + 1;
8235c4bbdfSmrg        if (len > BUFFER_SIZE)
8335c4bbdfSmrg            len = BUFFER_SIZE - 2;
8435c4bbdfSmrg        rtrn = tbGetBuffer(len);
8535c4bbdfSmrg        strlcpy(rtrn, atmstr, len);
8605b261ecSmrg    }
8705b261ecSmrg    else {
8835c4bbdfSmrg        rtrn = tbGetBuffer(1);
8935c4bbdfSmrg        rtrn[0] = '\0';
9005b261ecSmrg    }
9135c4bbdfSmrg    if (format == XkbCFile) {
9235c4bbdfSmrg        for (tmp = rtrn; *tmp != '\0'; tmp++) {
9335c4bbdfSmrg            if ((tmp == rtrn) && (!isalpha(*tmp)))
9435c4bbdfSmrg                *tmp = '_';
9535c4bbdfSmrg            else if (!isalnum(*tmp))
9635c4bbdfSmrg                *tmp = '_';
9735c4bbdfSmrg        }
9805b261ecSmrg    }
9935c4bbdfSmrg    return XkbStringText(rtrn, format);
10005b261ecSmrg}
10105b261ecSmrg
10205b261ecSmrg/***====================================================================***/
10305b261ecSmrg
10405b261ecSmrgchar *
10535c4bbdfSmrgXkbVModIndexText(XkbDescPtr xkb, unsigned ndx, unsigned format)
10605b261ecSmrg{
10735c4bbdfSmrg    register int len;
10835c4bbdfSmrg    register Atom *vmodNames;
10935c4bbdfSmrg    char *rtrn;
11035c4bbdfSmrg    const char *tmp;
11135c4bbdfSmrg    char numBuf[20];
11205b261ecSmrg
11305b261ecSmrg    if (xkb && xkb->names)
11435c4bbdfSmrg        vmodNames = xkb->names->vmods;
11535c4bbdfSmrg    else
11635c4bbdfSmrg        vmodNames = NULL;
11735c4bbdfSmrg
11835c4bbdfSmrg    tmp = NULL;
11935c4bbdfSmrg    if (ndx >= XkbNumVirtualMods)
12035c4bbdfSmrg        tmp = "illegal";
12135c4bbdfSmrg    else if (vmodNames && (vmodNames[ndx] != None))
12235c4bbdfSmrg        tmp = NameForAtom(vmodNames[ndx]);
12335c4bbdfSmrg    if (tmp == NULL) {
12435c4bbdfSmrg        snprintf(numBuf, sizeof(numBuf), "%d", ndx);
12535c4bbdfSmrg        tmp = numBuf;
1266747b715Smrg    }
12705b261ecSmrg
12835c4bbdfSmrg    len = strlen(tmp) + 1;
12935c4bbdfSmrg    if (format == XkbCFile)
13035c4bbdfSmrg        len += 4;
13135c4bbdfSmrg    if (len >= BUFFER_SIZE)
13235c4bbdfSmrg        len = BUFFER_SIZE - 1;
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
14305b261ecSmrgchar *
14435c4bbdfSmrgXkbVModMaskText(XkbDescPtr xkb,
14535c4bbdfSmrg                unsigned modMask, unsigned mask, unsigned format)
14605b261ecSmrg{
14735c4bbdfSmrg    register int i, bit;
14835c4bbdfSmrg    int len;
14935c4bbdfSmrg    char *mm, *rtrn;
15035c4bbdfSmrg    char *str, buf[BUFFER_SIZE];
15135c4bbdfSmrg
15235c4bbdfSmrg    if ((modMask == 0) && (mask == 0)) {
15335c4bbdfSmrg        rtrn = tbGetBuffer(5);
15435c4bbdfSmrg        if (format == XkbCFile)
15535c4bbdfSmrg            sprintf(rtrn, "0");
15635c4bbdfSmrg        else
15735c4bbdfSmrg            sprintf(rtrn, "none");
15835c4bbdfSmrg        return rtrn;
15905b261ecSmrg    }
16035c4bbdfSmrg    if (modMask != 0)
16135c4bbdfSmrg        mm = XkbModMaskText(modMask, format);
16235c4bbdfSmrg    else
16335c4bbdfSmrg        mm = NULL;
16405b261ecSmrg
16535c4bbdfSmrg    str = buf;
16635c4bbdfSmrg    buf[0] = '\0';
16705b261ecSmrg    if (mask) {
16835c4bbdfSmrg        char *tmp;
16935c4bbdfSmrg
17035c4bbdfSmrg        for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
17135c4bbdfSmrg            if (mask & bit) {
17235c4bbdfSmrg                tmp = XkbVModIndexText(xkb, i, format);
17335c4bbdfSmrg                len = strlen(tmp) + 1 + (str == buf ? 0 : 1);
17435c4bbdfSmrg                if (format == XkbCFile)
17535c4bbdfSmrg                    len += 4;
17635c4bbdfSmrg                if ((str - (buf + len)) <= BUFFER_SIZE) {
17735c4bbdfSmrg                    if (str != buf) {
17835c4bbdfSmrg                        if (format == XkbCFile)
17935c4bbdfSmrg                            *str++ = '|';
18035c4bbdfSmrg                        else
18135c4bbdfSmrg                            *str++ = '+';
18235c4bbdfSmrg                        len--;
18335c4bbdfSmrg                    }
18435c4bbdfSmrg                }
18535c4bbdfSmrg                if (format == XkbCFile)
18635c4bbdfSmrg                    sprintf(str, "%sMask", tmp);
18735c4bbdfSmrg                else
18835c4bbdfSmrg                    strcpy(str, tmp);
18935c4bbdfSmrg                str = &str[len - 1];
19035c4bbdfSmrg            }
19135c4bbdfSmrg        }
19235c4bbdfSmrg        str = buf;
19305b261ecSmrg    }
19435c4bbdfSmrg    else
19535c4bbdfSmrg        str = NULL;
19635c4bbdfSmrg    if (mm)
19735c4bbdfSmrg        len = strlen(mm);
19835c4bbdfSmrg    else
19935c4bbdfSmrg        len = 0;
20005b261ecSmrg    if (str)
20135c4bbdfSmrg        len += strlen(str) + (mm == NULL ? 0 : 1);
20235c4bbdfSmrg    if (len >= BUFFER_SIZE)
20335c4bbdfSmrg        len = BUFFER_SIZE - 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';
60635c4bbdfSmrg                sprintf(out, "%o", *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
87335c4bbdfSmrg    act = &action->iso;
87435c4bbdfSmrg    if (act->flags & XkbSA_ISODfltIsGroup) {
87535c4bbdfSmrg        TryCopyStr(tbuf, "group=", sz);
87635c4bbdfSmrg        if (act->flags & XkbSA_GroupAbsolute)
87735c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act) + 1);
87835c4bbdfSmrg        else if (XkbSAGroup(act) < 0)
87935c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act));
88035c4bbdfSmrg        else
88135c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAGroup(act));
88235c4bbdfSmrg        TryCopyStr(buf, tbuf, sz);
88305b261ecSmrg    }
88405b261ecSmrg    else {
88535c4bbdfSmrg        unsigned tmp;
88635c4bbdfSmrg
88735c4bbdfSmrg        tmp = XkbModActionVMods(act);
88835c4bbdfSmrg        TryCopyStr(buf, "modifiers=", sz);
88935c4bbdfSmrg        if (act->flags & XkbSA_UseModMapMods)
89035c4bbdfSmrg            TryCopyStr(buf, "modMapMods", sz);
89135c4bbdfSmrg        else if (act->real_mods || tmp) {
89235c4bbdfSmrg            if (act->real_mods) {
89335c4bbdfSmrg                TryCopyStr(buf, XkbModMaskText(act->real_mods, XkbXKBFile), sz);
89435c4bbdfSmrg                if (tmp)
89535c4bbdfSmrg                    TryCopyStr(buf, "+", sz);
89635c4bbdfSmrg            }
89735c4bbdfSmrg            if (tmp)
89835c4bbdfSmrg                TryCopyStr(buf, XkbVModMaskText(xkb, 0, tmp, XkbXKBFile), sz);
89935c4bbdfSmrg        }
90035c4bbdfSmrg        else
90135c4bbdfSmrg            TryCopyStr(buf, "none", sz);
90205b261ecSmrg    }
90335c4bbdfSmrg    TryCopyStr(buf, ",affect=", sz);
90435c4bbdfSmrg    if ((act->affect & XkbSA_ISOAffectMask) == 0)
90535c4bbdfSmrg        TryCopyStr(buf, "all", sz);
90605b261ecSmrg    else {
90735c4bbdfSmrg        int nOut = 0;
90835c4bbdfSmrg
90935c4bbdfSmrg        if ((act->affect & XkbSA_ISONoAffectMods) == 0) {
91035c4bbdfSmrg            TryCopyStr(buf, "mods", sz);
91135c4bbdfSmrg            nOut++;
91235c4bbdfSmrg        }
91335c4bbdfSmrg        if ((act->affect & XkbSA_ISONoAffectGroup) == 0) {
91435c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sgroups", (nOut > 0 ? "+" : ""));
91535c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
91635c4bbdfSmrg            nOut++;
91735c4bbdfSmrg        }
91835c4bbdfSmrg        if ((act->affect & XkbSA_ISONoAffectPtr) == 0) {
91935c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%spointer", (nOut > 0 ? "+" : ""));
92035c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
92135c4bbdfSmrg            nOut++;
92235c4bbdfSmrg        }
92335c4bbdfSmrg        if ((act->affect & XkbSA_ISONoAffectCtrls) == 0) {
92435c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%scontrols", (nOut > 0 ? "+" : ""));
92535c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
92635c4bbdfSmrg            nOut++;
92735c4bbdfSmrg        }
92805b261ecSmrg    }
9296747b715Smrg    return TRUE;
93005b261ecSmrg}
93105b261ecSmrg
93235c4bbdfSmrg /*ARGSUSED*/ static Bool
93335c4bbdfSmrgCopySwitchScreenArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
93405b261ecSmrg{
93535c4bbdfSmrg    XkbSwitchScreenAction *act;
93635c4bbdfSmrg    char tbuf[32];
93735c4bbdfSmrg
93835c4bbdfSmrg    act = &action->screen;
93935c4bbdfSmrg    if ((act->flags & XkbSA_SwitchAbsolute) || (XkbSAScreen(act) < 0))
94035c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "screen=%d", XkbSAScreen(act));
94135c4bbdfSmrg    else
94235c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "screen=+%d", XkbSAScreen(act));
94335c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
94435c4bbdfSmrg    if (act->flags & XkbSA_SwitchApplication)
94535c4bbdfSmrg        TryCopyStr(buf, ",!same", sz);
94635c4bbdfSmrg    else
94735c4bbdfSmrg        TryCopyStr(buf, ",same", sz);
9486747b715Smrg    return TRUE;
94905b261ecSmrg}
95005b261ecSmrg
95135c4bbdfSmrg /*ARGSUSED*/ static Bool
95235c4bbdfSmrgCopySetLockControlsArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
95305b261ecSmrg{
95435c4bbdfSmrg    XkbCtrlsAction *act;
95535c4bbdfSmrg    unsigned tmp;
95635c4bbdfSmrg    char tbuf[32];
95735c4bbdfSmrg
95835c4bbdfSmrg    act = &action->ctrls;
95935c4bbdfSmrg    tmp = XkbActionCtrls(act);
96035c4bbdfSmrg    TryCopyStr(buf, "controls=", sz);
96135c4bbdfSmrg    if (tmp == 0)
96235c4bbdfSmrg        TryCopyStr(buf, "none", sz);
96335c4bbdfSmrg    else if ((tmp & XkbAllBooleanCtrlsMask) == XkbAllBooleanCtrlsMask)
96435c4bbdfSmrg        TryCopyStr(buf, "all", sz);
96505b261ecSmrg    else {
96635c4bbdfSmrg        int nOut = 0;
96735c4bbdfSmrg
96835c4bbdfSmrg        if (tmp & XkbRepeatKeysMask) {
96935c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sRepeatKeys", (nOut > 0 ? "+" : ""));
97035c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
97135c4bbdfSmrg            nOut++;
97235c4bbdfSmrg        }
97335c4bbdfSmrg        if (tmp & XkbSlowKeysMask) {
97435c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sSlowKeys", (nOut > 0 ? "+" : ""));
97535c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
97635c4bbdfSmrg            nOut++;
97735c4bbdfSmrg        }
97835c4bbdfSmrg        if (tmp & XkbBounceKeysMask) {
97935c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sBounceKeys", (nOut > 0 ? "+" : ""));
98035c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
98135c4bbdfSmrg            nOut++;
98235c4bbdfSmrg        }
98335c4bbdfSmrg        if (tmp & XkbStickyKeysMask) {
98435c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sStickyKeys", (nOut > 0 ? "+" : ""));
98535c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
98635c4bbdfSmrg            nOut++;
98735c4bbdfSmrg        }
98835c4bbdfSmrg        if (tmp & XkbMouseKeysMask) {
98935c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sMouseKeys", (nOut > 0 ? "+" : ""));
99035c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
99135c4bbdfSmrg            nOut++;
99235c4bbdfSmrg        }
99335c4bbdfSmrg        if (tmp & XkbMouseKeysAccelMask) {
99435c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sMouseKeysAccel",
99535c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
99635c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
99735c4bbdfSmrg            nOut++;
99835c4bbdfSmrg        }
99935c4bbdfSmrg        if (tmp & XkbAccessXKeysMask) {
100035c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sAccessXKeys",
100135c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
100235c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
100335c4bbdfSmrg            nOut++;
100435c4bbdfSmrg        }
100535c4bbdfSmrg        if (tmp & XkbAccessXTimeoutMask) {
100635c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sAccessXTimeout",
100735c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
100835c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
100935c4bbdfSmrg            nOut++;
101035c4bbdfSmrg        }
101135c4bbdfSmrg        if (tmp & XkbAccessXFeedbackMask) {
101235c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sAccessXFeedback",
101335c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
101435c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
101535c4bbdfSmrg            nOut++;
101635c4bbdfSmrg        }
101735c4bbdfSmrg        if (tmp & XkbAudibleBellMask) {
101835c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sAudibleBell",
101935c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
102035c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
102135c4bbdfSmrg            nOut++;
102235c4bbdfSmrg        }
102335c4bbdfSmrg        if (tmp & XkbOverlay1Mask) {
102435c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sOverlay1", (nOut > 0 ? "+" : ""));
102535c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
102635c4bbdfSmrg            nOut++;
102735c4bbdfSmrg        }
102835c4bbdfSmrg        if (tmp & XkbOverlay2Mask) {
102935c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sOverlay2", (nOut > 0 ? "+" : ""));
103035c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
103135c4bbdfSmrg            nOut++;
103235c4bbdfSmrg        }
103335c4bbdfSmrg        if (tmp & XkbIgnoreGroupLockMask) {
103435c4bbdfSmrg            snprintf(tbuf, sizeof(tbuf), "%sIgnoreGroupLock",
103535c4bbdfSmrg                     (nOut > 0 ? "+" : ""));
103635c4bbdfSmrg            TryCopyStr(buf, tbuf, sz);
103735c4bbdfSmrg            nOut++;
103835c4bbdfSmrg        }
103905b261ecSmrg    }
10406747b715Smrg    return TRUE;
104105b261ecSmrg}
104205b261ecSmrg
104335c4bbdfSmrg /*ARGSUSED*/ static Bool
104435c4bbdfSmrgCopyActionMessageArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
104505b261ecSmrg{
104635c4bbdfSmrg    XkbMessageAction *act;
104735c4bbdfSmrg    unsigned all;
104835c4bbdfSmrg    char tbuf[32];
104935c4bbdfSmrg
105035c4bbdfSmrg    act = &action->msg;
105135c4bbdfSmrg    all = XkbSA_MessageOnPress | XkbSA_MessageOnRelease;
105235c4bbdfSmrg    TryCopyStr(buf, "report=", sz);
105335c4bbdfSmrg    if ((act->flags & all) == 0)
105435c4bbdfSmrg        TryCopyStr(buf, "none", sz);
105535c4bbdfSmrg    else if ((act->flags & all) == all)
105635c4bbdfSmrg        TryCopyStr(buf, "all", sz);
105735c4bbdfSmrg    else if (act->flags & XkbSA_MessageOnPress)
105835c4bbdfSmrg        TryCopyStr(buf, "KeyPress", sz);
105935c4bbdfSmrg    else
106035c4bbdfSmrg        TryCopyStr(buf, "KeyRelease", sz);
106135c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->message[0]);
106235c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
106335c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->message[1]);
106435c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
106535c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->message[2]);
106635c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
106735c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->message[3]);
106835c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
106935c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->message[4]);
107035c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
107135c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->message[5]);
107235c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
10736747b715Smrg    return TRUE;
107405b261ecSmrg}
107505b261ecSmrg
107605b261ecSmrgstatic Bool
107735c4bbdfSmrgCopyRedirectKeyArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
107805b261ecSmrg{
107935c4bbdfSmrg    XkbRedirectKeyAction *act;
108035c4bbdfSmrg    char tbuf[32], *tmp;
108135c4bbdfSmrg    unsigned kc;
108235c4bbdfSmrg    unsigned vmods, vmods_mask;
108335c4bbdfSmrg
108435c4bbdfSmrg    act = &action->redirect;
108535c4bbdfSmrg    kc = act->new_key;
108635c4bbdfSmrg    vmods = XkbSARedirectVMods(act);
108735c4bbdfSmrg    vmods_mask = XkbSARedirectVModsMask(act);
108835c4bbdfSmrg    if (xkb && xkb->names && xkb->names->keys && (kc <= xkb->max_key_code) &&
108935c4bbdfSmrg        (xkb->names->keys[kc].name[0] != '\0')) {
109035c4bbdfSmrg        char *kn;
109135c4bbdfSmrg
109235c4bbdfSmrg        kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile);
109335c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "key=%s", kn);
109405b261ecSmrg    }
109535c4bbdfSmrg    else
109635c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), "key=%d", kc);
109735c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
109835c4bbdfSmrg    if ((act->mods_mask == 0) && (vmods_mask == 0))
109935c4bbdfSmrg        return TRUE;
110035c4bbdfSmrg    if ((act->mods_mask == XkbAllModifiersMask) &&
110135c4bbdfSmrg        (vmods_mask == XkbAllVirtualModsMask)) {
110235c4bbdfSmrg        tmp = XkbVModMaskText(xkb, act->mods, vmods, XkbXKBFile);
110335c4bbdfSmrg        TryCopyStr(buf, ",mods=", sz);
110435c4bbdfSmrg        TryCopyStr(buf, tmp, sz);
110505b261ecSmrg    }
110605b261ecSmrg    else {
110735c4bbdfSmrg        if ((act->mods_mask & act->mods) || (vmods_mask & vmods)) {
110835c4bbdfSmrg            tmp = XkbVModMaskText(xkb, act->mods_mask & act->mods,
110935c4bbdfSmrg                                  vmods_mask & vmods, XkbXKBFile);
111035c4bbdfSmrg            TryCopyStr(buf, ",mods= ", sz);
111135c4bbdfSmrg            TryCopyStr(buf, tmp, sz);
111235c4bbdfSmrg        }
111335c4bbdfSmrg        if ((act->mods_mask & (~act->mods)) || (vmods_mask & (~vmods))) {
111435c4bbdfSmrg            tmp = XkbVModMaskText(xkb, act->mods_mask & (~act->mods),
111535c4bbdfSmrg                                  vmods_mask & (~vmods), XkbXKBFile);
111635c4bbdfSmrg            TryCopyStr(buf, ",clearMods= ", sz);
111735c4bbdfSmrg            TryCopyStr(buf, tmp, sz);
111835c4bbdfSmrg        }
111905b261ecSmrg    }
11206747b715Smrg    return TRUE;
112105b261ecSmrg}
112205b261ecSmrg
112335c4bbdfSmrg /*ARGSUSED*/ static Bool
112435c4bbdfSmrgCopyDeviceBtnArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
112505b261ecSmrg{
112635c4bbdfSmrg    XkbDeviceBtnAction *act;
112735c4bbdfSmrg    char tbuf[32];
112835c4bbdfSmrg
112935c4bbdfSmrg    act = &action->devbtn;
113035c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), "device= %d", act->device);
113135c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
113235c4bbdfSmrg    TryCopyStr(buf, ",button=", sz);
113335c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), "%d", act->button);
113435c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
113535c4bbdfSmrg    if (act->count > 0) {
113635c4bbdfSmrg        snprintf(tbuf, sizeof(tbuf), ",count=%d", act->count);
113735c4bbdfSmrg        TryCopyStr(buf, tbuf, sz);
113805b261ecSmrg    }
113935c4bbdfSmrg    if (action->type == XkbSA_LockDeviceBtn) {
114035c4bbdfSmrg        switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
114135c4bbdfSmrg        case XkbSA_LockNoLock:
114235c4bbdfSmrg            TryCopyStr(buf, ",affect=unlock", sz);
114335c4bbdfSmrg            break;
114435c4bbdfSmrg        case XkbSA_LockNoUnlock:
114535c4bbdfSmrg            TryCopyStr(buf, ",affect=lock", sz);
114635c4bbdfSmrg            break;
114735c4bbdfSmrg        case XkbSA_LockNoUnlock | XkbSA_LockNoLock:
114835c4bbdfSmrg            TryCopyStr(buf, ",affect=neither", sz);
114935c4bbdfSmrg            break;
115035c4bbdfSmrg        default:
115135c4bbdfSmrg            TryCopyStr(buf, ",affect=both", sz);
115235c4bbdfSmrg            break;
115335c4bbdfSmrg        }
115405b261ecSmrg    }
11556747b715Smrg    return TRUE;
115605b261ecSmrg}
115705b261ecSmrg
115835c4bbdfSmrg /*ARGSUSED*/ static Bool
115935c4bbdfSmrgCopyOtherArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
116005b261ecSmrg{
116135c4bbdfSmrg    XkbAnyAction *act;
116235c4bbdfSmrg    char tbuf[32];
116335c4bbdfSmrg
116435c4bbdfSmrg    act = &action->any;
116535c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), "type=0x%02x", act->type);
116635c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
116735c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->data[0]);
116835c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
116935c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->data[1]);
117035c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
117135c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->data[2]);
117235c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
117335c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->data[3]);
117435c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
117535c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->data[4]);
117635c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
117735c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->data[5]);
117835c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
117935c4bbdfSmrg    snprintf(tbuf, sizeof(tbuf), ",data[6]=0x%02x", act->data[6]);
118035c4bbdfSmrg    TryCopyStr(buf, tbuf, sz);
11816747b715Smrg    return TRUE;
118205b261ecSmrg}
118305b261ecSmrg
118435c4bbdfSmrgtypedef Bool (*actionCopy) (XkbDescPtr /* xkb */ ,
118535c4bbdfSmrg                            XkbAction * /* action */ ,
118635c4bbdfSmrg                            char * /* buf */ ,
118735c4bbdfSmrg                            int *       /* sz */
118835c4bbdfSmrg    );
118935c4bbdfSmrg
119035c4bbdfSmrgstatic actionCopy copyActionArgs[XkbSA_NumActions] = {
119135c4bbdfSmrg    CopyNoActionArgs /* NoAction     */ ,
119235c4bbdfSmrg    CopyModActionArgs /* SetMods      */ ,
119335c4bbdfSmrg    CopyModActionArgs /* LatchMods    */ ,
119435c4bbdfSmrg    CopyModActionArgs /* LockMods     */ ,
119535c4bbdfSmrg    CopyGroupActionArgs /* SetGroup     */ ,
119635c4bbdfSmrg    CopyGroupActionArgs /* LatchGroup   */ ,
119735c4bbdfSmrg    CopyGroupActionArgs /* LockGroup    */ ,
119835c4bbdfSmrg    CopyMovePtrArgs /* MovePtr      */ ,
119935c4bbdfSmrg    CopyPtrBtnArgs /* PtrBtn       */ ,
120035c4bbdfSmrg    CopyPtrBtnArgs /* LockPtrBtn   */ ,
120135c4bbdfSmrg    CopySetPtrDfltArgs /* SetPtrDflt   */ ,
120235c4bbdfSmrg    CopyISOLockArgs /* ISOLock      */ ,
120335c4bbdfSmrg    CopyNoActionArgs /* Terminate    */ ,
120435c4bbdfSmrg    CopySwitchScreenArgs /* SwitchScreen */ ,
120535c4bbdfSmrg    CopySetLockControlsArgs /* SetControls  */ ,
120635c4bbdfSmrg    CopySetLockControlsArgs /* LockControls */ ,
120735c4bbdfSmrg    CopyActionMessageArgs /* ActionMessage */ ,
120835c4bbdfSmrg    CopyRedirectKeyArgs /* RedirectKey  */ ,
120935c4bbdfSmrg    CopyDeviceBtnArgs /* DeviceBtn    */ ,
121035c4bbdfSmrg    CopyDeviceBtnArgs           /* LockDeviceBtn */
121105b261ecSmrg};
121205b261ecSmrg
121305b261ecSmrg#define	ACTION_SZ	256
121405b261ecSmrg
121505b261ecSmrgchar *
121635c4bbdfSmrgXkbActionText(XkbDescPtr xkb, XkbAction *action, unsigned format)
121705b261ecSmrg{
121835c4bbdfSmrg    char buf[ACTION_SZ], *tmp;
121935c4bbdfSmrg    int sz;
122035c4bbdfSmrg
122135c4bbdfSmrg    if (format == XkbCFile) {
122235c4bbdfSmrg        snprintf(buf, sizeof(buf),
122335c4bbdfSmrg                 "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }",
122435c4bbdfSmrg                 XkbActionTypeText(action->type, XkbCFile),
122535c4bbdfSmrg                 action->any.data[0], action->any.data[1], action->any.data[2],
122635c4bbdfSmrg                 action->any.data[3], action->any.data[4], action->any.data[5],
122735c4bbdfSmrg                 action->any.data[6]);
122805b261ecSmrg    }
122905b261ecSmrg    else {
123035c4bbdfSmrg        snprintf(buf, sizeof(buf), "%s(",
123135c4bbdfSmrg                 XkbActionTypeText(action->type, XkbXKBFile));
123235c4bbdfSmrg        sz = ACTION_SZ - strlen(buf) + 2;       /* room for close paren and NULL */
123335c4bbdfSmrg        if (action->type < (unsigned) XkbSA_NumActions)
123435c4bbdfSmrg            (*copyActionArgs[action->type]) (xkb, action, buf, &sz);
123535c4bbdfSmrg        else
123635c4bbdfSmrg            CopyOtherArgs(xkb, action, buf, &sz);
123735c4bbdfSmrg        TryCopyStr(buf, ")", &sz);
123805b261ecSmrg    }
123935c4bbdfSmrg    tmp = tbGetBuffer(strlen(buf) + 1);
124035c4bbdfSmrg    if (tmp != NULL)
124135c4bbdfSmrg        strcpy(tmp, buf);
124205b261ecSmrg    return tmp;
124305b261ecSmrg}
124405b261ecSmrg
124505b261ecSmrgchar *
124635c4bbdfSmrgXkbBehaviorText(XkbDescPtr xkb, XkbBehavior * behavior, unsigned format)
124705b261ecSmrg{
124835c4bbdfSmrg    char buf[256], *tmp;
124935c4bbdfSmrg
125035c4bbdfSmrg    if (format == XkbCFile) {
125135c4bbdfSmrg        if (behavior->type == XkbKB_Default)
125235c4bbdfSmrg            snprintf(buf, sizeof(buf), "{   0,    0 }");
125335c4bbdfSmrg        else
125435c4bbdfSmrg            snprintf(buf, sizeof(buf), "{ %3d, 0x%02x }", behavior->type,
125535c4bbdfSmrg                     behavior->data);
125605b261ecSmrg    }
125705b261ecSmrg    else {
125835c4bbdfSmrg        unsigned type, permanent;
125935c4bbdfSmrg
126035c4bbdfSmrg        type = behavior->type & XkbKB_OpMask;
126135c4bbdfSmrg        permanent = ((behavior->type & XkbKB_Permanent) != 0);
126235c4bbdfSmrg
126335c4bbdfSmrg        if (type == XkbKB_Lock) {
126435c4bbdfSmrg            snprintf(buf, sizeof(buf), "lock= %s",
126535c4bbdfSmrg                     (permanent ? "Permanent" : "TRUE"));
126635c4bbdfSmrg        }
126735c4bbdfSmrg        else if (type == XkbKB_RadioGroup) {
126835c4bbdfSmrg            int g;
126935c4bbdfSmrg
127035c4bbdfSmrg            g = ((behavior->data) & (~XkbKB_RGAllowNone)) + 1;
127135c4bbdfSmrg            if (XkbKB_RGAllowNone & behavior->data) {
127235c4bbdfSmrg                snprintf(buf, sizeof(buf), "allowNone,");
127335c4bbdfSmrg                tmp = &buf[strlen(buf)];
127435c4bbdfSmrg            }
127535c4bbdfSmrg            else
127635c4bbdfSmrg                tmp = buf;
127735c4bbdfSmrg            if (permanent)
127835c4bbdfSmrg                sprintf(tmp, "permanentRadioGroup= %d", g);
127935c4bbdfSmrg            else
128035c4bbdfSmrg                sprintf(tmp, "radioGroup= %d", g);
128135c4bbdfSmrg        }
128235c4bbdfSmrg        else if ((type == XkbKB_Overlay1) || (type == XkbKB_Overlay2)) {
128335c4bbdfSmrg            int ndx, kc;
128435c4bbdfSmrg            char *kn;
128535c4bbdfSmrg
128635c4bbdfSmrg            ndx = ((type == XkbKB_Overlay1) ? 1 : 2);
128735c4bbdfSmrg            kc = behavior->data;
128835c4bbdfSmrg            if ((xkb) && (xkb->names) && (xkb->names->keys))
128935c4bbdfSmrg                kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile);
129035c4bbdfSmrg            else {
129135c4bbdfSmrg                static char tbuf[8];
129235c4bbdfSmrg
129335c4bbdfSmrg                snprintf(tbuf, sizeof(tbuf), "%d", kc);
129435c4bbdfSmrg                kn = tbuf;
129535c4bbdfSmrg            }
129635c4bbdfSmrg            if (permanent)
129735c4bbdfSmrg                snprintf(buf, sizeof(buf), "permanentOverlay%d= %s", ndx, kn);
129835c4bbdfSmrg            else
129935c4bbdfSmrg                snprintf(buf, sizeof(buf), "overlay%d= %s", ndx, kn);
130035c4bbdfSmrg        }
130105b261ecSmrg    }
130235c4bbdfSmrg    tmp = tbGetBuffer(strlen(buf) + 1);
130335c4bbdfSmrg    if (tmp != NULL)
130435c4bbdfSmrg        strcpy(tmp, buf);
130505b261ecSmrg    return tmp;
130605b261ecSmrg}
130705b261ecSmrg
130805b261ecSmrg/***====================================================================***/
130905b261ecSmrg
131005b261ecSmrgchar *
131105b261ecSmrgXkbIndentText(unsigned size)
131205b261ecSmrg{
131335c4bbdfSmrg    static char buf[32];
131435c4bbdfSmrg    register int i;
131505b261ecSmrg
131635c4bbdfSmrg    if (size > 31)
131735c4bbdfSmrg        size = 31;
131805b261ecSmrg
131935c4bbdfSmrg    for (i = 0; i < size; i++) {
132035c4bbdfSmrg        buf[i] = ' ';
132105b261ecSmrg    }
132235c4bbdfSmrg    buf[size] = '\0';
132305b261ecSmrg    return buf;
132405b261ecSmrg}
1325