# HG changeset patch # User Darren Salt # Date 1199144921 0 # Node ID e6fe06de638b19b57e09b3ceca8db9ee23d5de70 # Parent f26790c9c8ccb4577e23279c9cf12059cfb80ec8 Optionally split the configuration between two files (front end & engine). The engine's config file defaults to ~/.config/xine/config; internal config items are written to this file. It is an error to try to use this file for the front end configuration; however, this is NOT checked for and you will lose your xine-lib configuration if you try it. Whether the config file is split is determined by misc.split_config and --enable-split-config build option. Both are disabled by default. The engine config file is read before the front end config file. If split config was not enabled at build time, it will only be read in the presence of the front end config file. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -52,6 +52,8 @@ xine-lib (1.1.90) (Unreleased) for specific input protocols. * Check for supported extensions before opening the plugin and remove redundant core from plugins. + * Allow the xine-lib configuration to be shareable between front ends. + (This is not compiled in by default.) xine-lib (1.1.9.1) (unreleased) * Fix a read-past-end bug in xine-lib's internal strtok_r replacement. diff --git a/configure.ac b/configure.ac --- a/configure.ac +++ b/configure.ac @@ -128,6 +128,12 @@ AC_ARG_ENABLE([antialiasing], [AS_HELP_STRING([--enable-antialiasing], [enable font antialiasing])], [if test x"$enableval" != x"no"; then AC_DEFINE([ENABLE_ANTIALIASING], 1, [Define this to 1 to enable font antialising.]) + fi]) + +AC_ARG_ENABLE([split-config], + [AS_HELP_STRING([--enable-split-config], [enable creation of a configuration file for xine-lib options, shareable among front ends])], + [if test x"$enableval" == x"yes"; then + AC_DEFINE([ENABLE_SPLIT_CONFIG], 1, [Define this to 1 to enable creation of split configuration.]) fi]) diff --git a/include/xine.h b/include/xine.h --- a/include/xine.h +++ b/include/xine.h @@ -1513,8 +1513,22 @@ void xine_config_set_translation_user (c /* * load/save config data from/to afile (e.g. $HOME/.xine/config) + * + * If split configuration is allowed: + * - xine_config_load() always reads first from the shared config file; + * - xine_config_load_unshared() never reads it; + * - xine_config_save() optionally writes to the shared config file. + * + * Otherwise: + * - xine_config_load() reads first from the shared config file only if the + * front end's config file is present; + * - xine_config_load_unshared() never reads it; + * - xine_config_save() never writes to the shared config file. + ( + * Split configuration is allowed if "misc.split_config" exists. */ void xine_config_load (xine_t *self, const char *cfg_filename) XINE_PROTECTED; +void xine_config_load_unshared (xine_t *self, const char *cfg_filename) XINE_PROTECTED; void xine_config_save (xine_t *self, const char *cfg_filename) XINE_PROTECTED; void xine_config_reset (xine_t *self) XINE_PROTECTED; diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c --- a/src/xine-engine/configfile.c +++ b/src/xine-engine/configfile.c @@ -41,6 +41,9 @@ #include #include + +/* XDG */ +#include static const xine_config_entry_translation_t *config_entry_translation_user = NULL; static const xine_config_entry_translation_t config_entry_translation[] = { @@ -913,8 +916,8 @@ void xine_config_set_translation_user (c /* * load/save config data from/to afile (e.g. $HOME/.xine/config) */ -void xine_config_load (xine_t *xine, const char *filename) { - +static void config_load (xine_t *xine, const char *filename) +{ config_values_t *this = xine->config; FILE *f_config; @@ -938,7 +941,8 @@ void xine_config_load (xine_t *xine, con sscanf(line + 9, "%d", &this->current_version); if (this->current_version > CONFIG_FILE_VERSION) xine_log(xine, XINE_LOG_MSG, - _("The current config file has been modified by a newer version of xine.")); + _("The config file '%s' has been modified by a newer version of xine."), + filename); } continue; } @@ -991,8 +995,13 @@ void xine_config_load (xine_t *xine, con } } -void xine_config_save (xine_t *xine, const char *filename) { +/* values for config_save()'s 'write' parameter */ +#define WRITE_ENGINE_CONFIG 0 +#define WRITE_FRONT_END_CONFIG 1 +#define WRITE_ALL_CONFIG 2 +static void config_save (xine_t *xine, const char *filename, int write) +{ config_values_t *this = xine->config; char temp[XINE_PATH_MAX]; int backup = 0; @@ -1069,6 +1078,10 @@ void xine_config_save (xine_t *xine, con if (!entry->key[0]) /* deleted key */ goto next; + + if (entry->xine_engine == write) + /* not for this file (despite what the test looks like...) */ + goto next; lprintf ("saving key '%s'\n", entry->key); @@ -1157,6 +1170,99 @@ void xine_config_save (xine_t *xine, con if (backup) unlink(temp); } + +static char *config_file (xine_t *xine) +{ + char *path; + asprintf (&path, "%s/"PACKAGE"/config", xdgConfigHome (xine->basedir_handle)); + return path; +} + +#ifdef ENABLE_SPLIT_CONFIG + +static void config_register_split (xine_t *xine) +{ + config_register_bool (xine->config, "misc.split_config", 0, + _("Write split configuration (engine & front end)"), + _("If enabled, the configuration will be written as " + "two files, one for the front end (containing only " + "its options) and one for xine-lib (ditto).\n" + "WARNING:\n" + "Enabling this and causing the configuration to be " + "written (e.g. by exiting the front end) will " + "affect the configuration of other front ends " + "for which you've also enabled it."), + 10, NULL, xine); + config_mark_external (xine->config, "misc.split_config"); +} + +void xine_config_load (xine_t *xine, const char *filename) +{ + char *xinecfg = config_file (xine); + config_register_split (xine); + config_load (xine, xinecfg); + config_load (xine, filename); + free (xinecfg); +} + +void xine_config_load_unshared (xine_t *xine, const char *filename) +{ + config_register_split (xine); + config_load (xine, filename); +} + +void xine_config_save (xine_t *xine, const char *filename) +{ + const cfg_entry_t *split = config_lookup_entry (xine->config, "misc.split_config"); + if (split->num_value) + { + char *xinecfg = config_file (xine); + config_save (xine, xinecfg, WRITE_ENGINE_CONFIG); + free (xinecfg); + config_save (xine, filename, WRITE_FRONT_END_CONFIG); + } + else + config_save (xine, filename, WRITE_ALL_CONFIG); +} + +#else /* !ENABLE_SPLIT_CONFIG */ + +void xine_config_load (xine_t *xine, const char *filename) +{ + char *xinecfg = config_file (xine); + /* only load the shared config in the presence of the front end's config + * (the test is subject to races, but that's acceptable here) + */ + if (!access (filename, F_OK | R_OK)) + config_load (xine, xinecfg); + config_load (xine, filename); + free (xinecfg); +} + +void xine_config_load_unshared (xine_t *xine, const char *filename) +{ + config_load (xine, filename); +} + +void xine_config_save (xine_t *xine, const char *filename) +{ + cfg_entry_t *split = config_lookup_entry (xine->config, "misc.split_config"); + if (split) + { + /* Force misc.split_config to 0. + * This is a safety measure in case of switching between builds with + * and without split config writing support. + */ + pthread_mutex_lock (&xine->config->config_lock); + free(split->unknown_value); + split->unknown_value = strdup ("0"); + split->num_value = 0; + pthread_mutex_unlock (&xine->config->config_lock); + } + config_save (xine, filename, WRITE_ALL_CONFIG); +} + +#endif /* !ENABLE_SPLIT_CONFIG */ static void config_dispose (config_values_t *this) { diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -1560,6 +1560,11 @@ xine_t *xine_new (void) { if (!this) _x_abort(); + /* First of all, initialise libxdg-basedir as it's used by plugins and + * xine_config_load(), which is called before xine_init(). + */ + this->basedir_handle = xdgAllocHandle(); + this->plugin_catalog = NULL; this->save_path = NULL; this->streams = NULL; @@ -1671,8 +1676,7 @@ void xine_init (xine_t *this) { static const char *const demux_strategies[] = {"default", "reverse", "content", "extension", NULL}; - /* First of all, initialise libxdg-basedir as it's used by plugins. */ - this->basedir_handle = xdgAllocHandle(); + /* basedir_handle is already initialised */ /* initialize color conversion tables and functions */ init_yuv_conversion();