summaryrefslogtreecommitdiff
path: root/xkb/xkbInit.c
diff options
context:
space:
mode:
Diffstat (limited to 'xkb/xkbInit.c')
-rw-r--r--xkb/xkbInit.c994
1 files changed, 994 insertions, 0 deletions
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
new file mode 100644
index 000000000..3ca52ebc5
--- /dev/null
+++ b/xkb/xkbInit.c
@@ -0,0 +1,994 @@
+/*
+ * @(#)$RCSfile$ $Revision$ (DEC) $Date$
+ */
+/* $Xorg: xkbInit.c,v 1.3 2000/08/17 19:53:47 cpqbld Exp $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <math.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "property.h"
+#define XKBSRV_NEED_FILE_FUNCS
+#include "XKBsrv.h"
+#include "XKBgeom.h"
+#include <X11/extensions/XKMformat.h>
+#include <X11/extensions/XKBfile.h>
+
+
+#define CREATE_ATOM(s) MakeAtom(s,sizeof(s)-1,1)
+
+#ifdef sgi
+#define LED_CAPS 5
+#define LED_NUM 6
+#define LED_SCROLL 7
+#define PHYS_LEDS 0x7f
+#define LED_COMPOSE 8
+#else
+#if defined(ultrix) || defined(__osf__) || defined(__alpha)
+#define LED_COMPOSE 2
+#define LED_CAPS 3
+#define LED_SCROLL 4
+#define LED_NUM 5
+#define PHYS_LEDS 0x1f
+#else
+#ifdef sun
+#define LED_NUM 1
+#define LED_SCROLL 2
+#define LED_COMPOSE 3
+#define LED_CAPS 4
+#define PHYS_LEDS 0x0f
+#else
+#define LED_CAPS 1
+#define LED_NUM 2
+#define LED_SCROLL 3
+#define PHYS_LEDS 0x07
+#endif
+#endif
+#endif
+
+#define MAX_TOC 16
+typedef struct _SrvXkmInfo {
+ DeviceIntPtr dev;
+ FILE * file;
+ XkbFileInfo xkbinfo;
+} SrvXkmInfo;
+
+
+/***====================================================================***/
+
+#ifndef XKB_BASE_DIRECTORY
+#define XKB_BASE_DIRECTORY "/usr/lib/X11/xkb"
+#endif
+#ifndef XKB_DFLT_RULES_FILE
+#define XKB_DFLT_RULES_FILE "rules"
+#endif
+#ifndef XKB_DFLT_KB_LAYOUT
+#define XKB_DFLT_KB_LAYOUT "us"
+#endif
+#ifndef XKB_DFLT_KB_MODEL
+#define XKB_DFLT_KB_MODEL "dflt"
+#endif
+#ifndef XKB_DFLT_KB_VARIANT
+#define XKB_DFLT_KB_VARIANT NULL
+#endif
+#ifndef XKB_DFLT_KB_OPTIONS
+#define XKB_DFLT_KB_OPTIONS NULL
+#endif
+#ifndef XKB_DFLT_DISABLED
+#define XKB_DFLT_DISABLED True
+#endif
+#ifndef XKB_DFLT_RULES_PROP
+#define XKB_DFLT_RULES_PROP True
+#endif
+
+char * XkbBaseDirectory= XKB_BASE_DIRECTORY;
+char * XkbInitialMap= NULL;
+int XkbWantAccessX= 0;
+static XkbFileInfo * _XkbInitFileInfo= NULL;
+char * XkbDB= NULL;
+int XkbAutoLoad= 1;
+
+static Bool rulesDefined= False;
+static char * XkbRulesFile= NULL;
+static char * XkbModelDflt= NULL;
+static char * XkbLayoutDflt= NULL;
+static char * XkbVariantDflt= NULL;
+static char * XkbOptionsDflt= NULL;
+
+char * XkbModelUsed= NULL;
+char * XkbLayoutUsed= NULL;
+char * XkbVariantUsed= NULL;
+char * XkbOptionsUsed= NULL;
+
+int _XkbClientMajor= XkbMajorVersion;
+int _XkbClientMinor= XkbMinorVersion;
+
+Bool noXkbExtension= XKB_DFLT_DISABLED;
+Bool XkbWantRulesProp= XKB_DFLT_RULES_PROP;
+
+/***====================================================================***/
+
+char *
+#if NeedFunctionPrototypes
+XkbGetRulesDflts(XkbRF_VarDefsPtr defs)
+#else
+XkbGetRulesDflts(defs)
+ XkbRF_VarDefsPtr defs;
+#endif
+{
+ if (XkbModelDflt) defs->model= XkbModelDflt;
+ else defs->model= XKB_DFLT_KB_MODEL;
+ if (XkbLayoutDflt) defs->layout= XkbLayoutDflt;
+ else defs->layout= XKB_DFLT_KB_LAYOUT;
+ if (XkbVariantDflt) defs->variant= XkbVariantDflt;
+ else defs->variant= XKB_DFLT_KB_VARIANT;
+ if (XkbOptionsDflt) defs->options= XkbOptionsDflt;
+ else defs->options= XKB_DFLT_KB_OPTIONS;
+ return (rulesDefined?XkbRulesFile:XKB_DFLT_RULES_FILE);
+}
+
+Bool
+#if NeedFunctionPrototypes
+XkbWriteRulesProp(ClientPtr client, pointer closure)
+#else
+XkbWriteRulesProp(client, closure)
+ ClientPtr client;
+ pointer closure;
+#endif
+{
+int len,out;
+extern WindowPtr * WindowTable;
+Atom name;
+char * pval;
+
+ if (rulesDefined && (!XkbRulesFile))
+ return False;
+ len= (XkbRulesFile?strlen(XkbRulesFile):strlen(XKB_DFLT_RULES_FILE));
+ len+= (XkbModelUsed?strlen(XkbModelUsed):0);
+ len+= (XkbLayoutUsed?strlen(XkbLayoutUsed):0);
+ len+= (XkbVariantUsed?strlen(XkbVariantUsed):0);
+ len+= (XkbOptionsUsed?strlen(XkbOptionsUsed):0);
+ if (len<1)
+ return True;
+
+ len+= 5; /* trailing NULs */
+
+ name= MakeAtom(_XKB_RF_NAMES_PROP_ATOM,strlen(_XKB_RF_NAMES_PROP_ATOM),1);
+ if (name==None) {
+ ErrorF("Atom error: %s not created\n",_XKB_RF_NAMES_PROP_ATOM);
+ return True;
+ }
+ pval= (char*) ALLOCATE_LOCAL(len);
+ if (!pval) {
+ ErrorF("Allocation error: %s proprerty not created\n",
+ _XKB_RF_NAMES_PROP_ATOM);
+ return True;
+ }
+ out= 0;
+ if (XkbRulesFile) {
+ strcpy(&pval[out],XkbRulesFile);
+ out+= strlen(XkbRulesFile);
+ }
+ pval[out++]= '\0';
+ if (XkbModelUsed) {
+ strcpy(&pval[out],XkbModelUsed);
+ out+= strlen(XkbModelUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbLayoutUsed) {
+ strcpy(&pval[out],XkbLayoutUsed);
+ out+= strlen(XkbLayoutUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbVariantUsed) {
+ strcpy(&pval[out],XkbVariantUsed);
+ out+= strlen(XkbVariantUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbOptionsUsed) {
+ strcpy(&pval[out],XkbOptionsUsed);
+ out+= strlen(XkbOptionsUsed);
+ }
+ pval[out++]= '\0';
+ if (out!=len) {
+ ErrorF("Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n",
+ out,len);
+ }
+ ChangeWindowProperty(WindowTable[0],name,XA_STRING,8,PropModeReplace,
+ len,pval,True);
+ DEALLOCATE_LOCAL(pval);
+ return True;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSetRulesUsed(XkbRF_VarDefsPtr defs)
+#else
+XkbSetRulesUsed(defs)
+ XkbRF_VarDefsPtr defs;
+#endif
+{
+ if (XkbModelUsed)
+ _XkbFree(XkbModelUsed);
+ XkbModelUsed= (defs->model?_XkbDupString(defs->model):NULL);
+ if (XkbLayoutUsed)
+ _XkbFree(XkbLayoutUsed);
+ XkbLayoutUsed= (defs->layout?_XkbDupString(defs->layout):NULL);
+ if (XkbVariantUsed)
+ _XkbFree(XkbVariantUsed);
+ XkbVariantUsed= (defs->variant?_XkbDupString(defs->variant):NULL);
+ if (XkbOptionsUsed)
+ _XkbFree(XkbOptionsUsed);
+ XkbOptionsUsed= (defs->options?_XkbDupString(defs->options):NULL);
+ if (XkbWantRulesProp)
+ QueueWorkProc(XkbWriteRulesProp,NULL,NULL);
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSetRulesDflts(char *rulesFile,char *model,char *layout,
+ char *variant,char *options)
+#else
+XkbSetRulesDflts(rulesFile,model,layout,variant,options)
+ char * rulesFile;
+ char * model;
+ char * layout;
+ char * variant;
+ char * options;
+#endif
+{
+ if (XkbRulesFile)
+ _XkbFree(XkbRulesFile);
+ XkbRulesFile= _XkbDupString(rulesFile);
+ rulesDefined= True;
+ if (model) {
+ if (XkbModelDflt)
+ _XkbFree(XkbModelDflt);
+ XkbModelDflt= _XkbDupString(model);
+ }
+ if (layout) {
+ if (XkbLayoutDflt)
+ _XkbFree(XkbLayoutDflt);
+ XkbLayoutDflt= _XkbDupString(layout);
+ }
+ if (variant) {
+ if (XkbVariantDflt)
+ _XkbFree(XkbVariantDflt);
+ XkbVariantDflt= _XkbDupString(variant);
+ }
+ if (options) {
+ if (XkbOptionsDflt)
+ _XkbFree(XkbOptionsDflt);
+ XkbOptionsDflt= _XkbDupString(options);
+ }
+ return;
+}
+
+/***====================================================================***/
+
+#if defined(luna)
+#define XKB_DDX_PERMANENT_LOCK 1
+#endif
+
+#include "xkbDflts.h"
+
+static Bool
+#if NeedFunctionPrototypes
+XkbInitKeyTypes(XkbDescPtr xkb,SrvXkmInfo *file)
+#else
+XkbInitKeyTypes(xkb,file)
+ XkbDescPtr xkb;
+ SrvXkmInfo * file;
+#endif
+{
+ if (file->xkbinfo.defined&XkmTypesMask)
+ return True;
+ initTypeNames(NULL);
+ if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_dflt_types)!=Success)
+ return False;
+ if (XkbCopyKeyTypes(dflt_types,xkb->map->types,num_dflt_types)!=
+ Success) {
+ return False;
+ }
+ xkb->map->size_types= xkb->map->num_types= num_dflt_types;
+ return True;
+}
+
+static void
+#if NeedFunctionPrototypes
+XkbInitRadioGroups(XkbSrvInfoPtr xkbi,SrvXkmInfo *file)
+#else
+XkbInitRadioGroups(xkbi,file)
+ XkbSrvInfoPtr xkbi;
+ SrvXkmInfo * file;
+#endif
+{
+ xkbi->nRadioGroups = 0;
+ xkbi->radioGroups = NULL;
+ return;
+}
+
+
+static Status
+#if NeedFunctionPrototypes
+XkbInitCompatStructs(XkbDescPtr xkb,SrvXkmInfo *file)
+#else
+XkbInitCompatStructs(xkb,file)
+ XkbDescPtr xkb;
+ SrvXkmInfo * file;
+#endif
+{
+register int i;
+XkbCompatMapPtr compat;
+
+ if (file->xkbinfo.defined&XkmCompatMapMask)
+ return Success;
+ if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_dfltSI)!=Success)
+ return BadAlloc;
+ compat = xkb->compat;
+ if (compat->sym_interpret) {
+ compat->num_si = num_dfltSI;
+ memcpy((char *)compat->sym_interpret,(char *)dfltSI,sizeof(dfltSI));
+ }
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ compat->groups[i]= compatMap.groups[i];
+ if (compat->groups[i].vmods!=0) {
+ unsigned mask;
+ mask= XkbMaskForVMask(xkb,compat->groups[i].vmods);
+ compat->groups[i].mask= compat->groups[i].real_mods|mask;
+ }
+ else compat->groups[i].mask= compat->groups[i].real_mods;
+ }
+ return Success;
+}
+
+static void
+#if NeedFunctionPrototypes
+XkbInitSemantics(XkbDescPtr xkb,SrvXkmInfo *file)
+#else
+XkbInitSemantics(xkb,file)
+ XkbDescPtr xkb;
+ SrvXkmInfo * file;
+#endif
+{
+ XkbInitKeyTypes(xkb,file);
+ XkbInitCompatStructs(xkb,file);
+ return;
+}
+
+/***====================================================================***/
+
+static Status
+#if NeedFunctionPrototypes
+XkbInitNames(XkbSrvInfoPtr xkbi,SrvXkmInfo *file)
+#else
+XkbInitNames(xkbi,file)
+ XkbSrvInfoPtr xkbi;
+ SrvXkmInfo * file;
+#endif
+{
+XkbDescPtr xkb;
+XkbNamesPtr names;
+Status rtrn;
+Atom unknown;
+
+ xkb= xkbi->desc;
+ if ((rtrn=XkbAllocNames(xkb,XkbAllNamesMask,0,0))!=Success)
+ return rtrn;
+ unknown= CREATE_ATOM("unknown");
+ names = xkb->names;
+ if (names->keycodes==None) names->keycodes= unknown;
+ if (names->geometry==None) names->geometry= unknown;
+ if (names->phys_symbols==None) names->phys_symbols= unknown;
+ if (names->symbols==None) names->symbols= unknown;
+ if (names->types==None) names->types= unknown;
+ if (names->compat==None) names->compat= unknown;
+ if ((file->xkbinfo.defined&XkmVirtualModsMask)==0) {
+ if (names->vmods[vmod_NumLock]==None)
+ names->vmods[vmod_NumLock]= CREATE_ATOM("NumLock");
+ if (names->vmods[vmod_Alt]==None)
+ names->vmods[vmod_Alt]= CREATE_ATOM("Alt");
+ if (names->vmods[vmod_AltGr]==None)
+ names->vmods[vmod_AltGr]= CREATE_ATOM("ModeSwitch");
+ }
+
+ if (((file->xkbinfo.defined&XkmIndicatorsMask)==0)||
+ ((file->xkbinfo.defined&XkmGeometryMask)==0)) {
+ initIndicatorNames(NULL,xkb);
+ if (names->indicators[LED_CAPS-1]==None)
+ names->indicators[LED_CAPS-1] = CREATE_ATOM("Caps Lock");
+ if (names->indicators[LED_NUM-1]==None)
+ names->indicators[LED_NUM-1] = CREATE_ATOM("Num Lock");
+ if (names->indicators[LED_SCROLL-1]==None)
+ names->indicators[LED_SCROLL-1] = CREATE_ATOM("Scroll Lock");
+#ifdef LED_COMPOSE
+ if (names->indicators[LED_COMPOSE-1]==None)
+ names->indicators[LED_COMPOSE-1] = CREATE_ATOM("Compose");
+#endif
+ }
+#ifdef DEBUG_RADIO_GROUPS
+ if (names->num_rg<1) {
+ names->radio_groups= (Atom *)Xcalloc(RG_COUNT*sizeof(Atom));
+ if (names->radio_groups) {
+ names->num_rg = RG_COUNT;
+ names->radio_groups[RG_BOGUS_FUNCTION_GROUP]= CREATE_ATOM("BOGUS");
+ }
+ }
+#endif
+ if (xkb->geom!=NULL)
+ names->geometry= xkb->geom->name;
+ else names->geometry= unknown;
+ return Success;
+}
+
+static Status
+#if NeedFunctionPrototypes
+XkbInitIndicatorMap(XkbSrvInfoPtr xkbi,SrvXkmInfo *file)
+#else
+XkbInitIndicatorMap(xkbi,file)
+ XkbSrvInfoPtr xkbi;
+ SrvXkmInfo * file;
+#endif
+{
+XkbDescPtr xkb;
+XkbIndicatorPtr map;
+XkbSrvLedInfoPtr sli;
+
+ xkb= xkbi->desc;
+ if (XkbAllocIndicatorMaps(xkb)!=Success)
+ return BadAlloc;
+ if ((file->xkbinfo.defined&XkmIndicatorsMask)==0) {
+ map= xkb->indicators;
+ map->phys_indicators = PHYS_LEDS;
+ map->maps[LED_CAPS-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_CAPS-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_CAPS-1].mods.mask= LockMask;
+ map->maps[LED_CAPS-1].mods.real_mods= LockMask;
+
+ map->maps[LED_NUM-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_NUM-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_NUM-1].mods.mask= 0;
+ map->maps[LED_NUM-1].mods.real_mods= 0;
+ map->maps[LED_NUM-1].mods.vmods= vmod_NumLockMask;
+ }
+ sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0);
+ if (sli)
+ XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask);
+ return Success;
+}
+
+static Status
+#if NeedFunctionPrototypes
+XkbInitControls(DeviceIntPtr pXDev,XkbSrvInfoPtr xkbi,SrvXkmInfo *file)
+#else
+XkbInitControls(pXDev,xkbi,file)
+ DeviceIntPtr pXDev;
+ XkbSrvInfoPtr xkbi;
+ SrvXkmInfo * file;
+#endif
+{
+XkbDescPtr xkb;
+XkbControlsPtr ctrls;
+
+ xkb= xkbi->desc;
+ /* 12/31/94 (ef) -- XXX! Should check if controls loaded from file */
+ if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success)
+ FatalError("Couldn't allocate keyboard controls\n");
+ ctrls= xkb->ctrls;
+ if ((file->xkbinfo.defined&XkmSymbolsMask)==0)
+ ctrls->num_groups = 1;
+ ctrls->groups_wrap = XkbSetGroupInfo(1,XkbWrapIntoRange,0);
+ ctrls->internal.mask = 0;
+ ctrls->internal.real_mods = 0;
+ ctrls->internal.vmods = 0;
+ ctrls->ignore_lock.mask = 0;
+ ctrls->ignore_lock.real_mods = 0;
+ ctrls->ignore_lock.vmods = 0;
+ ctrls->enabled_ctrls = XkbAccessXTimeoutMask|XkbRepeatKeysMask|
+ XkbMouseKeysAccelMask|XkbAudibleBellMask|
+ XkbIgnoreGroupLockMask;
+ if (XkbWantAccessX)
+ ctrls->enabled_ctrls|= XkbAccessXKeysMask;
+ AccessXInit(pXDev);
+ return Success;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbInitDevice(DeviceIntPtr pXDev)
+#else
+XkbInitDevice(pXDev)
+ DeviceIntPtr pXDev;
+#endif
+{
+int i;
+XkbSrvInfoPtr xkbi;
+XkbChangesRec changes;
+SrvXkmInfo file;
+unsigned check;
+XkbEventCauseRec cause;
+
+ file.dev= pXDev;
+ file.file=NULL;
+ bzero(&file.xkbinfo,sizeof(XkbFileInfo));
+ bzero(&changes,sizeof(XkbChangesRec));
+ if (XkbAutoLoad && (XkbInitialMap!=NULL)) {
+ if ((file.file=XkbDDXOpenConfigFile(XkbInitialMap,NULL,0))!=NULL) {
+ XkmReadFile(file.file,0,XkmKeymapLegal,&file.xkbinfo);
+ if (file.xkbinfo.xkb==NULL) {
+ ErrorF("Error loading keymap file %s (%s in %s)\n",
+ XkbInitialMap, _XkbErrMessages[_XkbErrCode],
+ (_XkbErrLocation?_XkbErrLocation:"unknown"));
+ ErrorF(" reverting to defaults\n");
+ fclose(file.file);
+ file.file= NULL;
+ bzero(&file.xkbinfo,sizeof(XkbFileInfo));
+ }
+ else {
+ if (_XkbInitFileInfo!=NULL) {
+ XkbDescPtr tmp;
+ if ((tmp=_XkbInitFileInfo->xkb)!=NULL) {
+ XkbFreeKeyboard(tmp,XkbAllComponentsMask,True);
+ _XkbInitFileInfo->xkb= NULL;
+ }
+ }
+ _XkbInitFileInfo= &file.xkbinfo;
+ }
+ }
+ else {
+ ErrorF("Error opening keymap file %s, reverting to defaults\n",
+ XkbInitialMap);
+ }
+ }
+ pXDev->key->xkbInfo= xkbi= _XkbTypedCalloc(1,XkbSrvInfoRec);
+ if ( xkbi ) {
+ XkbDescPtr xkb;
+ if ((_XkbInitFileInfo!=NULL)&&(_XkbInitFileInfo->xkb!=NULL)) {
+ file.xkbinfo= *_XkbInitFileInfo;
+ xkbi->desc= _XkbInitFileInfo->xkb;
+ _XkbInitFileInfo= NULL;
+ }
+ else {
+ xkbi->desc= XkbAllocKeyboard();
+ if (!xkbi->desc)
+ FatalError("Couldn't allocate keyboard description\n");
+ xkbi->desc->min_key_code = pXDev->key->curKeySyms.minKeyCode;
+ xkbi->desc->max_key_code = pXDev->key->curKeySyms.maxKeyCode;
+ }
+ xkb= xkbi->desc;
+ if (xkb->min_key_code == 0)
+ xkb->min_key_code = pXDev->key->curKeySyms.minKeyCode;
+ if (xkb->max_key_code == 0)
+ xkb->max_key_code = pXDev->key->curKeySyms.maxKeyCode;
+ if ((pXDev->key->curKeySyms.minKeyCode!=xkbi->desc->min_key_code)||
+ (pXDev->key->curKeySyms.maxKeyCode!=xkbi->desc->max_key_code)) {
+ /* 12/9/95 (ef) -- XXX! Maybe we should try to fix up one or */
+ /* the other here, but for now just complain */
+ /* can't just update the core range without */
+ /* reallocating the KeySymsRec (pain) */
+ ErrorF("Internal Error!! XKB and core keymap have different range\n");
+ }
+ if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success)
+ FatalError("Couldn't allocate client map in XkbInitDevice\n");
+ i= XkbNumKeys(xkb)/3+1;
+ if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,i)!=Success)
+ FatalError("Couldn't allocate server map in XkbInitDevice\n");
+
+ xkbi->dfltPtrDelta=1;
+ xkbi->device = pXDev;
+
+ file.xkbinfo.xkb= xkb;
+ XkbInitSemantics(xkb,&file);
+ XkbInitNames(xkbi,&file);
+ XkbInitRadioGroups(xkbi,&file);
+
+ /* 12/31/94 (ef) -- XXX! Should check if state loaded from file */
+ bzero(&xkbi->state,sizeof(XkbStateRec));
+
+ XkbInitControls(pXDev,xkbi,&file);
+
+ if (file.xkbinfo.defined&XkmSymbolsMask)
+ memcpy(pXDev->key->modifierMap,xkb->map->modmap,xkb->max_key_code+1);
+ else
+ memcpy(xkb->map->modmap,pXDev->key->modifierMap,xkb->max_key_code+1);
+
+ XkbInitIndicatorMap(xkbi,&file);
+
+ XkbDDXInitDevice(pXDev);
+
+ if (!(file.xkbinfo.defined&XkmSymbolsMask)) {
+ XkbUpdateKeyTypesFromCore(pXDev,xkb->min_key_code,XkbNumKeys(xkb),
+ &changes);
+ }
+ else {
+ XkbUpdateCoreDescription(pXDev,True);
+ }
+ XkbSetCauseUnknown(&cause);
+ XkbUpdateActions(pXDev,xkb->min_key_code, XkbNumKeys(xkb),&changes,
+ &check,&cause);
+ /* For sanity. The first time the connection
+ * is opened, the client side min and max are set
+ * using QueryMinMaxKeyCodes() which grabs them
+ * from pXDev.
+ */
+ pXDev->key->curKeySyms.minKeyCode = xkb->min_key_code;
+ pXDev->key->curKeySyms.maxKeyCode = xkb->max_key_code;
+ }
+ if (file.file!=NULL)
+ fclose(file.file);
+ return;
+}
+
+
+Bool
+#if NeedFunctionPrototypes
+XkbInitKeyboardDeviceStruct( DeviceIntPtr dev,
+ XkbComponentNamesPtr names,
+ KeySymsPtr pSymsIn,
+ CARD8 pModsIn[],
+ void (*bellProc)(),
+ void (*ctrlProc)())
+#else
+XkbInitKeyboardDeviceStruct( dev,names,pSymsIn,pModsIn,bellProc,ctrlProc )
+ DeviceIntPtr dev;
+ XkbComponentNamesPtr names;
+ KeySymsPtr pSymsIn;
+ CARD8 pModsIn[];
+ void (*bellProc)();
+ void (*ctrlProc)();
+#endif
+{
+XkbFileInfo finfo;
+KeySymsRec tmpSyms,*pSyms;
+CARD8 tmpMods[XkbMaxLegalKeyCode+1],*pMods;
+char name[PATH_MAX],*rules;
+Bool ok;
+XPointer config;
+XkbComponentNamesRec cfgNames;
+XkbRF_VarDefsRec defs;
+
+ if ((dev->key!=NULL)||(dev->kbdfeed!=NULL))
+ return False;
+ pSyms= pSymsIn;
+ pMods= pModsIn;
+ bzero(&defs,sizeof(XkbRF_VarDefsRec));
+ bzero(&cfgNames,sizeof(XkbComponentNamesRec));
+ rules= XkbGetRulesDflts(&defs);
+ config= XkbDDXPreloadConfig(&rules,&defs,&cfgNames,dev);
+
+ if (defs.model && defs.layout && rules) {
+ XkbComponentNamesRec rNames;
+ bzero(&rNames,sizeof(XkbComponentNamesRec));
+ if (XkbDDXNamesFromRules(dev,rules,&defs,&rNames)) {
+ if (rNames.keymap) names->keymap= rNames.keymap;
+ if (rNames.keycodes) names->keycodes= rNames.keycodes;
+ if (rNames.types) names->types= rNames.types;
+ if (rNames.compat) names->compat= rNames.compat;
+ if (rNames.symbols) names->symbols= rNames.symbols;
+ if (rNames.geometry) names->geometry= rNames.geometry;
+ XkbSetRulesUsed(&defs);
+ }
+ }
+ if (cfgNames.keymap) names->keymap= cfgNames.keymap;
+ if (cfgNames.keycodes) names->keycodes= cfgNames.keycodes;
+ if (cfgNames.types) names->types= cfgNames.types;
+ if (cfgNames.compat) names->compat= cfgNames.compat;
+ if (cfgNames.symbols) names->symbols= cfgNames.symbols;
+ if (cfgNames.geometry) names->geometry= cfgNames.geometry;
+
+ if ((XkbDDXLoadKeymapByNames(dev,names,XkmAllIndicesMask,0,
+ &finfo,name,PATH_MAX))&&
+ (finfo.xkb!=NULL)) {
+ XkbDescPtr xkb;
+ int minKC,maxKC;
+
+ xkb= finfo.xkb;
+ minKC= xkb->min_key_code;
+ maxKC= xkb->max_key_code;
+ if (XkbIsLegalKeycode(minKC)&&XkbIsLegalKeycode(maxKC)&&(minKC<=maxKC)&&
+ ((minKC!=pSyms->minKeyCode)||(maxKC!=pSyms->maxKeyCode))) {
+ if (xkb->map!=NULL) {
+ KeySym *inSym,*outSym;
+ int width= pSymsIn->mapWidth;
+
+ tmpSyms.minKeyCode= minKC;
+ tmpSyms.maxKeyCode= maxKC;
+
+ if (minKC<pSymsIn->minKeyCode)
+ minKC= pSymsIn->minKeyCode;
+ if (maxKC>pSymsIn->maxKeyCode)
+ maxKC= pSymsIn->maxKeyCode;
+
+ tmpSyms.mapWidth= width;
+ tmpSyms.map= _XkbTypedCalloc(width*XkbNumKeys(xkb),KeySym);
+ inSym= &pSymsIn->map[(minKC-pSymsIn->minKeyCode)*width];
+ outSym= &tmpSyms.map[(minKC-tmpSyms.minKeyCode)*width];
+ memcpy(outSym,inSym,((maxKC-minKC+1)*width)*sizeof(KeySym));
+ pSyms= &tmpSyms;
+ }
+ if ((xkb->map!=NULL)&&(xkb->map->modmap!=NULL)) {
+ bzero(tmpMods,XkbMaxKeyCount);
+ memcpy(tmpMods,xkb->map->modmap,maxKC+1);
+ pMods= tmpMods;
+ }
+ }
+ _XkbInitFileInfo= &finfo;
+ }
+ else {
+ ErrorF("Couldn't load XKB keymap, falling back to pre-XKB keymap\n");
+ }
+ ok= InitKeyboardDeviceStruct((DevicePtr)dev,pSyms,pMods,bellProc,ctrlProc);
+ if ((config!=NULL)&&(dev && dev->key && dev->key->xkbInfo))
+ XkbDDXApplyConfig(config,dev->key->xkbInfo);
+ _XkbInitFileInfo= NULL;
+ if ((pSyms==&tmpSyms)&&(pSyms->map!=NULL)) {
+ _XkbFree(pSyms->map);
+ pSyms->map= NULL;
+ }
+ return ok;
+}
+
+/***====================================================================***/
+
+ /*
+ * InitKeyClassDeviceStruct initializes the key class before it
+ * initializes the keyboard feedback class for a device.
+ * UpdateActions can't set up the correct autorepeat for keyboard
+ * initialization because the keyboard feedback isn't created yet.
+ * Instead, UpdateActions notes the "correct" autorepeat in the
+ * SrvInfo structure and InitKbdFeedbackClass calls UpdateAutoRepeat
+ * to apply the computed autorepeat once the feedback class exists.
+ *
+ * DIX will apply the changed autorepeat, so there's no need to
+ * do so here. This function returns True if both RepeatKeys and
+ * the core protocol autorepeat ctrls are set (i.e. should use
+ * software autorepeat), false otherwise.
+ *
+ * This function also computes the autorepeat accelerators for the
+ * default indicator feedback.
+ */
+int
+#if NeedFunctionPrototypes
+XkbFinishDeviceInit(DeviceIntPtr pXDev)
+#else
+XkbFinishDeviceInit(pXDev)
+ DeviceIntPtr pXDev;
+#endif
+{
+XkbSrvInfoPtr xkbi;
+XkbDescPtr xkb;
+int softRepeat;
+XkbSrvLedInfoPtr sli;
+
+ xkbi = NULL;
+ if (pXDev && pXDev->key && pXDev->key->xkbInfo && pXDev->kbdfeed) {
+ xkbi= pXDev->key->xkbInfo;
+ xkb= xkbi->desc;
+ if (pXDev->kbdfeed) {
+ xkbi->kbdProc= pXDev->kbdfeed->CtrlProc;
+ pXDev->kbdfeed->CtrlProc= XkbDDXKeybdCtrlProc;
+ }
+ if (pXDev->kbdfeed->ctrl.autoRepeat)
+ xkb->ctrls->enabled_ctrls|= XkbRepeatKeysMask;
+ softRepeat= (xkb->ctrls->enabled_ctrls&XkbRepeatKeysMask)!=0;
+ if (pXDev->kbdfeed) {
+ memcpy(pXDev->kbdfeed->ctrl.autoRepeats,
+ xkb->ctrls->per_key_repeat,XkbPerKeyBitArraySize);
+ softRepeat= softRepeat&&pXDev->kbdfeed->ctrl.autoRepeat;
+ }
+ }
+ else softRepeat= 0;
+ sli= XkbFindSrvLedInfo(pXDev,XkbDfltXIClass,XkbDfltXIId,0);
+ if (sli && xkbi)
+ XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask);
+#ifdef DEBUG
+ else ErrorF("No indicator feedback in XkbFinishInit (shouldn't happen)!\n");
+#endif
+ return softRepeat;
+}
+
+ /*
+ * Be very careful about what does and doesn't get freed by this
+ * function. To reduce fragmentation, XkbInitDevice allocates a
+ * single huge block per device and divides it up into most of the
+ * fixed-size structures for the device. Don't free anything that
+ * is part of this larger block.
+ */
+void
+#if NeedFunctionPrototypes
+XkbFreeInfo(XkbSrvInfoPtr xkbi)
+#else
+XkbFreeInfo(xkbi)
+ XkbSrvInfoPtr xkbi;
+#endif
+{
+ if (xkbi->radioGroups) {
+ Xfree(xkbi->radioGroups);
+ xkbi->radioGroups= NULL;
+ }
+ if (xkbi->mouseKeyTimer) {
+ TimerFree(xkbi->mouseKeyTimer);
+ xkbi->mouseKeyTimer= NULL;
+ }
+ if (xkbi->slowKeysTimer) {
+ TimerFree(xkbi->slowKeysTimer);
+ xkbi->slowKeysTimer= NULL;
+ }
+ if (xkbi->bounceKeysTimer) {
+ TimerFree(xkbi->bounceKeysTimer);
+ xkbi->bounceKeysTimer= NULL;
+ }
+ if (xkbi->repeatKeyTimer) {
+ TimerFree(xkbi->repeatKeyTimer);
+ xkbi->repeatKeyTimer= NULL;
+ }
+ if (xkbi->krgTimer) {
+ TimerFree(xkbi->krgTimer);
+ xkbi->krgTimer= NULL;
+ }
+ xkbi->beepType= _BEEP_NONE;
+ if (xkbi->beepTimer) {
+ TimerFree(xkbi->beepTimer);
+ xkbi->beepTimer= NULL;
+ }
+ if (xkbi->desc) {
+ XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,True);
+ xkbi->desc= NULL;
+ }
+ Xfree(xkbi);
+ return;
+}
+
+/***====================================================================***/
+
+extern int XkbDfltRepeatDelay;
+extern int XkbDfltRepeatInterval;
+
+extern unsigned short XkbDfltAccessXTimeout;
+extern unsigned int XkbDfltAccessXTimeoutMask;
+extern unsigned int XkbDfltAccessXFeedback;
+extern unsigned char XkbDfltAccessXOptions;
+
+int
+#if NeedFunctionPrototypes
+XkbProcessArguments(int argc,char *argv[],int i)
+#else
+XkbProcessArguments(argc,argv,i)
+ int argc;
+ char * argv[];
+ int i;
+#endif
+{
+ if (strcmp(argv[i],"-kb")==0) {
+ noXkbExtension= True;
+ return 1;
+ }
+ else if (strcmp(argv[i],"+kb")==0) {
+ noXkbExtension= False;
+ return 1;
+ }
+ else if (strncmp(argv[i], "-xkbmap", 7) == 0) {
+ if(++i < argc) {
+ XkbInitialMap= argv[i];
+ return 2;
+ }
+ else {
+ return -1;
+ }
+ }
+ else if (strncmp(argv[i], "-xkbdb", 7) == 0) {
+ if(++i < argc) {
+ XkbDB= argv[i];
+ return 2;
+ }
+ else {
+ return -1;
+ }
+ }
+ else if (strncmp(argv[i], "-noloadxkb", 7) == 0) {
+ XkbAutoLoad= 0;
+ return 1;
+ }
+ else if ((strncmp(argv[i],"-accessx",8)==0)||
+ (strncmp(argv[i],"+accessx",8)==0)) {
+ int j=1;
+ if (argv[i][0]=='-')
+ XkbWantAccessX= 0;
+ else {
+ XkbWantAccessX= 1;
+
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ XkbDfltAccessXTimeout = atoi(argv[++i]);
+ j++;
+
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ /*
+ * presumption that the reasonably useful range of
+ * values fits in 0..MAXINT since SunOS 4 doesn't
+ * have strtoul.
+ */
+ XkbDfltAccessXTimeoutMask=(unsigned int)
+ strtol(argv[++i],NULL,16);
+ j++;
+ }
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ if (argv[++i][0] == '1' )
+ XkbDfltAccessXFeedback=XkbAccessXFeedbackMask;
+ else
+ XkbDfltAccessXFeedback=0;
+ j++;
+ }
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ XkbDfltAccessXOptions=(unsigned char)
+ strtol(argv[++i],NULL,16);
+ j++;
+ }
+ }
+ }
+ return j;
+ }
+ if (strcmp (argv[i], "-ar1") == 0) { /* -ar1 int */
+ if (++i >= argc) UseMsg ();
+ XkbDfltRepeatDelay = (long)atoi(argv[i]);
+ return 2;
+ }
+ if (strcmp (argv[i], "-ar2") == 0) { /* -ar2 int */
+ if (++i >= argc) UseMsg ();
+ XkbDfltRepeatInterval = (long)atoi(argv[i]);
+ return 2;
+ }
+ return 0;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbUseMsg(void)
+#else
+XkbUseMsg()
+#endif
+{
+ ErrorF("The X Keyboard Extension adds the following arguments:\n");
+ ErrorF("-kb disable the X Keyboard Extension\n");
+ ErrorF("+kb enable the X Keyboard Extension\n");
+ ErrorF("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n");
+ ErrorF(" enable/disable accessx key sequences\n");
+ ErrorF("-ar1 set XKB autorepeat delay\n");
+ ErrorF("-ar2 set XKB autorepeat interval\n");
+ ErrorF("-noloadxkb don't load XKB keymap description\n");
+ ErrorF("-xkbcomp default keymap compiler\n");
+ ErrorF("-xkbdb file that contains default XKB keymaps\n");
+ ErrorF("-xkbmap XKB keyboard description to load on startup\n");
+}