xkbInit.c revision 1b5d61b8
105b261ecSmrg/************************************************************
205b261ecSmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
305b261ecSmrg
405b261ecSmrgPermission to use, copy, modify, and distribute this
505b261ecSmrgsoftware and its documentation for any purpose and without
605b261ecSmrgfee is hereby granted, provided that the above copyright
705b261ecSmrgnotice appear in all copies and that both that copyright
805b261ecSmrgnotice and this permission notice appear in supporting
935c4bbdfSmrgdocumentation, and that the name of Silicon Graphics not be
1035c4bbdfSmrgused in advertising or publicity pertaining to distribution
1105b261ecSmrgof the software without specific prior written permission.
1235c4bbdfSmrgSilicon Graphics makes no representation about the suitability
1305b261ecSmrgof this software for any purpose. It is provided "as is"
1405b261ecSmrgwithout any express or implied warranty.
1505b261ecSmrg
1635c4bbdfSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
1735c4bbdfSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1805b261ecSmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
1935c4bbdfSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
2035c4bbdfSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2135c4bbdfSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2205b261ecSmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
2305b261ecSmrgTHE 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 <xkb-config.h>
3205b261ecSmrg
3305b261ecSmrg#include <stdio.h>
3405b261ecSmrg#include <stdlib.h>
3505b261ecSmrg#include <ctype.h>
3605b261ecSmrg#include <unistd.h>
3705b261ecSmrg#include <math.h>
3805b261ecSmrg#include <X11/X.h>
3905b261ecSmrg#include <X11/Xproto.h>
4005b261ecSmrg#include <X11/keysym.h>
4105b261ecSmrg#include <X11/Xatom.h>
4205b261ecSmrg#include "misc.h"
4305b261ecSmrg#include "inputstr.h"
4405b261ecSmrg#include "opaque.h"
4505b261ecSmrg#include "property.h"
466747b715Smrg#include "scrnintstr.h"
4705b261ecSmrg#define	XKBSRV_NEED_FILE_FUNCS
4805b261ecSmrg#include <xkbsrv.h>
494642e01fSmrg#include "xkbgeom.h"
5005b261ecSmrg#include <X11/extensions/XKMformat.h>
514642e01fSmrg#include "xkbfile.h"
5205b261ecSmrg#include "xkb.h"
5305b261ecSmrg
5405b261ecSmrg#define	CREATE_ATOM(s)	MakeAtom(s,sizeof(s)-1,1)
5505b261ecSmrg
564642e01fSmrg#if defined(__alpha) || defined(__alpha__)
5705b261ecSmrg#define	LED_COMPOSE	2
5805b261ecSmrg#define LED_CAPS	3
5905b261ecSmrg#define	LED_SCROLL	4
6005b261ecSmrg#define	LED_NUM		5
6105b261ecSmrg#define	PHYS_LEDS	0x1f
6205b261ecSmrg#else
631b5d61b8Smrg#ifdef __sun
6405b261ecSmrg#define LED_NUM		1
6505b261ecSmrg#define	LED_SCROLL	2
6605b261ecSmrg#define	LED_COMPOSE	3
6705b261ecSmrg#define LED_CAPS	4
6805b261ecSmrg#define	PHYS_LEDS	0x0f
6905b261ecSmrg#else
7005b261ecSmrg#define	LED_CAPS	1
7105b261ecSmrg#define	LED_NUM		2
7205b261ecSmrg#define	LED_SCROLL	3
7305b261ecSmrg#define	PHYS_LEDS	0x07
7405b261ecSmrg#endif
7505b261ecSmrg#endif
7605b261ecSmrg
7705b261ecSmrg#define	MAX_TOC	16
7835c4bbdfSmrgtypedef struct _SrvXkmInfo {
7935c4bbdfSmrg    DeviceIntPtr dev;
8035c4bbdfSmrg    FILE *file;
8135c4bbdfSmrg    XkbDescPtr xkb;
8205b261ecSmrg} SrvXkmInfo;
8305b261ecSmrg
8405b261ecSmrg/***====================================================================***/
8505b261ecSmrg
8605b261ecSmrg#ifndef XKB_DFLT_RULES_PROP
876747b715Smrg#define	XKB_DFLT_RULES_PROP	TRUE
8805b261ecSmrg#endif
8905b261ecSmrg
9035c4bbdfSmrgconst char *XkbBaseDirectory = XKB_BASE_DIRECTORY;
9135c4bbdfSmrgconst char *XkbBinDirectory = XKB_BIN_DIRECTORY;
9235c4bbdfSmrgstatic int XkbWantAccessX = 0;
9305b261ecSmrg
9435c4bbdfSmrgstatic char *XkbRulesDflt = NULL;
9535c4bbdfSmrgstatic char *XkbModelDflt = NULL;
9635c4bbdfSmrgstatic char *XkbLayoutDflt = NULL;
9735c4bbdfSmrgstatic char *XkbVariantDflt = NULL;
9835c4bbdfSmrgstatic char *XkbOptionsDflt = NULL;
9905b261ecSmrg
10035c4bbdfSmrgstatic char *XkbRulesUsed = NULL;
10135c4bbdfSmrgstatic char *XkbModelUsed = NULL;
10235c4bbdfSmrgstatic char *XkbLayoutUsed = NULL;
10335c4bbdfSmrgstatic char *XkbVariantUsed = NULL;
10435c4bbdfSmrgstatic char *XkbOptionsUsed = NULL;
10505b261ecSmrg
10635c4bbdfSmrgstatic XkbDescPtr xkb_cached_map = NULL;
1074642e01fSmrg
10835c4bbdfSmrgstatic Bool XkbWantRulesProp = XKB_DFLT_RULES_PROP;
10905b261ecSmrg
11005b261ecSmrg/***====================================================================***/
11105b261ecSmrg
1126747b715Smrg/**
1136747b715Smrg * Get the current default XKB rules.
1146747b715Smrg * Caller must free the data in rmlvo.
1156747b715Smrg */
1166747b715Smrgvoid
11735c4bbdfSmrgXkbGetRulesDflts(XkbRMLVOSet * rmlvo)
11805b261ecSmrg{
11935c4bbdfSmrg    rmlvo->rules = strdup(XkbRulesDflt ? XkbRulesDflt : XKB_DFLT_RULES);
12035c4bbdfSmrg    rmlvo->model = strdup(XkbModelDflt ? XkbModelDflt : XKB_DFLT_MODEL);
12135c4bbdfSmrg    rmlvo->layout = strdup(XkbLayoutDflt ? XkbLayoutDflt : XKB_DFLT_LAYOUT);
12235c4bbdfSmrg    rmlvo->variant = strdup(XkbVariantDflt ? XkbVariantDflt : XKB_DFLT_VARIANT);
12335c4bbdfSmrg    rmlvo->options = strdup(XkbOptionsDflt ? XkbOptionsDflt : XKB_DFLT_OPTIONS);
1246747b715Smrg}
1256747b715Smrg
1266747b715Smrgvoid
12735c4bbdfSmrgXkbFreeRMLVOSet(XkbRMLVOSet * rmlvo, Bool freeRMLVO)
1286747b715Smrg{
1296747b715Smrg    if (!rmlvo)
1306747b715Smrg        return;
1316747b715Smrg
1326747b715Smrg    free(rmlvo->rules);
1336747b715Smrg    free(rmlvo->model);
1346747b715Smrg    free(rmlvo->layout);
1356747b715Smrg    free(rmlvo->variant);
1366747b715Smrg    free(rmlvo->options);
1376747b715Smrg
1386747b715Smrg    if (freeRMLVO)
1396747b715Smrg        free(rmlvo);
1406747b715Smrg    else
1416747b715Smrg        memset(rmlvo, 0, sizeof(XkbRMLVOSet));
14205b261ecSmrg}
14305b261ecSmrg
14405b261ecSmrgstatic Bool
14535c4bbdfSmrgXkbWriteRulesProp(ClientPtr client, void *closure)
14605b261ecSmrg{
14735c4bbdfSmrg    int len, out;
14835c4bbdfSmrg    Atom name;
14935c4bbdfSmrg    char *pval;
15035c4bbdfSmrg
15135c4bbdfSmrg    len = (XkbRulesUsed ? strlen(XkbRulesUsed) : 0);
15235c4bbdfSmrg    len += (XkbModelUsed ? strlen(XkbModelUsed) : 0);
15335c4bbdfSmrg    len += (XkbLayoutUsed ? strlen(XkbLayoutUsed) : 0);
15435c4bbdfSmrg    len += (XkbVariantUsed ? strlen(XkbVariantUsed) : 0);
15535c4bbdfSmrg    len += (XkbOptionsUsed ? strlen(XkbOptionsUsed) : 0);
15635c4bbdfSmrg    if (len < 1)
15735c4bbdfSmrg        return TRUE;
15835c4bbdfSmrg
15935c4bbdfSmrg    len += 5;                   /* trailing NULs */
16035c4bbdfSmrg
16135c4bbdfSmrg    name =
16235c4bbdfSmrg        MakeAtom(_XKB_RF_NAMES_PROP_ATOM, strlen(_XKB_RF_NAMES_PROP_ATOM), 1);
16335c4bbdfSmrg    if (name == None) {
16435c4bbdfSmrg        ErrorF("[xkb] Atom error: %s not created\n", _XKB_RF_NAMES_PROP_ATOM);
16535c4bbdfSmrg        return TRUE;
16635c4bbdfSmrg    }
16735c4bbdfSmrg    pval = (char *) malloc(len);
16805b261ecSmrg    if (!pval) {
16935c4bbdfSmrg        ErrorF("[xkb] Allocation error: %s proprerty not created\n",
17035c4bbdfSmrg               _XKB_RF_NAMES_PROP_ATOM);
17135c4bbdfSmrg        return TRUE;
17205b261ecSmrg    }
17335c4bbdfSmrg    out = 0;
1746747b715Smrg    if (XkbRulesUsed) {
17535c4bbdfSmrg        strcpy(&pval[out], XkbRulesUsed);
17635c4bbdfSmrg        out += strlen(XkbRulesUsed);
17705b261ecSmrg    }
17835c4bbdfSmrg    pval[out++] = '\0';
17905b261ecSmrg    if (XkbModelUsed) {
18035c4bbdfSmrg        strcpy(&pval[out], XkbModelUsed);
18135c4bbdfSmrg        out += strlen(XkbModelUsed);
18235c4bbdfSmrg    }
18335c4bbdfSmrg    pval[out++] = '\0';
18405b261ecSmrg    if (XkbLayoutUsed) {
18535c4bbdfSmrg        strcpy(&pval[out], XkbLayoutUsed);
18635c4bbdfSmrg        out += strlen(XkbLayoutUsed);
18705b261ecSmrg    }
18835c4bbdfSmrg    pval[out++] = '\0';
18905b261ecSmrg    if (XkbVariantUsed) {
19035c4bbdfSmrg        strcpy(&pval[out], XkbVariantUsed);
19135c4bbdfSmrg        out += strlen(XkbVariantUsed);
19205b261ecSmrg    }
19335c4bbdfSmrg    pval[out++] = '\0';
19405b261ecSmrg    if (XkbOptionsUsed) {
19535c4bbdfSmrg        strcpy(&pval[out], XkbOptionsUsed);
19635c4bbdfSmrg        out += strlen(XkbOptionsUsed);
19705b261ecSmrg    }
19835c4bbdfSmrg    pval[out++] = '\0';
19935c4bbdfSmrg    if (out != len) {
20035c4bbdfSmrg        ErrorF("[xkb] Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n",
20135c4bbdfSmrg               out, len);
20205b261ecSmrg    }
20335c4bbdfSmrg    dixChangeWindowProperty(serverClient, screenInfo.screens[0]->root, name,
20435c4bbdfSmrg                            XA_STRING, 8, PropModeReplace, len, pval, TRUE);
2056747b715Smrg    free(pval);
2066747b715Smrg    return TRUE;
20705b261ecSmrg}
20805b261ecSmrg
20935c4bbdfSmrgvoid
21035c4bbdfSmrgXkbInitRules(XkbRMLVOSet *rmlvo,
21135c4bbdfSmrg             const char *rules,
21235c4bbdfSmrg             const char *model,
21335c4bbdfSmrg             const char *layout,
21435c4bbdfSmrg             const char *variant,
21535c4bbdfSmrg             const char *options)
21635c4bbdfSmrg{
21735c4bbdfSmrg    rmlvo->rules = rules ? xnfstrdup(rules) : NULL;
21835c4bbdfSmrg    rmlvo->model = model ? xnfstrdup(model) : NULL;
21935c4bbdfSmrg    rmlvo->layout = layout ? xnfstrdup(layout) : NULL;
22035c4bbdfSmrg    rmlvo->variant = variant ? xnfstrdup(variant) : NULL;
22135c4bbdfSmrg    rmlvo->options = options ? xnfstrdup(options) : NULL;
22235c4bbdfSmrg}
22335c4bbdfSmrg
22405b261ecSmrgstatic void
22535c4bbdfSmrgXkbSetRulesUsed(XkbRMLVOSet * rmlvo)
22605b261ecSmrg{
2276747b715Smrg    free(XkbRulesUsed);
22835c4bbdfSmrg    XkbRulesUsed = (rmlvo->rules ? Xstrdup(rmlvo->rules) : NULL);
2296747b715Smrg    free(XkbModelUsed);
23035c4bbdfSmrg    XkbModelUsed = (rmlvo->model ? Xstrdup(rmlvo->model) : NULL);
2316747b715Smrg    free(XkbLayoutUsed);
23235c4bbdfSmrg    XkbLayoutUsed = (rmlvo->layout ? Xstrdup(rmlvo->layout) : NULL);
2336747b715Smrg    free(XkbVariantUsed);
23435c4bbdfSmrg    XkbVariantUsed = (rmlvo->variant ? Xstrdup(rmlvo->variant) : NULL);
2356747b715Smrg    free(XkbOptionsUsed);
23635c4bbdfSmrg    XkbOptionsUsed = (rmlvo->options ? Xstrdup(rmlvo->options) : NULL);
23705b261ecSmrg    if (XkbWantRulesProp)
23835c4bbdfSmrg        QueueWorkProc(XkbWriteRulesProp, NULL, NULL);
23905b261ecSmrg    return;
24005b261ecSmrg}
24105b261ecSmrg
2426747b715Smrgvoid
24335c4bbdfSmrgXkbSetRulesDflts(XkbRMLVOSet * rmlvo)
24405b261ecSmrg{
2456747b715Smrg    if (rmlvo->rules) {
2466747b715Smrg        free(XkbRulesDflt);
24735c4bbdfSmrg        XkbRulesDflt = Xstrdup(rmlvo->rules);
2484642e01fSmrg    }
2496747b715Smrg    if (rmlvo->model) {
25035c4bbdfSmrg        free(XkbModelDflt);
25135c4bbdfSmrg        XkbModelDflt = Xstrdup(rmlvo->model);
25205b261ecSmrg    }
2536747b715Smrg    if (rmlvo->layout) {
25435c4bbdfSmrg        free(XkbLayoutDflt);
25535c4bbdfSmrg        XkbLayoutDflt = Xstrdup(rmlvo->layout);
25605b261ecSmrg    }
2576747b715Smrg    if (rmlvo->variant) {
25835c4bbdfSmrg        free(XkbVariantDflt);
25935c4bbdfSmrg        XkbVariantDflt = Xstrdup(rmlvo->variant);
26005b261ecSmrg    }
2616747b715Smrg    if (rmlvo->options) {
26235c4bbdfSmrg        free(XkbOptionsDflt);
26335c4bbdfSmrg        XkbOptionsDflt = Xstrdup(rmlvo->options);
26405b261ecSmrg    }
26505b261ecSmrg    return;
26605b261ecSmrg}
26705b261ecSmrg
26835c4bbdfSmrgvoid
26935c4bbdfSmrgXkbDeleteRulesUsed(void)
27035c4bbdfSmrg{
27135c4bbdfSmrg    free(XkbRulesUsed);
27235c4bbdfSmrg    XkbRulesUsed = NULL;
27335c4bbdfSmrg    free(XkbModelUsed);
27435c4bbdfSmrg    XkbModelUsed = NULL;
27535c4bbdfSmrg    free(XkbLayoutUsed);
27635c4bbdfSmrg    XkbLayoutUsed = NULL;
27735c4bbdfSmrg    free(XkbVariantUsed);
27835c4bbdfSmrg    XkbVariantUsed = NULL;
27935c4bbdfSmrg    free(XkbOptionsUsed);
28035c4bbdfSmrg    XkbOptionsUsed = NULL;
28135c4bbdfSmrg}
28235c4bbdfSmrg
2834642e01fSmrgvoid
2846747b715SmrgXkbDeleteRulesDflts(void)
2854642e01fSmrg{
2866747b715Smrg    free(XkbRulesDflt);
2876747b715Smrg    XkbRulesDflt = NULL;
2886747b715Smrg    free(XkbModelDflt);
2894642e01fSmrg    XkbModelDflt = NULL;
2906747b715Smrg    free(XkbLayoutDflt);
2914642e01fSmrg    XkbLayoutDflt = NULL;
2926747b715Smrg    free(XkbVariantDflt);
2934642e01fSmrg    XkbVariantDflt = NULL;
2946747b715Smrg    free(XkbOptionsDflt);
2954642e01fSmrg    XkbOptionsDflt = NULL;
2964642e01fSmrg
2976747b715Smrg    XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
2984642e01fSmrg    xkb_cached_map = NULL;
2994642e01fSmrg}
30005b261ecSmrg
3016747b715Smrg#define DIFFERS(a, b) (strcmp((a) ? (a) : "", (b) ? (b) : "") != 0)
3026747b715Smrg
3036747b715Smrgstatic Bool
30435c4bbdfSmrgXkbCompareUsedRMLVO(XkbRMLVOSet * rmlvo)
3056747b715Smrg{
3066747b715Smrg    if (DIFFERS(rmlvo->rules, XkbRulesUsed) ||
3076747b715Smrg        DIFFERS(rmlvo->model, XkbModelUsed) ||
3086747b715Smrg        DIFFERS(rmlvo->layout, XkbLayoutUsed) ||
3096747b715Smrg        DIFFERS(rmlvo->variant, XkbVariantUsed) ||
3106747b715Smrg        DIFFERS(rmlvo->options, XkbOptionsUsed))
3116747b715Smrg        return FALSE;
3126747b715Smrg    return TRUE;
3136747b715Smrg}
3146747b715Smrg
3156747b715Smrg#undef DIFFERS
3166747b715Smrg
3174642e01fSmrg/***====================================================================***/
31805b261ecSmrg
31905b261ecSmrg#include "xkbDflts.h"
32005b261ecSmrg
32105b261ecSmrgstatic Bool
3224642e01fSmrgXkbInitKeyTypes(XkbDescPtr xkb)
32305b261ecSmrg{
3244642e01fSmrg    if (xkb->defined & XkmTypesMask)
3256747b715Smrg        return TRUE;
3264642e01fSmrg
32705b261ecSmrg    initTypeNames(NULL);
32835c4bbdfSmrg    if (XkbAllocClientMap(xkb, XkbKeyTypesMask, num_dflt_types) != Success)
32935c4bbdfSmrg        return FALSE;
33035c4bbdfSmrg    if (XkbCopyKeyTypes(dflt_types, xkb->map->types, num_dflt_types) != Success) {
33135c4bbdfSmrg        return FALSE;
33205b261ecSmrg    }
33335c4bbdfSmrg    xkb->map->size_types = xkb->map->num_types = num_dflt_types;
3346747b715Smrg    return TRUE;
33505b261ecSmrg}
33605b261ecSmrg
33705b261ecSmrgstatic void
3384642e01fSmrgXkbInitRadioGroups(XkbSrvInfoPtr xkbi)
33905b261ecSmrg{
34005b261ecSmrg    xkbi->nRadioGroups = 0;
34105b261ecSmrg    xkbi->radioGroups = NULL;
34205b261ecSmrg    return;
34305b261ecSmrg}
34405b261ecSmrg
34505b261ecSmrgstatic Status
3464642e01fSmrgXkbInitCompatStructs(XkbDescPtr xkb)
34705b261ecSmrg{
34835c4bbdfSmrg    register int i;
34935c4bbdfSmrg    XkbCompatMapPtr compat;
35005b261ecSmrg
3514642e01fSmrg    if (xkb->defined & XkmCompatMapMask)
3526747b715Smrg        return TRUE;
3534642e01fSmrg
35435c4bbdfSmrg    if (XkbAllocCompatMap(xkb, XkbAllCompatMask, num_dfltSI) != Success)
35535c4bbdfSmrg        return BadAlloc;
35605b261ecSmrg    compat = xkb->compat;
35705b261ecSmrg    if (compat->sym_interpret) {
35835c4bbdfSmrg        compat->num_si = num_dfltSI;
35935c4bbdfSmrg        memcpy((char *) compat->sym_interpret, (char *) dfltSI, sizeof(dfltSI));
36035c4bbdfSmrg    }
36135c4bbdfSmrg    for (i = 0; i < XkbNumKbdGroups; i++) {
36235c4bbdfSmrg        compat->groups[i] = compatMap.groups[i];
36335c4bbdfSmrg        if (compat->groups[i].vmods != 0) {
36435c4bbdfSmrg            unsigned mask;
36535c4bbdfSmrg
36635c4bbdfSmrg            mask = XkbMaskForVMask(xkb, compat->groups[i].vmods);
36735c4bbdfSmrg            compat->groups[i].mask = compat->groups[i].real_mods | mask;
36835c4bbdfSmrg        }
36935c4bbdfSmrg        else
37035c4bbdfSmrg            compat->groups[i].mask = compat->groups[i].real_mods;
37105b261ecSmrg    }
37205b261ecSmrg    return Success;
37305b261ecSmrg}
37405b261ecSmrg
37505b261ecSmrgstatic void
3764642e01fSmrgXkbInitSemantics(XkbDescPtr xkb)
37705b261ecSmrg{
3784642e01fSmrg    XkbInitKeyTypes(xkb);
3794642e01fSmrg    XkbInitCompatStructs(xkb);
38005b261ecSmrg    return;
38105b261ecSmrg}
38205b261ecSmrg
38305b261ecSmrg/***====================================================================***/
38405b261ecSmrg
38505b261ecSmrgstatic Status
3864642e01fSmrgXkbInitNames(XkbSrvInfoPtr xkbi)
38705b261ecSmrg{
38835c4bbdfSmrg    XkbDescPtr xkb;
38935c4bbdfSmrg    XkbNamesPtr names;
39035c4bbdfSmrg    Status rtrn;
39135c4bbdfSmrg    Atom unknown;
39235c4bbdfSmrg
39335c4bbdfSmrg    xkb = xkbi->desc;
39435c4bbdfSmrg    if ((rtrn = XkbAllocNames(xkb, XkbAllNamesMask, 0, 0)) != Success)
39535c4bbdfSmrg        return rtrn;
39635c4bbdfSmrg    unknown = CREATE_ATOM("unknown");
39705b261ecSmrg    names = xkb->names;
39835c4bbdfSmrg    if (names->keycodes == None)
39935c4bbdfSmrg        names->keycodes = unknown;
40035c4bbdfSmrg    if (names->geometry == None)
40135c4bbdfSmrg        names->geometry = unknown;
40235c4bbdfSmrg    if (names->phys_symbols == None)
40335c4bbdfSmrg        names->phys_symbols = unknown;
40435c4bbdfSmrg    if (names->symbols == None)
40535c4bbdfSmrg        names->symbols = unknown;
40635c4bbdfSmrg    if (names->types == None)
40735c4bbdfSmrg        names->types = unknown;
40835c4bbdfSmrg    if (names->compat == None)
40935c4bbdfSmrg        names->compat = unknown;
4104642e01fSmrg    if (!(xkb->defined & XkmVirtualModsMask)) {
41135c4bbdfSmrg        if (names->vmods[vmod_NumLock] == None)
41235c4bbdfSmrg            names->vmods[vmod_NumLock] = CREATE_ATOM("NumLock");
41335c4bbdfSmrg        if (names->vmods[vmod_Alt] == None)
41435c4bbdfSmrg            names->vmods[vmod_Alt] = CREATE_ATOM("Alt");
41535c4bbdfSmrg        if (names->vmods[vmod_AltGr] == None)
41635c4bbdfSmrg            names->vmods[vmod_AltGr] = CREATE_ATOM("ModeSwitch");
41705b261ecSmrg    }
41805b261ecSmrg
4194642e01fSmrg    if (!(xkb->defined & XkmIndicatorsMask) ||
4204642e01fSmrg        !(xkb->defined & XkmGeometryMask)) {
42135c4bbdfSmrg        initIndicatorNames(NULL, xkb);
42235c4bbdfSmrg        if (names->indicators[LED_CAPS - 1] == None)
42335c4bbdfSmrg            names->indicators[LED_CAPS - 1] = CREATE_ATOM("Caps Lock");
42435c4bbdfSmrg        if (names->indicators[LED_NUM - 1] == None)
42535c4bbdfSmrg            names->indicators[LED_NUM - 1] = CREATE_ATOM("Num Lock");
42635c4bbdfSmrg        if (names->indicators[LED_SCROLL - 1] == None)
42735c4bbdfSmrg            names->indicators[LED_SCROLL - 1] = CREATE_ATOM("Scroll Lock");
42805b261ecSmrg#ifdef LED_COMPOSE
42935c4bbdfSmrg        if (names->indicators[LED_COMPOSE - 1] == None)
43035c4bbdfSmrg            names->indicators[LED_COMPOSE - 1] = CREATE_ATOM("Compose");
43105b261ecSmrg#endif
43205b261ecSmrg    }
4334642e01fSmrg
43435c4bbdfSmrg    if (xkb->geom != NULL)
43535c4bbdfSmrg        names->geometry = xkb->geom->name;
43635c4bbdfSmrg    else
43735c4bbdfSmrg        names->geometry = unknown;
4384642e01fSmrg
43905b261ecSmrg    return Success;
44005b261ecSmrg}
44105b261ecSmrg
44205b261ecSmrgstatic Status
4434642e01fSmrgXkbInitIndicatorMap(XkbSrvInfoPtr xkbi)
44405b261ecSmrg{
44535c4bbdfSmrg    XkbDescPtr xkb;
44635c4bbdfSmrg    XkbIndicatorPtr map;
44735c4bbdfSmrg    XkbSrvLedInfoPtr sli;
44805b261ecSmrg
44935c4bbdfSmrg    xkb = xkbi->desc;
45035c4bbdfSmrg    if (XkbAllocIndicatorMaps(xkb) != Success)
45135c4bbdfSmrg        return BadAlloc;
4524642e01fSmrg
4534642e01fSmrg    if (!(xkb->defined & XkmIndicatorsMask)) {
45435c4bbdfSmrg        map = xkb->indicators;
4554642e01fSmrg        map->phys_indicators = PHYS_LEDS;
45635c4bbdfSmrg        map->maps[LED_CAPS - 1].flags = XkbIM_NoExplicit;
45735c4bbdfSmrg        map->maps[LED_CAPS - 1].which_mods = XkbIM_UseLocked;
45835c4bbdfSmrg        map->maps[LED_CAPS - 1].mods.mask = LockMask;
45935c4bbdfSmrg        map->maps[LED_CAPS - 1].mods.real_mods = LockMask;
4604642e01fSmrg
46135c4bbdfSmrg        map->maps[LED_NUM - 1].flags = XkbIM_NoExplicit;
46235c4bbdfSmrg        map->maps[LED_NUM - 1].which_mods = XkbIM_UseLocked;
46335c4bbdfSmrg        map->maps[LED_NUM - 1].mods.mask = 0;
46435c4bbdfSmrg        map->maps[LED_NUM - 1].mods.real_mods = 0;
46535c4bbdfSmrg        map->maps[LED_NUM - 1].mods.vmods = vmod_NumLockMask;
4664642e01fSmrg
46735c4bbdfSmrg        map->maps[LED_SCROLL - 1].flags = XkbIM_NoExplicit;
46835c4bbdfSmrg        map->maps[LED_SCROLL - 1].which_mods = XkbIM_UseLocked;
46935c4bbdfSmrg        map->maps[LED_SCROLL - 1].mods.mask = Mod3Mask;
47035c4bbdfSmrg        map->maps[LED_SCROLL - 1].mods.real_mods = Mod3Mask;
47105b261ecSmrg    }
4724642e01fSmrg
47335c4bbdfSmrg    sli = XkbFindSrvLedInfo(xkbi->device, XkbDfltXIClass, XkbDfltXIId, 0);
47405b261ecSmrg    if (sli)
47535c4bbdfSmrg        XkbCheckIndicatorMaps(xkbi->device, sli, XkbAllIndicatorsMask);
4764642e01fSmrg
47705b261ecSmrg    return Success;
47805b261ecSmrg}
47905b261ecSmrg
48005b261ecSmrgstatic Status
48135c4bbdfSmrgXkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
48205b261ecSmrg{
48335c4bbdfSmrg    XkbDescPtr xkb;
48435c4bbdfSmrg    XkbControlsPtr ctrls;
48505b261ecSmrg
48635c4bbdfSmrg    xkb = xkbi->desc;
48705b261ecSmrg    /* 12/31/94 (ef) -- XXX! Should check if controls loaded from file */
48835c4bbdfSmrg    if (XkbAllocControls(xkb, XkbAllControlsMask) != Success)
48935c4bbdfSmrg        FatalError("Couldn't allocate keyboard controls\n");
49035c4bbdfSmrg    ctrls = xkb->ctrls;
4914642e01fSmrg    if (!(xkb->defined & XkmSymbolsMask))
4924642e01fSmrg        ctrls->num_groups = 1;
49335c4bbdfSmrg    ctrls->groups_wrap = XkbSetGroupInfo(1, XkbWrapIntoRange, 0);
49405b261ecSmrg    ctrls->internal.mask = 0;
49505b261ecSmrg    ctrls->internal.real_mods = 0;
49605b261ecSmrg    ctrls->internal.vmods = 0;
49705b261ecSmrg    ctrls->ignore_lock.mask = 0;
49805b261ecSmrg    ctrls->ignore_lock.real_mods = 0;
49905b261ecSmrg    ctrls->ignore_lock.vmods = 0;
50035c4bbdfSmrg    ctrls->enabled_ctrls = XkbAccessXTimeoutMask | XkbRepeatKeysMask |
50135c4bbdfSmrg        XkbMouseKeysAccelMask | XkbAudibleBellMask | XkbIgnoreGroupLockMask;
50205b261ecSmrg    if (XkbWantAccessX)
50335c4bbdfSmrg        ctrls->enabled_ctrls |= XkbAccessXKeysMask;
50405b261ecSmrg    AccessXInit(pXDev);
50505b261ecSmrg    return Success;
50605b261ecSmrg}
50705b261ecSmrg
5081b5d61b8Smrgstatic Status
5091b5d61b8SmrgXkbInitOverlayState(XkbSrvInfoPtr xkbi)
5101b5d61b8Smrg{
5111b5d61b8Smrg    memset(xkbi->overlay_perkey_state, 0, sizeof(xkbi->overlay_perkey_state));
5121b5d61b8Smrg    return Success;
5131b5d61b8Smrg}
5141b5d61b8Smrg
51535c4bbdfSmrgstatic Bool
51635c4bbdfSmrgInitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
51735c4bbdfSmrg                                 const char *keymap, int keymap_length,
51835c4bbdfSmrg                                 BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
51905b261ecSmrg{
52035c4bbdfSmrg    int i;
5216747b715Smrg    unsigned int check;
5226747b715Smrg    XkbSrvInfoPtr xkbi;
5236747b715Smrg    XkbDescPtr xkb;
5246747b715Smrg    XkbSrvLedInfoPtr sli;
5256747b715Smrg    XkbChangesRec changes;
5266747b715Smrg    XkbEventCauseRec cause;
5276747b715Smrg    XkbRMLVOSet rmlvo_dflts = { NULL };
5286747b715Smrg
52935c4bbdfSmrg    BUG_RETURN_VAL(dev == NULL, FALSE);
53035c4bbdfSmrg    BUG_RETURN_VAL(dev->key != NULL, FALSE);
53135c4bbdfSmrg    BUG_RETURN_VAL(dev->kbdfeed != NULL, FALSE);
53235c4bbdfSmrg    BUG_RETURN_VAL(rmlvo && keymap, FALSE);
5336747b715Smrg
53435c4bbdfSmrg    if (!rmlvo && !keymap) {
5356747b715Smrg        rmlvo = &rmlvo_dflts;
5366747b715Smrg        XkbGetRulesDflts(rmlvo);
5376747b715Smrg    }
5384642e01fSmrg
5396747b715Smrg    memset(&changes, 0, sizeof(changes));
5406747b715Smrg    XkbSetCauseUnknown(&cause);
5416747b715Smrg
5426747b715Smrg    dev->key = calloc(1, sizeof(*dev->key));
5436747b715Smrg    if (!dev->key) {
5446747b715Smrg        ErrorF("XKB: Failed to allocate key class\n");
5456747b715Smrg        return FALSE;
5466747b715Smrg    }
5476747b715Smrg    dev->key->sourceid = dev->id;
5486747b715Smrg
5496747b715Smrg    dev->kbdfeed = calloc(1, sizeof(*dev->kbdfeed));
5506747b715Smrg    if (!dev->kbdfeed) {
5516747b715Smrg        ErrorF("XKB: Failed to allocate key feedback class\n");
5526747b715Smrg        goto unwind_key;
5536747b715Smrg    }
5546747b715Smrg
5556747b715Smrg    xkbi = calloc(1, sizeof(*xkbi));
5566747b715Smrg    if (!xkbi) {
5576747b715Smrg        ErrorF("XKB: Failed to allocate XKB info\n");
5586747b715Smrg        goto unwind_kbdfeed;
5596747b715Smrg    }
5606747b715Smrg    dev->key->xkbInfo = xkbi;
5616747b715Smrg
56235c4bbdfSmrg    if (xkb_cached_map && (keymap || (rmlvo && !XkbCompareUsedRMLVO(rmlvo)))) {
5636747b715Smrg        XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
5646747b715Smrg        xkb_cached_map = NULL;
5656747b715Smrg    }
5666747b715Smrg
5676747b715Smrg    if (xkb_cached_map)
5686747b715Smrg        LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
5696747b715Smrg    else {
57035c4bbdfSmrg        if (rmlvo)
57135c4bbdfSmrg            xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
57235c4bbdfSmrg        else
57335c4bbdfSmrg            xkb_cached_map = XkbCompileKeymapFromString(dev, keymap, keymap_length);
57435c4bbdfSmrg
5756747b715Smrg        if (!xkb_cached_map) {
5766747b715Smrg            ErrorF("XKB: Failed to compile keymap\n");
5776747b715Smrg            goto unwind_info;
5784642e01fSmrg        }
57905b261ecSmrg    }
58005b261ecSmrg
5816747b715Smrg    xkb = XkbAllocKeyboard();
5826747b715Smrg    if (!xkb) {
5836747b715Smrg        ErrorF("XKB: Failed to allocate keyboard description\n");
5846747b715Smrg        goto unwind_info;
5856747b715Smrg    }
58605b261ecSmrg
5876747b715Smrg    if (!XkbCopyKeymap(xkb, xkb_cached_map)) {
5886747b715Smrg        ErrorF("XKB: Failed to copy keymap\n");
5896747b715Smrg        goto unwind_desc;
59005b261ecSmrg    }
5916747b715Smrg    xkb->defined = xkb_cached_map->defined;
5926747b715Smrg    xkb->flags = xkb_cached_map->flags;
5936747b715Smrg    xkb->device_spec = xkb_cached_map->device_spec;
5946747b715Smrg    xkbi->desc = xkb;
59505b261ecSmrg
5966747b715Smrg    if (xkb->min_key_code == 0)
5976747b715Smrg        xkb->min_key_code = 8;
5986747b715Smrg    if (xkb->max_key_code == 0)
5996747b715Smrg        xkb->max_key_code = 255;
60005b261ecSmrg
6016747b715Smrg    i = XkbNumKeys(xkb) / 3 + 1;
6026747b715Smrg    if (XkbAllocClientMap(xkb, XkbAllClientInfoMask, 0) != Success)
6036747b715Smrg        goto unwind_desc;
6046747b715Smrg    if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, i) != Success)
6056747b715Smrg        goto unwind_desc;
60605b261ecSmrg
6076747b715Smrg    xkbi->dfltPtrDelta = 1;
6086747b715Smrg    xkbi->device = dev;
60905b261ecSmrg
6106747b715Smrg    XkbInitSemantics(xkb);
6116747b715Smrg    XkbInitNames(xkbi);
6126747b715Smrg    XkbInitRadioGroups(xkbi);
61305b261ecSmrg
6146747b715Smrg    XkbInitControls(dev, xkbi);
61505b261ecSmrg
6166747b715Smrg    XkbInitIndicatorMap(xkbi);
61705b261ecSmrg
6181b5d61b8Smrg    XkbInitOverlayState(xkbi);
6191b5d61b8Smrg
6206747b715Smrg    XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes,
6216747b715Smrg                     &check, &cause);
62205b261ecSmrg
62335c4bbdfSmrg    if (!dev->focus)
62435c4bbdfSmrg        InitFocusClassDeviceStruct(dev);
62505b261ecSmrg
6266747b715Smrg    xkbi->kbdProc = ctrl_func;
6276747b715Smrg    dev->kbdfeed->BellProc = bell_func;
6286747b715Smrg    dev->kbdfeed->CtrlProc = XkbDDXKeybdCtrlProc;
6296747b715Smrg
6306747b715Smrg    dev->kbdfeed->ctrl = defaultKeyboardControl;
6316747b715Smrg    if (dev->kbdfeed->ctrl.autoRepeat)
6326747b715Smrg        xkb->ctrls->enabled_ctrls |= XkbRepeatKeysMask;
6336747b715Smrg
6346747b715Smrg    memcpy(dev->kbdfeed->ctrl.autoRepeats, xkb->ctrls->per_key_repeat,
6356747b715Smrg           XkbPerKeyBitArraySize);
6366747b715Smrg
6376747b715Smrg    sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
6386747b715Smrg    if (sli)
63935c4bbdfSmrg        XkbCheckIndicatorMaps(dev, sli, XkbAllIndicatorsMask);
6406747b715Smrg    else
6416747b715Smrg        DebugF("XKB: No indicator feedback in XkbFinishInit!\n");
6426747b715Smrg
64335c4bbdfSmrg    dev->kbdfeed->CtrlProc(dev, &dev->kbdfeed->ctrl);
6446747b715Smrg
64535c4bbdfSmrg    if (rmlvo) {
64635c4bbdfSmrg        XkbSetRulesDflts(rmlvo);
64735c4bbdfSmrg        XkbSetRulesUsed(rmlvo);
64835c4bbdfSmrg    }
6496747b715Smrg    XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
6506747b715Smrg
6516747b715Smrg    return TRUE;
6526747b715Smrg
65335c4bbdfSmrg unwind_desc:
6546747b715Smrg    XkbFreeKeyboard(xkb, 0, TRUE);
65535c4bbdfSmrg unwind_info:
6566747b715Smrg    free(xkbi);
6576747b715Smrg    dev->key->xkbInfo = NULL;
65835c4bbdfSmrg unwind_kbdfeed:
6596747b715Smrg    free(dev->kbdfeed);
6606747b715Smrg    dev->kbdfeed = NULL;
66135c4bbdfSmrg unwind_key:
6626747b715Smrg    free(dev->key);
6636747b715Smrg    dev->key = NULL;
6646747b715Smrg    return FALSE;
66505b261ecSmrg}
66605b261ecSmrg
66735c4bbdfSmrg_X_EXPORT Bool
66835c4bbdfSmrgInitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
66935c4bbdfSmrg                         BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
67035c4bbdfSmrg{
67135c4bbdfSmrg    return InitKeyboardDeviceStructInternal(dev, rmlvo,
67235c4bbdfSmrg                                            NULL, 0, bell_func, ctrl_func);
67335c4bbdfSmrg}
67435c4bbdfSmrg
67535c4bbdfSmrg_X_EXPORT Bool
67635c4bbdfSmrgInitKeyboardDeviceStructFromString(DeviceIntPtr dev,
67735c4bbdfSmrg                                   const char *keymap, int keymap_length,
67835c4bbdfSmrg                                   BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
67935c4bbdfSmrg{
68035c4bbdfSmrg    return InitKeyboardDeviceStructInternal(dev, NULL,
68135c4bbdfSmrg                                            keymap, keymap_length,
68235c4bbdfSmrg                                            bell_func, ctrl_func);
68335c4bbdfSmrg}
6846747b715Smrg
6856747b715Smrg/***====================================================================***/
6866747b715Smrg
68735c4bbdfSmrg        /*
68835c4bbdfSmrg         * Be very careful about what does and doesn't get freed by this
68935c4bbdfSmrg         * function.  To reduce fragmentation, XkbInitDevice allocates a
69035c4bbdfSmrg         * single huge block per device and divides it up into most of the
69135c4bbdfSmrg         * fixed-size structures for the device.   Don't free anything that
69235c4bbdfSmrg         * is part of this larger block.
69335c4bbdfSmrg         */
69405b261ecSmrgvoid
69505b261ecSmrgXkbFreeInfo(XkbSrvInfoPtr xkbi)
69605b261ecSmrg{
6976747b715Smrg    free(xkbi->radioGroups);
6986747b715Smrg    xkbi->radioGroups = NULL;
69905b261ecSmrg    if (xkbi->mouseKeyTimer) {
70035c4bbdfSmrg        TimerFree(xkbi->mouseKeyTimer);
70135c4bbdfSmrg        xkbi->mouseKeyTimer = NULL;
70205b261ecSmrg    }
70305b261ecSmrg    if (xkbi->slowKeysTimer) {
70435c4bbdfSmrg        TimerFree(xkbi->slowKeysTimer);
70535c4bbdfSmrg        xkbi->slowKeysTimer = NULL;
70605b261ecSmrg    }
70705b261ecSmrg    if (xkbi->bounceKeysTimer) {
70835c4bbdfSmrg        TimerFree(xkbi->bounceKeysTimer);
70935c4bbdfSmrg        xkbi->bounceKeysTimer = NULL;
71005b261ecSmrg    }
71105b261ecSmrg    if (xkbi->repeatKeyTimer) {
71235c4bbdfSmrg        TimerFree(xkbi->repeatKeyTimer);
71335c4bbdfSmrg        xkbi->repeatKeyTimer = NULL;
71405b261ecSmrg    }
71505b261ecSmrg    if (xkbi->krgTimer) {
71635c4bbdfSmrg        TimerFree(xkbi->krgTimer);
71735c4bbdfSmrg        xkbi->krgTimer = NULL;
71805b261ecSmrg    }
71935c4bbdfSmrg    xkbi->beepType = _BEEP_NONE;
72005b261ecSmrg    if (xkbi->beepTimer) {
72135c4bbdfSmrg        TimerFree(xkbi->beepTimer);
72235c4bbdfSmrg        xkbi->beepTimer = NULL;
72305b261ecSmrg    }
72405b261ecSmrg    if (xkbi->desc) {
72535c4bbdfSmrg        XkbFreeKeyboard(xkbi->desc, XkbAllComponentsMask, TRUE);
72635c4bbdfSmrg        xkbi->desc = NULL;
72705b261ecSmrg    }
7286747b715Smrg    free(xkbi);
72905b261ecSmrg    return;
73005b261ecSmrg}
73105b261ecSmrg
73205b261ecSmrg/***====================================================================***/
73305b261ecSmrg
73435c4bbdfSmrgextern int XkbDfltRepeatDelay;
73535c4bbdfSmrgextern int XkbDfltRepeatInterval;
73605b261ecSmrg
73735c4bbdfSmrgextern unsigned short XkbDfltAccessXTimeout;
73835c4bbdfSmrgextern unsigned int XkbDfltAccessXTimeoutMask;
73935c4bbdfSmrgextern unsigned int XkbDfltAccessXFeedback;
7401b5d61b8Smrgextern unsigned short XkbDfltAccessXOptions;
74105b261ecSmrg
74205b261ecSmrgint
74335c4bbdfSmrgXkbProcessArguments(int argc, char *argv[], int i)
74405b261ecSmrg{
7456747b715Smrg    if (strncmp(argv[i], "-xkbdir", 7) == 0) {
74635c4bbdfSmrg        if (++i < argc) {
74705b261ecSmrg#if !defined(WIN32) && !defined(__CYGWIN__)
74835c4bbdfSmrg            if (getuid() != geteuid()) {
74935c4bbdfSmrg                LogMessage(X_WARNING,
75035c4bbdfSmrg                           "-xkbdir is not available for setuid X servers\n");
75135c4bbdfSmrg                return -1;
75235c4bbdfSmrg            }
75335c4bbdfSmrg            else
75405b261ecSmrg#endif
75535c4bbdfSmrg            {
75635c4bbdfSmrg                if (strlen(argv[i]) < PATH_MAX) {
75735c4bbdfSmrg                    XkbBaseDirectory = argv[i];
75835c4bbdfSmrg                    return 2;
75935c4bbdfSmrg                }
76035c4bbdfSmrg                else {
76135c4bbdfSmrg                    LogMessage(X_ERROR, "-xkbdir pathname too long\n");
76235c4bbdfSmrg                    return -1;
76335c4bbdfSmrg                }
76435c4bbdfSmrg            }
76535c4bbdfSmrg        }
76635c4bbdfSmrg        else {
76735c4bbdfSmrg            return -1;
76835c4bbdfSmrg        }
76935c4bbdfSmrg    }
77035c4bbdfSmrg    else if ((strncmp(argv[i], "-accessx", 8) == 0) ||
77135c4bbdfSmrg             (strncmp(argv[i], "+accessx", 8) == 0)) {
77235c4bbdfSmrg        int j = 1;
77335c4bbdfSmrg
77435c4bbdfSmrg        if (argv[i][0] == '-')
77535c4bbdfSmrg            XkbWantAccessX = 0;
77635c4bbdfSmrg        else {
77735c4bbdfSmrg            XkbWantAccessX = 1;
77835c4bbdfSmrg
77935c4bbdfSmrg            if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) {
78035c4bbdfSmrg                XkbDfltAccessXTimeout = atoi(argv[++i]);
78135c4bbdfSmrg                j++;
78235c4bbdfSmrg
78335c4bbdfSmrg                if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) {
78435c4bbdfSmrg                    /*
78535c4bbdfSmrg                     * presumption that the reasonably useful range of
78635c4bbdfSmrg                     * values fits in 0..MAXINT since SunOS 4 doesn't
78735c4bbdfSmrg                     * have strtoul.
78835c4bbdfSmrg                     */
78935c4bbdfSmrg                    XkbDfltAccessXTimeoutMask = (unsigned int)
79035c4bbdfSmrg                        strtol(argv[++i], NULL, 16);
79135c4bbdfSmrg                    j++;
79235c4bbdfSmrg                }
79335c4bbdfSmrg                if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) {
79435c4bbdfSmrg                    if (argv[++i][0] == '1')
79535c4bbdfSmrg                        XkbDfltAccessXFeedback = XkbAccessXFeedbackMask;
79635c4bbdfSmrg                    else
79735c4bbdfSmrg                        XkbDfltAccessXFeedback = 0;
79835c4bbdfSmrg                    j++;
79935c4bbdfSmrg                }
80035c4bbdfSmrg                if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) {
8011b5d61b8Smrg                    XkbDfltAccessXOptions = (unsigned short)
80235c4bbdfSmrg                        strtol(argv[++i], NULL, 16);
80335c4bbdfSmrg                    j++;
80435c4bbdfSmrg                }
80535c4bbdfSmrg            }
80635c4bbdfSmrg        }
80735c4bbdfSmrg        return j;
80835c4bbdfSmrg    }
80935c4bbdfSmrg    if ((strcmp(argv[i], "-ardelay") == 0) || (strcmp(argv[i], "-ar1") == 0)) { /* -ardelay int */
81035c4bbdfSmrg        if (++i >= argc)
81135c4bbdfSmrg            UseMsg();
81235c4bbdfSmrg        else
81335c4bbdfSmrg            XkbDfltRepeatDelay = (long) atoi(argv[i]);
81435c4bbdfSmrg        return 2;
81535c4bbdfSmrg    }
81635c4bbdfSmrg    if ((strcmp(argv[i], "-arinterval") == 0) || (strcmp(argv[i], "-ar2") == 0)) {      /* -arinterval int */
81735c4bbdfSmrg        if (++i >= argc)
81835c4bbdfSmrg            UseMsg();
81935c4bbdfSmrg        else
82035c4bbdfSmrg            XkbDfltRepeatInterval = (long) atoi(argv[i]);
82135c4bbdfSmrg        return 2;
82205b261ecSmrg    }
82305b261ecSmrg    return 0;
82405b261ecSmrg}
82505b261ecSmrg
82605b261ecSmrgvoid
82705b261ecSmrgXkbUseMsg(void)
82805b261ecSmrg{
82935c4bbdfSmrg    ErrorF
83035c4bbdfSmrg        ("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n");
83105b261ecSmrg    ErrorF("                       enable/disable accessx key sequences\n");
83205b261ecSmrg    ErrorF("-ardelay               set XKB autorepeat delay\n");
83305b261ecSmrg    ErrorF("-arinterval            set XKB autorepeat interval\n");
83405b261ecSmrg}
835