xkbInit.c revision 35c4bbdf
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 6305b261ecSmrg#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 50835c4bbdfSmrgstatic Bool 50935c4bbdfSmrgInitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo, 51035c4bbdfSmrg const char *keymap, int keymap_length, 51135c4bbdfSmrg BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func) 51205b261ecSmrg{ 51335c4bbdfSmrg int i; 5146747b715Smrg unsigned int check; 5156747b715Smrg XkbSrvInfoPtr xkbi; 5166747b715Smrg XkbDescPtr xkb; 5176747b715Smrg XkbSrvLedInfoPtr sli; 5186747b715Smrg XkbChangesRec changes; 5196747b715Smrg XkbEventCauseRec cause; 5206747b715Smrg XkbRMLVOSet rmlvo_dflts = { NULL }; 5216747b715Smrg 52235c4bbdfSmrg BUG_RETURN_VAL(dev == NULL, FALSE); 52335c4bbdfSmrg BUG_RETURN_VAL(dev->key != NULL, FALSE); 52435c4bbdfSmrg BUG_RETURN_VAL(dev->kbdfeed != NULL, FALSE); 52535c4bbdfSmrg BUG_RETURN_VAL(rmlvo && keymap, FALSE); 5266747b715Smrg 52735c4bbdfSmrg if (!rmlvo && !keymap) { 5286747b715Smrg rmlvo = &rmlvo_dflts; 5296747b715Smrg XkbGetRulesDflts(rmlvo); 5306747b715Smrg } 5314642e01fSmrg 5326747b715Smrg memset(&changes, 0, sizeof(changes)); 5336747b715Smrg XkbSetCauseUnknown(&cause); 5346747b715Smrg 5356747b715Smrg dev->key = calloc(1, sizeof(*dev->key)); 5366747b715Smrg if (!dev->key) { 5376747b715Smrg ErrorF("XKB: Failed to allocate key class\n"); 5386747b715Smrg return FALSE; 5396747b715Smrg } 5406747b715Smrg dev->key->sourceid = dev->id; 5416747b715Smrg 5426747b715Smrg dev->kbdfeed = calloc(1, sizeof(*dev->kbdfeed)); 5436747b715Smrg if (!dev->kbdfeed) { 5446747b715Smrg ErrorF("XKB: Failed to allocate key feedback class\n"); 5456747b715Smrg goto unwind_key; 5466747b715Smrg } 5476747b715Smrg 5486747b715Smrg xkbi = calloc(1, sizeof(*xkbi)); 5496747b715Smrg if (!xkbi) { 5506747b715Smrg ErrorF("XKB: Failed to allocate XKB info\n"); 5516747b715Smrg goto unwind_kbdfeed; 5526747b715Smrg } 5536747b715Smrg dev->key->xkbInfo = xkbi; 5546747b715Smrg 55535c4bbdfSmrg if (xkb_cached_map && (keymap || (rmlvo && !XkbCompareUsedRMLVO(rmlvo)))) { 5566747b715Smrg XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE); 5576747b715Smrg xkb_cached_map = NULL; 5586747b715Smrg } 5596747b715Smrg 5606747b715Smrg if (xkb_cached_map) 5616747b715Smrg LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n"); 5626747b715Smrg else { 56335c4bbdfSmrg if (rmlvo) 56435c4bbdfSmrg xkb_cached_map = XkbCompileKeymap(dev, rmlvo); 56535c4bbdfSmrg else 56635c4bbdfSmrg xkb_cached_map = XkbCompileKeymapFromString(dev, keymap, keymap_length); 56735c4bbdfSmrg 5686747b715Smrg if (!xkb_cached_map) { 5696747b715Smrg ErrorF("XKB: Failed to compile keymap\n"); 5706747b715Smrg goto unwind_info; 5714642e01fSmrg } 57205b261ecSmrg } 57305b261ecSmrg 5746747b715Smrg xkb = XkbAllocKeyboard(); 5756747b715Smrg if (!xkb) { 5766747b715Smrg ErrorF("XKB: Failed to allocate keyboard description\n"); 5776747b715Smrg goto unwind_info; 5786747b715Smrg } 57905b261ecSmrg 5806747b715Smrg if (!XkbCopyKeymap(xkb, xkb_cached_map)) { 5816747b715Smrg ErrorF("XKB: Failed to copy keymap\n"); 5826747b715Smrg goto unwind_desc; 58305b261ecSmrg } 5846747b715Smrg xkb->defined = xkb_cached_map->defined; 5856747b715Smrg xkb->flags = xkb_cached_map->flags; 5866747b715Smrg xkb->device_spec = xkb_cached_map->device_spec; 5876747b715Smrg xkbi->desc = xkb; 58805b261ecSmrg 5896747b715Smrg if (xkb->min_key_code == 0) 5906747b715Smrg xkb->min_key_code = 8; 5916747b715Smrg if (xkb->max_key_code == 0) 5926747b715Smrg xkb->max_key_code = 255; 59305b261ecSmrg 5946747b715Smrg i = XkbNumKeys(xkb) / 3 + 1; 5956747b715Smrg if (XkbAllocClientMap(xkb, XkbAllClientInfoMask, 0) != Success) 5966747b715Smrg goto unwind_desc; 5976747b715Smrg if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, i) != Success) 5986747b715Smrg goto unwind_desc; 59905b261ecSmrg 6006747b715Smrg xkbi->dfltPtrDelta = 1; 6016747b715Smrg xkbi->device = dev; 60205b261ecSmrg 6036747b715Smrg XkbInitSemantics(xkb); 6046747b715Smrg XkbInitNames(xkbi); 6056747b715Smrg XkbInitRadioGroups(xkbi); 60605b261ecSmrg 6076747b715Smrg XkbInitControls(dev, xkbi); 60805b261ecSmrg 6096747b715Smrg XkbInitIndicatorMap(xkbi); 61005b261ecSmrg 6116747b715Smrg XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes, 6126747b715Smrg &check, &cause); 61305b261ecSmrg 61435c4bbdfSmrg if (!dev->focus) 61535c4bbdfSmrg InitFocusClassDeviceStruct(dev); 61605b261ecSmrg 6176747b715Smrg xkbi->kbdProc = ctrl_func; 6186747b715Smrg dev->kbdfeed->BellProc = bell_func; 6196747b715Smrg dev->kbdfeed->CtrlProc = XkbDDXKeybdCtrlProc; 6206747b715Smrg 6216747b715Smrg dev->kbdfeed->ctrl = defaultKeyboardControl; 6226747b715Smrg if (dev->kbdfeed->ctrl.autoRepeat) 6236747b715Smrg xkb->ctrls->enabled_ctrls |= XkbRepeatKeysMask; 6246747b715Smrg 6256747b715Smrg memcpy(dev->kbdfeed->ctrl.autoRepeats, xkb->ctrls->per_key_repeat, 6266747b715Smrg XkbPerKeyBitArraySize); 6276747b715Smrg 6286747b715Smrg sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0); 6296747b715Smrg if (sli) 63035c4bbdfSmrg XkbCheckIndicatorMaps(dev, sli, XkbAllIndicatorsMask); 6316747b715Smrg else 6326747b715Smrg DebugF("XKB: No indicator feedback in XkbFinishInit!\n"); 6336747b715Smrg 63435c4bbdfSmrg dev->kbdfeed->CtrlProc(dev, &dev->kbdfeed->ctrl); 6356747b715Smrg 63635c4bbdfSmrg if (rmlvo) { 63735c4bbdfSmrg XkbSetRulesDflts(rmlvo); 63835c4bbdfSmrg XkbSetRulesUsed(rmlvo); 63935c4bbdfSmrg } 6406747b715Smrg XkbFreeRMLVOSet(&rmlvo_dflts, FALSE); 6416747b715Smrg 6426747b715Smrg return TRUE; 6436747b715Smrg 64435c4bbdfSmrg unwind_desc: 6456747b715Smrg XkbFreeKeyboard(xkb, 0, TRUE); 64635c4bbdfSmrg unwind_info: 6476747b715Smrg free(xkbi); 6486747b715Smrg dev->key->xkbInfo = NULL; 64935c4bbdfSmrg unwind_kbdfeed: 6506747b715Smrg free(dev->kbdfeed); 6516747b715Smrg dev->kbdfeed = NULL; 65235c4bbdfSmrg unwind_key: 6536747b715Smrg free(dev->key); 6546747b715Smrg dev->key = NULL; 6556747b715Smrg return FALSE; 65605b261ecSmrg} 65705b261ecSmrg 65835c4bbdfSmrg_X_EXPORT Bool 65935c4bbdfSmrgInitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo, 66035c4bbdfSmrg BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func) 66135c4bbdfSmrg{ 66235c4bbdfSmrg return InitKeyboardDeviceStructInternal(dev, rmlvo, 66335c4bbdfSmrg NULL, 0, bell_func, ctrl_func); 66435c4bbdfSmrg} 66535c4bbdfSmrg 66635c4bbdfSmrg_X_EXPORT Bool 66735c4bbdfSmrgInitKeyboardDeviceStructFromString(DeviceIntPtr dev, 66835c4bbdfSmrg const char *keymap, int keymap_length, 66935c4bbdfSmrg BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func) 67035c4bbdfSmrg{ 67135c4bbdfSmrg return InitKeyboardDeviceStructInternal(dev, NULL, 67235c4bbdfSmrg keymap, keymap_length, 67335c4bbdfSmrg bell_func, ctrl_func); 67435c4bbdfSmrg} 6756747b715Smrg 6766747b715Smrg/***====================================================================***/ 6776747b715Smrg 67835c4bbdfSmrg /* 67935c4bbdfSmrg * Be very careful about what does and doesn't get freed by this 68035c4bbdfSmrg * function. To reduce fragmentation, XkbInitDevice allocates a 68135c4bbdfSmrg * single huge block per device and divides it up into most of the 68235c4bbdfSmrg * fixed-size structures for the device. Don't free anything that 68335c4bbdfSmrg * is part of this larger block. 68435c4bbdfSmrg */ 68505b261ecSmrgvoid 68605b261ecSmrgXkbFreeInfo(XkbSrvInfoPtr xkbi) 68705b261ecSmrg{ 6886747b715Smrg free(xkbi->radioGroups); 6896747b715Smrg xkbi->radioGroups = NULL; 69005b261ecSmrg if (xkbi->mouseKeyTimer) { 69135c4bbdfSmrg TimerFree(xkbi->mouseKeyTimer); 69235c4bbdfSmrg xkbi->mouseKeyTimer = NULL; 69305b261ecSmrg } 69405b261ecSmrg if (xkbi->slowKeysTimer) { 69535c4bbdfSmrg TimerFree(xkbi->slowKeysTimer); 69635c4bbdfSmrg xkbi->slowKeysTimer = NULL; 69705b261ecSmrg } 69805b261ecSmrg if (xkbi->bounceKeysTimer) { 69935c4bbdfSmrg TimerFree(xkbi->bounceKeysTimer); 70035c4bbdfSmrg xkbi->bounceKeysTimer = NULL; 70105b261ecSmrg } 70205b261ecSmrg if (xkbi->repeatKeyTimer) { 70335c4bbdfSmrg TimerFree(xkbi->repeatKeyTimer); 70435c4bbdfSmrg xkbi->repeatKeyTimer = NULL; 70505b261ecSmrg } 70605b261ecSmrg if (xkbi->krgTimer) { 70735c4bbdfSmrg TimerFree(xkbi->krgTimer); 70835c4bbdfSmrg xkbi->krgTimer = NULL; 70905b261ecSmrg } 71035c4bbdfSmrg xkbi->beepType = _BEEP_NONE; 71105b261ecSmrg if (xkbi->beepTimer) { 71235c4bbdfSmrg TimerFree(xkbi->beepTimer); 71335c4bbdfSmrg xkbi->beepTimer = NULL; 71405b261ecSmrg } 71505b261ecSmrg if (xkbi->desc) { 71635c4bbdfSmrg XkbFreeKeyboard(xkbi->desc, XkbAllComponentsMask, TRUE); 71735c4bbdfSmrg xkbi->desc = NULL; 71805b261ecSmrg } 7196747b715Smrg free(xkbi); 72005b261ecSmrg return; 72105b261ecSmrg} 72205b261ecSmrg 72305b261ecSmrg/***====================================================================***/ 72405b261ecSmrg 72535c4bbdfSmrgextern int XkbDfltRepeatDelay; 72635c4bbdfSmrgextern int XkbDfltRepeatInterval; 72705b261ecSmrg 72835c4bbdfSmrgextern unsigned short XkbDfltAccessXTimeout; 72935c4bbdfSmrgextern unsigned int XkbDfltAccessXTimeoutMask; 73035c4bbdfSmrgextern unsigned int XkbDfltAccessXFeedback; 73135c4bbdfSmrgextern unsigned char XkbDfltAccessXOptions; 73205b261ecSmrg 73305b261ecSmrgint 73435c4bbdfSmrgXkbProcessArguments(int argc, char *argv[], int i) 73505b261ecSmrg{ 7366747b715Smrg if (strncmp(argv[i], "-xkbdir", 7) == 0) { 73735c4bbdfSmrg if (++i < argc) { 73805b261ecSmrg#if !defined(WIN32) && !defined(__CYGWIN__) 73935c4bbdfSmrg if (getuid() != geteuid()) { 74035c4bbdfSmrg LogMessage(X_WARNING, 74135c4bbdfSmrg "-xkbdir is not available for setuid X servers\n"); 74235c4bbdfSmrg return -1; 74335c4bbdfSmrg } 74435c4bbdfSmrg else 74505b261ecSmrg#endif 74635c4bbdfSmrg { 74735c4bbdfSmrg if (strlen(argv[i]) < PATH_MAX) { 74835c4bbdfSmrg XkbBaseDirectory = argv[i]; 74935c4bbdfSmrg return 2; 75035c4bbdfSmrg } 75135c4bbdfSmrg else { 75235c4bbdfSmrg LogMessage(X_ERROR, "-xkbdir pathname too long\n"); 75335c4bbdfSmrg return -1; 75435c4bbdfSmrg } 75535c4bbdfSmrg } 75635c4bbdfSmrg } 75735c4bbdfSmrg else { 75835c4bbdfSmrg return -1; 75935c4bbdfSmrg } 76035c4bbdfSmrg } 76135c4bbdfSmrg else if ((strncmp(argv[i], "-accessx", 8) == 0) || 76235c4bbdfSmrg (strncmp(argv[i], "+accessx", 8) == 0)) { 76335c4bbdfSmrg int j = 1; 76435c4bbdfSmrg 76535c4bbdfSmrg if (argv[i][0] == '-') 76635c4bbdfSmrg XkbWantAccessX = 0; 76735c4bbdfSmrg else { 76835c4bbdfSmrg XkbWantAccessX = 1; 76935c4bbdfSmrg 77035c4bbdfSmrg if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) { 77135c4bbdfSmrg XkbDfltAccessXTimeout = atoi(argv[++i]); 77235c4bbdfSmrg j++; 77335c4bbdfSmrg 77435c4bbdfSmrg if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) { 77535c4bbdfSmrg /* 77635c4bbdfSmrg * presumption that the reasonably useful range of 77735c4bbdfSmrg * values fits in 0..MAXINT since SunOS 4 doesn't 77835c4bbdfSmrg * have strtoul. 77935c4bbdfSmrg */ 78035c4bbdfSmrg XkbDfltAccessXTimeoutMask = (unsigned int) 78135c4bbdfSmrg strtol(argv[++i], NULL, 16); 78235c4bbdfSmrg j++; 78335c4bbdfSmrg } 78435c4bbdfSmrg if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) { 78535c4bbdfSmrg if (argv[++i][0] == '1') 78635c4bbdfSmrg XkbDfltAccessXFeedback = XkbAccessXFeedbackMask; 78735c4bbdfSmrg else 78835c4bbdfSmrg XkbDfltAccessXFeedback = 0; 78935c4bbdfSmrg j++; 79035c4bbdfSmrg } 79135c4bbdfSmrg if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) { 79235c4bbdfSmrg XkbDfltAccessXOptions = (unsigned char) 79335c4bbdfSmrg strtol(argv[++i], NULL, 16); 79435c4bbdfSmrg j++; 79535c4bbdfSmrg } 79635c4bbdfSmrg } 79735c4bbdfSmrg } 79835c4bbdfSmrg return j; 79935c4bbdfSmrg } 80035c4bbdfSmrg if ((strcmp(argv[i], "-ardelay") == 0) || (strcmp(argv[i], "-ar1") == 0)) { /* -ardelay int */ 80135c4bbdfSmrg if (++i >= argc) 80235c4bbdfSmrg UseMsg(); 80335c4bbdfSmrg else 80435c4bbdfSmrg XkbDfltRepeatDelay = (long) atoi(argv[i]); 80535c4bbdfSmrg return 2; 80635c4bbdfSmrg } 80735c4bbdfSmrg if ((strcmp(argv[i], "-arinterval") == 0) || (strcmp(argv[i], "-ar2") == 0)) { /* -arinterval int */ 80835c4bbdfSmrg if (++i >= argc) 80935c4bbdfSmrg UseMsg(); 81035c4bbdfSmrg else 81135c4bbdfSmrg XkbDfltRepeatInterval = (long) atoi(argv[i]); 81235c4bbdfSmrg return 2; 81305b261ecSmrg } 81405b261ecSmrg return 0; 81505b261ecSmrg} 81605b261ecSmrg 81705b261ecSmrgvoid 81805b261ecSmrgXkbUseMsg(void) 81905b261ecSmrg{ 82035c4bbdfSmrg ErrorF 82135c4bbdfSmrg ("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n"); 82205b261ecSmrg ErrorF(" enable/disable accessx key sequences\n"); 82305b261ecSmrg ErrorF("-ardelay set XKB autorepeat delay\n"); 82405b261ecSmrg ErrorF("-arinterval set XKB autorepeat interval\n"); 82505b261ecSmrg} 826