xkbtext.c revision 70728a38
18c9fbc29Smrg/************************************************************
28c9fbc29Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
38c9fbc29Smrg
48c9fbc29Smrg Permission to use, copy, modify, and distribute this
58c9fbc29Smrg software and its documentation for any purpose and without
68c9fbc29Smrg fee is hereby granted, provided that the above copyright
78c9fbc29Smrg notice appear in all copies and that both that copyright
88c9fbc29Smrg notice and this permission notice appear in supporting
94cd6a3aeSmrg documentation, and that the name of Silicon Graphics not be
104cd6a3aeSmrg used in advertising or publicity pertaining to distribution
118c9fbc29Smrg of the software without specific prior written permission.
124cd6a3aeSmrg Silicon Graphics makes no representation about the suitability
138c9fbc29Smrg of this software for any purpose. It is provided "as is"
148c9fbc29Smrg without any express or implied warranty.
154cd6a3aeSmrg
164cd6a3aeSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
174cd6a3aeSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
188c9fbc29Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
194cd6a3aeSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
204cd6a3aeSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
214cd6a3aeSmrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
228c9fbc29Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
238c9fbc29Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
248c9fbc29Smrg
258c9fbc29Smrg ********************************************************/
268c9fbc29Smrg
278c9fbc29Smrg#ifdef HAVE_DIX_CONFIG_H
288c9fbc29Smrg#include <dix-config.h>
298c9fbc29Smrg#elif defined(HAVE_CONFIG_H)
308c9fbc29Smrg#include <config.h>
318c9fbc29Smrg#endif
328c9fbc29Smrg
338c9fbc29Smrg#include <stdio.h>
348c9fbc29Smrg#include <ctype.h>
358c9fbc29Smrg#include <stdlib.h>
368c9fbc29Smrg
378c9fbc29Smrg#include <X11/Xos.h>
388c9fbc29Smrg
398c9fbc29Smrg
408c9fbc29Smrg#include <X11/Xlib.h>
418c9fbc29Smrg#include <X11/XKBlib.h>
428c9fbc29Smrg#include <X11/extensions/XKBgeom.h>
438c9fbc29Smrg
448c9fbc29Smrg#include "XKMformat.h"
458c9fbc29Smrg#include "XKBfileInt.h"
468c9fbc29Smrg
478c9fbc29Smrg
488c9fbc29Smrg/***====================================================================***/
498c9fbc29Smrg
508c9fbc29Smrg#define	BUFFER_SIZE	512
518c9fbc29Smrg
528c9fbc29Smrgstatic char textBuffer[BUFFER_SIZE];
5370728a38Smrgstatic int tbNext = 0;
548c9fbc29Smrg
558c9fbc29Smrgstatic char *
568c9fbc29SmrgtbGetBuffer(unsigned size)
578c9fbc29Smrg{
5870728a38Smrg    char *rtrn;
5970728a38Smrg
6070728a38Smrg    if (size >= BUFFER_SIZE)
6170728a38Smrg        return NULL;
6270728a38Smrg    if ((BUFFER_SIZE - tbNext) <= size)
6370728a38Smrg        tbNext = 0;
6470728a38Smrg    rtrn = &textBuffer[tbNext];
6570728a38Smrg    tbNext += size;
668c9fbc29Smrg    return rtrn;
678c9fbc29Smrg}
688c9fbc29Smrg
698c9fbc29Smrg/***====================================================================***/
708c9fbc29Smrg
718c9fbc29Smrgchar *
7270728a38SmrgXkbAtomText(Display *dpy, Atom atm, unsigned format)
738c9fbc29Smrg{
7470728a38Smrg    char *rtrn, *tmp;
7570728a38Smrg
7670728a38Smrg    tmp = XkbAtomGetString(dpy, atm);
7770728a38Smrg    if (tmp != NULL) {
7870728a38Smrg        int len;
7970728a38Smrg
8070728a38Smrg        len = strlen(tmp) + 1;
8170728a38Smrg        if (len > BUFFER_SIZE)
8270728a38Smrg            len = BUFFER_SIZE - 2;
8370728a38Smrg        rtrn = tbGetBuffer(len);
8470728a38Smrg        strncpy(rtrn, tmp, len);
8570728a38Smrg        rtrn[len] = '\0';
868c9fbc29Smrg        _XkbFree(tmp);
878c9fbc29Smrg    }
888c9fbc29Smrg    else {
8970728a38Smrg        rtrn = tbGetBuffer(1);
9070728a38Smrg        rtrn[0] = '\0';
9170728a38Smrg    }
9270728a38Smrg    if (format == XkbCFile) {
9370728a38Smrg        for (tmp = rtrn; *tmp != '\0'; tmp++) {
9470728a38Smrg            if ((tmp == rtrn) && (!isalpha(*tmp)))
9570728a38Smrg                *tmp = '_';
9670728a38Smrg            else if (!isalnum(*tmp))
9770728a38Smrg                *tmp = '_';
9870728a38Smrg        }
9970728a38Smrg    }
10070728a38Smrg    return XkbStringText(rtrn, format);
1018c9fbc29Smrg}
1028c9fbc29Smrg
1038c9fbc29Smrg/***====================================================================***/
1048c9fbc29Smrg
1058c9fbc29Smrgchar *
10670728a38SmrgXkbVModIndexText(Display *dpy, XkbDescPtr xkb, unsigned ndx, unsigned format)
1078c9fbc29Smrg{
10870728a38Smrg    register int len;
10970728a38Smrg    register Atom *vmodNames;
11070728a38Smrg    char *rtrn, *tmp;
1118c9fbc29Smrg
1128c9fbc29Smrg    if (xkb && xkb->names)
11370728a38Smrg        vmodNames = xkb->names->vmods;
11470728a38Smrg    else
11570728a38Smrg        vmodNames = NULL;
11670728a38Smrg
11770728a38Smrg    tmp = NULL;
11870728a38Smrg    if (ndx >= XkbNumVirtualMods)
11970728a38Smrg        tmp = strdup("illegal");
12070728a38Smrg    else if (vmodNames && (vmodNames[ndx] != None))
12170728a38Smrg        tmp = XkbAtomGetString(dpy, vmodNames[ndx]);
12270728a38Smrg    if (tmp == NULL) {
12370728a38Smrg        tmp = (char *) _XkbAlloc(20 * sizeof(char));
12470728a38Smrg        snprintf(tmp, 20, "%d", ndx);
12570728a38Smrg    }
12670728a38Smrg
12770728a38Smrg    len = strlen(tmp) + 1;
12870728a38Smrg    if (format == XkbCFile)
12970728a38Smrg        len += 4;
13070728a38Smrg    if (len >= BUFFER_SIZE)
13170728a38Smrg        len = BUFFER_SIZE - 1;
13270728a38Smrg    rtrn = tbGetBuffer(len);
13370728a38Smrg    if (format == XkbCFile) {
13470728a38Smrg        snprintf(rtrn, len, "vmod_%s", tmp);
13570728a38Smrg    }
13670728a38Smrg    else
13770728a38Smrg        strncpy(rtrn, tmp, len);
1388c9fbc29Smrg    _XkbFree(tmp);
1398c9fbc29Smrg    return rtrn;
1408c9fbc29Smrg}
1418c9fbc29Smrg
1428c9fbc29Smrgchar *
14370728a38SmrgXkbVModMaskText(Display *       dpy,
14470728a38Smrg                XkbDescPtr      xkb,
14570728a38Smrg                unsigned        modMask,
14670728a38Smrg                unsigned        mask,
14770728a38Smrg                unsigned        format)
1488c9fbc29Smrg{
14970728a38Smrg    register int i, bit;
15070728a38Smrg    int len;
15170728a38Smrg    char *mm, *rtrn;
15270728a38Smrg    char *str, buf[BUFFER_SIZE];
15370728a38Smrg
15470728a38Smrg    if ((modMask == 0) && (mask == 0)) {
15570728a38Smrg        const int rtrnsize = 5;
15670728a38Smrg        rtrn = tbGetBuffer(rtrnsize);
15770728a38Smrg        if (format == XkbCFile)
15870728a38Smrg            snprintf(rtrn, rtrnsize, "0");
15970728a38Smrg        else
16070728a38Smrg            snprintf(rtrn, rtrnsize, "none");
16170728a38Smrg        return rtrn;
16270728a38Smrg    }
16370728a38Smrg    if (modMask != 0)
16470728a38Smrg        mm = XkbModMaskText(modMask, format);
16570728a38Smrg    else
16670728a38Smrg        mm = NULL;
16770728a38Smrg
16870728a38Smrg    str = buf;
16970728a38Smrg    buf[0] = '\0';
1708c9fbc29Smrg    if (mask) {
17170728a38Smrg        char *tmp;
17270728a38Smrg
17370728a38Smrg        for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
17470728a38Smrg            if (mask & bit) {
17570728a38Smrg                tmp = XkbVModIndexText(dpy, xkb, i, format);
17670728a38Smrg                len = strlen(tmp) + 1 + (str == buf ? 0 : 1);
17770728a38Smrg                if (format == XkbCFile)
17870728a38Smrg                    len += 4;
17970728a38Smrg                if ((str - (buf + len)) <= BUFFER_SIZE) {
18070728a38Smrg                    if (str != buf) {
18170728a38Smrg                        if (format == XkbCFile)
18270728a38Smrg                            *str++ = '|';
18370728a38Smrg                        else
18470728a38Smrg                            *str++ = '+';
18570728a38Smrg                        len--;
18670728a38Smrg                    }
18770728a38Smrg                }
18870728a38Smrg                if (format == XkbCFile)
18970728a38Smrg                    sprintf(str, "%sMask", tmp);
19070728a38Smrg                else
19170728a38Smrg                    strcpy(str, tmp);
19270728a38Smrg                str = &str[len - 1];
19370728a38Smrg            }
19470728a38Smrg        }
19570728a38Smrg        str = buf;
19670728a38Smrg    }
19770728a38Smrg    else
19870728a38Smrg        str = NULL;
1994cd6a3aeSmrg    if (mm)
20070728a38Smrg        len = strlen(mm);
20170728a38Smrg    else
20270728a38Smrg        len = 0;
2038c9fbc29Smrg    if (str)
20470728a38Smrg        len += strlen(str) + (mm == NULL ? 0 : 1);
20570728a38Smrg    if (len >= BUFFER_SIZE)
20670728a38Smrg        len = BUFFER_SIZE - 1;
20770728a38Smrg    rtrn = tbGetBuffer(len + 1);
20870728a38Smrg    rtrn[0] = '\0';
20970728a38Smrg
21070728a38Smrg    if (mm != NULL) {
21170728a38Smrg        i = strlen(mm);
21270728a38Smrg        if (i > len)
21370728a38Smrg            i = len;
21470728a38Smrg        strcpy(rtrn, mm);
2158c9fbc29Smrg    }
2168c9fbc29Smrg    else {
21770728a38Smrg        i = 0;
21870728a38Smrg    }
21970728a38Smrg    if (str != NULL) {
22070728a38Smrg        if (mm != NULL) {
22170728a38Smrg            if (format == XkbCFile)
22270728a38Smrg                strcat(rtrn, "|");
22370728a38Smrg            else
22470728a38Smrg                strcat(rtrn, "+");
22570728a38Smrg        }
22670728a38Smrg        strncat(rtrn, str, len - i);
22770728a38Smrg    }
22870728a38Smrg    rtrn[len] = '\0';
2298c9fbc29Smrg    return rtrn;
2308c9fbc29Smrg}
2318c9fbc29Smrg
2324cd6a3aeSmrgstatic const char *modNames[XkbNumModifiers] = {
2338c9fbc29Smrg    "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5"
2348c9fbc29Smrg};
2358c9fbc29Smrg
2368c9fbc29Smrgchar *
23770728a38SmrgXkbModIndexText(unsigned ndx, unsigned format)
2388c9fbc29Smrg{
23970728a38Smrg    char *rtrn;
24070728a38Smrg    char buf[100];
2418c9fbc29Smrg
24270728a38Smrg    if (format == XkbCFile) {
24370728a38Smrg        if (ndx < XkbNumModifiers)
24470728a38Smrg            snprintf(buf, sizeof(buf), "%sMapIndex", modNames[ndx]);
24570728a38Smrg        else if (ndx == XkbNoModifier)
24670728a38Smrg            snprintf(buf, sizeof(buf), "XkbNoModifier");
24770728a38Smrg        else
24870728a38Smrg            snprintf(buf, sizeof(buf), "0x%02x", ndx);
2498c9fbc29Smrg    }
2508c9fbc29Smrg    else {
25170728a38Smrg        if (ndx < XkbNumModifiers)
25270728a38Smrg            strcpy(buf, modNames[ndx]);
25370728a38Smrg        else if (ndx == XkbNoModifier)
25470728a38Smrg            strcpy(buf, "none");
25570728a38Smrg        else
25670728a38Smrg            snprintf(buf, sizeof(buf), "ILLEGAL_%02x", ndx);
25770728a38Smrg    }
25870728a38Smrg    rtrn = tbGetBuffer(strlen(buf) + 1);
25970728a38Smrg    strcpy(rtrn, buf);
2608c9fbc29Smrg    return rtrn;
2618c9fbc29Smrg}
2628c9fbc29Smrg
2638c9fbc29Smrgchar *
26470728a38SmrgXkbModMaskText(unsigned mask, unsigned format)
2658c9fbc29Smrg{
26670728a38Smrg    register int i, bit;
26770728a38Smrg    char buf[64], *rtrn;
2688c9fbc29Smrg
26970728a38Smrg    if ((mask & 0xff) == 0xff) {
27070728a38Smrg        if (format == XkbCFile)
27170728a38Smrg            strcpy(buf, "0xff");
27270728a38Smrg        else
27370728a38Smrg            strcpy(buf, "all");
2748c9fbc29Smrg    }
27570728a38Smrg    else if ((mask & 0xff) == 0) {
27670728a38Smrg        if (format == XkbCFile)
27770728a38Smrg            strcpy(buf, "0");
27870728a38Smrg        else
27970728a38Smrg            strcpy(buf, "none");
2808c9fbc29Smrg    }
2818c9fbc29Smrg    else {
28270728a38Smrg        char *str = buf;
28370728a38Smrg
28470728a38Smrg        buf[0] = '\0';
28570728a38Smrg        for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) {
28670728a38Smrg            if (mask & bit) {
28770728a38Smrg                if (str != buf) {
28870728a38Smrg                    if (format == XkbCFile)
28970728a38Smrg                        *str++ = '|';
29070728a38Smrg                    else
29170728a38Smrg                        *str++ = '+';
29270728a38Smrg                }
29370728a38Smrg                strcpy(str, modNames[i]);
29470728a38Smrg                str = &str[strlen(str)];
29570728a38Smrg                if (format == XkbCFile) {
29670728a38Smrg                    strcpy(str, "Mask");
29770728a38Smrg                    str += 4;
29870728a38Smrg                }
29970728a38Smrg            }
30070728a38Smrg        }
30170728a38Smrg    }
30270728a38Smrg    rtrn = tbGetBuffer(strlen(buf) + 1);
30370728a38Smrg    strcpy(rtrn, buf);
3048c9fbc29Smrg    return rtrn;
3058c9fbc29Smrg}
3068c9fbc29Smrg
3078c9fbc29Smrg/***====================================================================***/
3088c9fbc29Smrg
3098c9fbc29Smrg/*ARGSUSED*/
3108c9fbc29Smrgchar *
31170728a38SmrgXkbConfigText(unsigned config, unsigned format)
3128c9fbc29Smrg{
31370728a38Smrg    static char *buf;
31470728a38Smrg    const int bufsize = 32;
3158c9fbc29Smrg
31670728a38Smrg    buf = tbGetBuffer(bufsize);
3178c9fbc29Smrg    switch (config) {
31870728a38Smrg    case XkmSemanticsFile:
31970728a38Smrg        strcpy(buf, "Semantics");
32070728a38Smrg        break;
32170728a38Smrg    case XkmLayoutFile:
32270728a38Smrg        strcpy(buf, "Layout");
32370728a38Smrg        break;
32470728a38Smrg    case XkmKeymapFile:
32570728a38Smrg        strcpy(buf, "Keymap");
32670728a38Smrg        break;
32770728a38Smrg    case XkmGeometryFile:
32870728a38Smrg    case XkmGeometryIndex:
32970728a38Smrg        strcpy(buf, "Geometry");
33070728a38Smrg        break;
33170728a38Smrg    case XkmTypesIndex:
33270728a38Smrg        strcpy(buf, "Types");
33370728a38Smrg        break;
33470728a38Smrg    case XkmCompatMapIndex:
33570728a38Smrg        strcpy(buf, "CompatMap");
33670728a38Smrg        break;
33770728a38Smrg    case XkmSymbolsIndex:
33870728a38Smrg        strcpy(buf, "Symbols");
33970728a38Smrg        break;
34070728a38Smrg    case XkmIndicatorsIndex:
34170728a38Smrg        strcpy(buf, "Indicators");
34270728a38Smrg        break;
34370728a38Smrg    case XkmKeyNamesIndex:
34470728a38Smrg        strcpy(buf, "KeyNames");
34570728a38Smrg        break;
34670728a38Smrg    case XkmVirtualModsIndex:
34770728a38Smrg        strcpy(buf, "VirtualMods");
34870728a38Smrg        break;
34970728a38Smrg    default:
35070728a38Smrg        snprintf(buf, bufsize, "unknown(%d)", config);
35170728a38Smrg        break;
3528c9fbc29Smrg    }
3538c9fbc29Smrg    return buf;
3548c9fbc29Smrg}
3558c9fbc29Smrg
3568c9fbc29Smrg/***====================================================================***/
3578c9fbc29Smrg
3588c9fbc29Smrgchar *
35970728a38SmrgXkbKeysymText(KeySym sym, unsigned format)
3608c9fbc29Smrg{
36170728a38Smrg    static char buf[32], *rtrn;
3628c9fbc29Smrg
36370728a38Smrg    if (sym == NoSymbol)
36470728a38Smrg        strcpy(rtrn = buf, "NoSymbol");
36570728a38Smrg    else if ((rtrn = XKeysymToString(sym)) == NULL) {
36670728a38Smrg        snprintf(buf, sizeof(buf), "0x%lx", (long) sym);
36770728a38Smrg        rtrn = buf;
36870728a38Smrg    }
36970728a38Smrg    else if (format == XkbCFile) {
37070728a38Smrg        snprintf(buf, sizeof(buf), "XK_%s", rtrn);
37170728a38Smrg        rtrn = buf;
3728c9fbc29Smrg    }
3738c9fbc29Smrg    return rtrn;
3748c9fbc29Smrg}
3758c9fbc29Smrg
3768c9fbc29Smrgchar *
37770728a38SmrgXkbKeyNameText(char *name, unsigned format)
3788c9fbc29Smrg{
37970728a38Smrg    char *buf;
3808c9fbc29Smrg
38170728a38Smrg    if (format == XkbCFile) {
38270728a38Smrg        buf = tbGetBuffer(5);
38370728a38Smrg        memcpy(buf, name, 4);
38470728a38Smrg        buf[4] = '\0';
3858c9fbc29Smrg    }
3868c9fbc29Smrg    else {
38770728a38Smrg        int len;
38870728a38Smrg
38970728a38Smrg        buf = tbGetBuffer(7);
39070728a38Smrg        buf[0] = '<';
39170728a38Smrg        memcpy(&buf[1], name, 4);
39270728a38Smrg        buf[5] = '\0';
39370728a38Smrg        len = strlen(buf);
39470728a38Smrg        buf[len++] = '>';
39570728a38Smrg        buf[len] = '\0';
3968c9fbc29Smrg    }
3978c9fbc29Smrg    return buf;
3988c9fbc29Smrg}
3998c9fbc29Smrg
4008c9fbc29Smrg/***====================================================================***/
4018c9fbc29Smrg
4028c9fbc29Smrgstatic char *siMatchText[5] = {
40370728a38Smrg    "NoneOf", "AnyOfOrNone", "AnyOf", "AllOf", "Exactly"
4048c9fbc29Smrg};
4058c9fbc29Smrg
4068c9fbc29Smrgchar *
40770728a38SmrgXkbSIMatchText(unsigned type, unsigned format)
4088c9fbc29Smrg{
40970728a38Smrg    static char buf[40];
41070728a38Smrg
41170728a38Smrg    char *rtrn;
41270728a38Smrg
41370728a38Smrg    switch (type & XkbSI_OpMask) {
41470728a38Smrg    case XkbSI_NoneOf:      rtrn = siMatchText[0]; break;
41570728a38Smrg    case XkbSI_AnyOfOrNone: rtrn = siMatchText[1]; break;
41670728a38Smrg    case XkbSI_AnyOf:       rtrn = siMatchText[2]; break;
41770728a38Smrg    case XkbSI_AllOf:       rtrn = siMatchText[3]; break;
41870728a38Smrg    case XkbSI_Exactly:     rtrn = siMatchText[4]; break;
41970728a38Smrg    default:
42070728a38Smrg        snprintf(buf, sizeof(buf), "0x%x", type & XkbSI_OpMask);
42170728a38Smrg        return buf;
42270728a38Smrg    }
42370728a38Smrg    if (format == XkbCFile) {
42470728a38Smrg        if (type & XkbSI_LevelOneOnly)
42570728a38Smrg            snprintf(buf, sizeof(buf), "XkbSI_LevelOneOnly|XkbSI_%s", rtrn);
42670728a38Smrg        else
42770728a38Smrg            snprintf(buf, sizeof(buf), "XkbSI_%s", rtrn);
42870728a38Smrg        rtrn = buf;
4298c9fbc29Smrg    }
4308c9fbc29Smrg    return rtrn;
4318c9fbc29Smrg}
4328c9fbc29Smrg
4338c9fbc29Smrg/***====================================================================***/
4348c9fbc29Smrg
43570728a38Smrgstatic const char *imWhichNames[] = {
43670728a38Smrg    "base",
43770728a38Smrg    "latched",
43870728a38Smrg    "locked",
43970728a38Smrg    "effective",
44070728a38Smrg    "compat"
4418c9fbc29Smrg};
4428c9fbc29Smrg
4438c9fbc29Smrgchar *
44470728a38SmrgXkbIMWhichStateMaskText(unsigned use_which, unsigned format)
4458c9fbc29Smrg{
44670728a38Smrg    int len, bufsize;
44770728a38Smrg    unsigned i, bit, tmp;
44870728a38Smrg    char *buf;
44970728a38Smrg
45070728a38Smrg    if (use_which == 0) {
45170728a38Smrg        buf = tbGetBuffer(2);
45270728a38Smrg        strcpy(buf, "0");
45370728a38Smrg        return buf;
45470728a38Smrg    }
45570728a38Smrg    tmp = use_which & XkbIM_UseAnyMods;
45670728a38Smrg    for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
45770728a38Smrg        if (tmp & bit) {
45870728a38Smrg            tmp &= ~bit;
45970728a38Smrg            len += strlen(imWhichNames[i]) + 1;
46070728a38Smrg            if (format == XkbCFile)
46170728a38Smrg                len += 9;
46270728a38Smrg        }
46370728a38Smrg    }
46470728a38Smrg    bufsize = len + 1;
46570728a38Smrg    buf = tbGetBuffer(bufsize);
46670728a38Smrg    tmp = use_which & XkbIM_UseAnyMods;
46770728a38Smrg    for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
46870728a38Smrg        if (tmp & bit) {
46970728a38Smrg            tmp &= ~bit;
47070728a38Smrg            if (format == XkbCFile) {
47170728a38Smrg                if (len != 0)
47270728a38Smrg                    buf[len++] = '|';
47370728a38Smrg                snprintf(&buf[len], bufsize - len,
47470728a38Smrg                         "XkbIM_Use%s", imWhichNames[i]);
47570728a38Smrg                buf[len + 9] = toupper(buf[len + 9]);
47670728a38Smrg            }
47770728a38Smrg            else {
47870728a38Smrg                if (len != 0)
47970728a38Smrg                    buf[len++] = '+';
48070728a38Smrg                snprintf(&buf[len], bufsize - len,
48170728a38Smrg                         "%s", imWhichNames[i]);
48270728a38Smrg            }
48370728a38Smrg            len += strlen(&buf[len]);
48470728a38Smrg        }
4858c9fbc29Smrg    }
4868c9fbc29Smrg    return buf;
4878c9fbc29Smrg}
4888c9fbc29Smrg
4898c9fbc29Smrgchar *
49070728a38SmrgXkbAccessXDetailText(unsigned state, unsigned format)
4918c9fbc29Smrg{
49270728a38Smrg    char *buf;
49370728a38Smrg    const char *prefix;
49470728a38Smrg    const int bufsize = 32;
49570728a38Smrg
49670728a38Smrg    buf = tbGetBuffer(bufsize);
49770728a38Smrg    if (format == XkbMessage)
49870728a38Smrg        prefix = "";
49970728a38Smrg    else
50070728a38Smrg        prefix = "XkbAXN_";
50170728a38Smrg    switch (state) {
50270728a38Smrg    case XkbAXN_SKPress:
50370728a38Smrg        snprintf(buf, bufsize, "%sSKPress", prefix);
50470728a38Smrg        break;
50570728a38Smrg    case XkbAXN_SKAccept:
50670728a38Smrg        snprintf(buf, bufsize, "%sSKAccept", prefix);
50770728a38Smrg        break;
50870728a38Smrg    case XkbAXN_SKRelease:
50970728a38Smrg        snprintf(buf, bufsize, "%sSKRelease", prefix);
51070728a38Smrg        break;
51170728a38Smrg    case XkbAXN_SKReject:
51270728a38Smrg        snprintf(buf, bufsize, "%sSKReject", prefix);
51370728a38Smrg        break;
51470728a38Smrg    case XkbAXN_BKAccept:
51570728a38Smrg        snprintf(buf, bufsize, "%sBKAccept", prefix);
51670728a38Smrg        break;
51770728a38Smrg    case XkbAXN_BKReject:
51870728a38Smrg        snprintf(buf, bufsize, "%sBKReject", prefix);
51970728a38Smrg        break;
52070728a38Smrg    case XkbAXN_AXKWarning:
52170728a38Smrg        snprintf(buf, bufsize, "%sAXKWarning", prefix);
52270728a38Smrg        break;
52370728a38Smrg    default:
52470728a38Smrg        snprintf(buf, bufsize, "ILLEGAL");
52570728a38Smrg        break;
5268c9fbc29Smrg    }
5278c9fbc29Smrg    return buf;
5288c9fbc29Smrg}
5298c9fbc29Smrg
5304cd6a3aeSmrgstatic const char *nknNames[] = {
53170728a38Smrg    "keycodes", "geometry", "deviceID"
5328c9fbc29Smrg};
5338c9fbc29Smrg#define	NUM_NKN	(sizeof(nknNames)/sizeof(char *))
5348c9fbc29Smrg
5358c9fbc29Smrgchar *
53670728a38SmrgXkbNKNDetailMaskText(unsigned detail, unsigned format)
5378c9fbc29Smrg{
53870728a38Smrg    char *buf;
53970728a38Smrg    const char *prefix, *suffix;
54070728a38Smrg    register int i;
54170728a38Smrg    register unsigned bit;
54270728a38Smrg    int len, plen, slen;
54370728a38Smrg
54470728a38Smrg    if ((detail & XkbAllNewKeyboardEventsMask) == 0) {
54570728a38Smrg        const char *tmp = "";
54670728a38Smrg
54770728a38Smrg        if (format == XkbCFile)
54870728a38Smrg            tmp = "0";
54970728a38Smrg        else if (format == XkbMessage)
55070728a38Smrg            tmp = "none";
55170728a38Smrg        buf = tbGetBuffer(strlen(tmp) + 1);
55270728a38Smrg        strcpy(buf, tmp);
55370728a38Smrg        return buf;
55470728a38Smrg    }
55570728a38Smrg    else if ((detail & XkbAllNewKeyboardEventsMask) ==
55670728a38Smrg             XkbAllNewKeyboardEventsMask) {
55770728a38Smrg        const char *tmp;
55870728a38Smrg
55970728a38Smrg        if (format == XkbCFile)
56070728a38Smrg            tmp = "XkbAllNewKeyboardEventsMask";
56170728a38Smrg        else
56270728a38Smrg            tmp = "all";
56370728a38Smrg        buf = tbGetBuffer(strlen(tmp) + 1);
56470728a38Smrg        strcpy(buf, tmp);
56570728a38Smrg        return buf;
56670728a38Smrg    }
56770728a38Smrg    if (format == XkbMessage) {
56870728a38Smrg        prefix = "";
56970728a38Smrg        suffix = "";
57070728a38Smrg        slen = plen = 0;
5718c9fbc29Smrg    }
5728c9fbc29Smrg    else {
57370728a38Smrg        prefix = "XkbNKN_";
57470728a38Smrg        plen = 7;
57570728a38Smrg        if (format == XkbCFile)
57670728a38Smrg            suffix = "Mask";
57770728a38Smrg        else
57870728a38Smrg            suffix = "";
57970728a38Smrg        slen = strlen(suffix);
58070728a38Smrg    }
58170728a38Smrg    for (len = 0, i = 0, bit = 1; i < NUM_NKN; i++, bit <<= 1) {
58270728a38Smrg        if (detail & bit) {
58370728a38Smrg            if (len != 0)
58470728a38Smrg                len += 1;       /* room for '+' or '|' */
58570728a38Smrg            len += plen + slen + strlen(nknNames[i]);
58670728a38Smrg        }
58770728a38Smrg    }
58870728a38Smrg    buf = tbGetBuffer(len + 1);
58970728a38Smrg    buf[0] = '\0';
59070728a38Smrg    for (len = 0, i = 0, bit = 1; i < NUM_NKN; i++, bit <<= 1) {
59170728a38Smrg        if (detail & bit) {
59270728a38Smrg            if (len != 0) {
59370728a38Smrg                if (format == XkbCFile)
59470728a38Smrg                    buf[len++] = '|';
59570728a38Smrg                else
59670728a38Smrg                    buf[len++] = '+';
59770728a38Smrg            }
59870728a38Smrg            if (plen) {
59970728a38Smrg                strcpy(&buf[len], prefix);
60070728a38Smrg                len += plen;
60170728a38Smrg            }
60270728a38Smrg            strcpy(&buf[len], nknNames[i]);
60370728a38Smrg            len += strlen(nknNames[i]);
60470728a38Smrg            if (slen) {
60570728a38Smrg                strcpy(&buf[len], suffix);
60670728a38Smrg                len += slen;
60770728a38Smrg            }
60870728a38Smrg        }
60970728a38Smrg    }
61070728a38Smrg    buf[len++] = '\0';
6118c9fbc29Smrg    return buf;
6128c9fbc29Smrg}
6138c9fbc29Smrg
6144cd6a3aeSmrgstatic const char *ctrlNames[] = {
61570728a38Smrg    "repeatKeys",
61670728a38Smrg    "slowKeys",
61770728a38Smrg    "bounceKeys",
61870728a38Smrg    "stickyKeys",
61970728a38Smrg    "mouseKeys",
62070728a38Smrg    "mouseKeysAccel",
62170728a38Smrg    "accessXKeys",
62270728a38Smrg    "accessXTimeout",
62370728a38Smrg    "accessXFeedback",
62470728a38Smrg    "audibleBell",
62570728a38Smrg    "overlay1",
62670728a38Smrg    "overlay2",
62770728a38Smrg    "ignoreGroupLock"
6288c9fbc29Smrg};
6298c9fbc29Smrg
6308c9fbc29Smrgchar *
63170728a38SmrgXkbControlsMaskText(unsigned ctrls, unsigned format)
6328c9fbc29Smrg{
63370728a38Smrg    int len;
63470728a38Smrg    unsigned i, bit, tmp;
63570728a38Smrg    char *buf;
63670728a38Smrg
63770728a38Smrg    if (ctrls == 0) {
63870728a38Smrg        buf = tbGetBuffer(5);
63970728a38Smrg        if (format == XkbCFile)
64070728a38Smrg            strcpy(buf, "0");
64170728a38Smrg        else
64270728a38Smrg            strcpy(buf, "none");
64370728a38Smrg        return buf;
64470728a38Smrg    }
64570728a38Smrg    tmp = ctrls & XkbAllBooleanCtrlsMask;
64670728a38Smrg    for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
64770728a38Smrg        if (tmp & bit) {
64870728a38Smrg            tmp &= ~bit;
64970728a38Smrg            len += strlen(ctrlNames[i]) + 1;
65070728a38Smrg            if (format == XkbCFile)
65170728a38Smrg                len += 7;
65270728a38Smrg        }
65370728a38Smrg    }
65470728a38Smrg    buf = tbGetBuffer(len + 1);
65570728a38Smrg    tmp = ctrls & XkbAllBooleanCtrlsMask;
65670728a38Smrg    for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
65770728a38Smrg        if (tmp & bit) {
65870728a38Smrg            tmp &= ~bit;
65970728a38Smrg            if (format == XkbCFile) {
66070728a38Smrg                if (len != 0)
66170728a38Smrg                    buf[len++] = '|';
66270728a38Smrg                sprintf(&buf[len], "Xkb%sMask", ctrlNames[i]);
66370728a38Smrg                buf[len + 3] = toupper(buf[len + 3]);
66470728a38Smrg            }
66570728a38Smrg            else {
66670728a38Smrg                if (len != 0)
66770728a38Smrg                    buf[len++] = '+';
66870728a38Smrg                sprintf(&buf[len], "%s", ctrlNames[i]);
66970728a38Smrg            }
67070728a38Smrg            len += strlen(&buf[len]);
67170728a38Smrg        }
6728c9fbc29Smrg    }
6738c9fbc29Smrg    return buf;
6748c9fbc29Smrg}
6758c9fbc29Smrg
6768c9fbc29Smrg/***====================================================================***/
6778c9fbc29Smrg
6788c9fbc29Smrgchar *
67970728a38SmrgXkbStringText(char *str, unsigned format)
6808c9fbc29Smrg{
68170728a38Smrg    char *buf;
68270728a38Smrg    register char *in, *out;
68370728a38Smrg    int len;
68470728a38Smrg    Bool ok;
68570728a38Smrg
68670728a38Smrg    if (str == NULL) {
68770728a38Smrg        buf = tbGetBuffer(2);
68870728a38Smrg        buf[0] = '\0';
68970728a38Smrg        return buf;
69070728a38Smrg    }
69170728a38Smrg    else if (format == XkbXKMFile)
69270728a38Smrg        return str;
69370728a38Smrg    for (ok = True, len = 0, in = str; *in != '\0'; in++, len++) {
69470728a38Smrg        if (!isprint(*in)) {
69570728a38Smrg            ok = False;
69670728a38Smrg            switch (*in) {
69770728a38Smrg            case '\n':
69870728a38Smrg            case '\t':
69970728a38Smrg            case '\v':
70070728a38Smrg            case '\b':
70170728a38Smrg            case '\r':
70270728a38Smrg            case '\f':
70370728a38Smrg                len++;
70470728a38Smrg                break;
70570728a38Smrg            default:
70670728a38Smrg                len += 4;
70770728a38Smrg                break;
70870728a38Smrg            }
70970728a38Smrg        }
7108c9fbc29Smrg    }
7118c9fbc29Smrg    if (ok)
71270728a38Smrg        return str;
71370728a38Smrg    buf = tbGetBuffer(len + 1);
71470728a38Smrg    for (in = str, out = buf; *in != '\0'; in++) {
71570728a38Smrg        if (isprint(*in))
71670728a38Smrg            *out++ = *in;
71770728a38Smrg        else {
71870728a38Smrg            *out++ = '\\';
71970728a38Smrg            if (*in == '\n')
72070728a38Smrg                *out++ = 'n';
72170728a38Smrg            else if (*in == '\t')
72270728a38Smrg                *out++ = 't';
72370728a38Smrg            else if (*in == '\v')
72470728a38Smrg                *out++ = 'v';
72570728a38Smrg            else if (*in == '\b')
72670728a38Smrg                *out++ = 'b';
72770728a38Smrg            else if (*in == '\r')
72870728a38Smrg                *out++ = 'r';
72970728a38Smrg            else if (*in == '\f')
73070728a38Smrg                *out++ = 'f';
73170728a38Smrg            else if ((*in == '\033') && (format == XkbXKMFile)) {
73270728a38Smrg                *out++ = 'e';
73370728a38Smrg            }
73470728a38Smrg            else {
73570728a38Smrg                *out++ = '0';
73670728a38Smrg                sprintf(out, "%o", *in);
73770728a38Smrg                while (*out != '\0')
73870728a38Smrg                    out++;
73970728a38Smrg            }
74070728a38Smrg        }
74170728a38Smrg    }
74270728a38Smrg    *out++ = '\0';
7438c9fbc29Smrg    return buf;
7448c9fbc29Smrg}
7458c9fbc29Smrg
7468c9fbc29Smrg/***====================================================================***/
7478c9fbc29Smrg
7488c9fbc29Smrgchar *
74970728a38SmrgXkbGeomFPText(int val, unsigned format)
7508c9fbc29Smrg{
75170728a38Smrg    int whole, frac;
75270728a38Smrg    char *buf;
75370728a38Smrg    const int bufsize = 12;
7548c9fbc29Smrg
75570728a38Smrg    buf = tbGetBuffer(bufsize);
75670728a38Smrg    if (format == XkbCFile) {
75770728a38Smrg        snprintf(buf, bufsize, "%d", val);
7588c9fbc29Smrg    }
7598c9fbc29Smrg    else {
76070728a38Smrg        whole = val / XkbGeomPtsPerMM;
76170728a38Smrg        frac = val % XkbGeomPtsPerMM;
76270728a38Smrg        if (frac != 0)
76370728a38Smrg            snprintf(buf, bufsize, "%d.%d", whole, frac);
76470728a38Smrg        else
76570728a38Smrg            snprintf(buf, bufsize, "%d", whole);
7668c9fbc29Smrg    }
7678c9fbc29Smrg    return buf;
7688c9fbc29Smrg}
7698c9fbc29Smrg
7708c9fbc29Smrgchar *
77170728a38SmrgXkbDoodadTypeText(unsigned type, unsigned format)
7728c9fbc29Smrg{
77370728a38Smrg    char *buf;
77470728a38Smrg
77570728a38Smrg    if (format == XkbCFile) {
77670728a38Smrg        const int bufsize = 24;
77770728a38Smrg        buf = tbGetBuffer(bufsize);
77870728a38Smrg        if (type == XkbOutlineDoodad)
77970728a38Smrg            strcpy(buf, "XkbOutlineDoodad");
78070728a38Smrg        else if (type == XkbSolidDoodad)
78170728a38Smrg            strcpy(buf, "XkbSolidDoodad");
78270728a38Smrg        else if (type == XkbTextDoodad)
78370728a38Smrg            strcpy(buf, "XkbTextDoodad");
78470728a38Smrg        else if (type == XkbIndicatorDoodad)
78570728a38Smrg            strcpy(buf, "XkbIndicatorDoodad");
78670728a38Smrg        else if (type == XkbLogoDoodad)
78770728a38Smrg            strcpy(buf, "XkbLogoDoodad");
78870728a38Smrg        else
78970728a38Smrg            snprintf(buf, bufsize, "UnknownDoodad%d", type);
7908c9fbc29Smrg    }
7918c9fbc29Smrg    else {
79270728a38Smrg        const int bufsize = 12;
79370728a38Smrg        buf = tbGetBuffer(bufsize);
79470728a38Smrg        if (type == XkbOutlineDoodad)
79570728a38Smrg            strcpy(buf, "outline");
79670728a38Smrg        else if (type == XkbSolidDoodad)
79770728a38Smrg            strcpy(buf, "solid");
79870728a38Smrg        else if (type == XkbTextDoodad)
79970728a38Smrg            strcpy(buf, "text");
80070728a38Smrg        else if (type == XkbIndicatorDoodad)
80170728a38Smrg            strcpy(buf, "indicator");
80270728a38Smrg        else if (type == XkbLogoDoodad)
80370728a38Smrg            strcpy(buf, "logo");
80470728a38Smrg        else
80570728a38Smrg            snprintf(buf, bufsize, "unknown%d", type);
8068c9fbc29Smrg    }
8078c9fbc29Smrg    return buf;
8088c9fbc29Smrg}
8098c9fbc29Smrg
81070728a38Smrgstatic char *actionTypeNames[XkbSA_NumActions] = {
8114cd6a3aeSmrg    "NoAction",
8124cd6a3aeSmrg    "SetMods",      "LatchMods",    "LockMods",
8138c9fbc29Smrg    "SetGroup",     "LatchGroup",   "LockGroup",
8148c9fbc29Smrg    "MovePtr",
8158c9fbc29Smrg    "PtrBtn",       "LockPtrBtn",
8168c9fbc29Smrg    "SetPtrDflt",
8178c9fbc29Smrg    "ISOLock",
8184cd6a3aeSmrg    "Terminate",    "SwitchScreen",
8198c9fbc29Smrg    "SetControls",  "LockControls",
8208c9fbc29Smrg    "ActionMessage",
8218c9fbc29Smrg    "RedirectKey",
8228c9fbc29Smrg    "DeviceBtn",    "LockDeviceBtn"
8238c9fbc29Smrg};
8248c9fbc29Smrg
8258c9fbc29Smrgchar *
82670728a38SmrgXkbActionTypeText(unsigned type, unsigned format)
8278c9fbc29Smrg{
82870728a38Smrg    static char buf[32];
82970728a38Smrg    char *rtrn;
83070728a38Smrg
83170728a38Smrg    if (type <= XkbSA_LastAction) {
83270728a38Smrg        rtrn = actionTypeNames[type];
83370728a38Smrg        if (format == XkbCFile) {
83470728a38Smrg            snprintf(buf, sizeof(buf), "XkbSA_%s", rtrn);
83570728a38Smrg            return buf;
83670728a38Smrg        }
83770728a38Smrg        return rtrn;
83870728a38Smrg    }
83970728a38Smrg    snprintf(buf, sizeof(buf), "Private");
8408c9fbc29Smrg    return buf;
8418c9fbc29Smrg}
8428c9fbc29Smrg
8438c9fbc29Smrg/***====================================================================***/
8448c9fbc29Smrg
8458c9fbc29Smrgstatic int
84670728a38SmrgTryCopyStr(char *to, const char *from, int *pLeft)
8478c9fbc29Smrg{
84870728a38Smrg    register int len;
84970728a38Smrg
85070728a38Smrg    if (*pLeft > 0) {
85170728a38Smrg        len = strlen(from);
85270728a38Smrg        if (len < ((*pLeft) - 3)) {
85370728a38Smrg            strcat(to, from);
85470728a38Smrg            *pLeft -= len;
85570728a38Smrg            return True;
85670728a38Smrg        }
85770728a38Smrg    }
85870728a38Smrg    *pLeft = -1;
8598c9fbc29Smrg    return False;
8608c9fbc29Smrg}
8618c9fbc29Smrg
8628c9fbc29Smrg/*ARGSUSED*/
8638c9fbc29Smrgstatic Bool
86470728a38SmrgCopyNoActionArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action,
86570728a38Smrg                 char *buf, int *sz)
8668c9fbc29Smrg{
8678c9fbc29Smrg    return True;
8688c9fbc29Smrg}
8698c9fbc29Smrg
8708c9fbc29Smrgstatic Bool
87170728a38SmrgCopyModActionArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action,
87270728a38Smrg                  char *buf, int *sz)
8738c9fbc29Smrg{
87470728a38Smrg    XkbModAction *act;
87570728a38Smrg    unsigned tmp;
87670728a38Smrg
87770728a38Smrg    act = &action->mods;
87870728a38Smrg    tmp = XkbModActionVMods(act);
87970728a38Smrg    TryCopyStr(buf, "modifiers=", sz);
88070728a38Smrg    if (act->flags & XkbSA_UseModMapMods)
88170728a38Smrg        TryCopyStr(buf, "modMapMods", sz);
8828c9fbc29Smrg    else if (act->real_mods || tmp) {
88370728a38Smrg        TryCopyStr(buf,
88470728a38Smrg                   XkbVModMaskText(dpy, xkb, act->real_mods, tmp, XkbXKBFile),
88570728a38Smrg                   sz);
88670728a38Smrg    }
88770728a38Smrg    else
88870728a38Smrg        TryCopyStr(buf, "none", sz);
88970728a38Smrg    if (act->type == XkbSA_LockMods)
89070728a38Smrg        return True;
89170728a38Smrg    if (act->flags & XkbSA_ClearLocks)
89270728a38Smrg        TryCopyStr(buf, ",clearLocks", sz);
89370728a38Smrg    if (act->flags & XkbSA_LatchToLock)
89470728a38Smrg        TryCopyStr(buf, ",latchToLock", sz);
8958c9fbc29Smrg    return True;
8968c9fbc29Smrg}
8978c9fbc29Smrg
8988c9fbc29Smrg/*ARGSUSED*/
8998c9fbc29Smrgstatic Bool
90070728a38SmrgCopyGroupActionArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action,
90170728a38Smrg                    char *buf, int *sz)
9028c9fbc29Smrg{
90370728a38Smrg    XkbGroupAction *act;
90470728a38Smrg    char tbuf[32];
90570728a38Smrg
90670728a38Smrg    act = &action->group;
90770728a38Smrg    TryCopyStr(buf, "group=", sz);
90870728a38Smrg    if (act->flags & XkbSA_GroupAbsolute)
90970728a38Smrg        snprintf(tbuf, sizeof(buf), "%d", XkbSAGroup(act) + 1);
91070728a38Smrg    else if (XkbSAGroup(act) < 0)
91170728a38Smrg        snprintf(tbuf, sizeof(buf), "%d", XkbSAGroup(act));
91270728a38Smrg    else
91370728a38Smrg        snprintf(tbuf, sizeof(buf), "+%d", XkbSAGroup(act));
91470728a38Smrg    TryCopyStr(buf, tbuf, sz);
91570728a38Smrg    if (act->type == XkbSA_LockGroup)
91670728a38Smrg        return True;
91770728a38Smrg    if (act->flags & XkbSA_ClearLocks)
91870728a38Smrg        TryCopyStr(buf, ",clearLocks", sz);
91970728a38Smrg    if (act->flags & XkbSA_LatchToLock)
92070728a38Smrg        TryCopyStr(buf, ",latchToLock", sz);
9218c9fbc29Smrg    return True;
9228c9fbc29Smrg}
9238c9fbc29Smrg
9248c9fbc29Smrg/*ARGSUSED*/
9258c9fbc29Smrgstatic Bool
92670728a38SmrgCopyMovePtrArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action,
92770728a38Smrg                char *buf, int *sz)
9288c9fbc29Smrg{
92970728a38Smrg    XkbPtrAction *act;
93070728a38Smrg    int x, y;
93170728a38Smrg    char tbuf[32];
93270728a38Smrg
93370728a38Smrg    act = &action->ptr;
93470728a38Smrg    x = XkbPtrActionX(act);
93570728a38Smrg    y = XkbPtrActionY(act);
93670728a38Smrg    if ((act->flags & XkbSA_MoveAbsoluteX) || (x < 0))
93770728a38Smrg        snprintf(tbuf, sizeof(tbuf), "x=%d", x);
93870728a38Smrg    else
93970728a38Smrg        snprintf(tbuf, sizeof(tbuf), "x=+%d", x);
94070728a38Smrg    TryCopyStr(buf, tbuf, sz);
94170728a38Smrg
94270728a38Smrg    if ((act->flags & XkbSA_MoveAbsoluteY) || (y < 0))
94370728a38Smrg        snprintf(tbuf, sizeof(tbuf), ",y=%d", y);
94470728a38Smrg    else
94570728a38Smrg        snprintf(tbuf, sizeof(tbuf), ",y=+%d", y);
94670728a38Smrg    TryCopyStr(buf, tbuf, sz);
94770728a38Smrg    if (act->flags & XkbSA_NoAcceleration)
94870728a38Smrg        TryCopyStr(buf, ",!accel", sz);
9498c9fbc29Smrg    return True;
9508c9fbc29Smrg}
9518c9fbc29Smrg
9528c9fbc29Smrg/*ARGSUSED*/
9538c9fbc29Smrgstatic Bool
95470728a38SmrgCopyPtrBtnArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action,
95570728a38Smrg               char *buf, int *sz)
9568c9fbc29Smrg{
95770728a38Smrg    XkbPtrBtnAction *act;
95870728a38Smrg    char tbuf[32];
95970728a38Smrg
96070728a38Smrg    act = &action->btn;
96170728a38Smrg    TryCopyStr(buf, "button=", sz);
96270728a38Smrg    if ((act->button > 0) && (act->button < 6)) {
96370728a38Smrg        snprintf(tbuf, sizeof(tbuf), "%d", act->button);
96470728a38Smrg        TryCopyStr(buf, tbuf, sz);
96570728a38Smrg    }
96670728a38Smrg    else
96770728a38Smrg        TryCopyStr(buf, "default", sz);
96870728a38Smrg    if (act->count > 0) {
96970728a38Smrg        snprintf(tbuf, sizeof(tbuf), ",count=%d", act->count);
97070728a38Smrg        TryCopyStr(buf, tbuf, sz);
97170728a38Smrg    }
97270728a38Smrg    if (action->type == XkbSA_LockPtrBtn) {
97370728a38Smrg        switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
97470728a38Smrg        case XkbSA_LockNoLock:
97570728a38Smrg            snprintf(tbuf, sizeof(tbuf), ",affect=unlock");
97670728a38Smrg            break;
97770728a38Smrg        case XkbSA_LockNoUnlock:
97870728a38Smrg            snprintf(tbuf, sizeof(tbuf), ",affect=lock");
97970728a38Smrg            break;
98070728a38Smrg        case XkbSA_LockNoUnlock | XkbSA_LockNoLock:
98170728a38Smrg            snprintf(tbuf, sizeof(tbuf), ",affect=neither");
98270728a38Smrg            break;
98370728a38Smrg        default:
98470728a38Smrg            snprintf(tbuf, sizeof(tbuf), ",affect=both");
98570728a38Smrg            break;
98670728a38Smrg        }
98770728a38Smrg        TryCopyStr(buf, tbuf, sz);
9888c9fbc29Smrg    }
9898c9fbc29Smrg    return True;
9908c9fbc29Smrg}
9918c9fbc29Smrg
9928c9fbc29Smrg/*ARGSUSED*/
9938c9fbc29Smrgstatic Bool
99470728a38SmrgCopySetPtrDfltArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action,
99570728a38Smrg                   char *buf, int *sz)
9968c9fbc29Smrg{
99770728a38Smrg    XkbPtrDfltAction *act;
99870728a38Smrg    char tbuf[32];
99970728a38Smrg
100070728a38Smrg    act = &action->dflt;
100170728a38Smrg    if (act->affect == XkbSA_AffectDfltBtn) {
100270728a38Smrg        TryCopyStr(buf, "affect=button,button=", sz);
100370728a38Smrg        if ((act->flags & XkbSA_DfltBtnAbsolute) ||
100470728a38Smrg            (XkbSAPtrDfltValue(act) < 0))
100570728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%d", XkbSAPtrDfltValue(act));
100670728a38Smrg        else
100770728a38Smrg            snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAPtrDfltValue(act));
100870728a38Smrg        TryCopyStr(buf, tbuf, sz);
10098c9fbc29Smrg    }
10108c9fbc29Smrg    return True;
10118c9fbc29Smrg}
10128c9fbc29Smrg
10138c9fbc29Smrgstatic Bool
101470728a38SmrgCopyISOLockArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action,
101570728a38Smrg                char *buf, int *sz)
10168c9fbc29Smrg{
101770728a38Smrg    XkbISOAction *act;
101870728a38Smrg    char tbuf[64];
101970728a38Smrg
102070728a38Smrg    act = &action->iso;
102170728a38Smrg    if (act->flags & XkbSA_ISODfltIsGroup) {
102270728a38Smrg        TryCopyStr(tbuf, "group=", sz);
102370728a38Smrg        if (act->flags & XkbSA_GroupAbsolute)
102470728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act) + 1);
102570728a38Smrg        else if (XkbSAGroup(act) < 0)
102670728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%d", XkbSAGroup(act));
102770728a38Smrg        else
102870728a38Smrg            snprintf(tbuf, sizeof(tbuf), "+%d", XkbSAGroup(act));
102970728a38Smrg        TryCopyStr(buf, tbuf, sz);
10308c9fbc29Smrg    }
10318c9fbc29Smrg    else {
103270728a38Smrg        unsigned tmp;
103370728a38Smrg
103470728a38Smrg        tmp = XkbModActionVMods(act);
103570728a38Smrg        TryCopyStr(buf, "modifiers=", sz);
103670728a38Smrg        if (act->flags & XkbSA_UseModMapMods)
103770728a38Smrg            TryCopyStr(buf, "modMapMods", sz);
103870728a38Smrg        else if (act->real_mods || tmp) {
103970728a38Smrg            if (act->real_mods) {
104070728a38Smrg                TryCopyStr(buf, XkbModMaskText(act->real_mods, XkbXKBFile), sz);
104170728a38Smrg                if (tmp)
104270728a38Smrg                    TryCopyStr(buf, "+", sz);
104370728a38Smrg            }
104470728a38Smrg            if (tmp)
104570728a38Smrg                TryCopyStr(buf, XkbVModMaskText(dpy, xkb, 0, tmp, XkbXKBFile),
104670728a38Smrg                           sz);
104770728a38Smrg        }
104870728a38Smrg        else
104970728a38Smrg            TryCopyStr(buf, "none", sz);
105070728a38Smrg    }
105170728a38Smrg    TryCopyStr(buf, ",affect=", sz);
105270728a38Smrg    if ((act->affect & XkbSA_ISOAffectMask) == 0)
105370728a38Smrg        TryCopyStr(buf, "all", sz);
10548c9fbc29Smrg    else {
105570728a38Smrg        int nOut = 0;
105670728a38Smrg
105770728a38Smrg        if ((act->affect & XkbSA_ISONoAffectMods) == 0) {
105870728a38Smrg            TryCopyStr(buf, "mods", sz);
105970728a38Smrg            nOut++;
106070728a38Smrg        }
106170728a38Smrg        if ((act->affect & XkbSA_ISONoAffectGroup) == 0) {
106270728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sgroups", (nOut > 0 ? "+" : ""));
106370728a38Smrg            TryCopyStr(buf, tbuf, sz);
106470728a38Smrg            nOut++;
106570728a38Smrg        }
106670728a38Smrg        if ((act->affect & XkbSA_ISONoAffectPtr) == 0) {
106770728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%spointer", (nOut > 0 ? "+" : ""));
106870728a38Smrg            TryCopyStr(buf, tbuf, sz);
106970728a38Smrg            nOut++;
107070728a38Smrg        }
107170728a38Smrg        if ((act->affect & XkbSA_ISONoAffectCtrls) == 0) {
107270728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%scontrols", (nOut > 0 ? "+" : ""));
107370728a38Smrg            TryCopyStr(buf, tbuf, sz);
107470728a38Smrg            nOut++;
107570728a38Smrg        }
10768c9fbc29Smrg    }
10778c9fbc29Smrg    return True;
10788c9fbc29Smrg}
10798c9fbc29Smrg
10808c9fbc29Smrg/*ARGSUSED*/
10818c9fbc29Smrgstatic Bool
108270728a38SmrgCopySwitchScreenArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action,
108370728a38Smrg                     char *buf, int *sz)
10848c9fbc29Smrg{
108570728a38Smrg    XkbSwitchScreenAction *act;
108670728a38Smrg    char tbuf[32];
108770728a38Smrg
108870728a38Smrg    act = &action->screen;
108970728a38Smrg    if ((act->flags & XkbSA_SwitchAbsolute) || (XkbSAScreen(act) < 0))
109070728a38Smrg        snprintf(tbuf, sizeof(tbuf), "screen=%d", XkbSAScreen(act));
109170728a38Smrg    else
109270728a38Smrg        snprintf(tbuf, sizeof(tbuf), "screen=+%d", XkbSAScreen(act));
109370728a38Smrg    TryCopyStr(buf, tbuf, sz);
109470728a38Smrg    if (act->flags & XkbSA_SwitchApplication)
109570728a38Smrg        TryCopyStr(buf, ",!same", sz);
109670728a38Smrg    else
109770728a38Smrg        TryCopyStr(buf, ",same", sz);
10988c9fbc29Smrg    return True;
10998c9fbc29Smrg}
11008c9fbc29Smrg
11018c9fbc29Smrg/*ARGSUSED*/
11028c9fbc29Smrgstatic Bool
110370728a38SmrgCopySetLockControlsArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action,
110470728a38Smrg                        char *buf, int *sz)
11058c9fbc29Smrg{
110670728a38Smrg    XkbCtrlsAction *act;
110770728a38Smrg    unsigned tmp;
110870728a38Smrg    char tbuf[32];
110970728a38Smrg
111070728a38Smrg    act = &action->ctrls;
111170728a38Smrg    tmp = XkbActionCtrls(act);
111270728a38Smrg    TryCopyStr(buf, "controls=", sz);
111370728a38Smrg    if (tmp == 0)
111470728a38Smrg        TryCopyStr(buf, "none", sz);
111570728a38Smrg    else if ((tmp & XkbAllBooleanCtrlsMask) == XkbAllBooleanCtrlsMask)
111670728a38Smrg        TryCopyStr(buf, "all", sz);
11178c9fbc29Smrg    else {
111870728a38Smrg        int nOut = 0;
111970728a38Smrg
112070728a38Smrg        if (tmp & XkbRepeatKeysMask) {
112170728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sRepeatKeys", (nOut > 0 ? "+" : ""));
112270728a38Smrg            TryCopyStr(buf, tbuf, sz);
112370728a38Smrg            nOut++;
112470728a38Smrg        }
112570728a38Smrg        if (tmp & XkbSlowKeysMask) {
112670728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sSlowKeys", (nOut > 0 ? "+" : ""));
112770728a38Smrg            TryCopyStr(buf, tbuf, sz);
112870728a38Smrg            nOut++;
112970728a38Smrg        }
113070728a38Smrg        if (tmp & XkbBounceKeysMask) {
113170728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sBounceKeys", (nOut > 0 ? "+" : ""));
113270728a38Smrg            TryCopyStr(buf, tbuf, sz);
113370728a38Smrg            nOut++;
113470728a38Smrg        }
113570728a38Smrg        if (tmp & XkbStickyKeysMask) {
113670728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sStickyKeys", (nOut > 0 ? "+" : ""));
113770728a38Smrg            TryCopyStr(buf, tbuf, sz);
113870728a38Smrg            nOut++;
113970728a38Smrg        }
114070728a38Smrg        if (tmp & XkbMouseKeysMask) {
114170728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sMouseKeys", (nOut > 0 ? "+" : ""));
114270728a38Smrg            TryCopyStr(buf, tbuf, sz);
114370728a38Smrg            nOut++;
114470728a38Smrg        }
114570728a38Smrg        if (tmp & XkbMouseKeysAccelMask) {
114670728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sMouseKeysAccel", (nOut > 0 ? "+" : ""));
114770728a38Smrg            TryCopyStr(buf, tbuf, sz);
114870728a38Smrg            nOut++;
114970728a38Smrg        }
115070728a38Smrg        if (tmp & XkbAccessXKeysMask) {
115170728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sAccessXKeys", (nOut > 0 ? "+" : ""));
115270728a38Smrg            TryCopyStr(buf, tbuf, sz);
115370728a38Smrg            nOut++;
115470728a38Smrg        }
115570728a38Smrg        if (tmp & XkbAccessXTimeoutMask) {
115670728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sAccessXTimeout", (nOut > 0 ? "+" : ""));
115770728a38Smrg            TryCopyStr(buf, tbuf, sz);
115870728a38Smrg            nOut++;
115970728a38Smrg        }
116070728a38Smrg        if (tmp & XkbAccessXFeedbackMask) {
116170728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sAccessXFeedback", (nOut > 0 ? "+" : ""));
116270728a38Smrg            TryCopyStr(buf, tbuf, sz);
116370728a38Smrg            nOut++;
116470728a38Smrg        }
116570728a38Smrg        if (tmp & XkbAudibleBellMask) {
116670728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sAudibleBell", (nOut > 0 ? "+" : ""));
116770728a38Smrg            TryCopyStr(buf, tbuf, sz);
116870728a38Smrg            nOut++;
116970728a38Smrg        }
117070728a38Smrg        if (tmp & XkbOverlay1Mask) {
117170728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sOverlay1", (nOut > 0 ? "+" : ""));
117270728a38Smrg            TryCopyStr(buf, tbuf, sz);
117370728a38Smrg            nOut++;
117470728a38Smrg        }
117570728a38Smrg        if (tmp & XkbOverlay2Mask) {
117670728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sOverlay2", (nOut > 0 ? "+" : ""));
117770728a38Smrg            TryCopyStr(buf, tbuf, sz);
117870728a38Smrg            nOut++;
117970728a38Smrg        }
118070728a38Smrg        if (tmp & XkbIgnoreGroupLockMask) {
118170728a38Smrg            snprintf(tbuf, sizeof(tbuf), "%sIgnoreGroupLock", (nOut > 0 ? "+" : ""));
118270728a38Smrg            TryCopyStr(buf, tbuf, sz);
118370728a38Smrg            nOut++;
118470728a38Smrg        }
11858c9fbc29Smrg    }
11868c9fbc29Smrg    return True;
11878c9fbc29Smrg}
11888c9fbc29Smrg
11898c9fbc29Smrg/*ARGSUSED*/
11908c9fbc29Smrgstatic Bool
119170728a38SmrgCopyActionMessageArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action,
119270728a38Smrg                      char *buf, int *sz)
11938c9fbc29Smrg{
119470728a38Smrg    XkbMessageAction *act;
119570728a38Smrg    unsigned all;
119670728a38Smrg    char tbuf[32];
119770728a38Smrg
119870728a38Smrg    act = &action->msg;
119970728a38Smrg    all = XkbSA_MessageOnPress | XkbSA_MessageOnRelease;
120070728a38Smrg    TryCopyStr(buf, "report=", sz);
120170728a38Smrg    if ((act->flags & all) == 0)
120270728a38Smrg        TryCopyStr(buf, "none", sz);
120370728a38Smrg    else if ((act->flags & all) == all)
120470728a38Smrg        TryCopyStr(buf, "all", sz);
120570728a38Smrg    else if (act->flags & XkbSA_MessageOnPress)
120670728a38Smrg        TryCopyStr(buf, "KeyPress", sz);
120770728a38Smrg    else
120870728a38Smrg        TryCopyStr(buf, "KeyRelease", sz);
120970728a38Smrg    snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->message[0]);
121070728a38Smrg    TryCopyStr(buf, tbuf, sz);
121170728a38Smrg    snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->message[1]);
121270728a38Smrg    TryCopyStr(buf, tbuf, sz);
121370728a38Smrg    snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->message[2]);
121470728a38Smrg    TryCopyStr(buf, tbuf, sz);
121570728a38Smrg    snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->message[3]);
121670728a38Smrg    TryCopyStr(buf, tbuf, sz);
121770728a38Smrg    snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->message[4]);
121870728a38Smrg    TryCopyStr(buf, tbuf, sz);
121970728a38Smrg    snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->message[5]);
122070728a38Smrg    TryCopyStr(buf, tbuf, sz);
12218c9fbc29Smrg    return True;
12228c9fbc29Smrg}
12238c9fbc29Smrg
12248c9fbc29Smrgstatic Bool
122570728a38SmrgCopyRedirectKeyArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action,
122670728a38Smrg                    char *buf, int *sz)
12278c9fbc29Smrg{
122870728a38Smrg    XkbRedirectKeyAction *act;
122970728a38Smrg    char tbuf[32], *tmp;
123070728a38Smrg    unsigned kc;
123170728a38Smrg    unsigned vmods, vmods_mask;
123270728a38Smrg
123370728a38Smrg    act = &action->redirect;
123470728a38Smrg    kc = act->new_key;
123570728a38Smrg    vmods = XkbSARedirectVMods(act);
123670728a38Smrg    vmods_mask = XkbSARedirectVModsMask(act);
123770728a38Smrg    if (xkb && xkb->names && xkb->names->keys && (kc <= xkb->max_key_code) &&
123870728a38Smrg        (xkb->names->keys[kc].name[0] != '\0')) {
123970728a38Smrg        char *kn;
124070728a38Smrg
124170728a38Smrg        kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile);
124270728a38Smrg        snprintf(tbuf, sizeof(tbuf), "key=%s", kn);
124370728a38Smrg    }
124470728a38Smrg    else
124570728a38Smrg        snprintf(tbuf, sizeof(tbuf), "key=%d", kc);
124670728a38Smrg    TryCopyStr(buf, tbuf, sz);
124770728a38Smrg    if ((act->mods_mask == 0) && (vmods_mask == 0))
124870728a38Smrg        return True;
124970728a38Smrg    if ((act->mods_mask == XkbAllModifiersMask) &&
125070728a38Smrg        (vmods_mask == XkbAllVirtualModsMask)) {
125170728a38Smrg        tmp = XkbVModMaskText(dpy, xkb, act->mods, vmods, XkbXKBFile);
125270728a38Smrg        TryCopyStr(buf, ",mods=", sz);
125370728a38Smrg        TryCopyStr(buf, tmp, sz);
12548c9fbc29Smrg    }
12558c9fbc29Smrg    else {
125670728a38Smrg        if ((act->mods_mask & act->mods) || (vmods_mask & vmods)) {
125770728a38Smrg            tmp = XkbVModMaskText(dpy, xkb, act->mods_mask & act->mods,
125870728a38Smrg                                  vmods_mask & vmods, XkbXKBFile);
125970728a38Smrg            TryCopyStr(buf, ",mods= ", sz);
126070728a38Smrg            TryCopyStr(buf, tmp, sz);
126170728a38Smrg        }
126270728a38Smrg        if ((act->mods_mask & (~act->mods)) || (vmods_mask & (~vmods))) {
126370728a38Smrg            tmp = XkbVModMaskText(dpy, xkb, act->mods_mask & (~act->mods),
126470728a38Smrg                                  vmods_mask & (~vmods), XkbXKBFile);
126570728a38Smrg            TryCopyStr(buf, ",clearMods= ", sz);
126670728a38Smrg            TryCopyStr(buf, tmp, sz);
126770728a38Smrg        }
12688c9fbc29Smrg    }
12698c9fbc29Smrg    return True;
12708c9fbc29Smrg}
12718c9fbc29Smrg
12728c9fbc29Smrg/*ARGSUSED*/
12738c9fbc29Smrgstatic Bool
127470728a38SmrgCopyDeviceBtnArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action,
127570728a38Smrg                  char *buf, int *sz)
12768c9fbc29Smrg{
127770728a38Smrg    XkbDeviceBtnAction *act;
127870728a38Smrg    char tbuf[32];
127970728a38Smrg
128070728a38Smrg    act = &action->devbtn;
128170728a38Smrg    snprintf(tbuf, sizeof(tbuf), "device= %d", act->device);
128270728a38Smrg    TryCopyStr(buf, tbuf, sz);
128370728a38Smrg    TryCopyStr(buf, ",button=", sz);
128470728a38Smrg    snprintf(tbuf, sizeof(tbuf), "%d", act->button);
128570728a38Smrg    TryCopyStr(buf, tbuf, sz);
128670728a38Smrg    if (act->count > 0) {
128770728a38Smrg        snprintf(tbuf, sizeof(tbuf), ",count=%d", act->count);
128870728a38Smrg        TryCopyStr(buf, tbuf, sz);
128970728a38Smrg    }
129070728a38Smrg    if (action->type == XkbSA_LockDeviceBtn) {
129170728a38Smrg        switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
129270728a38Smrg        case XkbSA_LockNoLock:
129370728a38Smrg            snprintf(tbuf, sizeof(tbuf), ",affect=unlock");
129470728a38Smrg            break;
129570728a38Smrg        case XkbSA_LockNoUnlock:
129670728a38Smrg            snprintf(tbuf, sizeof(tbuf), ",affect=lock");
129770728a38Smrg            break;
129870728a38Smrg        case XkbSA_LockNoUnlock | XkbSA_LockNoLock:
129970728a38Smrg            snprintf(tbuf, sizeof(tbuf), ",affect=neither");
130070728a38Smrg            break;
130170728a38Smrg        default:
130270728a38Smrg            snprintf(tbuf, sizeof(tbuf), ",affect=both");
130370728a38Smrg            break;
130470728a38Smrg        }
130570728a38Smrg        TryCopyStr(buf, tbuf, sz);
13068c9fbc29Smrg    }
13078c9fbc29Smrg    return True;
13088c9fbc29Smrg}
13098c9fbc29Smrg
13108c9fbc29Smrg/*ARGSUSED*/
13118c9fbc29Smrgstatic Bool
131270728a38SmrgCopyOtherArgs(Display *dpy, XkbDescPtr xkb, XkbAction *action,
131370728a38Smrg              char *buf, int *sz)
13148c9fbc29Smrg{
131570728a38Smrg    XkbAnyAction *act;
131670728a38Smrg    char tbuf[32];
131770728a38Smrg
131870728a38Smrg    act = &action->any;
131970728a38Smrg    snprintf(tbuf, sizeof(tbuf), "type=0x%02x", act->type);
132070728a38Smrg    TryCopyStr(buf, tbuf, sz);
132170728a38Smrg    snprintf(tbuf, sizeof(tbuf), ",data[0]=0x%02x", act->data[0]);
132270728a38Smrg    TryCopyStr(buf, tbuf, sz);
132370728a38Smrg    snprintf(tbuf, sizeof(tbuf), ",data[1]=0x%02x", act->data[1]);
132470728a38Smrg    TryCopyStr(buf, tbuf, sz);
132570728a38Smrg    snprintf(tbuf, sizeof(tbuf), ",data[2]=0x%02x", act->data[2]);
132670728a38Smrg    TryCopyStr(buf, tbuf, sz);
132770728a38Smrg    snprintf(tbuf, sizeof(tbuf), ",data[3]=0x%02x", act->data[3]);
132870728a38Smrg    TryCopyStr(buf, tbuf, sz);
132970728a38Smrg    snprintf(tbuf, sizeof(tbuf), ",data[4]=0x%02x", act->data[4]);
133070728a38Smrg    TryCopyStr(buf, tbuf, sz);
133170728a38Smrg    snprintf(tbuf, sizeof(tbuf), ",data[5]=0x%02x", act->data[5]);
133270728a38Smrg    TryCopyStr(buf, tbuf, sz);
133370728a38Smrg    snprintf(tbuf, sizeof(tbuf), ",data[6]=0x%02x", act->data[6]);
133470728a38Smrg    TryCopyStr(buf, tbuf, sz);
13358c9fbc29Smrg    return True;
13368c9fbc29Smrg}
13378c9fbc29Smrg
133870728a38Smrgtypedef Bool (*actionCopy) (Display *   /* dpy */ ,
133970728a38Smrg                            XkbDescPtr  /* xkb */ ,
134070728a38Smrg                            XkbAction * /* action */ ,
134170728a38Smrg                            char *      /* buf */ ,
134270728a38Smrg                            int *       /* sz */
134370728a38Smrg    );
134470728a38Smrg
134570728a38Smrgstatic actionCopy copyActionArgs[XkbSA_NumActions] = {
134670728a38Smrg    CopyNoActionArgs            /* NoAction     */ ,
134770728a38Smrg    CopyModActionArgs           /* SetMods      */ ,
134870728a38Smrg    CopyModActionArgs           /* LatchMods    */ ,
134970728a38Smrg    CopyModActionArgs           /* LockMods     */ ,
135070728a38Smrg    CopyGroupActionArgs         /* SetGroup     */ ,
135170728a38Smrg    CopyGroupActionArgs         /* LatchGroup   */ ,
135270728a38Smrg    CopyGroupActionArgs         /* LockGroup    */ ,
135370728a38Smrg    CopyMovePtrArgs             /* MovePtr      */ ,
135470728a38Smrg    CopyPtrBtnArgs              /* PtrBtn       */ ,
135570728a38Smrg    CopyPtrBtnArgs              /* LockPtrBtn   */ ,
135670728a38Smrg    CopySetPtrDfltArgs          /* SetPtrDflt   */ ,
135770728a38Smrg    CopyISOLockArgs             /* ISOLock      */ ,
135870728a38Smrg    CopyNoActionArgs            /* Terminate    */ ,
135970728a38Smrg    CopySwitchScreenArgs        /* SwitchScreen */ ,
136070728a38Smrg    CopySetLockControlsArgs     /* SetControls  */ ,
136170728a38Smrg    CopySetLockControlsArgs     /* LockControls */ ,
136270728a38Smrg    CopyActionMessageArgs       /* ActionMessage */ ,
136370728a38Smrg    CopyRedirectKeyArgs         /* RedirectKey  */ ,
136470728a38Smrg    CopyDeviceBtnArgs           /* DeviceBtn    */ ,
136570728a38Smrg    CopyDeviceBtnArgs           /* LockDeviceBtn */
13668c9fbc29Smrg};
13678c9fbc29Smrg
13688c9fbc29Smrg#define	ACTION_SZ	256
13698c9fbc29Smrg
13708c9fbc29Smrgchar *
137170728a38SmrgXkbActionText(Display *dpy, XkbDescPtr xkb, XkbAction *action, unsigned format)
13728c9fbc29Smrg{
137370728a38Smrg    char buf[ACTION_SZ], *tmp;
137470728a38Smrg    int sz;
13758c9fbc29Smrg
137670728a38Smrg    if (format == XkbCFile) {
137770728a38Smrg        snprintf(buf, sizeof(buf),
137870728a38Smrg                "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }",
137970728a38Smrg                XkbActionTypeText(action->type, XkbCFile),
138070728a38Smrg                action->any.data[0], action->any.data[1], action->any.data[2],
138170728a38Smrg                action->any.data[3], action->any.data[4], action->any.data[5],
138270728a38Smrg                action->any.data[6]);
13838c9fbc29Smrg    }
13848c9fbc29Smrg    else {
138570728a38Smrg        snprintf(buf, sizeof(buf),
138670728a38Smrg                 "%s(", XkbActionTypeText(action->type, XkbXKBFile));
138770728a38Smrg        sz = ACTION_SZ - strlen(buf) + 2;       /* room for close paren and NULL */
138870728a38Smrg        if (action->type < (unsigned) XkbSA_NumActions)
138970728a38Smrg            (*copyActionArgs[action->type]) (dpy, xkb, action, buf, &sz);
139070728a38Smrg        else
139170728a38Smrg            CopyOtherArgs(dpy, xkb, action, buf, &sz);
139270728a38Smrg        TryCopyStr(buf, ")", &sz);
139370728a38Smrg    }
139470728a38Smrg    tmp = tbGetBuffer(strlen(buf) + 1);
139570728a38Smrg    if (tmp != NULL)
139670728a38Smrg        strcpy(tmp, buf);
13978c9fbc29Smrg    return tmp;
13988c9fbc29Smrg}
13998c9fbc29Smrg
14008c9fbc29Smrgchar *
140170728a38SmrgXkbBehaviorText(XkbDescPtr xkb, XkbBehavior * behavior, unsigned format)
14028c9fbc29Smrg{
140370728a38Smrg    char buf[256], *tmp;
14048c9fbc29Smrg
140570728a38Smrg    if (format == XkbCFile) {
140670728a38Smrg        if (behavior->type == XkbKB_Default)
140770728a38Smrg            snprintf(buf, sizeof(buf), "{   0,    0 }");
140870728a38Smrg        else
140970728a38Smrg            snprintf(buf, sizeof(buf), "{ %3d, 0x%02x }", behavior->type, behavior->data);
14108c9fbc29Smrg    }
14118c9fbc29Smrg    else {
141270728a38Smrg        unsigned type, permanent;
141370728a38Smrg
141470728a38Smrg        type = behavior->type & XkbKB_OpMask;
141570728a38Smrg        permanent = ((behavior->type & XkbKB_Permanent) != 0);
141670728a38Smrg
141770728a38Smrg        if (type == XkbKB_Lock) {
141870728a38Smrg            snprintf(buf, sizeof(buf), "lock= %s", (permanent ? "Permanent" : "True"));
141970728a38Smrg        }
142070728a38Smrg        else if (type == XkbKB_RadioGroup) {
142170728a38Smrg            int g;
142270728a38Smrg            char *tmp;
142370728a38Smrg            size_t tmpsize;
142470728a38Smrg
142570728a38Smrg            g = ((behavior->data) & (~XkbKB_RGAllowNone)) + 1;
142670728a38Smrg            if (XkbKB_RGAllowNone & behavior->data) {
142770728a38Smrg                snprintf(buf, sizeof(buf), "allowNone,");
142870728a38Smrg                tmp = &buf[strlen(buf)];
142970728a38Smrg            }
143070728a38Smrg            else
143170728a38Smrg                tmp = buf;
143270728a38Smrg            tmpsize = sizeof(buf) - (tmp - buf);
143370728a38Smrg            if (permanent)
143470728a38Smrg                snprintf(tmp, tmpsize, "permanentRadioGroup= %d", g);
143570728a38Smrg            else
143670728a38Smrg                snprintf(tmp, tmpsize, "radioGroup= %d", g);
143770728a38Smrg        }
143870728a38Smrg        else if ((type == XkbKB_Overlay1) || (type == XkbKB_Overlay2)) {
143970728a38Smrg            int ndx, kc;
144070728a38Smrg            char *kn;
144170728a38Smrg
144270728a38Smrg            ndx = ((type == XkbKB_Overlay1) ? 1 : 2);
144370728a38Smrg            kc = behavior->data;
144470728a38Smrg            if ((xkb) && (xkb->names) && (xkb->names->keys))
144570728a38Smrg                kn = XkbKeyNameText(xkb->names->keys[kc].name, XkbXKBFile);
144670728a38Smrg            else {
144770728a38Smrg                static char tbuf[8];
144870728a38Smrg
144970728a38Smrg                snprintf(tbuf, sizeof(tbuf), "%d", kc);
145070728a38Smrg                kn = tbuf;
145170728a38Smrg            }
145270728a38Smrg            if (permanent)
145370728a38Smrg                snprintf(buf, sizeof(buf), "permanentOverlay%d= %s", ndx, kn);
145470728a38Smrg            else
145570728a38Smrg                snprintf(buf, sizeof(buf), "overlay%d= %s", ndx, kn);
145670728a38Smrg        }
145770728a38Smrg    }
145870728a38Smrg    tmp = tbGetBuffer(strlen(buf) + 1);
145970728a38Smrg    if (tmp != NULL)
146070728a38Smrg        strcpy(tmp, buf);
14618c9fbc29Smrg    return tmp;
14628c9fbc29Smrg}
14638c9fbc29Smrg
14648c9fbc29Smrg/***====================================================================***/
14658c9fbc29Smrg
14668c9fbc29Smrgchar *
14678c9fbc29SmrgXkbIndentText(unsigned size)
14688c9fbc29Smrg{
146970728a38Smrg    static char buf[32];
147070728a38Smrg    register int i;
14718c9fbc29Smrg
147270728a38Smrg    if (size > 31)
147370728a38Smrg        size = 31;
14748c9fbc29Smrg
147570728a38Smrg    for (i = 0; i < size; i++) {
147670728a38Smrg        buf[i] = ' ';
14778c9fbc29Smrg    }
147870728a38Smrg    buf[size] = '\0';
14798c9fbc29Smrg    return buf;
14808c9fbc29Smrg}
14818c9fbc29Smrg
14828c9fbc29Smrg
14838c9fbc29Smrg/***====================================================================***/
14848c9fbc29Smrg
14858c9fbc29Smrg#define	PIXEL_MAX	65535
14868c9fbc29Smrg
14878c9fbc29SmrgBool
148870728a38SmrgXkbLookupCanonicalRGBColor(char *def, XColor *color)
14898c9fbc29Smrg{
149070728a38Smrg    int tmp;
149170728a38Smrg
149270728a38Smrg    if (_XkbStrCaseEqual(def, "black")) {
149370728a38Smrg        color->red = color->green = color->blue = 0;
149470728a38Smrg        return True;
149570728a38Smrg    }
149670728a38Smrg    else if (_XkbStrCaseEqual(def, "white")) {
149770728a38Smrg        color->red = color->green = color->blue = PIXEL_MAX;
149870728a38Smrg        return True;
149970728a38Smrg    }
150070728a38Smrg    else if ((sscanf(def, "grey%d", &tmp) == 1) ||
150170728a38Smrg             (sscanf(def, "gray%d", &tmp) == 1) ||
150270728a38Smrg             (sscanf(def, "Grey%d", &tmp) == 1) ||
150370728a38Smrg             (sscanf(def, "Gray%d", &tmp) == 1)) {
150470728a38Smrg        if ((tmp > 0) && (tmp <= 100)) {
150570728a38Smrg            tmp = (PIXEL_MAX * tmp) / 100;
150670728a38Smrg            color->red = color->green = color->blue = tmp;
150770728a38Smrg            return True;
150870728a38Smrg        }
150970728a38Smrg    }
151070728a38Smrg    else if ((tmp = (_XkbStrCaseEqual(def, "red") * 100)) ||
151170728a38Smrg             (sscanf(def, "red%d", &tmp) == 1)) {
151270728a38Smrg        if ((tmp > 0) && (tmp <= 100)) {
151370728a38Smrg            tmp = (PIXEL_MAX * tmp) / 100;
151470728a38Smrg            color->red = tmp;
151570728a38Smrg            color->green = color->blue = 0;
151670728a38Smrg            return True;
151770728a38Smrg        }
151870728a38Smrg    }
151970728a38Smrg    else if ((tmp = (_XkbStrCaseEqual(def, "green") * 100)) ||
152070728a38Smrg             (sscanf(def, "green%d", &tmp) == 1)) {
152170728a38Smrg        if ((tmp > 0) && (tmp <= 100)) {
152270728a38Smrg            tmp = (PIXEL_MAX * tmp) / 100;
152370728a38Smrg            color->green = tmp;
152470728a38Smrg            color->red = color->blue = 0;
152570728a38Smrg            return True;
152670728a38Smrg        }
152770728a38Smrg    }
152870728a38Smrg    else if ((tmp = (_XkbStrCaseEqual(def, "blue") * 100)) ||
152970728a38Smrg             (sscanf(def, "blue%d", &tmp) == 1)) {
153070728a38Smrg        if ((tmp > 0) && (tmp <= 100)) {
153170728a38Smrg            tmp = (PIXEL_MAX * tmp) / 100;
153270728a38Smrg            color->blue = tmp;
153370728a38Smrg            color->red = color->green = 0;
153470728a38Smrg            return True;
153570728a38Smrg        }
153670728a38Smrg    }
153770728a38Smrg    else if ((tmp = (_XkbStrCaseEqual(def, "magenta") * 100)) ||
153870728a38Smrg             (sscanf(def, "magenta%d", &tmp) == 1)) {
153970728a38Smrg        if ((tmp > 0) && (tmp <= 100)) {
154070728a38Smrg            tmp = (PIXEL_MAX * tmp) / 100;
154170728a38Smrg            color->green = 0;
154270728a38Smrg            color->red = color->blue = tmp;
154370728a38Smrg            return True;
154470728a38Smrg        }
154570728a38Smrg    }
154670728a38Smrg    else if ((tmp = (_XkbStrCaseEqual(def, "cyan") * 100)) ||
154770728a38Smrg             (sscanf(def, "cyan%d", &tmp) == 1)) {
154870728a38Smrg        if ((tmp > 0) && (tmp <= 100)) {
154970728a38Smrg            tmp = (PIXEL_MAX * tmp) / 100;
155070728a38Smrg            color->red = 0;
155170728a38Smrg            color->green = color->blue = tmp;
155270728a38Smrg            return True;
155370728a38Smrg        }
155470728a38Smrg    }
155570728a38Smrg    else if ((tmp = (_XkbStrCaseEqual(def, "yellow") * 100)) ||
155670728a38Smrg             (sscanf(def, "yellow%d", &tmp) == 1)) {
155770728a38Smrg        if ((tmp > 0) && (tmp <= 100)) {
155870728a38Smrg            tmp = (PIXEL_MAX * tmp) / 100;
155970728a38Smrg            color->blue = 0;
156070728a38Smrg            color->red = color->green = tmp;
156170728a38Smrg            return True;
156270728a38Smrg        }
15638c9fbc29Smrg    }
15648c9fbc29Smrg    return False;
15658c9fbc29Smrg}
15668c9fbc29Smrg
1567