예제 #1
0
파일: xkbInit.c 프로젝트: narenas/nx-libs
void
XkbSetRulesDflts(char *rulesFile,char *model,char *layout,
					char *variant,char *options)
{
    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;
}
static Bool
MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
{

   bzero((char *)mdefs,sizeof(XkbRF_MultiDefsRec));
   mdefs->model = defs->model;
   mdefs->options = _XkbDupString(defs->options);
   if (mdefs->options) squeeze_spaces(mdefs->options); 

   if (defs->layout) {
       if (!strchr(defs->layout, ',')) {
           mdefs->layout[0] = defs->layout;
       } else {
           char *p;
           int i;
           mdefs->layout[1] = _XkbDupString(defs->layout);
	   if (mdefs->layout[1] == NULL)
	      return FALSE;
           squeeze_spaces(mdefs->layout[1]);
           p = mdefs->layout[1];
           for (i = 2; i <= XkbNumKbdGroups; i++) {
              if ((p = strchr(p, ','))) {
                 *p++ = '\0';
                 mdefs->layout[i] = p;
              } else {
                 break;
              }
           }
           if (p && (p = strchr(p, ',')))
              *p = '\0';
       }
   }

   if (defs->variant) {
       if (!strchr(defs->variant, ',')) {
           mdefs->variant[0] = defs->variant;
       } else {
           char *p;
           int i;
           mdefs->variant[1] = _XkbDupString(defs->variant);
	   if (mdefs->variant[1] == NULL)
	      return FALSE;
           squeeze_spaces(mdefs->variant[1]);
           p = mdefs->variant[1];
           for (i = 2; i <= XkbNumKbdGroups; i++) {
              if ((p = strchr(p, ','))) {
                 *p++ = '\0';
                 mdefs->variant[i] = p;
              } else {
                 break;
              }
           }
           if (p && (p = strchr(p, ',')))
              *p = '\0';
       }
   }
   return TRUE;
}
예제 #3
0
파일: maprules.c 프로젝트: narenas/nx-libs
XkbRF_VarDescPtr
XkbRF_AddVarDescCopy(XkbRF_DescribeVarsPtr vars,XkbRF_VarDescPtr from)
{
XkbRF_VarDescPtr	nd;

    if ((nd=XkbRF_AddVarDesc(vars))!=NULL) {
	nd->name= _XkbDupString(from->name);
	nd->desc= _XkbDupString(from->desc);
    }
    return nd;
}
예제 #4
0
/*ARGSUSED*/
static Bool
DefaultFinish(XkbConfigFieldsPtr fields, XkbDescPtr xkb,
              XkbConfigRtrnPtr rtrn, int what)
{
    if ((what == XkbCF_Destroy) || (what == XkbCF_CleanUp))
        return DefaultCleanUp(rtrn);
    if (what == XkbCF_Check) {
        if ((rtrn->symbols == NULL) && (rtrn->phys_symbols != NULL))
            rtrn->symbols = _XkbDupString(rtrn->phys_symbols);
    }
    if ((what == XkbCF_Apply) || (what == XkbCF_Check)) {
        if (xkb && xkb->names && (rtrn->num_unbound_mods > 0))
            XkbCFBindMods(rtrn, xkb);
        XkbCFApplyMods(rtrn, XkbCF_InitialMods, &rtrn->initial_mods);
        XkbCFApplyMods(rtrn, XkbCF_InternalMods, &rtrn->internal_mods);
        XkbCFApplyMods(rtrn, XkbCF_IgnoreLockMods, &rtrn->ignore_lock_mods);
    }
    if (what == XkbCF_Apply) {
        if (xkb != NULL) {
            DefaultApplyNames(rtrn, xkb);
            DefaultApplyControls(rtrn, xkb);
            XkbCFBindMods(rtrn, xkb);
        }
    }
    return True;
}
예제 #5
0
파일: xkbInit.c 프로젝트: narenas/nx-libs
void
XkbSetRulesUsed(XkbRF_VarDefsPtr defs)
{
    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;
}
예제 #6
0
XkbConfigUnboundModPtr
XkbCFAddModByName(	XkbConfigRtrnPtr	rtrn,
			int			what,
			char *			name,
			Bool			merge,
			XkbConfigUnboundModPtr	last)
{
    if (rtrn->num_unbound_mods>=rtrn->sz_unbound_mods) {
	rtrn->sz_unbound_mods+= 5;
	rtrn->unbound_mods= _XkbTypedRealloc(rtrn->unbound_mods,
						  rtrn->sz_unbound_mods,
						  XkbConfigUnboundModRec);
	if (rtrn->unbound_mods==NULL) {
	    rtrn->error= XkbCF_BadAlloc;
	    return False;
	}
    }
    if (last==NULL) {
	last= &rtrn->unbound_mods[rtrn->num_unbound_mods++];
	last->what= what;
	last->mods= 0;
	last->vmods= 0;
	last->merge= merge;
	last->name= NULL;
    }
    if (_XkbStrCaseCmp(name,"shift")==0)
	last->mods|= ShiftMask;
    else if (_XkbStrCaseCmp(name,"lock")==0)
	last->mods|= LockMask;
    else if ((_XkbStrCaseCmp(name,"control")==0)||
		(_XkbStrCaseCmp(name,"ctrl")==0))
	last->mods|= ControlMask;
    else if (_XkbStrCaseCmp(name,"mod1")==0)
	last->mods|= Mod1Mask;
    else if (_XkbStrCaseCmp(name,"mod2")==0)
	last->mods|= Mod2Mask;
    else if (_XkbStrCaseCmp(name,"mod3")==0)
	last->mods|= Mod3Mask;
    else if (_XkbStrCaseCmp(name,"mod4")==0)
	last->mods|= Mod4Mask;
    else if (_XkbStrCaseCmp(name,"mod5")==0)
	last->mods|= Mod5Mask;
    else {
	if (last->name!=NULL) {
	    last= &rtrn->unbound_mods[rtrn->num_unbound_mods++];
	    last->what= what;
	    last->mods= 0;
	    last->vmods= 0;
	    last->merge= merge;
	    last->name= NULL;
	}
	last->name= _XkbDupString(name);
    }
    return last;
}
static void
Apply(char *src, char **dst)
{
    if (src) {
        if (*src == '+' || *src == '!') {
	    *dst= _Concat(*dst, src);
        } else {
            if (*dst == NULL)
	        *dst= _XkbDupString(src);
        }
    }
}
예제 #8
0
파일: xkbfmisc.c 프로젝트: aosm/X11server
Bool
XkbWriteXKBKeymapForNames(	FILE *			file,
				XkbComponentNamesPtr	names,
				XkbDescPtr		xkb,
				unsigned		want,
				unsigned		need)
{
char *		name,*tmp;
unsigned	complete;
XkbNamesPtr	old_names;
int		multi_section;
unsigned	wantNames,wantConfig,wantDflts;

    complete= 0;
    if ((name=names->keymap)==NULL)	name= "default";
    if (COMPLETE(names->keycodes))	complete|= XkmKeyNamesMask;
    if (COMPLETE(names->types))		complete|= XkmTypesMask;
    if (COMPLETE(names->compat))	complete|= XkmCompatMapMask;
    if (COMPLETE(names->symbols))	complete|= XkmSymbolsMask;
    if (COMPLETE(names->geometry))	complete|= XkmGeometryMask;
    want|= (complete|need);
    if (want&XkmSymbolsMask)
	want|= XkmKeyNamesMask|XkmTypesMask;

    if (want==0)
	return False;

    if (xkb) {
        old_names = xkb->names;

        xkb->defined = 0;
        /* Wow would it ever be neat if we didn't need this noise. */
        if (xkb->names && xkb->names->keys)
            xkb->defined |= XkmKeyNamesMask;
        if (xkb->map && xkb->map->types)
            xkb->defined |= XkmTypesMask;
        if (xkb->compat)
            xkb->defined |= XkmCompatMapMask;
        if (xkb->map && xkb->map->num_syms)
            xkb->defined |= XkmSymbolsMask;
        if (xkb->indicators)
            xkb->defined |= XkmIndicatorsMask;
        if (xkb->geom)
            xkb->defined |= XkmGeometryMask;
    }
    else {
        old_names= NULL;
    }

    wantConfig= want&(~complete);
    if (xkb!=NULL) {
	if (wantConfig&XkmTypesMask) {
	    if ((!xkb->map) || (xkb->map->num_types<XkbNumRequiredTypes))
		wantConfig&= ~XkmTypesMask;
	}
	if (wantConfig&XkmCompatMapMask) {
	    if ((!xkb->compat) || (xkb->compat->num_si<1))
		wantConfig&= ~XkmCompatMapMask;
	}
	if (wantConfig&XkmSymbolsMask) {
	    if ((!xkb->map) || (!xkb->map->key_sym_map))
		wantConfig&= ~XkmSymbolsMask;
	}
	if (wantConfig&XkmIndicatorsMask) {
	    if (!xkb->indicators)
		wantConfig&= ~XkmIndicatorsMask;
	}
	if (wantConfig&XkmKeyNamesMask) {
	    if ((!xkb->names)||(!xkb->names->keys))
		wantConfig&= ~XkmKeyNamesMask;
	}
	if ((wantConfig&XkmGeometryMask)&&(!xkb->geom))
	    wantConfig&= ~XkmGeometryMask;
    }
    else {
	wantConfig= 0;
    }
    complete|= wantConfig;

    wantDflts= 0;
    wantNames= want&(~complete);
    if ((xkb!=NULL) && (old_names!=NULL)) {
	if (wantNames&XkmTypesMask) {
	    if (old_names->types!=None) {
		tmp= XkbAtomGetString(old_names->types);
		names->types= _XkbDupString(tmp);
	    }
	    else {
		wantDflts|= XkmTypesMask;
	    }
	    complete|= XkmTypesMask; 
	}
	if (wantNames&XkmCompatMapMask) {
	    if (old_names->compat!=None) {
		tmp= XkbAtomGetString(old_names->compat);
		names->compat= _XkbDupString(tmp);
	    }
	    else wantDflts|= XkmCompatMapMask;
	    complete|= XkmCompatMapMask; 
	}
	if (wantNames&XkmSymbolsMask) {
	    if (old_names->symbols==None)
		return False;
	    tmp= XkbAtomGetString(old_names->symbols);
	    names->symbols= _XkbDupString(tmp);
	    complete|= XkmSymbolsMask; 
	}
	if (wantNames&XkmKeyNamesMask) {
	   if (old_names->keycodes!=None) {
		tmp= XkbAtomGetString(old_names->keycodes);
		names->keycodes= _XkbDupString(tmp);
	    }
	    else wantDflts|= XkmKeyNamesMask;
	    complete|= XkmKeyNamesMask;
	}
	if (wantNames&XkmGeometryMask) {
	    if (old_names->geometry==None)
		return False;
	    tmp= XkbAtomGetString(old_names->geometry);
	    names->geometry= _XkbDupString(tmp);
	    complete|= XkmGeometryMask; 
	    wantNames&= ~XkmGeometryMask;
	}
    }
    if (complete&XkmCompatMapMask)
	complete|= XkmIndicatorsMask|XkmVirtualModsMask;
    else if (complete&(XkmSymbolsMask|XkmTypesMask))
	complete|= XkmVirtualModsMask;
    if (need & (~complete))
	return False;
    if ((complete&XkmSymbolsMask)&&((XkmKeyNamesMask|XkmTypesMask)&(~complete)))
	return False;

    multi_section= 1;
    if (((complete&XkmKeymapRequired)==XkmKeymapRequired)&&
	((complete&(~XkmKeymapLegal))==0)) {
	fprintf(file,"xkb_keymap \"%s\" {\n",name);
    }
    else if (((complete&XkmSemanticsRequired)==XkmSemanticsRequired)&&
	((complete&(~XkmSemanticsLegal))==0)) {
	fprintf(file,"xkb_semantics \"%s\" {\n",name);
    }
    else if (((complete&XkmLayoutRequired)==XkmLayoutRequired)&&
	((complete&(~XkmLayoutLegal))==0)) {
	fprintf(file,"xkb_layout \"%s\" {\n",name);
    }
    else if (XkmSingleSection(complete&(~XkmVirtualModsMask))) {
	multi_section= 0;
    }
    else {
	return False;
    }

    wantNames= complete&(~(wantConfig|wantDflts));
    name= names->keycodes;
    if (wantConfig&XkmKeyNamesMask)
	XkbWriteXKBKeycodes(file,xkb,False,False,_AddIncl,name);
    else if (wantDflts&XkmKeyNamesMask)
	fprintf(stderr,"Default symbols not implemented yet!\n");
    else if (wantNames&XkmKeyNamesMask)
	XkbWriteSectionFromName(file,"keycodes",name);

    name= names->types;
    if (wantConfig&XkmTypesMask)
	XkbWriteXKBKeyTypes(file,xkb,False,False,_AddIncl,name);
    else if (wantDflts&XkmTypesMask)
	fprintf(stderr,"Default types not implemented yet!\n");
    else if (wantNames&XkmTypesMask)
	XkbWriteSectionFromName(file,"types",name);

    name= names->compat;
    if (wantConfig&XkmCompatMapMask)
	XkbWriteXKBCompatMap(file,xkb,False,False,_AddIncl,name);
    else if (wantDflts&XkmCompatMapMask)
	fprintf(stderr,"Default interps not implemented yet!\n");
    else if (wantNames&XkmCompatMapMask)
	XkbWriteSectionFromName(file,"compatibility",name);

    name= names->symbols;
    if (wantConfig&XkmSymbolsMask)
	XkbWriteXKBSymbols(file,xkb,False,False,_AddIncl,name);
    else if (wantNames&XkmSymbolsMask)
	XkbWriteSectionFromName(file,"symbols",name);

    name= names->geometry;
    if (wantConfig&XkmGeometryMask)
	XkbWriteXKBGeometry(file,xkb,False,False,_AddIncl,name);
    else if (wantNames&XkmGeometryMask)
	XkbWriteSectionFromName(file,"geometry",name);

    if (multi_section)
	fprintf(file,"};\n");
    return True;
}
static Bool
CheckLine(	InputLine *		line,
		RemapSpec *		remap,
		XkbRF_RulePtr		rule,
		XkbRF_GroupPtr		group)
{
char *		str,*tok;
register int	nread, i;
FileSpec	tmp;
_Xstrtokparams	strtok_buf;
Bool 		append = FALSE;

    if (line->line[0]=='!') {
        if (line->line[1] == '$' ||
            (line->line[1] == ' ' && line->line[2] == '$')) {
            char *gname = strchr(line->line, '$');
            char *words = strchr(gname, ' ');
            if(!words)
                return FALSE;
            *words++ = '\0';
            for (; *words; words++) {
                if (*words != '=' && *words != ' ')
                    break;
            }
            if (*words == '\0')
                return FALSE;
            group->name = _XkbDupString(gname);
            group->words = _XkbDupString(words);
            for (i = 1, words = group->words; *words; words++) {
                 if ( *words == ' ') {
                     *words++ = '\0';
                     i++;
                 }
            }
            group->number = i;
            return TRUE;
        } else {
	    SetUpRemap(line,remap);
	    return FALSE;
        }
    }

    if (remap->num_remap==0) {
	DebugF("Must have a mapping before first line of data\n");
	DebugF("Illegal line of data ignored\n");
	return FALSE;
    }
    bzero((char *)&tmp,sizeof(FileSpec));
    str= line->line;
    for (nread= 0;(tok=_XStrtok(str," ",strtok_buf))!=NULL;nread++) {
	str= NULL;
	if (strcmp(tok,"=")==0) {
	    nread--;
	    continue;
	}
	if (nread>remap->num_remap) {
	    DebugF("Too many words on a line\n");
	    DebugF("Extra word \"%s\" ignored\n",tok);
	    continue;
	}
	tmp.name[remap->remap[nread].word]= tok;
	if (*tok == '+' || *tok == '|')
	    append = TRUE;
    }
    if (nread<remap->num_remap) {
	DebugF("Too few words on a line: %s\n", line->line);
	DebugF("line ignored\n");
	return FALSE;
    }

    rule->flags= 0;
    rule->number = remap->number;
    if (tmp.name[OPTION])
	 rule->flags|= XkbRF_Option;
    else if (append)
	 rule->flags|= XkbRF_Append;
    else
	 rule->flags|= XkbRF_Normal;
    rule->model= _XkbDupString(tmp.name[MODEL]);
    rule->layout= _XkbDupString(tmp.name[LAYOUT]);
    rule->variant= _XkbDupString(tmp.name[VARIANT]);
    rule->option= _XkbDupString(tmp.name[OPTION]);

    rule->keycodes= _XkbDupString(tmp.name[KEYCODES]);
    rule->symbols= _XkbDupString(tmp.name[SYMBOLS]);
    rule->types= _XkbDupString(tmp.name[TYPES]);
    rule->compat= _XkbDupString(tmp.name[COMPAT]);
    rule->geometry= _XkbDupString(tmp.name[GEOMETRY]);

    rule->layout_num = rule->variant_num = 0;
    for (i = 0; i < nread; i++) {
        if (remap->remap[i].index) {
	    if (remap->remap[i].word == LAYOUT)
	        rule->layout_num = remap->remap[i].index;
	    if (remap->remap[i].word == VARIANT)
	        rule->variant_num = remap->remap[i].index;
        }
    }
    return TRUE;
}
예제 #10
0
파일: ddxLoad.c 프로젝트: narenas/nx-libs
Bool
XkbDDXCompileNamedKeymap(	XkbDescPtr		xkb,
				XkbComponentNamesPtr	names,
				char *			nameRtrn,
				int			nameRtrnLen)
{
char 	*cmd = NULL,file[PATH_MAX],xkm_output_dir[PATH_MAX],*map,*outFile;

    if (names->keymap==NULL)
	return False;
    strncpy(file,names->keymap,PATH_MAX); file[PATH_MAX-1]= '\0';
    if ((map= strrchr(file,'('))!=NULL) {
	char *tmp;
	if ((tmp= strrchr(map,')'))!=NULL) {
	    *map++= '\0';
	    *tmp= '\0';
	}
	else {
	    map= NULL;
	}
    }
    if ((outFile= strrchr(file,'/'))!=NULL)
	 outFile= _XkbDupString(&outFile[1]);
    else outFile= _XkbDupString(file);
    XkbEnsureSafeMapName(outFile);
    OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));

#ifdef NXAGENT_SERVER

    if (_NXGetXkbCompPath(XkbBaseDirectory) != NULL)
    {

#else

    if (XkbBaseDirectory!=NULL) {

#endif

#ifndef __UNIXOS2__

#ifdef NXAGENT_SERVER
        char *xkbbasedir = _NXGetXkbBasePath(XkbBaseDirectory);
        char *xkbbindir = _NXGetXkbCompPath(XkbBinDirectory);
#else
        char *xkbbasedir = XkbBaseDirectory;
        char *xkbbindir = XkbBinDirectory;
#endif

#else
        /* relocate the basedir and replace the slashes with backslashes */
#ifdef NXAGENT_SERVER
        char *xkbbasedir = (char*)__XOS2RedirRoot(_NXGetXkbBasePath(XkbBaseDirectory));
        char *xkbbindir = (char*)__XOS2RedirRoot(_NXGetXkbCompPath(XkbBinDirectory));
#else
        char *xkbbasedir = (char*)__XOS2RedirRoot(XkbBaseDirectory);
        char *xkbbindir = (char*)__XOS2RedirRoot(XkbBinDirectory);
#endif
        int i;

	for (i=0; i<strlen(xkbbasedir); i++) 
            if (xkbbasedir[i]=='/') xkbbasedir[i]='\\';
	for (i=0; i<strlen(xkbbindir); i++) 
            if (xkbbindir[i]=='/') xkbbindir[i]='\\';
#endif

	cmd = Xprintf("\"%s" PATHSEPARATOR "xkbcomp\" -w %d \"-R%s\" -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s \"%s%s.xkm\"",
		xkbbindir,
		((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
		xkbbasedir,(map?"-m ":""),(map?map:""),
		PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,file,
		xkm_output_dir,outFile);
    }
    else {
	cmd = Xprintf("xkbcomp -w %d -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s \"%s%s.xkm\"",
		((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
		(map?"-m ":""),(map?map:""),
		PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,file,
		xkm_output_dir,outFile);
    }
#ifdef DEBUG
    if (xkbDebugFlags) {
	ErrorF("XkbDDXCompileNamedKeymap compiling keymap using:\n");
	ErrorF("    \"cmd\"\n");
    }
#endif
#ifdef DEBUG_CMD
    ErrorF("xkb executes: %s\n",cmd);
#endif
    if (System(cmd)==0) {
	if (nameRtrn) {
	    strncpy(nameRtrn,outFile,nameRtrnLen);
	    nameRtrn[nameRtrnLen-1]= '\0';
	}
	if (outFile!=NULL)
	    _XkbFree(outFile);
        if (cmd!=NULL)
            xfree(cmd);
	return True;
    } 
#ifdef DEBUG
    ErrorF("Error compiling keymap (%s)\n",names->keymap);
#endif
    if (outFile!=NULL)
	_XkbFree(outFile);
    if (cmd!=NULL)
        xfree(cmd);
    return False;
}

Bool    	
XkbDDXCompileKeymapByNames(	XkbDescPtr		xkb,
				XkbComponentNamesPtr	names,
				unsigned		want,
				unsigned		need,
				char *			nameRtrn,
				int			nameRtrnLen)
{
FILE *	out;
char	*buf = NULL, keymap[PATH_MAX],xkm_output_dir[PATH_MAX];

#ifdef WIN32
char tmpname[PATH_MAX];
#endif    
    if ((names->keymap==NULL)||(names->keymap[0]=='\0')) {
	sprintf(keymap,"server-%s",display);
    }
    else {
	if (strlen(names->keymap) > PATH_MAX - 1) {
	    ErrorF("name of keymap (%s) exceeds max length\n", names->keymap);
	    return False;
	}
	strcpy(keymap,names->keymap);
    }

    XkbEnsureSafeMapName(keymap);
    OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
#ifdef WIN32
    strcpy(tmpname, Win32TempDir());
    strcat(tmpname, "\\xkb_XXXXXX");
    (void) mktemp(tmpname);
#endif

#ifdef NXAGENT_SERVER
    if (_NXGetXkbCompPath(XkbBaseDirectory)!=NULL) {
#else
    if (XkbBaseDirectory!=NULL) {
#endif

#ifndef WIN32
        char *xkmfile = "-";
#else
        /* WIN32 has no popen. The input must be stored in a file which is used as input
           for xkbcomp. xkbcomp does not read from stdin. */
        char *xkmfile = tmpname;
#endif
#ifndef __UNIXOS2__
#ifdef NXAGENT_SERVER
        char *xkbbasedir = _NXGetXkbBasePath(XkbBaseDirectory);
        char *xkbbindir = _NXGetXkbCompPath(XkbBinDirectory);
#else
        char *xkbbasedir = XkbBaseDirectory;
        char *xkbbindir = XkbBinDirectory;
#endif
#else
        int i;
#ifdef NXAGENT_SERVER
        char *xkbbasedir = (char*)__XOS2RedirRoot(_NXGetXkbBasePath(XkbBaseDirectory));
        char *xkbbindir = (char*)__XOS2RedirRoot(_NXGetXkbCompPath(XkbBinDirectory));
#else
        char *xkbbasedir = (char*)__XOS2RedirRoot(XkbBaseDirectory);
        char *xkbbindir = (char*)__XOS2RedirRoot(XkbBinDirectory);
#endif
	for (i=0; i<strlen(xkbbasedir); i++) 
            if (xkbbasedir[i]=='/') xkbbasedir[i]='\\';
	for (i=0; i<strlen(xkbbindir); i++) 
            if (xkbbindir[i]=='/') xkbbindir[i]='\\';
#endif
        
	buf = Xprintf(
	   "\"%s" PATHSEPARATOR "xkbcomp\" -w %d \"-R%s\" -xkm \"%s\" -em1 %s -emp %s -eml %s \"%s%s.xkm\"",
		xkbbindir,
		((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
		xkbbasedir, xkmfile,
		PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,
		xkm_output_dir,keymap);
    }
    else {
#ifndef WIN32
        char *xkmfile = "-";
#else
        char *xkmfile = tmpname;
#endif
	buf = Xprintf(
		"xkbcomp -w %d -xkm \"%s\" -em1 %s -emp %s -eml %s \"%s%s.xkm\"",
		((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
                xkmfile,
		PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,
		xkm_output_dir,keymap);
    }
    
    #ifdef TEST
    if (buf != NULL)
        fprintf(stderr, "XkbDDXCompileKeymapByNames: "
                    "Executing command [%s].\n", buf);
    else
        fprintf(stderr, "XkbDDXCompileKeymapByNames: "
                    "Callin Popen() with null command.\n");
    #endif

#ifndef WIN32
    out= Popen(buf,"w");
#else
    out= fopen(tmpname, "w");
#endif
    
    if (out!=NULL) {
#ifdef DEBUG
    if (xkbDebugFlags) {
       ErrorF("XkbDDXCompileKeymapByNames compiling keymap:\n");
       XkbWriteXKBKeymapForNames(stderr,names,NULL,xkb,want,need);
    }
#endif
	XkbWriteXKBKeymapForNames(out,names,NULL,xkb,want,need);
#ifndef WIN32
#ifdef __sun
        if (Pclose(out) != 0)
        {
            ErrorF("Warning: Spurious failure reported in Pclose() runnning 'xkbcomp'.\n");
        }
        if (1)
#else
	if (Pclose(out)==0)
#endif
#else
	if (fclose(out)==0 && System(buf) >= 0)
#endif
	{
#ifdef DEBUG_CMD
	    ErrorF("xkb executes: %s\n",buf);
	    ErrorF("xkbcomp input:\n");
	    XkbWriteXKBKeymapForNames(stderr,names,NULL,xkb,want,need);
	    ErrorF("end xkbcomp input\n");
#endif
	    if (nameRtrn) {
		strncpy(nameRtrn,keymap,nameRtrnLen);
		nameRtrn[nameRtrnLen-1]= '\0';
	    }
#if defined(Lynx) && defined(__i386__) && defined(NEED_POPEN_WORKAROUND)
	/* somehow popen/pclose is broken on LynxOS AT 2.3.0/2.4.0!
	 * the problem usually shows up with XF86Setup
	 * this hack waits at max 5 seconds after pclose() returns
	 * for the output of the xkbcomp output file.
	 * I didn't manage to get a patch in time for the 3.2 release
	 */
            {
		int i;
		char name[PATH_MAX];
#ifdef NXAGENT_SERVER
                if (_NXGetXkbCompPath(XkbBaseDirectory)!=NULL)
		    sprintf(name,"%s/%s%s.xkm", _NXGetXkbCompPath(XkbBaseDirectory)
			,xkm_output_dir, keymap);
#else
                if (XkbBaseDirectory!=NULL)
		    sprintf(name,"%s/%s%s.xkm", XkbBaseDirectory
			,xkm_output_dir, keymap);
#endif
		else
                    sprintf(name,"%s%s.xkm", xkm_output_dir, keymap);
		for (i = 0; i < 10; i++) {
	            if (access(name, 0) == 0) break;
		    usleep(500000);
		}
#ifdef DEBUG
		if (i) ErrorF(">>>> Waited %d times for %s\n", i, name);
#endif
	    }
#endif
            if (buf != NULL)
                xfree (buf);
	    return True;
	}
#ifdef DEBUG
	else
	    ErrorF("Error compiling keymap (%s)\n",keymap);
#endif
#ifdef WIN32
        /* remove the temporary file */
        unlink(tmpname);
#endif
    }
#ifdef DEBUG
    else {
#ifndef WIN32
	ErrorF("Could not invoke keymap compiler\n");
#else
	ErrorF("Could not open file %s\n", tmpname);
#endif
    }
#endif
    if (nameRtrn)
	nameRtrn[0]= '\0';
    if (buf != NULL)
        xfree (buf);
    return False;
}

FILE *
XkbDDXOpenConfigFile(char *mapName,char *fileNameRtrn,int fileNameRtrnLen)
{
char	buf[PATH_MAX],xkm_output_dir[PATH_MAX];
FILE *	file;

    buf[0]= '\0';
    if (mapName!=NULL) {
	OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
	if ((XkbBaseDirectory!=NULL)&&(xkm_output_dir[0]!='/')
#ifdef WIN32
                &&(!isalpha(xkm_output_dir[0]) || xkm_output_dir[1]!=':')
#endif
                ) {
	    if (strlen(XkbBaseDirectory)+strlen(xkm_output_dir)
		     +strlen(mapName)+6 <= PATH_MAX)
	    {
	        sprintf(buf,"%s/%s%s.xkm",XkbBaseDirectory,
					xkm_output_dir,mapName);
	    }
	}
	else if (strlen(xkm_output_dir)+strlen(mapName)+5 <= PATH_MAX)
	    sprintf(buf,"%s%s.xkm",xkm_output_dir,mapName);
	if (buf[0] != '\0')
	    file= fopen(buf,"rb");
	else file= NULL;
    }
    else file= NULL;
    if ((fileNameRtrn!=NULL)&&(fileNameRtrnLen>0)) {
	strncpy(fileNameRtrn,buf,fileNameRtrnLen);
	buf[fileNameRtrnLen-1]= '\0';
    }
    return file;
}
예제 #11
0
/*ARGSUSED*/
static Bool
DefaultParser(FILE *             file,
              XkbConfigFieldsPtr fields,
              XkbConfigFieldPtr  field,
              XkbDescPtr         xkb,
              XkbConfigRtrnPtr   rtrn)
{
    int tok;
    XkbCFScanResultRec val;
    char **str;
    int merge;
    unsigned long *ctrls, ctrls_mask;
    unsigned short *opts, opts_mask;
    int *pival, sign;
    int onoff;
    XkbConfigUnboundModPtr last;
    unsigned what;

    tok = XkbCFScan(file, &val, rtrn);
    str = NULL;
    onoff = 0;
    pival = NULL;
    switch (field->field_id) {
    case _XkbCF_RulesFile:      if (!str) str = &rtrn->rules_file;
    case _XkbCF_Model:          if (!str) str = &rtrn->model;
    case _XkbCF_Layout:         if (!str) str = &rtrn->layout;
    case _XkbCF_Variant:        if (!str) str = &rtrn->variant;
    case _XkbCF_Options:        if (!str) str = &rtrn->options;
    case _XkbCF_Keymap:         if (!str) str = &rtrn->keymap;
    case _XkbCF_Keycodes:       if (!str) str = &rtrn->keycodes;
    case _XkbCF_Geometry:       if (!str) str = &rtrn->geometry;
    case _XkbCF_PhysSymbols:    if (!str) str = &rtrn->phys_symbols;
    case _XkbCF_Symbols:        if (!str) str = &rtrn->symbols;
    case _XkbCF_Types:          if (!str) str = &rtrn->types;
    case _XkbCF_CompatMap:      if (!str) str = &rtrn->compat;
        if (tok != XkbCF_Equals) {
            rtrn->error = XkbCF_MissingEquals;
            goto BAILOUT;
        }
        tok = XkbCFScan(file, &val, rtrn);
        if ((tok != XkbCF_String) && (tok != XkbCF_Ident)) {
            rtrn->error = XkbCF_ExpectedString;
            return False;
        }
        tok = XkbCFScan(file, &val, rtrn);
        if ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) {
            rtrn->error = XkbCF_ExpectedEOS;
            return False;
        }
        if (*str != NULL)
            _XkbFree(*str);
        *str = _XkbDupString(val.str);
        break;
    case _XkbCF_InitialMods:
    case _XkbCF_IgnoreLockMods:
    case _XkbCF_InternalMods:
        what = XkbCF_InitialMods;
        if (field->field_id == _XkbCF_InitialMods)
            rtrn->defined |= (what = XkbCF_InitialMods);
        else if (field->field_id == _XkbCF_InternalMods)
            rtrn->defined |= (what = XkbCF_InternalMods);
        else if (field->field_id == _XkbCF_IgnoreLockMods)
            rtrn->defined |= (what = XkbCF_IgnoreLockMods);
        if (tok == XkbCF_Equals)
            merge = XkbCF_MergeSet;
        else if (tok == XkbCF_MinusEquals)
            merge = XkbCF_MergeRemove;
        else if (tok == XkbCF_PlusEquals)
            merge = XkbCF_MergeAdd;
        else {
            rtrn->error = XkbCF_MissingEquals;
            goto BAILOUT;
        }
        tok = XkbCFScan(file, &val, rtrn);
        if ((tok == XkbCF_EOL) || (tok == XkbCF_Semi) || (tok == XkbCF_EOF)) {
            rtrn->error = XkbCF_ExpectedModifier;
            return False;
        }
        last = NULL;
        while ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) {
            if ((tok != XkbCF_Ident) && (tok != XkbCF_String)) {
                rtrn->error = XkbCF_ExpectedModifier;
                return False;
            }
            last = XkbCFAddModByName(rtrn, what, val.str, merge, last);
            if (last == NULL)
                return False;
            if (merge == XkbCF_MergeSet)
                merge = XkbCF_MergeAdd;
            tok = XkbCFScan(file, &val, rtrn);
            if ((tok != XkbCF_EOL) && (tok != XkbCF_EOF) && (tok != XkbCF_Semi)) {
                if (tok != XkbCF_Plus) {
                    rtrn->error = XkbCF_ExpectedOperator;
                    return False;
                }
                tok = XkbCFScan(file, &val, rtrn);
            }
        }
        break;
    case _XkbCF_InitialCtrls:
        rtrn->defined |= XkbCF_InitialCtrls;
        ctrls = NULL;
        if (tok == XkbCF_PlusEquals)
            ctrls = &rtrn->initial_ctrls;
        else if (tok == XkbCF_MinusEquals)
            ctrls = &rtrn->initial_ctrls_clear;
        else if (tok == XkbCF_Equals) {
            ctrls = &rtrn->initial_ctrls;
            rtrn->replace_initial_ctrls = True;
            *ctrls = 0;
        }
        else {
            rtrn->error = XkbCF_MissingEquals;
            goto BAILOUT;
        }
        tok = XkbCFScan(file, &val, rtrn);
        if ((tok == XkbCF_EOL) || (tok == XkbCF_Semi) || (tok == XkbCF_EOF)) {
            rtrn->error = XkbCF_ExpectedControl;
            return False;
        }
        while ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) {
            if ((tok != XkbCF_Ident) && (tok != XkbCF_String)) {
                rtrn->error = XkbCF_ExpectedControl;
                return False;
            }
            if (!AddCtrlByName(rtrn, val.str, &ctrls_mask)) {
                return False;
            }
            *ctrls |= ctrls_mask;
            tok = XkbCFScan(file, &val, rtrn);
            if ((tok != XkbCF_EOL) && (tok != XkbCF_EOF) && (tok != XkbCF_Semi)) {
                if (tok != XkbCF_Plus) {
                    rtrn->error = XkbCF_ExpectedOperator;
                    return False;
                }
                tok = XkbCFScan(file, &val, rtrn);
            }
        }
        break;
    case _XkbCF_AccessXTimeoutCtrlsOn:
    case _XkbCF_AccessXTimeoutCtrlsOff:
        opts = NULL;
        if (tok == XkbCF_MinusEquals) {
            ctrls = &rtrn->axt_ctrls_ignore;
            opts = &rtrn->axt_opts_ignore;
        }
        else if ((tok == XkbCF_PlusEquals) || (tok == XkbCF_Equals)) {
            if (field->field_id == _XkbCF_AccessXTimeoutCtrlsOff) {
                ctrls = &rtrn->axt_ctrls_off;
                opts = &rtrn->axt_opts_off;
                if (tok == XkbCF_Equals)
                    rtrn->replace_axt_ctrls_off = True;
            }
            else {
                ctrls = &rtrn->axt_ctrls_on;
                opts = &rtrn->axt_opts_on;
                if (tok == XkbCF_Equals)
                    rtrn->replace_axt_ctrls_on = True;
            }
            *ctrls = 0;
        }
        else {
            rtrn->error = XkbCF_MissingEquals;
            goto BAILOUT;
        }
        tok = XkbCFScan(file, &val, rtrn);
        if ((tok == XkbCF_EOL) || (tok == XkbCF_Semi) || (tok == XkbCF_EOF)) {
            rtrn->error = XkbCF_ExpectedControl;
            return False;
        }
        while ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) {
            if ((tok != XkbCF_Ident) && (tok != XkbCF_String)) {
                rtrn->error = XkbCF_ExpectedControl;
                return False;
            }
            if (!AddCtrlByName(rtrn, val.str, &ctrls_mask)) {
                if (!AddAXTimeoutOptByName(rtrn, val.str, &opts_mask))
                    return False;
                *opts |= opts_mask;
                if (field->field_id == _XkbCF_AccessXTimeoutCtrlsOff) {
                    rtrn->defined |= XkbCF_AccessXTimeoutOptsOff;
                    if (rtrn->replace_axt_ctrls_off)
                        rtrn->replace_axt_opts_off = True;
                }
                else {
                    rtrn->defined |= XkbCF_AccessXTimeoutOptsOn;
                    if (rtrn->replace_axt_ctrls_on)
                        rtrn->replace_axt_opts_on = True;
                }
            }
            else
                *ctrls |= ctrls_mask;
            tok = XkbCFScan(file, &val, rtrn);
            if ((tok != XkbCF_EOL) && (tok != XkbCF_EOF) && (tok != XkbCF_Semi)) {
                if (tok != XkbCF_Plus) {
                    rtrn->error = XkbCF_ExpectedOperator;
                    return False;
                }
                tok = XkbCFScan(file, &val, rtrn);
            }
        }
        break;
    case _XkbCF_InitialFeedback:
        rtrn->defined |= XkbCF_InitialOpts;
        opts = NULL;
        if (tok == XkbCF_PlusEquals)
            opts = &rtrn->initial_opts;
        else if (tok == XkbCF_MinusEquals)
            opts = &rtrn->initial_opts_clear;
        else if (tok == XkbCF_Equals) {
            opts = &rtrn->initial_opts;
            rtrn->replace_initial_opts = True;
            *opts = 0;
        }
        else {
            rtrn->error = XkbCF_MissingEquals;
            goto BAILOUT;
        }
        tok = XkbCFScan(file, &val, rtrn);
        if ((tok == XkbCF_EOL) || (tok == XkbCF_Semi) || (tok == XkbCF_EOF)) {
            rtrn->error = XkbCF_ExpectedAXOption;
            return False;
        }
        while ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) {
            if ((tok != XkbCF_Ident) && (tok != XkbCF_String)) {
                rtrn->error = XkbCF_ExpectedAXOption;
                return False;
            }
            if (!AddAXTimeoutOptByName(rtrn, val.str, &opts_mask)) {
                return False;
            }
            *opts |= opts_mask;
            tok = XkbCFScan(file, &val, rtrn);
            if ((tok != XkbCF_EOL) && (tok != XkbCF_EOF) && (tok != XkbCF_Semi)) {
                if (tok != XkbCF_Plus) {
                    rtrn->error = XkbCF_ExpectedOperator;
                    return False;
                }
                tok = XkbCFScan(file, &val, rtrn);
            }
        }
        break;
    case _XkbCF_AccessXTimeoutOptsOff:
    case _XkbCF_AccessXTimeoutOptsOn:
        opts = NULL;
        if (tok == XkbCF_MinusEquals)
            opts = &rtrn->axt_opts_ignore;
        else if ((tok == XkbCF_PlusEquals) || (tok == XkbCF_Equals)) {
            if (field->field_id == _XkbCF_AccessXTimeoutOptsOff) {
                opts = &rtrn->axt_opts_off;
                if (tok == XkbCF_Equals)
                    rtrn->replace_axt_opts_off = True;
            }
            else {
                opts = &rtrn->axt_opts_on;
                if (tok == XkbCF_Equals)
                    rtrn->replace_axt_opts_on = True;
            }
            *opts = 0;
        }
        else {
            rtrn->error = XkbCF_MissingEquals;
            goto BAILOUT;
        }
        tok = XkbCFScan(file, &val, rtrn);
        if ((tok == XkbCF_EOL) || (tok == XkbCF_Semi) || (tok == XkbCF_EOF)) {
            rtrn->error = XkbCF_ExpectedControl;
            return False;
        }
        while ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) {
            if ((tok != XkbCF_Ident) && (tok != XkbCF_String)) {
                rtrn->error = XkbCF_ExpectedControl;
                return False;
            }
            if (!AddAXTimeoutOptByName(rtrn, val.str, &opts_mask))
                return False;
            *opts |= opts_mask;

            tok = XkbCFScan(file, &val, rtrn);
            if ((tok != XkbCF_EOL) && (tok != XkbCF_EOF) && (tok != XkbCF_Semi)) {
                if (tok != XkbCF_Plus) {
                    rtrn->error = XkbCF_ExpectedOperator;
                    return False;
                }
                tok = XkbCFScan(file, &val, rtrn);
            }
        }
        break;
    case _XkbCF_ClickVolume:
        if (!pival) {
            pival = &rtrn->click_volume;
            onoff = 100;
        }
    case _XkbCF_BellVolume:
        if (!pival) {
            pival = &rtrn->bell_volume;
            onoff = 100;
        }
    case _XkbCF_BellPitch:          if (!pival) pival = &rtrn->bell_pitch;
    case _XkbCF_BellDuration:       if (!pival) pival = &rtrn->bell_duration;
    case _XkbCF_RepeatDelay:        if (!pival) pival = &rtrn->repeat_delay;
    case _XkbCF_RepeatInterval:     if (!pival) pival = &rtrn->repeat_interval;
    case _XkbCF_SlowKeysDelay:      if (!pival) pival = &rtrn->slow_keys_delay;
    case _XkbCF_DebounceDelay:      if (!pival) pival = &rtrn->debounce_delay;
    case _XkbCF_MouseKeysDelay:     if (!pival) pival = &rtrn->mk_delay;
    case _XkbCF_MouseKeysInterval:  if (!pival) pival = &rtrn->mk_interval;
    case _XkbCF_MouseKeysTimeToMax: if (!pival) pival = &rtrn->mk_time_to_max;
    case _XkbCF_MouseKeysMaxSpeed:  if (!pival) pival = &rtrn->mk_max_speed;
    case _XkbCF_MouseKeysCurve:     if (!pival) pival = &rtrn->mk_curve;
    case _XkbCF_AccessXTimeout:     if (!pival) pival = &rtrn->ax_timeout;
        if (tok != XkbCF_Equals) {
            rtrn->error = XkbCF_MissingEquals;
            goto BAILOUT;
        }
        tok = XkbCFScan(file, &val, rtrn);
        if (tok == XkbCF_Minus && field->field_id == _XkbCF_MouseKeysCurve) {
            /* This can be a negative value */
            tok = XkbCFScan(file, &val, rtrn);
            sign = -1;
        }
        else
            sign = 1;
        if (tok != XkbCF_Integer) {
            Bool ok = False;

            if ((onoff) && (tok == XkbCF_Ident) && (val.str != NULL)) {
                if (_XkbStrCaseCmp(val.str, "on")) {
                    val.ival = onoff;
                    ok = True;
                }
                else if (_XkbStrCaseCmp(val.str, "off")) {
                    val.ival = 0;
                    ok = True;
                }
            }
            if (!ok) {
                rtrn->error = XkbCF_ExpectedInteger;
                goto BAILOUT;
            }
        }
        *pival = val.ival * sign;
        if (field->field_id == _XkbCF_AccessXTimeout)
            rtrn->defined |= XkbCF_AccessXTimeout;
        tok = XkbCFScan(file, &val, rtrn);
        if ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) {
            rtrn->error = XkbCF_ExpectedEOS;
            return False;
        }
        break;
    case _XkbCF_GroupsWrap:
        if (tok != XkbCF_Equals) {
            rtrn->error = XkbCF_MissingEquals;
            goto BAILOUT;
        }
        tok = XkbCFScan(file, &val, rtrn);
        if (tok == XkbCF_Ident) {
            if (_XkbStrCaseCmp(val.str, "wrap") == 0) {
                rtrn->groups_wrap = XkbSetGroupInfo(0, XkbWrapIntoRange, 0);
            }
            else if (_XkbStrCaseCmp(val.str, "clamp") == 0) {
                rtrn->groups_wrap = XkbSetGroupInfo(0, XkbClampIntoRange, 0);
            }
            else {
                rtrn->error = XkbCF_ExpectedOORGroupBehavior;
                return False;
            }
        }
        else if ((tok == XkbCF_Integer) && (XkbIsLegalGroup(val.ival - 1))) {
            rtrn->groups_wrap = XkbSetGroupInfo(0, XkbRedirectIntoRange,
                                                val.ival - 1);
        }
        else {
            rtrn->error = XkbCF_ExpectedOORGroupBehavior;
            return False;
        }
        rtrn->defined |= XkbCF_GroupsWrap;
        tok = XkbCFScan(file, &val, rtrn);
        if ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) {
            rtrn->error = XkbCF_ExpectedEOS;
            return False;
        }
        break;
    default:
        rtrn->error = XkbCF_ExpectedInteger;
        goto BAILOUT;

    }
    return True;
 BAILOUT:
    return False;
}
예제 #12
0
파일: xkbInit.c 프로젝트: narenas/nx-libs
Bool
XkbInitKeyboardDeviceStruct(
    DeviceIntPtr		dev,
    XkbComponentNamesPtr	names,
    KeySymsPtr                  pSymsIn,
    CARD8                       pModsIn[],
    void                        (*bellProc)(
        int /*percent*/,
        DeviceIntPtr /*device*/,
        pointer /*ctrl*/,
        int),
    void                        (*ctrlProc)(
        DeviceIntPtr /*device*/,
        KeybdCtrl * /*ctrl*/))
{
XkbFileInfo		finfo;
KeySymsRec		tmpSyms,*pSyms;
CARD8			tmpMods[XkbMaxLegalKeyCode+1],*pMods;
char			name[PATH_MAX],*rules;
Bool			ok=False;
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);

    /*
     * The strings are duplicated because it is not guaranteed that
     * they are allocated, or that they are allocated for every server
     * generation. Eventually they will be freed at the end of this
     * function.
     */
    if (names->keymap) names->keymap = _XkbDupString(names->keymap);
    if (names->keycodes) names->keycodes = _XkbDupString(names->keycodes);
    if (names->types) names->types = _XkbDupString(names->types);
    if (names->compat) names->compat = _XkbDupString(names->compat);
    if (names->geometry) names->geometry = _XkbDupString(names->geometry);
    if (names->symbols) names->symbols = _XkbDupString(names->symbols);

    if (defs.model && defs.layout && rules) {
	XkbComponentNamesRec	rNames;
	bzero(&rNames,sizeof(XkbComponentNamesRec));
	if (XkbDDXNamesFromRules(dev,rules,&defs,&rNames)) {
	    if (rNames.keymap) {
		if (!names->keymap)
		    names->keymap = rNames.keymap;
		else _XkbFree(rNames.keymap);
	    }
	    if (rNames.keycodes) {
		if (!names->keycodes)
		    names->keycodes =  rNames.keycodes;
		else
		    _XkbFree(rNames.keycodes);
	    }
	    if (rNames.types) {
		if (!names->types)
		    names->types = rNames.types;
		else  _XkbFree(rNames.types);
	    }
	    if (rNames.compat) {
		if (!names->compat) 
		    names->compat =  rNames.compat;
		else  _XkbFree(rNames.compat);
	    }
	    if (rNames.symbols) {
		if (!names->symbols)
		    names->symbols =  rNames.symbols;
		else _XkbFree(rNames.symbols);
	    }
	    if (rNames.geometry) {
		if (!names->geometry)
		    names->geometry = rNames.geometry;
		else _XkbFree(rNames.geometry);
	    }
	    XkbSetRulesUsed(&defs);
	}
    }
    if (cfgNames.keymap){
	if (names->keymap) _XkbFree(names->keymap);
	names->keymap= cfgNames.keymap;
    }
    if (cfgNames.keycodes){
	if (names->keycodes) _XkbFree(names->keycodes);	
	names->keycodes= cfgNames.keycodes;
    }
    if (cfgNames.types) {
	if (names->types) _XkbFree(names->types);	
	names->types= cfgNames.types;
    }
    if (cfgNames.compat) {
	if (names->compat) _XkbFree(names->compat);	
	names->compat= cfgNames.compat;
    }
    if (cfgNames.symbols){
	if (names->symbols) _XkbFree(names->symbols);	
	names->symbols= cfgNames.symbols;
    }
    if (cfgNames.geometry) {
	if (names->geometry) _XkbFree(names->geometry);
	names->geometry= cfgNames.geometry;
    }

    if (names->keymap) {
        XkbComponentNamesRec	tmpNames;
	bzero(&tmpNames,sizeof(XkbComponentNamesRec));
	tmpNames.keymap = names->keymap;
        ok = (Bool) XkbDDXLoadKeymapByNames(dev,&tmpNames,XkmAllIndicesMask,0,
					    &finfo,name,PATH_MAX);
    }
    if (!(ok && (finfo.xkb!=NULL)))
        ok = (Bool) XkbDDXLoadKeymapByNames(dev,names,XkmAllIndicesMask,0,
					    &finfo,name,PATH_MAX);

    if (ok && (finfo.xkb!=NULL)) {
	XkbDescPtr	xkb;
	KeyCode		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 {
	LogMessage(X_WARNING, "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;
    }

    if (names->keymap) _XkbFree(names->keymap);
    names->keymap = NULL;
    if (names->keycodes) _XkbFree(names->keycodes);
    names->keycodes = NULL;
    if (names->types) _XkbFree(names->types);
    names->types = NULL;
    if (names->compat) _XkbFree(names->compat);
    names->compat = NULL;
    if (names->geometry) _XkbFree(names->geometry);
    names->geometry = NULL;
    if (names->symbols) _XkbFree(names->symbols);
    names->symbols = NULL;

    return ok;
}