API to allow constructing arbitrary stacks of sources
- From: Mark McLoughlin <mark skynet ie>
- To: gconf-list gnome org
- Subject: API to allow constructing arbitrary stacks of sources
- Date: Mon, 29 Mar 2004 16:59:43 +0100
Hi,
I've gone back over a long standing patch[1] of mine which allows you
to construct a GConfEngine from an arbitrary stack of sources -
basically the same effect as editing the path file, but without editing
the path file ... if you get my meaning ... :-)
The idea is that we could start making gconf-editor into a much more
useful sysadmin tool where you could setup some new configuration
sources and try things out before pushing it out to users.
It really just adds a single new public function:
GConfEngine* gconf_engine_get_for_addresses (GSList *addresses,
GError** err);
However, a lot of internals are re-factored by the patch. Attaching it
here so people can look over it if they like. I'd really appreciate some
more eyes on it.
Thanks,
Mark.
[1] - http://bugzilla.gnome.org/show_bug.cgi?id=88829
Index: ChangeLog
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/ChangeLog,v
retrieving revision 1.495
retrieving revision 1.496
diff -u -p -r1.495 -r1.496
--- ChangeLog 29 Mar 2004 13:48:07 -0000 1.495
+++ ChangeLog 29 Mar 2004 14:44:10 -0000 1.496
@@ -1,1 +1,82 @@
+2004-03-29 Mark McLoughlin <mark skynet ie>
+
+ * gconf/gconf-engine.h: add gconf_engine_get_for_addresses()
+ and gconf_engine_get_local_for_addresses().
+
+ * gconf/gconf.c:
+ (gconf_engine_connect): implement setting up a database from
+ an arbitrary stack of sources.
+ (register_engine): use the concatenation of addresses for the key.
+ (unregister_engine): free the persistent address and address list on
+ unregistering.
+ (lookup_engine): use the concatenation of addresses for the key.
+ (gconf_engine_get_local_for_addresses): add.
+ (gconf_engine_get_for_address): update for register_engine change.
+ (gconf_engine_get_for_addresses): impl support for remote composite dbs.
+ (update_listener): update for the fact that listeners are now saved using
+ the persistent name.
+
+ * gconf/GConfX.idl: extend the ConfigServer interface
+ by adding ConfigServer2 inherting from ConfigServer.
+ Add ConfigServer2::get_database_for_addresses().
+
+ * gconf/gconf-backend.c:
+ (gconf_address_valid), (gconf_get_backend): check the backend
+ address doesn't contain any special characters.
+
+ * gconf/gconf-database.[ch]:
+ (source_notify_cb): don't notify unless this change could
+ actually cause a change for the client.
+ (gconf_database_notify_listeners): impl. notifying "other"
+ listeners - clients listening on other stacks which contains
+ any of the modified sources.
+ (gconf_database_set), (gconf_database_unset): keep track of
+ the sources modified by the change and update for the
+ notify_listeners change.
+ (gconf_database_recursive_unset): ditto and upd. for the
+ change in the listeners list returned by
+ gconf_sources_recursive_unset().
+ (gconf_database_get_persistent_name): make the persistent
+ name a concatenation of the individual addresses instead
+ of the first address.
+
+ * gconf/gconf-internals.[ch]:
+ (gconf_address_list_get_persistent_name): impl method similar
+ to gconf_database_get_persistent_name, except concatenate
+ the addresses from a GSList.
+ (gconf_persistent_name_get_address_list): do the reverse.
+ (gconf_address_list_free): free the list of strings.
+
+ * gconf/gconf-sources.[ch]:
+ (gconf_sources_new_from_source): allow creating an empty source
+ list.
+ (gconf_sources_set_value),
+ (gconf_sources_unset_value): return the sources modified by
+ the change.
+ (prepend_unset_notify), (recursive_unset_helper),
+ (gconf_sources_recursive_unset): return a list of GConfUnsetNotifys
+ which contains both the key and the modified source.
+ (get_address_resource): copy and paste of gconf_address_resource
+ except it doesn't dup the return value.
+ (gconf_sources_is_affected): figure out if a change to a particular
+ key in one source affects the key with a particular stack of sources.
+
+ * gconf/gconfd.[ch]: impl ConfigServer2 inheritance.
+ (gconfd_get_database): upd for obtain_database change.
+ (gconfd_get_composite_database): implement.
+ (init_databases): rename dbs_by_address to dbs_by_addresses.
+ (set_default_database): register the default db like the others.
+ (register_database): use the persistent name as the key.
+ (unregister_database): ditto.
+ (lookup_database): ditto.
+ (obtain_database): use a list of addresses, not a single one.
+ (gconfd_notify_other_listeners): impl notifying listeners
+ on GConfDatabases other than the one which was changed.
+ (listener_logentry_restore_and_destroy_foreach): restore by
+ splitting the address list string.
+
+ * gconf/gconftool.c: (main): enable --config-source without
+ --direct as it works better now. Also allow --config-source
+ to be an address list.
+
Index: doc/gconf/tmpl/gconf-backend.sgml
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/doc/gconf/tmpl/gconf-backend.sgml,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -p -r1.9 -r1.10
--- doc/gconf/tmpl/gconf-backend.sgml 25 Mar 2004 17:59:07 -0000 1.9
+++ doc/gconf/tmpl/gconf-backend.sgml 29 Mar 2004 14:44:19 -0000 1.10
@@ -321,6 +321,7 @@ by the integer supplied.
@destroy_source:
@clear_cache:
@blow_away_locks:
+ set_notify_func:
@add_listener:
@remove_listener:
Index: doc/gconf/tmpl/gconf-sources.sgml
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/doc/gconf/tmpl/gconf-sources.sgml,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -p -r1.7 -r1.8
--- doc/gconf/tmpl/gconf-sources.sgml 7 Dec 2001 04:42:36 -0000 1.7
+++ doc/gconf/tmpl/gconf-sources.sgml 29 Mar 2004 14:44:20 -0000 1.8
@@ -109,6 +109,7 @@ gconf-sources
@sources:
@key:
@value:
+ modified_sources:
@err:
@@ -120,6 +121,7 @@ gconf-sources
@sources:
@key:
@locale:
+ modified_sources:
@err:
Index: gconf/GConfX.idl
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/gconf/GConfX.idl,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -p -r1.48 -r1.49
--- gconf/GConfX.idl 15 Jan 2002 02:01:06 -0000 1.48
+++ gconf/GConfX.idl 29 Mar 2004 14:44:29 -0000 1.49
@@ -261,3 +261,8 @@ interface ConfigServer {
void shutdown();
};
+interface ConfigServer2 : ConfigServer {
+ typedef sequence<string> AddressList;
+
+ ConfigDatabase get_database_for_addresses (in AddressList addresses);
+};
Index: gconf/gconf-backend.c
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/gconf/gconf-backend.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -p -r1.24 -r1.25
--- gconf/gconf-backend.c 29 Mar 2004 13:48:11 -0000 1.24
+++ gconf/gconf-backend.c 29 Mar 2004 14:44:29 -0000 1.25
@@ -26,6 +26,46 @@
#include <sys/stat.h>
#include <unistd.h>
+
+/* Don't allow special characters in configuration source addresses.
+ * The important one here is not to allow ';' because we use that
+ * internally as a list delimiter. See GCONF_DATABASE_LIST_DELIM
+ */
+static const char invalid_chars[] = " \t\r\n\"$&<>,+=#!()'|{}[]?~`;%\\";
+
+static gboolean
+gconf_address_valid (const char *address,
+ char **why_invalid)
+{
+ const char *s;
+
+ g_return_val_if_fail (address != NULL, FALSE);
+
+ if (why_invalid)
+ *why_invalid = NULL;
+
+ s = address;
+ while (*s)
+ {
+ const char *inv = invalid_chars;
+
+ while (*inv)
+ {
+ if (*inv == *s)
+ {
+ if (why_invalid)
+ *why_invalid = g_strdup_printf(_("`%c' is an invalid character in a configuration storage address"), *s);
+ return FALSE;
+ }
+ ++inv;
+ }
+
+ ++s;
+ }
+
+ return TRUE;
+}
+
gchar*
gconf_address_backend(const gchar* address)
{
@@ -239,11 +279,23 @@ gconf_get_backend(const gchar* address,
{
GConfBackend* backend;
gchar* name;
+ gchar* why_invalid;
if (loaded_backends == NULL)
{
loaded_backends = g_hash_table_new(g_str_hash, g_str_equal);
}
+
+ why_invalid = NULL;
+ if (!gconf_address_valid (address, &why_invalid))
+ {
+ g_assert (why_invalid != NULL);
+ gconf_set_error (err, GCONF_ERROR_BAD_ADDRESS, _("Bad address `%s': %s"),
+ address, why_invalid);
+ g_free (why_invalid);
+ return NULL;
+ }
+
name = gconf_address_backend(address);
if (name == NULL)
Index: gconf/gconf-database.c
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/gconf/gconf-database.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -p -r1.36 -r1.37
--- gconf/gconf-database.c 29 Mar 2004 09:47:34 -0000 1.36
+++ gconf/gconf-database.c 29 Mar 2004 14:44:30 -0000 1.37
@@ -1039,51 +1039,51 @@ source_notify_cb (GConfSource *source,
const gchar *location,
GConfDatabase *db)
{
- GConfValue *value;
- ConfigValue *cvalue;
- GError *error;
- gboolean is_default;
- gboolean is_writable;
-
g_return_if_fail (source != NULL);
g_return_if_fail (location != NULL);
g_return_if_fail (db != NULL);
- error = NULL;
- is_default = is_writable = FALSE;
-
- /* FIXME: only notify if this location isn't already set
- * in a source above this one.
- */
-
- value = gconf_database_query_value (db,
- location,
- NULL,
- TRUE,
- NULL,
- &is_default,
- &is_writable,
- &error);
- if (error != NULL)
+ if (gconf_sources_is_affected (db->sources, source, location))
{
- gconf_log (GCL_WARNING,
- _("Error obtaining new value for `%s' after change notification from backend `%s': %s"),
- location,
- source->address,
- error->message);
- g_error_free (error);
- return;
- }
+ GConfValue *value;
+ ConfigValue *cvalue;
+ GError *error;
+ gboolean is_default;
+ gboolean is_writable;
- cvalue = gconf_corba_value_from_gconf_value (value);
- gconf_database_notify_listeners (db,
- location,
- cvalue,
- is_default,
- is_writable);
+ error = NULL;
+ is_default = is_writable = FALSE;
- CORBA_free (cvalue);
- gconf_value_free (value);
+ value = gconf_database_query_value (db,
+ location,
+ NULL,
+ TRUE,
+ NULL,
+ &is_default,
+ &is_writable,
+ &error);
+ if (error != NULL)
+ {
+ gconf_log (GCL_WARNING,
+ _("Error obtaining new value for `%s' after change notification from backend `%s': %s"),
+ location,
+ source->address,
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ cvalue = gconf_corba_value_from_gconf_value (value);
+ gconf_database_notify_listeners (db,
+ NULL,
+ location,
+ cvalue,
+ is_default,
+ is_writable,
+ FALSE);
+ CORBA_free (cvalue);
+ gconf_value_free (value);
+ }
}
CORBA_unsigned_long
@@ -1245,10 +1245,12 @@ notify_listeners_cb(GConfListeners* list
void
gconf_database_notify_listeners (GConfDatabase *db,
+ GConfSources *modified_sources,
const gchar *key,
const ConfigValue *value,
gboolean is_default,
- gboolean is_writable)
+ gboolean is_writable,
+ gboolean notify_others)
{
ListenerNotifyClosure closure;
GSList* tmp;
@@ -1278,6 +1280,16 @@ gconf_database_notify_listeners (GConfDa
tmp = g_slist_next(tmp);
}
+
+ if (notify_others)
+ {
+ g_return_if_fail (modified_sources != NULL);
+
+ gconfd_notify_other_listeners (db, modified_sources, key);
+
+ g_list_free (modified_sources->sources);
+ g_free (modified_sources);
+ }
}
GConfValue*
@@ -1338,6 +1350,7 @@ gconf_database_set (GConfDatabase
GError **err)
{
GError *error = NULL;
+ GConfSources *modified_sources;
g_assert(db->listeners != NULL);
g_return_if_fail(err == NULL || *err == NULL);
@@ -1349,10 +1362,12 @@ gconf_database_set (GConfDatabase
gconf_log(GCL_DEBUG, "Received request to set key `%s'", key);
#endif
- gconf_sources_set_value(db->sources, key, value, &error);
+ gconf_sources_set_value(db->sources, key, value, &modified_sources, &error);
if (error)
{
+ g_assert (modified_sources == NULL);
+
gconf_log(GCL_ERR, _("Error setting value for `%s': %s"),
key, error->message);
@@ -1364,14 +1379,16 @@ gconf_database_set (GConfDatabase
{
gconf_database_schedule_sync(db);
- gconf_database_notify_listeners(db, key, cvalue,
- /* Can't possibly be the default,
- since we just set it,
- and must be writable since
- setting it succeeded.
- */
- FALSE,
- TRUE);
+ /* Can't possibly be the default, since we just set it,
+ * and must be writable since setting it succeeded.
+ */
+ gconf_database_notify_listeners (db,
+ modified_sources,
+ key,
+ cvalue,
+ FALSE,
+ TRUE,
+ TRUE);
}
}
@@ -1383,6 +1400,7 @@ gconf_database_unset (GConfDatabase
{
ConfigValue* val;
GError* error = NULL;
+ GConfSources *modified_sources;
g_return_if_fail(err == NULL || *err == NULL);
@@ -1392,10 +1410,12 @@ gconf_database_unset (GConfDatabase
gconf_log(GCL_DEBUG, "Received request to unset key `%s'", key);
- gconf_sources_unset_value(db->sources, key, locale, &error);
+ gconf_sources_unset_value(db->sources, key, locale, &modified_sources, &error);
if (error != NULL)
{
+ g_assert (modified_sources == NULL);
+
gconf_log(GCL_ERR, _("Error unsetting `%s': %s"),
key, error->message);
@@ -1440,8 +1460,13 @@ gconf_database_unset (GConfDatabase
gconf_database_schedule_sync(db);
- gconf_database_notify_listeners(db, key, val, TRUE, is_writable);
-
+ gconf_database_notify_listeners(db,
+ modified_sources,
+ key,
+ val,
+ TRUE,
+ is_writable,
+ TRUE);
CORBA_free(val);
}
}
@@ -1476,6 +1501,8 @@ gconf_database_recursive_unset (GConfDat
*/
if (error != NULL)
{
+ g_assert (notifies == NULL);
+
gconf_log (GCL_ERR, _("Error unsetting \"%s\": %s"),
key, error->message);
@@ -1494,12 +1521,11 @@ gconf_database_recursive_unset (GConfDat
const gchar* locale_list[] = { NULL, NULL };
gboolean is_writable = TRUE;
gboolean is_default = TRUE;
- char *notify_key = tmp->data;
-
+ GConfUnsetNotify *notify = tmp->data;
locale_list[0] = locale;
new_value = gconf_database_query_value (db,
- notify_key,
+ notify->key,
locale_list,
TRUE,
NULL,
@@ -1509,7 +1535,7 @@ gconf_database_recursive_unset (GConfDat
if (error)
gconf_log (GCL_ERR, _("Error getting new value for \"%s\": %s"),
- notify_key, error->message);
+ notify->key, error->message);
g_propagate_error (err, error);
error = NULL;
@@ -1525,11 +1551,17 @@ gconf_database_recursive_unset (GConfDat
gconf_database_schedule_sync (db);
- gconf_database_notify_listeners (db, notify_key, val,
- is_default, is_writable);
+ gconf_database_notify_listeners (db,
+ notify->modified_sources,
+ notify->key,
+ val,
+ is_default,
+ is_writable,
+ TRUE);
CORBA_free (val);
- g_free (notify_key);
+ g_free (notify->key);
+ g_free (notify);
tmp = tmp->next;
}
@@ -1709,17 +1741,43 @@ gconf_database_clear_cache (GConfDatabas
gconf_sources_clear_cache(db->sources);
}
-const gchar*
+const gchar *
gconf_database_get_persistent_name (GConfDatabase *db)
{
- if (db->persistent_name == NULL)
+ GList *tmp;
+ GString *str = NULL;
+
+ if (db->persistent_name != NULL)
+ return db->persistent_name;
+
+ if (db->sources == NULL || db->sources->sources == NULL)
+ {
+ db->persistent_name = g_strdup ("empty");
+ return db->persistent_name;
+ }
+
+ tmp = db->sources->sources;
+ while (tmp != NULL)
{
- if (db->sources->sources)
- db->persistent_name =
- g_strdup (((GConfSource*)db->sources->sources->data)->address);
+ GConfSource *source = tmp->data;
+
+ if (str == NULL)
+ {
+ str = g_string_new (source->address);
+ }
else
- db->persistent_name = g_strdup ("empty");
+ {
+ g_string_append_c (str, GCONF_DATABASE_LIST_DELIM);
+ g_string_append (str, source->address);
+ }
+
+ tmp = tmp->next;
}
+
+ g_assert (str != NULL);
+
+ db->persistent_name = str->str;
+ g_string_free (str, FALSE);
return db->persistent_name;
}
Index: gconf/gconf-database.h
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/gconf/gconf-database.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -p -r1.11 -r1.12
--- gconf/gconf-database.h 9 Sep 2002 20:13:47 -0000 1.11
+++ gconf/gconf-database.h 29 Mar 2004 14:44:30 -0000 1.12
@@ -70,11 +70,12 @@ CORBA_unsigned_long gconf_database_readd
const gchar *where);
void gconf_database_notify_listeners (GConfDatabase *db,
+ GConfSources *modified_sources,
const gchar *key,
const ConfigValue *value,
gboolean is_default,
- gboolean is_writable);
-
+ gboolean is_writable,
+ gboolean notify_others);
GConfValue* gconf_database_query_value (GConfDatabase *db,
const gchar *key,
Index: gconf/gconf-engine.h
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/gconf/gconf-engine.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -p -r1.10 -r1.11
--- gconf/gconf-engine.h 17 Sep 2000 00:55:01 -0000 1.10
+++ gconf/gconf-engine.h 29 Mar 2004 14:44:31 -0000 1.11
@@ -36,11 +36,16 @@ GConfEngine* gconf_engine_get_default
/* returns NULL on error; requests single specified source */
GConfEngine* gconf_engine_get_for_address (const gchar* address,
GError** err);
+GConfEngine* gconf_engine_get_for_addresses (GSList *addresses,
+ GError** err);
void gconf_engine_unref (GConfEngine* conf);
void gconf_engine_ref (GConfEngine* conf);
#ifdef GCONF_ENABLE_INTERNALS
-GConfEngine* gconf_engine_get_local (const gchar* address, GError** err);
+GConfEngine *gconf_engine_get_local (const char *address,
+ GError **err);
+GConfEngine *gconf_engine_get_local_for_addresses (GSList *addresses,
+ GError **err);
#endif
/* For use by language bindings only, will be deprecated in GNOME 2.0
Index: gconf/gconf-internals.c
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/gconf/gconf-internals.c,v
retrieving revision 1.121
retrieving revision 1.122
diff -u -p -r1.121 -r1.122
--- gconf/gconf-internals.c 22 Oct 2003 21:03:08 -0000 1.121
+++ gconf/gconf-internals.c 29 Mar 2004 14:44:31 -0000 1.122
@@ -917,6 +917,82 @@ gconf_load_source_path(const gchar* file
return l;
}
+char *
+gconf_address_list_get_persistent_name (GSList *addresses)
+{
+ GSList *tmp;
+ GString *str = NULL;
+
+ if (!addresses)
+ {
+ return g_strdup ("empty");
+ }
+
+ tmp = addresses;
+ while (tmp != NULL)
+ {
+ const char *address = tmp->data;
+
+ if (str == NULL)
+ {
+ str = g_string_new (address);
+ }
+ else
+ {
+ g_string_append_c (str, GCONF_DATABASE_LIST_DELIM);
+ g_string_append (str, address);
+ }
+
+ tmp = tmp->next;
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+GSList *
+gconf_persistent_name_get_address_list (const char *persistent_name)
+{
+ char delim [2] = { GCONF_DATABASE_LIST_DELIM, '\0' };
+ char **address_vector;
+
+ address_vector = g_strsplit (persistent_name, delim, -1);
+ if (address_vector != NULL)
+ {
+ GSList *retval = NULL;
+ int i;
+
+ i = 0;
+ while (address_vector [i] != NULL)
+ {
+ retval = g_slist_append (retval, g_strdup (address_vector [i]));
+ ++i;
+ }
+
+ g_strfreev (address_vector);
+
+ return retval;
+ }
+ else
+ {
+ return g_slist_append (NULL, g_strdup (persistent_name));
+ }
+}
+
+void
+gconf_address_list_free (GSList *addresses)
+{
+ GSList *tmp;
+
+ tmp = addresses;
+ while (tmp != NULL)
+ {
+ g_free (tmp->data);
+ tmp = tmp->next;
+ }
+
+ g_slist_free (addresses);
+}
+
/* This should also support concatting filesystem dirs and keys,
or dir and subdir.
*/
Index: gconf/gconf-internals.h
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/gconf/gconf-internals.h,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -p -r1.77 -r1.78
--- gconf/gconf-internals.h 27 Mar 2003 10:14:47 -0000 1.77
+++ gconf/gconf-internals.h 29 Mar 2004 14:44:32 -0000 1.78
@@ -39,6 +39,8 @@
#include "gconf-sources.h"
#include "GConfX.h"
+#define GCONF_DATABASE_LIST_DELIM ';'
+
gchar* gconf_key_directory (const gchar* key);
const gchar* gconf_key_key (const gchar* key);
@@ -66,6 +68,10 @@ GConfSchema* gconf_schema_from_corba_sc
gchar* gconf_object_to_string (CORBA_Object obj,
GError **err);
+
+char *gconf_address_list_get_persistent_name (GSList *addresses);
+GSList *gconf_persistent_name_get_address_list (const char *persistent_name);
+void gconf_address_list_free (GSList *addresses);
const gchar* gconf_value_type_to_string (GConfValueType type);
GConfValueType gconf_value_type_from_string (const gchar *str);
Index: gconf/gconf-sources.c
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/gconf/gconf-sources.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -p -r1.47 -r1.48
--- gconf/gconf-sources.c 29 Mar 2004 09:47:34 -0000 1.47
+++ gconf/gconf-sources.c 29 Mar 2004 14:44:32 -0000 1.48
@@ -77,7 +77,7 @@ gconf_source_free (GConfSource* source)
g_return_if_fail(source != NULL);
backend = source->backend;
-
+
(*source->backend->vtable.destroy_source)(source);
/* Remove ref held by the source. */
@@ -418,7 +418,8 @@ gconf_sources_new_from_source (GCo
sources = g_new0(GConfSources, 1);
- sources->sources = g_list_append(NULL, source);
+ if (source)
+ sources->sources = g_list_append(NULL, source);
return sources;
}
@@ -663,6 +664,7 @@ void
gconf_sources_set_value (GConfSources* sources,
const gchar* key,
const GConfValue* value,
+ GConfSources **modified_sources,
GError** err)
{
GList* tmp;
@@ -670,6 +672,9 @@ gconf_sources_set_value (GConfSources*
g_return_if_fail(sources != NULL);
g_return_if_fail(key != NULL);
g_return_if_fail((err == NULL) || (*err == NULL));
+
+ if (modified_sources)
+ *modified_sources = NULL;
if (!gconf_key_check(key, err))
return;
@@ -699,7 +704,11 @@ gconf_sources_set_value (GConfSources*
{
/* source was writable, err may be set */
gconf_log (GCL_DEBUG, "%s was writable in %s", key, src->address);
- return;
+ if (modified_sources)
+ {
+ *modified_sources = gconf_sources_new_from_source (src);
+ }
+ return;
}
else
{
@@ -737,6 +746,7 @@ void
gconf_sources_unset_value (GConfSources* sources,
const gchar* key,
const gchar* locale,
+ GConfSources **modified_sources,
GError** err)
{
/* We unset in every layer we can write to... */
@@ -768,12 +778,40 @@ gconf_sources_unset_value (GConfSource
return;
}
}
+
+ if (modified_sources)
+ {
+ if (*modified_sources)
+ {
+ *modified_sources = gconf_sources_new_from_source (src);
+ }
+ else
+ {
+ (*modified_sources)->sources =
+ g_list_prepend ((*modified_sources)->sources, src);
+ }
+ }
}
tmp = g_list_next(tmp);
}
}
+static GSList *
+prepend_unset_notify (GSList *notifies,
+ GConfSources *modified_sources,
+ char *key)
+{
+ GConfUnsetNotify *notify;
+
+ notify = g_new0 (GConfUnsetNotify, 1);
+
+ notify->modified_sources = modified_sources;
+ notify->key = key;
+
+ return g_slist_append (notifies, notify);
+}
+
static void
recursive_unset_helper (GConfSources *sources,
const char *key,
@@ -787,6 +825,14 @@ recursive_unset_helper (GConfSources *
GSList* entries;
GSList* tmp;
const char *locales[2] = { NULL, NULL };
+ GConfSources* modified_sources;
+ GConfSources** modifiedp = NULL;
+
+ if (notifies)
+ {
+ modified_sources = NULL;
+ modifiedp = &modified_sources;
+ }
err = NULL;
@@ -849,16 +895,19 @@ recursive_unset_helper (GConfSources *
while (tmp != NULL)
{
GConfEntry* entry = tmp->data;
- char *full = gconf_concat_dir_and_key (key,
- gconf_entry_get_key (entry));
+ char *full, *freeme;
+
+ full = freeme = gconf_concat_dir_and_key (key,
+ gconf_entry_get_key (entry));
- if (notifies)
- *notifies = g_slist_prepend (*notifies, g_strdup (full));
- gconf_sources_unset_value (sources,
- full,
- locale,
- &err);
+ gconf_sources_unset_value (sources, full, locale, modifiedp, &err);
+ if (notifies)
+ {
+ *notifies = prepend_unset_notify (*notifies, modified_sources, full);
+ freeme = NULL;
+ }
+
if (err != NULL)
{
gconf_log (GCL_DEBUG, "Error unsetting '%s': %s\n",
@@ -890,7 +939,7 @@ recursive_unset_helper (GConfSources *
}
gconf_entry_free (entry);
- g_free (full);
+ g_free (freeme);
tmp = g_slist_next (tmp);
}
@@ -898,10 +947,13 @@ recursive_unset_helper (GConfSources *
g_slist_free (entries);
}
+ gconf_sources_unset_value (sources, key, locale, modifiedp, &err);
if (notifies)
- *notifies = g_slist_prepend (*notifies, g_strdup (key));
-
- gconf_sources_unset_value (sources, key, locale, &err);
+ {
+ *notifies = prepend_unset_notify (*notifies,
+ modified_sources,
+ g_strdup (key));
+ }
if (err != NULL)
{
@@ -935,7 +987,28 @@ gconf_sources_recursive_unset (GConfSour
notifies, &first_error);
if (first_error)
- g_propagate_error (err, first_error);
+ {
+ if (notifies != NULL && *notifies != NULL)
+ {
+ GSList *tmp;
+
+ tmp = *notifies;
+ while (tmp != NULL)
+ {
+ GConfUnsetNotify *notify = tmp->data;
+
+ g_free (notify->key);
+ g_free (notify);
+
+ tmp = tmp->next;
+ }
+
+ g_slist_free (*notifies);
+ *notifies = NULL;
+ }
+
+ g_propagate_error (err, first_error);
+ }
}
gboolean
@@ -1636,4 +1709,72 @@ gconf_sources_remove_listener (GConfSour
tmp = tmp->next;
}
+}
+
+/* Non-allocating variant of gconf_address_resource()
+ */
+static const char *
+get_address_resource (const char *address)
+{
+ const char *start;
+
+ g_return_val_if_fail (address != NULL, NULL);
+
+ start = strchr (address, ':');
+ if (start != NULL)
+ {
+ start = strchr (++start, ':');
+
+ if (start != NULL)
+ start++;
+ }
+
+ return start;
+}
+
+/* Return TRUE if
+ * 1. @sources contains @modified_src and
+ * 2. @key is not set in any source above @modified_src.
+ */
+gboolean
+gconf_sources_is_affected (GConfSources *sources,
+ GConfSource *modified_src,
+ const char *key)
+{
+ const char *modified_resource;
+ GList *tmp;
+
+ modified_resource = get_address_resource (modified_src->address);
+
+ tmp = sources->sources;
+ while (tmp != NULL)
+ {
+ GConfSource *source = tmp->data;
+
+ if (source->backend == modified_src->backend &&
+ strcmp (modified_resource, get_address_resource (source->address)) == 0)
+ break;
+
+ tmp = tmp->next;
+ }
+
+ if (tmp)
+ {
+ tmp = tmp->prev;
+ while (tmp != NULL)
+ {
+ GConfValue *val;
+
+ val = gconf_source_query_value (tmp->data, key, NULL, NULL, NULL);
+ if (val != NULL)
+ {
+ gconf_value_free (val);
+ return FALSE;
+ }
+
+ tmp = tmp->prev;
+ }
+ }
+
+ return TRUE;
}
Index: gconf/gconf-sources.h
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/gconf/gconf-sources.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -p -r1.23 -r1.24
--- gconf/gconf-sources.h 29 Mar 2004 09:47:34 -0000 1.23
+++ gconf/gconf-sources.h 29 Mar 2004 14:44:33 -0000 1.24
@@ -65,9 +65,15 @@ typedef struct _GConfSources GConfSource
struct _GConfSources {
GList* sources;
-
};
+typedef struct
+{
+ GConfSources *modified_sources;
+ char *key;
+} GConfUnsetNotify;
+
+
/* Even on error, this gives you an empty source list, i.e. never
returns NULL but may set the error if some addresses weren't
resolved and may contain no sources. */
@@ -87,10 +93,12 @@ GConfValue* gconf_sources_query_value
void gconf_sources_set_value (GConfSources *sources,
const gchar *key,
const GConfValue *value,
+ GConfSources **modified_sources,
GError **err);
void gconf_sources_unset_value (GConfSources *sources,
const gchar *key,
const gchar *locale,
+ GConfSources **modified_sources,
GError **err);
void gconf_sources_recursive_unset (GConfSources *sources,
const gchar *key,
@@ -137,5 +145,9 @@ void gconf_sources_add_listener
const gchar *location);
void gconf_sources_remove_listener (GConfSources *sources,
guint id);
+
+gboolean gconf_sources_is_affected (GConfSources *sources,
+ GConfSource *modified_src,
+ const char *key);
#endif
Index: gconf/gconf.c
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/gconf/gconf.c,v
retrieving revision 1.144
retrieving revision 1.145
diff -u -p -r1.144 -r1.145
--- gconf/gconf.c 22 Oct 2003 21:03:08 -0000 1.144
+++ gconf/gconf.c 29 Mar 2004 14:44:33 -0000 1.145
@@ -80,10 +80,15 @@ struct _GConfEngine {
local engines don't do notification! */
GConfSources* local_sources;
- /* An address if this is not the default engine;
+ /* A list of addresses that make up this db
+ * if this is not the default engine;
* NULL if it's the default
*/
- gchar *address;
+ GSList *addresses;
+
+ /* A concatentation of the addresses above.
+ */
+ char *persistent_address;
gpointer user_data;
GDestroyNotify dnotify;
@@ -147,7 +152,7 @@ static ConfigDatabase gconf_engine_get_d
static void register_engine (GConfEngine *conf);
static void unregister_engine (GConfEngine *conf);
-static GConfEngine *lookup_engine (const gchar *address);
+static GConfEngine *lookup_engine (GSList *addresses);
static GConfEngine *lookup_engine_by_database (ConfigDatabase db);
@@ -320,9 +325,40 @@ gconf_engine_connect (GConfEngine *conf,
return FALSE; /* Error should already be set */
if (conf->is_default)
- db = ConfigServer_get_default_database (cs, &ev);
+ {
+ db = ConfigServer_get_default_database (cs, &ev);
+ }
+ else if (conf->addresses->next == NULL) /* single element list */
+ {
+ db = ConfigServer_get_database (cs, conf->addresses->data, &ev);
+ }
else
- db = ConfigServer_get_database (cs, conf->address, &ev);
+ {
+ ConfigServer2_AddressList *address_list;
+ GSList *tmp;
+ int i;
+
+ address_list = ConfigServer2_AddressList__alloc ();
+ address_list->_length = address_list->_maximum = g_slist_length (conf->addresses);
+ address_list->_buffer = ConfigServer2_AddressList_allocbuf (address_list->_length);
+ address_list->_release = CORBA_TRUE;
+
+ i = 0;
+ tmp = conf->addresses;
+ while (tmp != NULL)
+ {
+ g_assert (i < address_list->_length);
+
+ address_list->_buffer [i] = CORBA_string_dup (tmp->data);
+
+ tmp = tmp->next;
+ i++;
+ }
+
+ db = ConfigServer2_get_database_for_addresses ((ConfigServer2) cs, address_list, &ev);
+
+ CORBA_free (address_list);
+ }
if (gconf_server_broken(&ev))
{
@@ -343,7 +379,7 @@ gconf_engine_connect (GConfEngine *conf,
if (err)
*err = gconf_error_new(GCONF_ERROR_BAD_ADDRESS,
_("Server couldn't resolve the address `%s'"),
- conf->address ? conf->address : "default");
+ conf->persistent_address);
return FALSE;
}
@@ -375,21 +411,29 @@ static GHashTable *engines_by_address =
static void
register_engine (GConfEngine *conf)
{
- g_return_if_fail (conf->address != NULL);
+ g_return_if_fail (conf->addresses != NULL);
+
+ g_assert (conf->persistent_address == NULL);
+
+ conf->persistent_address =
+ gconf_address_list_get_persistent_name (conf->addresses);
if (engines_by_address == NULL)
engines_by_address = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (engines_by_address, conf->address, conf);
+ g_hash_table_insert (engines_by_address, conf->persistent_address, conf);
}
static void
unregister_engine (GConfEngine *conf)
{
- g_return_if_fail (conf->address != NULL);
g_return_if_fail (engines_by_address != NULL);
+
+ g_assert (conf->persistent_address != NULL);
- g_hash_table_remove (engines_by_address, conf->address);
+ g_hash_table_remove (engines_by_address, conf->persistent_address);
+ g_free (conf->persistent_address);
+ conf->persistent_address = NULL;
if (g_hash_table_size (engines_by_address) == 0)
{
@@ -400,12 +444,23 @@ unregister_engine (GConfEngine *conf)
}
static GConfEngine *
-lookup_engine (const gchar *address)
+lookup_engine (GSList *addresses)
{
- if (engines_by_address)
- return g_hash_table_lookup (engines_by_address, address);
- else
- return NULL;
+ if (engines_by_address != NULL)
+ {
+ GConfEngine *retval;
+ char *key;
+
+ key = gconf_address_list_get_persistent_name (addresses);
+
+ retval = g_hash_table_lookup (engines_by_address, key);
+
+ g_free (key);
+
+ return retval;
+ }
+
+ return NULL;
}
@@ -437,6 +492,24 @@ gconf_engine_get_local (const gchar
return conf;
}
+GConfEngine *
+gconf_engine_get_local_for_addresses (GSList *addresses,
+ GError **err)
+{
+ GConfEngine *conf;
+
+ g_return_val_if_fail (addresses != NULL, NULL);
+ g_return_val_if_fail (err == NULL || *err == NULL, NULL);
+
+ conf = gconf_engine_blank (FALSE);
+
+ conf->local_sources = gconf_sources_new_from_addresses (addresses, err);
+
+ g_assert (gconf_engine_is_local (conf));
+
+ return conf;
+}
+
GConfEngine*
gconf_engine_get_default (void)
{
@@ -466,18 +539,64 @@ gconf_engine_get_default (void)
}
GConfEngine*
-gconf_engine_get_for_address (const gchar* address, GError** err)
+gconf_engine_get_for_address (const char *address,
+ GError **err)
+{
+ GConfEngine *conf;
+ GSList *addresses;
+
+ addresses = g_slist_append (NULL, g_strdup (address));
+
+ conf = lookup_engine (addresses);
+
+ if (conf == NULL)
+ {
+ conf = gconf_engine_blank (TRUE);
+
+ conf->is_default = FALSE;
+ conf->addresses = addresses;
+
+ if (!gconf_engine_connect (conf, TRUE, err))
+ {
+ gconf_engine_unref (conf);
+ return NULL;
+ }
+
+ register_engine (conf);
+ }
+ else
+ {
+ g_free (addresses->data);
+ g_slist_free (addresses);
+ conf->refcount += 1;
+ }
+
+ return conf;
+}
+
+GConfEngine*
+gconf_engine_get_for_addresses (GSList *addresses, GError** err)
{
GConfEngine* conf;
- conf = lookup_engine (address);
+ conf = lookup_engine (addresses);
if (conf == NULL)
{
- conf = gconf_engine_blank(TRUE);
+ GSList *tmp;
+
+ conf = gconf_engine_blank (TRUE);
conf->is_default = FALSE;
- conf->address = g_strdup (address);
+ conf->addresses = NULL;
+
+ tmp = addresses;
+ while (tmp != NULL)
+ {
+ conf->addresses = g_slist_append (conf->addresses,
+ g_strdup (tmp->data));
+ tmp = tmp->next;
+ }
if (!gconf_engine_connect (conf, TRUE, err))
{
@@ -568,10 +687,16 @@ gconf_engine_unref(GConfEngine* conf)
(* conf->dnotify) (conf->user_data);
}
- /* do this after removing the notifications,
- to avoid funky race conditions */
- if (conf->address)
- unregister_engine (conf);
+ if (conf->addresses)
+ {
+ gconf_address_list_free (conf->addresses);
+ conf->addresses = NULL;
+ }
+
+ if (conf->persistent_address)
+ {
+ unregister_engine (conf);
+ }
/* Release the ConfigDatabase */
gconf_engine_detach (conf);
@@ -1096,7 +1221,7 @@ gconf_engine_set (GConfEngine* conf, con
{
GError* error = NULL;
- gconf_sources_set_value(conf->local_sources, key, value, &error);
+ gconf_sources_set_value(conf->local_sources, key, value, NULL, &error);
if (error != NULL)
{
@@ -1174,7 +1299,7 @@ gconf_engine_unset (GConfEngine* conf, c
{
GError* error = NULL;
- gconf_sources_unset_value(conf->local_sources, key, NULL, &error);
+ gconf_sources_unset_value(conf->local_sources, key, NULL, NULL, &error);
if (error != NULL)
{
@@ -2302,7 +2427,15 @@ update_listener (PortableServer_Servant
if (strcmp (address, "def") == 0)
conf = default_engine;
else
- conf = lookup_engine (address);
+ {
+ GSList *addresses;
+
+ addresses = gconf_persistent_name_get_address_list (address);
+
+ conf = lookup_engine (addresses);
+
+ gconf_address_list_free (addresses);
+ }
if (conf)
gconf_engine_set_database (conf,
Index: gconf/gconfd.c
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/gconf/gconfd.c,v
retrieving revision 1.137
retrieving revision 1.138
diff -u -p -r1.137 -r1.138
--- gconf/gconfd.c 22 Oct 2003 21:03:08 -0000 1.137
+++ gconf/gconfd.c 29 Mar 2004 14:44:34 -0000 1.138
@@ -103,8 +103,8 @@ static void shutdown_dat
static void set_default_database (GConfDatabase* db);
static void register_database (GConfDatabase* db);
static void unregister_database (GConfDatabase* db);
-static GConfDatabase* lookup_database (const gchar *address);
-static GConfDatabase* obtain_database (const gchar *address,
+static GConfDatabase* lookup_database (GSList *addresses);
+static GConfDatabase* obtain_database (GSList *addresses,
GError **err);
static void drop_old_databases (void);
static gboolean no_databases_in_use (void);
@@ -124,7 +124,7 @@ static gboolean in_shutdown = FALSE;
* CORBA goo
*/
-static ConfigServer server = CORBA_OBJECT_NIL;
+static ConfigServer2 server = CORBA_OBJECT_NIL;
static PortableServer_POA the_poa;
static GConfLock *daemon_lock = NULL;
@@ -137,6 +137,11 @@ gconfd_get_database(PortableServer_Serva
const CORBA_char* address,
CORBA_Environment* ev);
+static ConfigDatabase
+gconfd_get_database_for_addresses (PortableServer_Servant servant,
+ const ConfigServer2_AddressList *addresses,
+ CORBA_Environment *ev);
+
static void
gconfd_add_client (PortableServer_Servant servant,
const ConfigListener client,
@@ -169,8 +174,13 @@ static POA_ConfigServer__epv server_epv
gconfd_shutdown
};
-static POA_ConfigServer__vepv poa_server_vepv = { &base_epv, &server_epv };
-static POA_ConfigServer poa_server_servant = { NULL, &poa_server_vepv };
+static POA_ConfigServer2__epv server2_epv = {
+ NULL,
+ gconfd_get_database_for_addresses
+};
+
+static POA_ConfigServer2__vepv poa_server_vepv = { &base_epv, &server_epv, &server2_epv };
+static POA_ConfigServer2 poa_server_servant = { NULL, &poa_server_vepv };
static ConfigDatabase
gconfd_get_default_database(PortableServer_Servant servant,
@@ -195,19 +205,51 @@ gconfd_get_database(PortableServer_Serva
CORBA_Environment* ev)
{
GConfDatabase *db;
+ GSList *addresses;
GError* error = NULL;
if (gconfd_check_in_shutdown (ev))
return CORBA_OBJECT_NIL;
- db = obtain_database (address, &error);
+ addresses = g_slist_append (NULL, (char *) address);
+ db = obtain_database (addresses, &error);
+ g_slist_free (addresses);
if (db != NULL)
return CORBA_Object_duplicate (db->objref, ev);
- else if (gconf_set_exception(&error, ev))
- return CORBA_OBJECT_NIL;
- else
+
+ gconf_set_exception (&error, ev);
+
+ return CORBA_OBJECT_NIL;
+}
+
+static ConfigDatabase
+gconfd_get_database_for_addresses (PortableServer_Servant servant,
+ const ConfigServer2_AddressList *seq,
+ CORBA_Environment *ev)
+{
+ GConfDatabase *db;
+ GSList *addresses = NULL;
+ GError *error = NULL;
+ int i;
+
+ if (gconfd_check_in_shutdown (ev))
return CORBA_OBJECT_NIL;
+
+ i = 0;
+ while (i < seq->_length)
+ addresses = g_slist_append (addresses, seq->_buffer [i++]);
+
+ db = obtain_database (addresses, &error);
+
+ g_slist_free (addresses);
+
+ if (db != NULL)
+ return CORBA_Object_duplicate (db->objref, ev);
+
+ gconf_set_exception (&error, ev);
+
+ return CORBA_OBJECT_NIL;
}
static void
@@ -613,7 +655,7 @@ main(int argc, char** argv)
orb = gconf_orb_get ();
- POA_ConfigServer__init (&poa_server_servant, &ev);
+ POA_ConfigServer2__init (&poa_server_servant, &ev);
the_poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references(orb, "RootPOA", &ev);
PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(the_poa, &ev), &ev);
@@ -835,7 +877,7 @@ gconf_main_is_running (void)
*/
static GList* db_list = NULL;
-static GHashTable* dbs_by_address = NULL;
+static GHashTable* dbs_by_addresses = NULL;
static GConfDatabase *default_db = NULL;
static void
@@ -844,13 +886,9 @@ init_databases (void)
gconfd_need_log_cleanup ();
g_assert(db_list == NULL);
- g_assert(dbs_by_address == NULL);
+ g_assert(dbs_by_addresses == NULL);
- dbs_by_address = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* Default database isn't in the address hash since it has
- multiple addresses in a stack
- */
+ dbs_by_addresses = g_hash_table_new (g_str_hash, g_str_equal);
}
static void
@@ -859,10 +897,8 @@ set_default_database (GConfDatabase* db)
gconfd_need_log_cleanup ();
default_db = db;
-
- /* Default database isn't in the address hash since it has
- multiple addresses in a stack
- */
+
+ register_database (db);
}
static void
@@ -871,9 +907,9 @@ register_database (GConfDatabase *db)
gconfd_need_log_cleanup ();
if (db->sources->sources)
- safe_g_hash_table_insert(dbs_by_address,
- ((GConfSource*)db->sources->sources->data)->address,
- db);
+ safe_g_hash_table_insert (dbs_by_addresses,
+ (char *) gconf_database_get_persistent_name (db),
+ db);
db_list = g_list_prepend (db_list, db);
}
@@ -884,8 +920,10 @@ unregister_database (GConfDatabase *db)
gconfd_need_log_cleanup ();
if (db->sources->sources)
- g_hash_table_remove(dbs_by_address,
- ((GConfSource*)(db->sources->sources->data))->address);
+ {
+ g_hash_table_remove (dbs_by_addresses,
+ gconf_database_get_persistent_name (db));
+ }
db_list = g_list_remove (db_list, db);
@@ -893,32 +931,37 @@ unregister_database (GConfDatabase *db)
}
static GConfDatabase*
-lookup_database (const gchar *address)
+lookup_database (GSList *addresses)
{
- if (address == NULL)
+ GConfDatabase *retval;
+ char *key;
+
+ if (addresses == NULL)
return default_db;
- else
- return g_hash_table_lookup (dbs_by_address, address);
+
+ key = gconf_address_list_get_persistent_name (addresses);
+
+ retval = g_hash_table_lookup (dbs_by_addresses, key);
+
+ g_free (key);
+
+ return retval;
}
static GConfDatabase*
-obtain_database (const gchar *address,
+obtain_database (GSList *addresses,
GError **err)
{
-
GConfSources* sources;
- GSList* addresses = NULL;
GError* error = NULL;
GConfDatabase *db;
- db = lookup_database (address);
+ db = lookup_database (addresses);
if (db)
return db;
- addresses = g_slist_append(addresses, g_strdup(address));
sources = gconf_sources_new_from_addresses(addresses, &error);
- g_slist_free (addresses);
if (error != NULL)
{
@@ -1005,10 +1048,10 @@ shutdown_databases (void)
g_list_free (db_list);
db_list = NULL;
- if (dbs_by_address)
- g_hash_table_destroy(dbs_by_address);
+ if (dbs_by_addresses)
+ g_hash_table_destroy(dbs_by_addresses);
- dbs_by_address = NULL;
+ dbs_by_addresses = NULL;
if (default_db)
gconf_database_free (default_db);
@@ -1026,6 +1069,76 @@ no_databases_in_use (void)
gconf_listeners_count (default_db->listeners) == 0;
}
+void
+gconfd_notify_other_listeners (GConfDatabase *modified_db,
+ GConfSources *modified_sources,
+ const char *key)
+{
+ GList *tmp;
+
+ if (!modified_sources)
+ return;
+
+ tmp = db_list;
+ while (tmp != NULL)
+ {
+ GConfDatabase *db = tmp->data;
+
+ if (db != modified_db)
+ {
+ GList *tmp2;
+
+ tmp2 = modified_sources->sources;
+ while (tmp2)
+ {
+ GConfSource *modified_source = tmp2->data;
+
+ if (gconf_sources_is_affected (db->sources, modified_source, key))
+ {
+ GConfValue *value;
+ ConfigValue *cvalue;
+ GError *error;
+ gboolean is_default;
+ gboolean is_writable;
+
+ error = NULL;
+ value = gconf_database_query_value (db,
+ key,
+ NULL,
+ TRUE,
+ NULL,
+ &is_default,
+ &is_writable,
+ &error);
+ if (error != NULL)
+ {
+ gconf_log (GCL_WARNING,
+ _("Error obtaining new value for `%s': %s"),
+ key, error->message);
+ g_error_free (error);
+ return;
+ }
+
+ cvalue = gconf_corba_value_from_gconf_value (value);
+ gconf_database_notify_listeners (db,
+ NULL,
+ key,
+ cvalue,
+ is_default,
+ is_writable,
+ FALSE);
+ CORBA_free (cvalue);
+ gconf_value_free (value);
+ }
+
+ tmp2 = tmp2->next;
+ }
+ }
+
+ tmp = tmp->next;
+ }
+}
+
/*
* Cleanup
*/
@@ -1841,12 +1954,20 @@ listener_logentry_restore_and_destroy_fo
gpointer data)
{
ListenerLogEntry *lle = key;
- GConfDatabase *db;
+ GConfDatabase *db = NULL;
if (strcmp (lle->address, "def") == 0)
db = default_db;
else
- db = obtain_database (lle->address, NULL);
+ {
+ GSList *addresses;
+
+ addresses = gconf_persistent_name_get_address_list (lle->address);
+
+ db = obtain_database (addresses, NULL);
+
+ gconf_address_list_free (addresses);
+ }
if (db == NULL)
{
Index: gconf/gconfd.h
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/gconf/gconfd.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -p -r1.7 -r1.8
--- gconf/gconfd.h 22 Oct 2003 21:03:09 -0000 1.7
+++ gconf/gconfd.h 29 Mar 2004 14:44:34 -0000 1.8
@@ -44,6 +44,10 @@ gboolean gconfd_logfile_change_listener
gboolean gconfd_check_in_shutdown (CORBA_Environment *ev);
+void gconfd_notify_other_listeners (GConfDatabase *modified_db,
+ GConfSources *modified_sources,
+ const char *key);
+
void gconfd_need_log_cleanup (void);
#ifdef __cplusplus
Index: gconf/gconftool.c
===================================================================
RCS file: /home/markmc/gnome-devel/local-repository/gconf/gconf/gconftool.c,v
retrieving revision 1.87
retrieving revision 1.88
diff -u -p -r1.87 -r1.88
--- gconf/gconftool.c 27 Oct 2003 18:11:18 -0000 1.87
+++ gconf/gconftool.c 29 Mar 2004 14:44:35 -0000 1.88
@@ -703,12 +703,6 @@ main (int argc, char** argv)
return 1;
}
- if (config_source && !use_local_source)
- {
- g_printerr (_("You should use --direct when using a non-default configuration source\n"));
- return 1;
- }
-
if (!gconf_init(argc, argv, &err))
{
g_printerr (_("Failed to init GConf: %s\n"), err->message);
@@ -780,10 +774,16 @@ main (int argc, char** argv)
conf = gconf_engine_get_default();
else
{
+ GSList *addresses;
+
+ addresses = gconf_persistent_name_get_address_list (config_source);
+
if (use_local_source)
- conf = gconf_engine_get_local(config_source, &err);
+ conf = gconf_engine_get_local_for_addresses (addresses, &err);
else
- conf = gconf_engine_get_for_address(config_source, &err);
+ conf = gconf_engine_get_for_addresses (addresses, &err);
+
+ gconf_address_list_free (addresses);
}
if (conf == NULL)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]