[gnome-db] Patch for new gconf-free gda-config.c
- From: Gonzalo Paniagua Javier <gonzalo gnome-db org>
- To: Gnome-db list <gnome-db-list gnome org>
- Subject: [gnome-db] Patch for new gconf-free gda-config.c
- Date: Wed, 1 May 2002 16:00:29 +0200
Hi!
Here's the patch that does what the subject says.
Comments? Suggestions?
--
Gonzalo Paniagua Javier <gonzalo gnome-db org>
http://www.gnome-db.org/~gonzalo/
Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/libgda/libgda/Makefile.am,v
retrieving revision 1.19
diff -u -r1.19 Makefile.am
--- Makefile.am 26 Apr 2002 21:20:17 -0000 1.19
+++ Makefile.am 1 May 2002 13:56:15 -0000
@@ -5,7 +5,8 @@
-I$(top_srcdir) \
-I$(top_builddir) \
-DLIBGDA_PLUGINDIR=\""$(prefix)/lib/libgda/providers"\" \
- -DLIBGDA_LOCALEDIR=\""$(datadir)/locale"\"
+ -DLIBGDA_LOCALEDIR=\""$(datadir)/locale"\" \
+ -DLIBGDA_GLOBAL_CONFIG_FILE=\""$(sysconfdir)/libgda/config"\"
gda_marshal_built_files = gda-marshal.h gda-marshal.c
Index: gda-config.c
===================================================================
RCS file: /cvs/gnome/libgda/libgda/gda-config.c,v
retrieving revision 1.24
diff -u -r1.24 gda-config.c
--- gda-config.c 27 Apr 2002 16:13:49 -0000 1.24
+++ gda-config.c 1 May 2002 13:56:15 -0000
@@ -3,6 +3,7 @@
*
* AUTHORS:
* Rodrigo Moya <rodrigo gnome-db org>
+ * Gonzalo Paniagua Javier <gonzalo gnome-db org>
*
* This Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License as
@@ -21,34 +22,284 @@
*/
#include <config.h>
-#include <glib/gdir.h>
-#include <glib/gstrfuncs.h>
+#include <string.h>
+#include <glib.h>
#include <gmodule.h>
#include <libgda/gda-config.h>
#include <libgda/gda-data-model-array.h>
#include <libgda/gda-intl.h>
#include <libgda/gda-log.h>
-#include <gconf/gconf-client.h>
-#include <string.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+
+#ifndef LIBGDA_USER_CONFIG_FILE
+#define LIBGDA_USER_CONFIG_FILE "/.libgda/config" /* Appended to $HOME */
+#endif
+
+//FIXME: many functions are not thread safe!
-static GConfClient *conf_client = NULL;
+typedef struct {
+ gchar *name;
+ gchar *type;
+ gchar *value;
+} gda_config_entry;
+
+typedef struct {
+ gchar *path;
+ GList *entries;
+} gda_config_section;
+
+typedef struct {
+ GList *global;
+ GList *user;
+} gda_config_client;
+
+static gda_config_client *config_client;
+static void do_notify (const gchar *path);
/*
* Private functions
*/
+static GList *
+gda_config_read_entries (xmlNodePtr cur)
+{
+ GList *list;
+ gda_config_entry *entry;
+
+ g_return_val_if_fail (cur != NULL, NULL);
+
+ list = NULL;
+ cur = cur->xmlChildrenNode;
+ while (cur != NULL){
+ if (!strcmp(cur->name, "entry")){
+ entry = g_new (gda_config_entry, 1);
+ entry->name = xmlGetProp(cur, "name");
+ if (entry->name == NULL)
+ g_warning ("NULL 'name' in an entry");
+
+ entry->type = xmlGetProp(cur, "type");
+ if (entry->type == NULL)
+ g_warning ("NULL 'type' in an entry");
+
+ entry->value = xmlGetProp(cur, "value");
+ if (entry->value == NULL)
+ g_warning ("NULL 'value' in an entry");
+
+ list = g_list_append (list, entry);
+ } else {
+ g_warning ("'entry' expected, got '%s'. Ignoring...",
+ cur->name);
+ }
+ cur = cur->next;
+ }
+
+ return list;
+}
+
+static GList *
+gda_config_parse_config_file (gchar *buffer, gint len)
+{
+ xmlDocPtr doc;
+ xmlNodePtr cur;
+ GList *list = NULL;
+ gda_config_section *section;
+
+ g_return_val_if_fail (buffer != NULL, NULL);
+ g_return_val_if_fail (len != 0, NULL);
+
+ doc = xmlParseMemory (buffer, len);
+ if (doc == NULL){
+ g_warning ("File empty or not well-formed.");
+ return NULL;
+ }
+
+ cur = xmlDocGetRootElement (doc);
+ if (cur == NULL){
+ g_warning ("Cannot get root element!");
+ xmlFreeDoc (doc);
+ return NULL;
+ }
+
+ if (strcmp (cur->name, "libgda-config") != 0){
+ g_warning ("root node != 'libgda-config' -> '%s'", cur->name);
+ xmlFreeDoc (doc);
+ return NULL;
+ }
+
+ cur = cur->xmlChildrenNode;
+ while (cur != NULL) {
+ if (!strcmp(cur->name, "section")){
+ section = g_new (gda_config_section, 1);
+ section->path = xmlGetProp (cur, "path");
+ if (section->path != NULL){
+ section->entries = gda_config_read_entries (cur);
+ list = g_list_append (list, section);
+ } else {
+ g_warning ("section without 'path'!");
+ g_free (section);
+ }
+ } else {
+ g_warning ("'section' expected, got '%s'. Ignoring...",
+ cur->name);
+ }
+
+ cur = cur->next;
+ }
+
+ xmlFreeDoc (doc);
+ return list;
+}
+
+static gda_config_client *
+get_config_client ()
+{
+ //FIXME: if we're updating or writing config_client,
+ // wait until the operation finishes
+ if (config_client == NULL){
+ gint len;
+ gchar *full_file;
+ gchar *user_config;
+
+ config_client = g_new0 (gda_config_client, 1);
+ xmlKeepBlanksDefault(0);
+ if (g_file_get_contents (LIBGDA_GLOBAL_CONFIG_FILE, &full_file,
+ &len, NULL)){
+ config_client->global =
+ gda_config_parse_config_file (full_file, len);
+ }
+
+ user_config = g_strdup_printf ("%s%s", g_get_home_dir (),
+ LIBGDA_USER_CONFIG_FILE);
+ if (g_file_get_contents (user_config, &full_file, &len, NULL)){
+ config_client->user =
+ gda_config_parse_config_file (full_file, len);
+ }
+ g_free (user_config);
+ }
+
+ return config_client;
+}
-static GConfClient *
-get_conf_client (void)
+static gda_config_section *
+gda_config_search_section (GList *sections, const gchar *path)
{
- if (!conf_client) {
- /* initialize GConf */
- if (!gconf_is_initialized ())
- gconf_init (0, NULL, NULL);
- conf_client = gconf_client_get_default ();
- }
- return conf_client;
+ GList *ls;
+ gda_config_section *section;
+
+ section = NULL;
+ for (ls = sections; ls; ls = ls->next){
+ section = ls->data;
+ if (!strcmp (section->path, path))
+ break;
+
+ section = NULL;
+ }
+
+ return section;
}
+static gda_config_entry *
+gda_config_search_entry (GList *sections, const gchar *path, const gchar *type)
+{
+ gint last_dash;
+ gchar *ptr_last_dash;
+ gchar *section_path;
+ GList *le;
+ gda_config_section *section;
+ gda_config_entry *entry;
+
+ if (sections == NULL)
+ return NULL;
+
+ ptr_last_dash = strrchr (path, '/');
+ if (ptr_last_dash == NULL)
+ return NULL;
+
+ last_dash = ptr_last_dash - path;
+ section_path = g_strdup (path);
+ section_path [last_dash] = '\0';
+ entry = NULL;
+ section = gda_config_search_section (sections, section_path);
+ if (section){
+ for (le = section->entries; le; le = le->next){
+ entry = le->data;
+ if (!strcmp (entry->type, type) &&
+ !strcmp (entry->name, ptr_last_dash + 1))
+ break;
+
+ entry = NULL;
+ }
+ }
+
+ g_free (section_path);
+ return entry;
+}
+
+static gda_config_section *
+gda_config_add_section (const gchar *section_path)
+{
+ gda_config_client *cfg_client;
+ gda_config_section *section;
+
+ section = g_new (gda_config_section, 1);
+ section->path = g_strdup (section_path);
+ section->entries = NULL;
+
+ cfg_client = get_config_client ();
+ cfg_client->user = g_list_append (cfg_client->user, section);
+
+ return section;
+}
+
+static void
+gda_config_add_entry (const gchar *section_path,
+ const gchar *name,
+ const gchar *type,
+ const gchar *value)
+{
+ gda_config_entry *entry;
+ gda_config_section *section;
+ gda_config_client *cfg_client;
+
+ cfg_client = get_config_client ();
+ entry = g_new (gda_config_entry, 1);
+ entry->name = g_strdup (name);
+ entry->type = g_strdup (type);
+ entry->value = g_strdup (value);
+
+ section = gda_config_search_section (cfg_client->global, section_path);
+ if (section == NULL)
+ section = gda_config_add_section (section_path);
+
+ section->entries = g_list_append (section->entries, entry);
+}
+
+static void
+free_entry (gpointer data, gpointer user_data)
+{
+ gda_config_entry *entry = data;
+
+ g_free (entry->name);
+ g_free (entry->type);
+ g_free (entry->value);
+ g_free (entry);
+}
+
+static void
+free_section (gpointer data, gpointer user_data)
+{
+ gda_config_section *section = data;
+
+ g_list_foreach (section->entries, free_entry, NULL);
+ g_list_free (section->entries);
+ g_free (section->path);
+ g_free (section);
+}
+
+/*
+ * Public functions
+ */
+
/**
* gda_config_get_string
* @path: path to the configuration entry
@@ -61,7 +312,19 @@
gchar *
gda_config_get_string (const gchar *path)
{
- return gconf_client_get_string (get_conf_client (), path, NULL);
+ gda_config_client *cfg_client;
+ gda_config_entry *entry;
+
+ g_return_val_if_fail (path != NULL, NULL);
+
+ cfg_client = get_config_client ();
+
+ entry = gda_config_search_entry (cfg_client->user, path, "string");
+ if (entry == NULL)
+ entry = gda_config_search_entry (cfg_client->global, path, "string");
+
+ return (entry != NULL && entry->value != NULL) ?
+ g_strdup (entry->value) : NULL;
}
/**
@@ -75,7 +338,19 @@
gint
gda_config_get_int (const gchar *path)
{
- return gconf_client_get_int (get_conf_client (), path, NULL);
+ gda_config_client *cfg_client;
+ gda_config_entry *entry;
+
+ g_return_val_if_fail (path != NULL, 0);
+
+ cfg_client = get_config_client ();
+
+ entry = gda_config_search_entry (cfg_client->user, path, "long");
+ if (entry == NULL)
+ entry = gda_config_search_entry (cfg_client->global, path, "long");
+
+ return (entry != NULL && entry->value != NULL) ?
+ atoi (entry->value) : 0;
}
/**
@@ -89,7 +364,19 @@
gdouble
gda_config_get_float (const gchar *path)
{
- return gconf_client_get_float (get_conf_client (), path, NULL);
+ gda_config_client *cfg_client;
+ gda_config_entry *entry;
+
+ g_return_val_if_fail (path != NULL, 0.0);
+
+ cfg_client = get_config_client ();
+
+ entry = gda_config_search_entry (cfg_client->user, path, "float");
+ if (entry == NULL)
+ entry = gda_config_search_entry (cfg_client->global, path, "float");
+
+ return (entry != NULL && entry->value != NULL) ?
+ g_strtod (entry->value, NULL) : 0.0;
}
/**
@@ -103,7 +390,19 @@
gboolean
gda_config_get_boolean (const gchar *path)
{
- return gconf_client_get_bool (get_conf_client (), path, NULL);
+ gda_config_client *cfg_client;
+ gda_config_entry *entry;
+
+ g_return_val_if_fail (path != NULL, FALSE);
+
+ cfg_client = get_config_client ();
+
+ entry = gda_config_search_entry (cfg_client->user, path, "boolean");
+ if (entry == NULL)
+ entry = gda_config_search_entry (cfg_client->global, path, "boolean");
+
+ return (entry != NULL && entry->value != NULL) ?
+ (*(entry->value) - '0') : FALSE;
}
/**
@@ -116,7 +415,35 @@
void
gda_config_set_string (const gchar *path, const gchar *new_value)
{
- gconf_client_set_string (get_conf_client (), path, new_value, NULL);
+ gda_config_entry *entry;
+ gchar *ptr_last_dash;
+ gchar *section_path;
+ gint last_dash;
+ gda_config_client *cfg_client;
+
+ g_return_if_fail (path != NULL);
+ g_return_if_fail (new_value != NULL);
+
+ cfg_client = get_config_client ();
+ entry = gda_config_search_entry (cfg_client->user, path, "string");
+ if (entry == NULL){
+ ptr_last_dash = strrchr (path, '/');
+ if (ptr_last_dash == NULL){
+ g_warning ("%s does not containt any '/'!?", path);
+ return;
+ }
+ last_dash = ptr_last_dash - path;
+ section_path = g_strdup (path);
+ section_path [last_dash] = '\0';
+ gda_config_add_entry (section_path, ptr_last_dash + 1,
+ "string", new_value);
+ g_free (section_path);
+ } else {
+ g_free (entry->value);
+ entry->value = g_strdup (new_value);
+ }
+
+ do_notify (path);
}
/**
@@ -129,7 +456,37 @@
void
gda_config_set_int (const gchar *path, gint new_value)
{
- gconf_client_set_int (get_conf_client (), path, new_value, NULL);
+ gda_config_entry *entry;
+ gchar *ptr_last_dash;
+ gchar *section_path;
+ gint last_dash;
+ gchar *newstr;
+ gda_config_client *cfg_client;
+
+ g_return_if_fail (path !=NULL);
+
+ cfg_client = get_config_client ();
+ entry = gda_config_search_entry (cfg_client->user, path, "long");
+ if (entry == NULL){
+ ptr_last_dash = strrchr (path, '/');
+ if (ptr_last_dash == NULL){
+ g_warning ("%s does not containt any '/'!?", path);
+ return;
+ }
+ last_dash = ptr_last_dash - path;
+ section_path = g_strdup (path);
+ section_path [last_dash] = '\0';
+ newstr = g_strdup_printf ("%d", new_value);
+ gda_config_add_entry (section_path, ptr_last_dash + 1,
+ "long", newstr);
+ g_free (newstr);
+ g_free (section_path);
+ } else {
+ g_free (entry->value);
+ entry->value = g_strdup_printf ("%d", new_value);
+ }
+
+ do_notify (path);
}
/**
@@ -142,7 +499,37 @@
void
gda_config_set_float (const gchar * path, gdouble new_value)
{
- gconf_client_set_float (get_conf_client (), path, new_value, NULL);
+ gda_config_entry *entry;
+ gchar *ptr_last_dash;
+ gchar *section_path;
+ gint last_dash;
+ gchar *newstr;
+ gda_config_client *cfg_client;
+
+ g_return_if_fail (path !=NULL);
+
+ cfg_client = get_config_client ();
+ entry = gda_config_search_entry (cfg_client->user, path, "float");
+ if (entry == NULL){
+ ptr_last_dash = strrchr (path, '/');
+ if (ptr_last_dash == NULL){
+ g_warning ("%s does not containt any '/'!?", path);
+ return;
+ }
+ last_dash = ptr_last_dash - path;
+ section_path = g_strdup (path);
+ section_path [last_dash] = '\0';
+ newstr = g_strdup_printf ("%f", new_value);
+ gda_config_add_entry (section_path, ptr_last_dash + 1,
+ "float", newstr);
+ g_free (newstr);
+ g_free (section_path);
+ } else {
+ g_free (entry->value);
+ entry->value = g_strdup_printf ("%f", new_value);
+ }
+
+ do_notify (path);
}
/**
@@ -155,8 +542,38 @@
void
gda_config_set_boolean (const gchar *path, gboolean new_value)
{
- g_return_if_fail (path != NULL);
- gconf_client_set_bool (get_conf_client (), path, new_value, NULL);
+ gda_config_entry *entry;
+ gchar *ptr_last_dash;
+ gchar *section_path;
+ gint last_dash;
+ gchar *newstr;
+ gda_config_client *cfg_client;
+
+ g_return_if_fail (path !=NULL);
+
+ new_value = new_value != 0 ? TRUE : FALSE;
+ cfg_client = get_config_client ();
+ entry = gda_config_search_entry (cfg_client->user, path, "boolean");
+ if (entry == NULL){
+ ptr_last_dash = strrchr (path, '/');
+ if (ptr_last_dash == NULL){
+ g_warning ("%s does not containt any '/'!?", path);
+ return;
+ }
+ last_dash = ptr_last_dash - path;
+ section_path = g_strdup (path);
+ section_path [last_dash] = '\0';
+ newstr = g_strdup_printf ("%d", new_value);
+ gda_config_add_entry (section_path, ptr_last_dash + 1,
+ "boolean", newstr);
+ g_free (newstr);
+ g_free (section_path);
+ } else {
+ g_free (entry->value);
+ entry->value = g_strdup_printf ("%d", new_value);
+ }
+
+ do_notify (path);
}
/**
@@ -168,9 +585,21 @@
void
gda_config_remove_section (const gchar *path)
{
- g_return_if_fail (path != NULL);
- /* FIXME: see bug #73323 */
- //gconf_client_recursive_unset (get_conf_client (), path, 0, NULL);
+ gda_config_section *section;
+ gda_config_client *cfg_client;
+
+ g_return_if_fail (path != NULL);
+
+ cfg_client = get_config_client ();
+ section = gda_config_search_section (cfg_client->user, path);
+ if (section == NULL){
+ g_warning ("Section %s not found!", path);
+ return;
+ }
+
+ cfg_client->user = g_list_remove (cfg_client->user, section);
+ free_section (section, NULL);
+ do_notify (path);
}
/**
@@ -182,7 +611,42 @@
void
gda_config_remove_key (const gchar *path)
{
- gconf_client_unset (get_conf_client (), path, NULL);
+ gint last_dash;
+ gchar *ptr_last_dash;
+ gchar *section_path;
+ GList *le;
+ gda_config_section *section;
+ gda_config_entry *entry;
+ gda_config_client *cfg_client;
+
+ g_return_if_fail (path != NULL);
+
+ ptr_last_dash = strrchr (path, '/');
+ if (ptr_last_dash == NULL)
+ return;
+
+ last_dash = ptr_last_dash - path;
+ section_path = g_strdup (path);
+ section_path [last_dash] = '\0';
+ entry = NULL;
+ cfg_client = get_config_client ();
+ section = gda_config_search_section (cfg_client->user, section_path);
+ if (section){
+ for (le = section->entries; le; le = le->next){
+ entry = le->data;
+ if (!strcmp (entry->name, ptr_last_dash + 1))
+ break;
+
+ entry = NULL;
+ }
+ }
+
+ g_free (section_path);
+ if (entry != NULL){
+ section->entries = g_list_remove (section->entries, entry);
+ free_entry (entry, NULL);
+ do_notify (path);
+ }
}
/**
@@ -197,7 +661,14 @@
gboolean
gda_config_has_section (const gchar *path)
{
- return gconf_client_dir_exists (get_conf_client (), path, NULL);
+ gda_config_section *section;
+ gda_config_client *cfg_client;
+
+ g_return_val_if_fail (path != NULL, FALSE);
+
+ cfg_client = get_config_client ();
+ section = gda_config_search_section (cfg_client->user, path);
+ return (section != NULL) ? TRUE : FALSE;
}
/**
@@ -211,16 +682,14 @@
gboolean
gda_config_has_key (const gchar *path)
{
- GConfValue *value;
+ gda_config_entry *entry;
+ gda_config_client *cfg_client;
- g_return_val_if_fail (path != NULL, FALSE);
+ g_return_val_if_fail (path != NULL, FALSE);
- value = gconf_client_get (get_conf_client (), path, NULL);
- if (value) {
- gconf_value_free (value);
- return TRUE;
- }
- return FALSE;
+ cfg_client = get_config_client ();
+ entry = gda_config_search_entry (cfg_client->user, path, NULL);
+ return (entry != NULL) ? TRUE : FALSE;
}
/**
@@ -237,25 +706,34 @@
GList *
gda_config_list_sections (const gchar *path)
{
+ gda_config_client *cfg_client;
+ GList *list;
GList *ret = NULL;
- GSList *slist;
+ gda_config_section *section;
+ gint len;
g_return_val_if_fail (path != NULL, NULL);
- slist = gconf_client_all_dirs (get_conf_client (), path, NULL);
- if (slist) {
- GSList *node;
-
- for (node = slist; node != NULL; node = g_slist_next (node)) {
- gchar *section_name;
-
- section_name = strrchr ((const char *) node->data, '/');
- if (section_name) {
- ret = g_list_append (ret, g_strdup (section_name + 1));
- }
- }
- g_slist_free (slist);
- }
+ len = strlen (path);
+ cfg_client = get_config_client ();
+ if (cfg_client->global){
+ for (list = cfg_client->global; list; list = list->next){
+ section = list->data;
+ if (section && len < strlen (section->path) &&
+ !strncmp (path, section->path, len)){
+ ret = g_list_append (ret, g_strdup (section->path + len + 1));
+ }
+ }
+
+ if (cfg_client->user){
+ for (list = cfg_client->user; list; list = list->next){
+ section = list->data;
+ if (section && len < strlen (section->path) &&
+ !strncmp (path, section->path, len))
+ ret = g_list_append (ret, g_strdup (section->path + len + 1));
+ }
+ }
+
return ret;
}
@@ -272,33 +750,44 @@
GList *
gda_config_list_keys (const gchar * path)
{
+ GList *ls;
+ GList *le;
GList *ret = NULL;
- GSList *slist;
+ gda_config_section *section;
+ gda_config_entry *entry;
+ gda_config_client *cfg_client;
+ gint len;
g_return_val_if_fail (path != NULL, NULL);
- slist = gconf_client_all_entries (get_conf_client (), path, NULL);
- if (slist) {
- GSList *node;
-
- for (node = slist; node != NULL; node = g_slist_next (node)) {
- GConfEntry *entry = (GConfEntry *) node->data;
- if (entry) {
- gchar *entry_name;
-
- entry_name = strrchr (
- (const char *) gconf_entry_get_key (entry),
- '/');
- if (entry_name) {
- ret = g_list_append (
- ret,
- g_strdup (entry_name + 1));
- }
- gconf_entry_free (entry);
- }
- }
- g_slist_free (slist);
- }
+ len = strlen (path);
+ cfg_client = get_config_client ();
+ if (cfg_client->global){
+ for (ls = cfg_client->global; ls; ls = ls->next){
+ section = ls->data;
+ if (!strcmp (path, section->path))
+ for (le = section->entries; le; le = le->next){
+ entry = le->data;
+ if (entry && entry->name)
+ ret = g_list_append (ret,
+ g_strdup (entry->name));
+ }
+ }
+ }
+
+ if (cfg_client->user){
+ for (ls = cfg_client->user; ls; ls = ls->next){
+ section = ls->data;
+ if (!strcmp (path, section->path))
+ for (le = section->entries; le; le = le->next){
+ entry = le->data;
+ if (entry && entry->name)
+ ret = g_list_append (ret,
+ g_strdup (entry->name));
+ }
+ }
+ }
+
return ret;
}
@@ -310,84 +799,10 @@
* from either #gda_config_list_sections and #gda_config_list_keys
*/
void
-gda_config_free_list (GList * list)
-{
- while (list != NULL) {
- gchar *str = (gchar *) list->data;
- list = g_list_remove (list, (gpointer) str);
- g_free ((gpointer) str);
- }
-}
-
-typedef struct {
- guint id;
- GdaConfigListenerFunc func;
- gpointer user_data;
-} config_listener_data_t;
-
-static void
-config_listener_func (GConfClient *conf, guint id, GConfEntry *entry, gpointer user_data)
-{
- config_listener_data_t *listener_data = (config_listener_data_t *) user_data;
-
- g_return_if_fail (entry != NULL);
- g_return_if_fail (listener_data != NULL);
- g_return_if_fail (listener_data->func != NULL);
-
- listener_data->func (entry->key, listener_data->user_data);
-}
-
-/**
- * gda_config_add_listener
- * @path: configuration path to listen to.
- * @func: callback function.
- * @user_data: data to be passed to the callback function.
- *
- * Installs a configuration listener, which is a callback function
- * which will be called every time a change occurs on a given
- * configuration entry.
- *
- * Returns: the ID of the listener, which you will need for
- * calling #gda_config_remove_listener. If an error occurs,
- * 0 is returned.
- */
-guint
-gda_config_add_listener (const gchar *path, GdaConfigListenerFunc func, gpointer user_data)
+gda_config_free_list (GList *list)
{
- config_listener_data_t *listener_data;
- GError *err;
-
- g_return_val_if_fail (path != NULL, 0);
- g_return_val_if_fail (func != NULL, 0);
-
- listener_data = g_new0 (config_listener_data_t, 1);
- listener_data->func = func;
- listener_data->user_data = user_data;
-
- gconf_client_add_dir (get_conf_client (), path, GCONF_CLIENT_PRELOAD_NONE, NULL);
- listener_data->id = gconf_client_notify_add (
- get_conf_client (),
- path,
- (GConfClientNotifyFunc) config_listener_func,
- listener_data,
- (GFreeFunc) g_free,
- &err);
- if (listener_data->id == 0) {
- g_free (listener_data);
- return 0;
- }
-
- return listener_data->id;
-}
-
-/**
- * gda_config_remove_listener
- */
-void
-gda_config_remove_listener (guint id)
-{
- /* FIXME: remove directory from GConf list of watched dirs */
- gconf_client_notify_remove (get_conf_client (), id);
+ g_list_foreach (list, (GFunc) g_free, NULL);
+ g_list_free (list);
}
/**
@@ -431,7 +846,8 @@
if (strcmp (ext, ".so"))
continue;
- path = g_build_path (G_DIR_SEPARATOR_S, LIBGDA_PLUGINDIR, name, NULL);
+ path = g_build_path (G_DIR_SEPARATOR_S, LIBGDA_PLUGINDIR,
+ name, NULL);
handle = g_module_open (path, G_MODULE_BIND_LAZY);
if (!handle) {
g_free (path);
@@ -772,3 +1188,95 @@
gda_config_remove_section (dir);
g_free (dir);
}
+
+typedef struct {
+ guint id;
+ GdaConfigListenerFunc func;
+ gpointer user_data;
+ gchar *path;
+} config_listener_data_t;
+
+static GList *listeners;
+static guint next_id;
+
+static void
+config_listener_func (gpointer data, gpointer user_data)
+{
+ GList *l;
+ config_listener_data_t *listener = data;
+ gchar *path = user_data;
+ gint len;
+
+ g_return_if_fail (listener != NULL);
+ g_return_if_fail (path != NULL);
+
+ len = strlen (path);
+ for (l = listeners; l; l = l->next){
+ listener = l->data;
+ if (!strncmp (listener->path, path, len)){
+ listener->func (path, listener->user_data);
+ }
+ }
+
+}
+
+static void
+do_notify (const gchar *path)
+{
+ g_list_foreach (listeners, config_listener_func, (gpointer) path);
+}
+
+/**
+ * gda_config_add_listener
+ * @path: configuration path to listen to.
+ * @func: callback function.
+ * @user_data: data to be passed to the callback function.
+ *
+ * Installs a configuration listener, which is a callback function
+ * which will be called every time a change occurs on a given
+ * configuration entry.
+ *
+ * Returns: the ID of the listener, which you will need for
+ * calling #gda_config_remove_listener. If an error occurs,
+ * 0 is returned.
+ */
+guint
+gda_config_add_listener (const gchar *path,
+ GdaConfigListenerFunc func,
+ gpointer user_data)
+{
+ config_listener_data_t *listener;
+
+ g_return_val_if_fail (path != NULL, 0);
+ g_return_val_if_fail (func != NULL, 0);
+
+ listener = g_new (config_listener_data_t, 1);
+ listener->id = next_id++;
+ listener->func = func;
+ listener->user_data = user_data;
+ listener->path = g_strdup (path);
+ listeners = g_list_append (listeners, listener);
+
+ return listener->id;
+}
+
+/**
+ * gda_config_remove_listener
+ */
+void
+gda_config_remove_listener (guint id)
+{
+ GList *l;
+ config_listener_data_t *listener;
+
+ for (l = listeners; l; l = l->next){
+ listener = l->data;
+ if (listener->id == id){
+ listeners = g_list_remove (listeners, listener);
+ g_free (listener->path);
+ g_free (listener);
+ break;
+ }
+ }
+}
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]