static 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; }
static 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]; const char *emptystring = ""; char *xkbbasedirflag = NULL; const char *xkbbindir = emptystring; const char *xkbbindirsep = emptystring; #ifdef WIN32 /* 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 tmpname[PATH_MAX]; const char *xkmfile = tmpname; #else const char *xkmfile = "-"; #endif snprintf(keymap, sizeof(keymap), "server-%s", display); OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir)); #ifdef WIN32 strcpy(tmpname, Win32TempDir()); strcat(tmpname, "\\xkb_XXXXXX"); (void) mktemp(tmpname); #endif if (XkbBaseDirectory != NULL) { xkbbasedirflag = Xprintf("\"-R%s\"", XkbBaseDirectory); } if (XkbBinDirectory != NULL) { int ld = strlen(XkbBinDirectory); int lps = strlen(PATHSEPARATOR); xkbbindir = XkbBinDirectory; if ((ld >= lps) && (strcmp(xkbbindir + ld - lps, PATHSEPARATOR) != 0)) { xkbbindirsep = PATHSEPARATOR; } } buf = Xprintf("\"%s%sxkbcomp\" -w %d %s -xkm \"%s\" " "-em1 %s -emp %s -eml %s \"%s%s.xkm\"", xkbbindir, xkbbindirsep, ( (xkbDebugFlags < 2) ? 1 : ((xkbDebugFlags > 10) ? 10 : (int)xkbDebugFlags) ), xkbbasedirflag ? xkbbasedirflag : "", xkmfile, PRE_ERROR_MSG, ERROR_PREFIX, POST_ERROR_MSG1, xkm_output_dir, keymap); free(xkbbasedirflag); if (!buf) { LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp: not enough memory\n"); return FALSE; } #ifndef WIN32 out= Popen(buf,"w"); #else out= fopen(tmpname, "w"); #endif if (out!=NULL) { #ifdef DEBUG if (xkbDebugFlags) { ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n"); XkbWriteXKBKeymapForNames(stderr,names,xkb,want,need); } #endif XkbWriteXKBKeymapForNames(out,names,xkb,want,need); #ifndef WIN32 if (Pclose(out)==0) #else if (fclose(out)==0 && System(buf) >= 0) #endif { if (xkbDebugFlags) DebugF("[xkb] xkb executes: %s\n",buf); if (nameRtrn) { strncpy(nameRtrn,keymap,nameRtrnLen); nameRtrn[nameRtrnLen-1]= '\0'; } if (buf != NULL) free(buf); return TRUE; } else LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap); #ifdef WIN32 /* remove the temporary file */ unlink(tmpname); #endif } else { #ifndef WIN32 LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp\n"); #else LogMessage(X_ERROR, "Could not open file %s\n", tmpname); #endif } if (nameRtrn) nameRtrn[0]= '\0'; if (buf != NULL) free(buf); return FALSE; }
/** * Start xkbcomp, let the callback write into xkbcomp's stdin. When done, * return a strdup'd copy of the file name we've written to. */ static char * RunXkbComp(xkbcomp_buffer_callback callback, void *userdata) { FILE *out; char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX]; const char *emptystring = ""; char *xkbbasedirflag = NULL; const char *xkbbindir = emptystring; const char *xkbbindirsep = emptystring; #ifdef WIN32 /* 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 tmpname[PATH_MAX]; const char *xkmfile = tmpname; #else const char *xkmfile = "-"; #endif snprintf(keymap, sizeof(keymap), "server-%s", display); OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir)); #ifdef WIN32 strcpy(tmpname, Win32TempDir()); strcat(tmpname, "\\xkb_XXXXXX"); (void) mktemp(tmpname); #endif if (XkbBaseDirectory != NULL) { if (asprintf(&xkbbasedirflag, "\"-R%s\"", XkbBaseDirectory) == -1) xkbbasedirflag = NULL; } if (XkbBinDirectory != NULL) { int ld = strlen(XkbBinDirectory); int lps = strlen(PATHSEPARATOR); xkbbindir = XkbBinDirectory; if ((ld >= lps) && (strcmp(xkbbindir + ld - lps, PATHSEPARATOR) != 0)) { xkbbindirsep = PATHSEPARATOR; } } if (asprintf(&buf, "\"%s%sxkbcomp\" -w %d %s -xkm \"%s\" " "-em1 %s -emp %s -eml %s \"%s%s.xkm\"", xkbbindir, xkbbindirsep, ((xkbDebugFlags < 2) ? 1 : ((xkbDebugFlags > 10) ? 10 : (int) xkbDebugFlags)), xkbbasedirflag ? xkbbasedirflag : "", xkmfile, PRE_ERROR_MSG, ERROR_PREFIX, POST_ERROR_MSG1, xkm_output_dir, keymap) == -1) buf = NULL; free(xkbbasedirflag); if (!buf) { LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp: not enough memory\n"); return NULL; } #ifndef WIN32 out = Popen(buf, "w"); #else out = fopen(tmpname, "w"); #endif if (out != NULL) { /* Now write to xkbcomp */ (*callback)(out, userdata); #ifndef WIN32 if (Pclose(out) == 0) #else if (fclose(out) == 0 && System(buf) >= 0) #endif { if (xkbDebugFlags) DebugF("[xkb] xkb executes: %s\n", buf); free(buf); #ifdef WIN32 unlink(tmpname); #endif return xnfstrdup(keymap); } else { LogMessage(X_ERROR, "Error compiling keymap (%s) executing '%s'\n", keymap, buf); } #ifdef WIN32 /* remove the temporary file */ unlink(tmpname); #endif } else { #ifndef WIN32 LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp\n"); #else LogMessage(X_ERROR, "Could not open file %s\n", tmpname); #endif } free(buf); return NULL; }
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; }
static 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 if (XkbBaseDirectory!=NULL) { #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 char *xkbbasedir = XkbBaseDirectory; char *xkbbindir = XkbBinDirectory; 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); } #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,xkb,want,need); } #endif XkbWriteXKBKeymapForNames(out,names,xkb,want,need); #ifndef WIN32 if (Pclose(out)==0) #else if (fclose(out)==0 && System(buf) >= 0) #endif { if (xkbDebugFlags) DebugF("xkb executes: %s\n",buf); if (nameRtrn) { strncpy(nameRtrn,keymap,nameRtrnLen); nameRtrn[nameRtrnLen-1]= '\0'; } if (buf != NULL) xfree (buf); return True; } else LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap); #ifdef WIN32 /* remove the temporary file */ unlink(tmpname); #endif } else { #ifndef WIN32 LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp\n"); #else LogMessage(X_ERROR, "Could not open file %s\n", tmpname); #endif } if (nameRtrn) nameRtrn[0]= '\0'; if (buf != NULL) xfree (buf); return False; }