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? Cheers, Peter _______________________________________________ xorg-devel mailing list [email protected] http://lists.x.org/mailman/listinfo/xorg-devel
