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; }
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; }
/*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; }
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; }
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); } } }
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; }
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; }
/*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; }
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; }