On Wed, Dec 16, 2009 at 11:00 PM, Peter Hutterer <[email protected]> wrote: > On Wed, Dec 16, 2009 at 10:38:05PM -0800, Dan Nicholson wrote: >> Currently there is a single file, xorg.conf, for configuring the server. >> This works fine most of the time, but it becomes a problem when packages >> or system services need to adjust the configuration. Instead, allow >> multiple configuration files to live in a directory. Typically this will >> be /etc/X11/xorg.conf.d. >> >> Files with a suffix of .conf will be read and added to the server >> configuration after xorg.conf. The server won't fall back to using the >> auto configuration unless there is no config file and there are no files >> in the config directory. >> >> Right now this uses a simpler search template than the config file >> search path by not using the command line or environment variable >> parameters. The matching code was refactored a bit to make this more >> coherent. >> >> Signed-off-by: Dan Nicholson <[email protected]> >> --- >> This should address Peter's review. Someone with a better knowledge of >> the API should look through xf86Parser.h, though. I doubt most of those >> functions are intended to be used externally. >> >> configure.ac | 2 + >> cpprules.in | 3 +- >> hw/xfree86/common/xf86Config.c | 37 +++-- >> hw/xfree86/doc/man/xorg.conf.man.pre | 53 +++++-- >> hw/xfree86/parser/scan.c | 310 >> ++++++++++++++++++++++++--------- >> hw/xfree86/parser/xf86Parser.h | 12 +- >> hw/xwin/winconfig.c | 43 ++++- >> include/xorg-config.h.in | 3 + >> 8 files changed, 341 insertions(+), 122 deletions(-) >> >> diff --git a/configure.ac b/configure.ac >> index 6cdef15..950dee0 100644 >> --- a/configure.ac >> +++ b/configure.ac >> @@ -1720,6 +1720,7 @@ if test "x$XORG" = xyes; then >> >> dnl these only go in xorg-config.h >> XF86CONFIGFILE="xorg.conf" >> + XF86CONFIGDIR="xorg.conf.d" >> CONFIGFILE="$sysconfdir/$XF86CONFIGFILE" >> LOGPREFIX="$logdir/Xorg." >> AC_DEFINE(XORG_SERVER, 1, [Building Xorg server]) >> @@ -1732,6 +1733,7 @@ if test "x$XORG" = xyes; then >> AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server]) >> AC_DEFINE_DIR(__XCONFIGFILE__, XF86CONFIGFILE, [Name of configuration >> file]) >> AC_DEFINE_DIR(XF86CONFIGFILE, XF86CONFIGFILE, [Name of configuration >> file]) >> + AC_DEFINE_DIR(__XCONFIGDIR__, XF86CONFIGDIR, [Name of configuration >> directory]) >> AC_DEFINE_DIR(DEFAULT_MODULE_PATH, moduledir, [Default module search >> path]) >> AC_DEFINE_DIR(DEFAULT_LIBRARY_PATH, libdir, [Default library install >> path]) >> AC_DEFINE_DIR(DEFAULT_LOGPREFIX, LOGPREFIX, [Default log location]) >> diff --git a/cpprules.in b/cpprules.in >> index 7fcb9bd..7219e36 100644 >> --- a/cpprules.in >> +++ b/cpprules.in >> @@ -36,7 +36,8 @@ MANDEFS = \ >> -D__adminmansuffix__=$(ADMIN_MAN_SUFFIX) \ >> -D__mandir__=$(mandir) \ >> -D__projectroot__=$(prefix) \ >> - -D__xconfigfile__=$(__XCONFIGFILE__) -D__xconfigdir__=$(XCONFIGDIR) \ >> + -D__xconfigfile__=$(__XCONFIGFILE__) \ >> + -D__xconfigdir__=$(__XCONFIGDIR__) \ >> -D__xkbdir__=$(XKB_BASE_DIRECTORY) \ >> -D__modulepath__="$(DEFAULT_MODULE_PATH)" \ >> -D__xlogfile__=$(XLOGFILE) -D__xservername__=$(XSERVERNAME) >> diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c >> index e1283f9..df70950 100644 >> --- a/hw/xfree86/common/xf86Config.c >> +++ b/hw/xfree86/common/xf86Config.c >> @@ -102,6 +102,13 @@ extern DeviceAssocRec mouse_assoc; >> "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ >> "%P/lib/X11/%X" >> #endif >> +#ifndef DIR_CONFIGPATH >> +#define DIR_CONFIGPATH "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \ >> + "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \ >> + "%P/etc/X11/%X," \ >> + "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ >> + "%P/lib/X11/%X" >> +#endif >> #ifndef PROJECTROOT >> #define PROJECTROOT "/usr/X11R6" >> #endif >> @@ -2437,7 +2444,7 @@ checkInput(serverLayoutPtr layout, Bool >> implicit_layout) { >> ConfigStatus >> xf86HandleConfigFile(Bool autoconfig) >> { >> - const char *filename; >> + XF86ConfPathsPtr paths; >> char *searchpath; >> MessageType from = X_DEFAULT; >> char *scanptr; >> @@ -2453,18 +2460,26 @@ xf86HandleConfigFile(Bool autoconfig) >> if (xf86ConfigFile) >> from = X_CMDLINE; >> >> - filename = xf86openConfigFile(searchpath, xf86ConfigFile, PROJECTROOT); >> - if (filename) { >> - xf86MsgVerb(from, 0, "Using config file: \"%s\"\n", filename); >> - xf86ConfigFile = xnfstrdup(filename); >> - } else { >> - if (xf86ConfigFile) >> - xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n", >> - xf86ConfigFile); >> + paths = xf86openConfigFile(searchpath, DIR_CONFIGPATH, >> + xf86ConfigFile, PROJECTROOT); >> + if (paths && (paths->file || paths->dir)) { >> + if (paths->file) { >> + xf86MsgVerb(from, 0, "Using config file: \"%s\"\n", >> + paths->file); >> + xf86ConfigFile = xnfstrdup(paths->file); >> + } else { >> + if (xf86ConfigFile) >> + xf86Msg(X_ERROR, >> + "Unable to locate/open config file: \"%s\"\n", >> + xf86ConfigFile); >> + } >> + if (paths && paths->dir) >> + xf86MsgVerb(X_DEFAULT, 0, "Using config directory: \"%s\"\n", >> + paths->dir); >> + } else >> return CONFIG_NOFILE; >> - } >> } >> - >> + >> if ((xf86configptr = xf86readConfigFile ()) == NULL) { >> xf86Msg(X_ERROR, "Problem parsing the config file\n"); >> return CONFIG_PARSE_ERROR; >> diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre >> b/hw/xfree86/doc/man/xorg.conf.man.pre >> index ace041c..60ce512 100644 >> --- a/hw/xfree86/doc/man/xorg.conf.man.pre >> +++ b/hw/xfree86/doc/man/xorg.conf.man.pre >> @@ -2,27 +2,35 @@ >> .ds q \N'34' >> .TH __xconfigfile__ __filemansuffix__ __vendorversion__ >> .SH NAME >> -__xconfigfile__ \- configuration File for __xservername__ X server >> +__xconfigfile__ and __xconfigdir__ \- configuration files for >> +__xservername__ X server >> .SH INTRODUCTION >> .B __xservername__ >> supports several mechanisms for supplying/obtaining configuration and >> run-time parameters: command line options, environment variables, the >> -__xconfigfile__ configuration file, auto-detection, and fallback defaults. >> -When the same information is supplied in more than one way, the highest >> -precedence mechanism is used. The list of mechanisms is ordered from >> -highest precedence to lowest. Note that not all parameters can be >> -supplied via all methods. The available command line options and >> -environment variables (and some defaults) are described in the >> Xserver(__appmansuffix__) >> -and __xservername__(__appmansuffix__) manual pages. Most configuration >> file parameters, with >> -their defaults, are described below. Driver and module specific >> -configuration parameters are described in the relevant driver or module >> -manual page. >> +__xconfigfile__ and __xconfigdir__ configuration files, auto-detection, >> +and fallback defaults. When the same information is supplied in more >> +than one way, the highest precedence mechanism is used. The list of >> +mechanisms is ordered from highest precedence to lowest. Note that not >> +all parameters can be supplied via all methods. The available command >> +line options and environment variables (and some defaults) are >> +described in the Xserver(__appmansuffix__) and >> +__xservername__(__appmansuffix__) manual pages. Most configuration file >> +parameters, with their defaults, are described below. Driver and module >> +specific configuration parameters are described in the relevant driver >> +or module manual page. >> .SH DESCRIPTION >> .B __xservername__ >> uses a configuration file called >> .I __xconfigfile__ >> +and files ending in the suffix >> +.I .conf >> +from the directory >> +.I __xconfigdir__ >> for its initial setup. >> -This configuration file is searched for in the following places when the >> +The >> +.I __xconfigfile__ >> +configuration file is searched for in the following places when the >> server is started as a normal user: >> .PP >> .RS 4 >> @@ -93,9 +101,28 @@ directory), and >> is the machine's hostname as reported by >> .BR gethostname (__libmansuffix__). >> .PP >> +Additional configuration files are searched for in the following >> +directories: >> +.PP >> +.RS 4 >> +.nf >> +.I /etc/X11/__xconfigdir__\-4 >> +.I /etc/X11/__xconfigdir__ >> +.I /etc/__xconfigdir__ >> +.IR __projectroot__/etc/X11/__xconfigdir__. <hostname> >> +.I __projectroot__/etc/X11/__xconfigdir__\-4 >> +.I __projectroot__/etc/X11/__xconfigdir__ >> +.IR __projectroot__/lib/X11/__xconfigdir__. <hostname> >> +.I __projectroot__/lib/X11/__xconfigdir__\-4 >> +.I __projectroot__/lib/X11/__xconfigdir__ >> +.fi >> +.RE >> +.PP >> The >> .I __xconfigfile__ >> -file is composed of a number of sections which may be present in any order, >> +and >> +.I __xconfigdir__ >> +files are composed of a number of sections which may be present in any >> order, >> or omitted to use default configuration values. >> Each section has the form: >> .PP >> diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c >> index d2e8b6d..02db351 100644 >> --- a/hw/xfree86/parser/scan.c >> +++ b/hw/xfree86/parser/scan.c >> @@ -62,8 +62,11 @@ >> #include <stdio.h> >> #include <stdlib.h> >> #include <string.h> >> +#include <sys/types.h> >> +#include <dirent.h> >> #include <unistd.h> >> #include <stdarg.h> >> +#include <X11/Xdefs.h> >> #include <X11/Xfuncproto.h> >> >> #if defined(_POSIX_SOURCE) >> @@ -90,17 +93,23 @@ >> #include "xf86tokens.h" >> >> #define CONFIG_BUF_LEN 1024 >> +#define CONFIG_MAX_FILES 64 >> >> static int StringToToken (char *, xf86ConfigSymTabRec *); >> >> -static FILE *configFile = NULL; >> +static struct { >> + FILE *file; >> + char *path; >> +} configFiles[CONFIG_MAX_FILES]; >> static const char **builtinConfig = NULL; >> static int builtinIndex = 0; >> static int configPos = 0; /* current readers position */ >> static int configLineNo = 0; /* linenumber */ >> static char *configBuf, *configRBuf; /* buffer for lines */ >> -static char *configPath; /* path to config file */ >> +static XF86ConfPathsRec configPaths = { NULL }; /* paths to >> configuration */ >> static char *configSection = NULL; /* name of current section being >> parsed */ >> +static int numFiles = 0; /* number of config files */ >> +static int curFileIndex = 0; /* index of current config file */ >> static int pushToken = LOCK_TOKEN; >> static int eol_seen = 0; /* private state to handle comments */ >> LexRec val; >> @@ -155,7 +164,7 @@ xf86strToUL (char *str) >> /* >> * xf86getNextLine -- >> * >> - * read from the configFile FILE stream until we encounter a new >> + * read from the configFiles FILE stream until we encounter a new >> * line; this is effectively just a big wrapper for fgets(3). >> * >> * xf86getToken() assumes that we will read up to the next >> @@ -213,9 +222,18 @@ xf86getNextLine(void) >> /* read in another block of chars */ >> >> do { >> - ret = fgets(configBuf + pos, configBufLen - pos - 1, >> configFile); >> + ret = fgets(configBuf + pos, configBufLen - pos - 1, >> + configFiles[curFileIndex].file); >> >> - if (!ret) break; >> + if (!ret) { >> + /* stop if there are no more files */ >> + if (++curFileIndex >= numFiles) { >> + curFileIndex = 0; >> + break; >> + } >> + configLineNo = 0; >> + continue; >> + } >> >> /* search for EOL in the new block of chars */ >> >> @@ -306,7 +324,7 @@ again: >> if (!c) >> { >> char *ret; >> - if (configFile) >> + if (numFiles > 0) >> ret = xf86getNextLine(); >> else { >> if (builtinConfig[builtinIndex] == NULL) >> @@ -575,6 +593,12 @@ xf86pathIsSafe(const char *path) >> #ifndef XCONFIGFILE >> #define XCONFIGFILE "xorg.conf" >> #endif >> +#ifndef XCONFIGDIR >> +#define XCONFIGDIR "xorg.conf.d" >> +#endif >> +#ifndef XCONFIGSUFFIX >> +#define XCONFIGSUFFIX ".conf" >> +#endif >> #ifndef PROJECTROOT >> #define PROJECTROOT "/usr/X11R6" >> #endif >> @@ -616,7 +640,8 @@ xf86pathIsSafe(const char *path) >> >> static char * >> DoSubstitution(const char *template, const char *cmdline, const char >> *projroot, >> - int *cmdlineUsed, int *envUsed, char >> *XConfigFile) >> + int *cmdlineUsed, int *envUsed, >> + const char *XConfigFile) >> { >> char *result; >> int i, l; >> @@ -745,20 +770,154 @@ DoSubstitution(const char *template, const char >> *cmdline, const char *projroot, >> return result; >> } >> >> -/* >> +/* >> + * Given some searching parameters, locate and open the xorg config file. >> + */ >> +static char * >> +OpenConfigFile(const char *path, const char *cmdline, const char *projroot, >> + const char *confname) >> +{ >> + char *filepath = NULL; >> + char *pathcopy; >> + const char *template; >> + int cmdlineUsed = 0; >> + FILE *file = NULL; >> + >> + pathcopy = strdup(path); >> + for (template = strtok(pathcopy, ","); template && !file; >> + template = strtok(NULL, ",")) { >> + filepath = DoSubstitution(template, cmdline, projroot, >> + &cmdlineUsed, NULL, confname); >> + if (!filepath) >> + continue; >> + if (cmdline && !cmdlineUsed) { >> + free(filepath); >> + filepath = NULL; >> + continue; >> + } >> + file = fopen(filepath, "r"); >> + if (!file) { >> + free(filepath); >> + filepath = NULL; >> + } >> + } >> + >> + if (file) { >> + configFiles[numFiles].file = file; >> + configFiles[numFiles].path = strdup(filepath); >> + numFiles++; >> + } >> + return filepath; >> +} >> + >> +/* >> + * Match non-hidden files in the xorg config directory with a .conf >> + * suffix. This filter is passed to scandir(3). >> + */ >> +static int >> +ConfigFilter(const struct dirent *de) >> +{ >> + const char *name = de->d_name; >> + size_t len = strlen(name); >> + size_t suflen = strlen(XCONFIGSUFFIX); >> + >> + if (!name || name[0] == '.' || len <= suflen) >> + return 0; >> + if (strcmp(&name[len-suflen], XCONFIGSUFFIX) != 0) >> + return 0; >> + return 1; >> +} >> + >> +static Bool >> +AddConfigDirFiles(const char *dirpath, struct dirent **list, int num) >> +{ >> + int i; >> + Bool openedFile = FALSE; >> + Bool warnOnce = FALSE; >> + >> + for (i = 0; i < num; i++) { >> + char *path; >> + FILE *file; >> + >> + if (numFiles >= CONFIG_MAX_FILES) { >> + if (!warnOnce) { >> + ErrorF("Maximum number of configuration " >> + "files opened\n"); >> + warnOnce = TRUE; >> + } >> + free(list[i]); >> + continue; >> + } >> + >> + path = malloc(PATH_MAX + 1); >> + snprintf(path, PATH_MAX + 1, "%s/%s", dirpath, >> + list[i]->d_name); >> + free(list[i]); >> + file = fopen(path, "r"); >> + if (!file) { >> + free(path); >> + continue; >> + } >> + openedFile = TRUE; >> + >> + configFiles[numFiles].file = file; >> + configFiles[numFiles].path = path; >> + numFiles++; >> + } >> + >> + return openedFile; >> +} >> + >> +/* >> + * Given some searching parameters, locate and open the xorg config >> + * directory. The directory does not need to contain config files. >> + */ >> +static char * >> +OpenConfigDir(const char *path, const char *projroot, const char *confname) >> +{ >> + char *dirpath, *pathcopy; >> + const char *template; >> + Bool found = FALSE; >> + >> + pathcopy = strdup(path); >> + for (template = strtok(pathcopy, ","); template && !found; >> + template = strtok(NULL, ",")) { >> + struct dirent **list = NULL; >> + int num; >> + >> + if (!(dirpath = DoSubstitution(template, NULL, projroot, >> + NULL, NULL, confname))) >> + continue; >> + /* match files named *.conf */ >> + num = scandir(dirpath, &list, ConfigFilter, alphasort); >> + found = AddConfigDirFiles(dirpath, list, num); >> + if (!found) { >> + free(dirpath); >> + dirpath = NULL; >> + if (list) >> + free(list); >> + } >> + } >> + >> + return dirpath; >> +} >> + >> +/* >> * xf86openConfigFile -- >> * >> - * This function take a config file search path (optional), a command-line >> - * specified file name (optional) and the ProjectRoot path (optional) and >> - * locates and opens a config file based on that information. If a >> + * This function take a config file search path (optional), a config >> + * directory search path (optional), command-line specified file name >> + * (optional) and the ProjectRoot path (optional) and locates and opens >> + * a config file and config directory based on that information. If a >> * command-line file name is specified, then this function fails if none >> * of the located files. >> * >> - * The return value is a pointer to the actual name of the file that was >> - * opened. When no file is found, the return value is NULL. >> + * The return value is a pointer to a structure with the the actual name of >> + * the file and directory that were opened. The entries will be NULL if >> + * they are not found. >> * >> * The escape sequences allowed in the search path are defined above. >> - * >> + * >> */ >> >> #ifndef DEFAULT_CONF_PATH >> @@ -776,108 +935,85 @@ DoSubstitution(const char *template, const char >> *cmdline, const char *projroot, >> "%P/lib/X11/%X-%M," \ >> "%P/lib/X11/%X" >> #endif >> +#ifndef DEFAULT_DIR_PATH >> +#define DEFAULT_DIR_PATH "/etc/X11/%S," \ >> + "%P/etc/X11/%S," \ >> + "/etc/X11/%X-%M," \ >> + "/etc/X11/%X," \ >> + "/etc/%X," \ >> + "%P/etc/X11/%X.%H," \ >> + "%P/etc/X11/%X-%M," \ >> + "%P/etc/X11/%X," \ >> + "%P/lib/X11/%X.%H," \ >> + "%P/lib/X11/%X-%M," \ >> + "%P/lib/X11/%X" >> +#endif >> >> -const char * >> -xf86openConfigFile(const char *path, const char *cmdline, const char >> *projroot) >> +const XF86ConfPathsPtr >> +xf86openConfigFile(const char *filepath, const char *dirpath, >> + const char *cmdline, const char *projroot) >> { >> - char *pathcopy; >> - const char *template; >> - int cmdlineUsed = 0; >> - >> - configFile = NULL; >> + memset(configFiles, 0, sizeof(configFiles)); >> + numFiles = 0; >> + curFileIndex = 0; >> configPos = 0; /* current readers position */ >> configLineNo = 0; /* linenumber */ >> pushToken = LOCK_TOKEN; >> >> - if (!path || !path[0]) >> - path = DEFAULT_CONF_PATH; >> - pathcopy = malloc(strlen(path) + 1); >> - strcpy(pathcopy, path); >> + if (!filepath || !filepath[0]) >> + filepath = DEFAULT_CONF_PATH; >> + if (!dirpath || !dirpath[0]) >> + dirpath = DEFAULT_DIR_PATH; >> if (!projroot || !projroot[0]) >> projroot = PROJECTROOT; >> >> - template = strtok(pathcopy, ","); >> - >> - /* First, search for a config file. */ >> - while (template && !configFile) { >> - if ((configPath = DoSubstitution(template, cmdline, projroot, >> - &cmdlineUsed, NULL, >> - XCONFIGFILE))) { >> - if ((configFile = fopen(configPath, "r")) != 0) { >> - if (cmdline && !cmdlineUsed) { >> - fclose(configFile); >> - configFile = NULL; >> - } >> - } >> - } >> - if (configPath && !configFile) { >> - free(configPath); >> - configPath = NULL; >> - } >> - template = strtok(NULL, ","); >> - } >> - >> - /* Then search for fallback */ >> - if (!configFile) { >> - strcpy(pathcopy, path); >> - template = strtok(pathcopy, ","); >> - >> - while (template && !configFile) { >> - if ((configPath = DoSubstitution(template, cmdline, projroot, >> - &cmdlineUsed, NULL, >> - XFREE86CFGFILE))) { >> - if ((configFile = fopen(configPath, "r")) != 0) { >> - if (cmdline && !cmdlineUsed) { >> - fclose(configFile); >> - configFile = NULL; >> - } >> - } >> - } >> - if (configPath && !configFile) { >> - free(configPath); >> - configPath = NULL; >> - } >> - template = strtok(NULL, ","); >> - } >> - } >> - >> - free(pathcopy); >> - if (!configFile) { >> - >> - return NULL; >> - } >> + /* Search for a config file or a fallback */ >> + configPaths.file = OpenConfigFile(filepath, cmdline, projroot, >> + XCONFIGFILE); >> + if (!configPaths.file) >> + configPaths.file = OpenConfigFile(filepath, cmdline, projroot, >> + XFREE86CFGFILE); >> + /* Search for the multiconf directory */ >> + configPaths.dir = OpenConfigDir(dirpath, projroot, XCONFIGDIR); >> >> configBuf = malloc (CONFIG_BUF_LEN); >> configRBuf = malloc (CONFIG_BUF_LEN); >> configBuf[0] = '\0'; /* sanity ... */ >> >> - return configPath; >> + return &configPaths; >> } >> >> void >> xf86closeConfigFile (void) >> { >> - free (configPath); >> - configPath = NULL; >> + int i; >> + >> + free (configPaths.file); >> + configPaths.file = NULL; >> + free (configPaths.dir); >> + configPaths.dir = NULL; >> free (configRBuf); >> configRBuf = NULL; >> free (configBuf); >> configBuf = NULL; >> >> - if (configFile) { >> - fclose (configFile); >> - configFile = NULL; >> - } else { >> + if (numFiles == 0) { >> builtinConfig = NULL; >> builtinIndex = 0; >> } >> + for (i = 0; i < numFiles; i++) { >> + fclose(configFiles[i].file); >> + configFiles[i].file = NULL; >> + free(configFiles[i].path); >> + configFiles[i].path = NULL; >> + } >> + numFiles = 0; >> } >> >> void >> xf86setBuiltinConfig(const char *config[]) >> { >> builtinConfig = config; >> - configPath = strdup("<builtin configuration>"); >> configBuf = malloc (CONFIG_BUF_LEN); >> configRBuf = malloc (CONFIG_BUF_LEN); >> configBuf[0] = '\0'; /* sanity ... */ >> @@ -888,9 +1024,11 @@ void >> xf86parseError (char *format,...) >> { >> va_list ap; >> + char *filename = numFiles ? configFiles[curFileIndex].path : >> + "<builtin configuration>"; >> >> ErrorF ("Parse error on line %d of section %s in file %s\n\t", >> - configLineNo, configSection, configPath); >> + configLineNo, configSection, filename); >> va_start (ap, format); >> VErrorF (format, ap); >> va_end (ap); >> @@ -902,8 +1040,10 @@ void >> xf86validationError (char *format,...) >> { >> va_list ap; >> + char *filename = numFiles ? configFiles[curFileIndex].path : >> + "<builtin configuration>"; >> >> - ErrorF ("Data incomplete in file %s\n\t", configPath); >> + ErrorF ("Data incomplete in file %s\n\t", filename); >> va_start (ap, format); >> VErrorF (format, ap); >> va_end (ap); >> diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h >> index 6030800..d00c0ea 100644 >> --- a/hw/xfree86/parser/xf86Parser.h >> +++ b/hw/xfree86/parser/xf86Parser.h >> @@ -453,11 +453,19 @@ typedef struct >> } >> xf86ConfigSymTabRec, *xf86ConfigSymTabPtr; >> >> +typedef struct >> +{ >> + char *file; /* config file */ >> + char *dir; /* multiconf directory */ >> +} >> +XF86ConfPathsRec, *XF86ConfPathsPtr; >> + >> /* >> * prototypes for public functions >> */ >> -extern _X_EXPORT const char *xf86openConfigFile (const char *, const char *, >> - const char *); >> +extern const XF86ConfPathsPtr >> +xf86openConfigFile(const char *filepath, const char *dirpath, >> + const char *cmdline, const char *projroot); >> extern _X_EXPORT void xf86setBuiltinConfig(const char *config[]); >> extern _X_EXPORT XF86ConfigPtr xf86readConfigFile (void); >> extern _X_EXPORT void xf86closeConfigFile (void); >> diff --git a/hw/xwin/winconfig.c b/hw/xwin/winconfig.c >> index 3e1908c..51981c4 100644 >> --- a/hw/xwin/winconfig.c >> +++ b/hw/xwin/winconfig.c >> @@ -50,6 +50,13 @@ >> "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ >> "%P/lib/X11/%X" >> #endif >> +#ifndef CONFIGDIRPATH >> +#define CONFIGDIRPATH "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \ >> + "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \ >> + "%P/etc/X11/%X," \ >> + "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ >> + "%P/lib/X11/%X" >> +#endif >> >> XF86ConfigPtr g_xf86configptr = NULL; >> #endif >> @@ -109,7 +116,9 @@ Bool >> winReadConfigfile () >> { >> Bool retval = TRUE; >> + XF86ConfPathsPtr paths; >> const char *filename; >> + const char *dirname; >> MessageType from = X_DEFAULT; >> char *xf86ConfigFile = NULL; >> >> @@ -121,24 +130,38 @@ winReadConfigfile () >> >> /* Parse config file into data structure */ >> >> - filename = xf86openConfigFile (CONFIGPATH, xf86ConfigFile, PROJECTROOT); >> - >> + paths = xf86openConfigFile (CONFIGPATH, CONFIGDIRPATH, xf86ConfigFile, >> + PROJECTROOT); >> + >> /* Hack for backward compatibility */ >> - if (!filename && from == X_DEFAULT) >> - filename = xf86openConfigFile (CONFIGPATH, "XF86Config", PROJECTROOT); >> + if (!(paths && paths->file) && from == X_DEFAULT) >> + paths = xf86openConfigFile (CONFIGPATH, CONFIGDIRPATH, "XF86Config", >> + PROJECTROOT); >> >> - if (filename) >> + if (paths && (paths->file || paths->dir)) >> { >> - winMsg (from, "Using config file: \"%s\"\n", filename); >> + if (paths && paths->file) >> + { >> + winMsg (from, "Using config file: \"%s\"\n", paths->file); >> + } >> + else >> + { >> + winMsg (X_ERROR, "Unable to locate/open config file"); >> + if (xf86ConfigFile) >> + ErrorF (": \"%s\"", xf86ConfigFile); >> + ErrorF ("\n"); >> + } >> + >> + if (paths && paths->dir) >> + { >> + winMsg (X_DEFAULT, "Using config directory \"%s\"\n", paths->dir); >> + } >> } >> else >> { >> - winMsg (X_ERROR, "Unable to locate/open config file"); >> - if (xf86ConfigFile) >> - ErrorF (": \"%s\"", xf86ConfigFile); >> - ErrorF ("\n"); >> return FALSE; >> } >> + >> if ((g_xf86configptr = xf86readConfigFile ()) == NULL) >> { >> winMsg (X_ERROR, "Problem parsing the config file\n"); >> diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in >> index 794de7a..d28dc0d 100644 >> --- a/include/xorg-config.h.in >> +++ b/include/xorg-config.h.in >> @@ -36,6 +36,9 @@ >> /* Path to configuration file. */ >> #undef __XCONFIGFILE__ >> >> +/* Name of configuration directory. */ >> +#undef __XCONFIGDIR__ >> + >> /* Path to loadable modules. */ >> #undef DEFAULT_MODULE_PATH >> >> -- >> 1.6.2.5 > > Reviewed-by: Peter Hutterer <[email protected]> > > do you want to get this merged now or wait for the input class patches and > all in one go?
However you want. You can put this in now and I'll just rebase. It makes it a little easier if one's in master, though. -- Dan _______________________________________________ xorg-devel mailing list [email protected] http://lists.x.org/mailman/listinfo/xorg-devel
