corba -> dbus
- From: David Vanderson <david vanderson gmail com>
- To: gconf-list gnome org
- Subject: corba -> dbus
- Date: Thu, 15 Feb 2007 16:23:56 -0500
Hello,
I have attached a rough patch as a start towards goal #1 on:
http://www.gnome.org/projects/gconf/plans.html
Please comment and let me know if I'm even going in the right direction.
Here's what it does:
- converts simple Get and Set requests, as well as notifications, to
run over dbus (everything else still goes over corba, including
changesets I think)
- gconfd exits on startup if it can't own the "org.gnome.gconf" name
- uses dbus 1.0 api
Known badness:
- gconfd broadcasts notifications to everyone
- handling dbus messages uses polling
- error checking is severely lacking
Thanks to Imendio for some good starting code for putting GConfValues
through dbus that I shamelessly ripped.
Thanks,
Dave
Index: configure.in
===================================================================
--- configure.in (revision 2360)
+++ configure.in (working copy)
@@ -136,6 +136,13 @@
PKGCONFIG_MODULES_WITH_GTK=" $PKGCONFIG_MODULES gtk+-2.0 >= 2.0.0"
PKGCONFIG_MODULES_WITH_XML_AND_GTK=" $PKGCONFIG_MODULES gtk+-2.0 libxml-2.0"
+#this should require dbus >= 1.0
+PKG_CHECK_MODULES(GCONF_DBUS, dbus-1 >= 0.93, have_dbus=yes, have_dbus=no)
+AC_DEFINE(HAVE_DBUS, 1, D-BUS support in the daemon)
+PC_REQUIRES="dbus-1"
+AC_SUBST(GCONF_DBUS_CFLAGS)
+AC_SUBST(GCONF_DBUS_LIBS)
+
PKG_CHECK_MODULES(DEPENDENT, $PKGCONFIG_MODULES)
PKG_CHECK_MODULES(DEPENDENT_WITH_XML, $PKGCONFIG_MODULES_WITH_XML)
Index: gconf/gconfd.c
===================================================================
--- gconf/gconfd.c (revision 2360)
+++ gconf/gconfd.c (working copy)
@@ -57,6 +57,10 @@
#include <sys/wait.h>
#endif
#include <locale.h>
+#define DBUS_API_SUBJECT_TO_CHANGE 1
+#include <dbus/dbus.h>
+#include "gconf-dbus-utils.h"
+static DBusConnection *dbus_connection;
/* This makes hash table safer when debugging */
#ifndef GCONF_ENABLE_DEBUG
@@ -617,6 +621,40 @@
int dev_null_fd;
int write_byte_fd;
+ DBusError error;
+ dbus_error_init (&error);
+ dbus_connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
+ if (dbus_error_is_set(&error))
+ {
+ dbus_connection = NULL;
+ fprintf (stderr, "Error opening connection to dbus: %s\n", error.message);
+ dbus_error_free (&error);
+ exit (1);
+ }
+ else
+ {
+ int ret = dbus_bus_request_name (dbus_connection,
+ "org.gnome.gconf",
+ 0,
+ &error);
+ if (dbus_error_is_set(&error))
+ {
+ fprintf (stderr, "Error requesting name : %s\n", error.message);
+ dbus_error_free (&error);
+ }
+
+ if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
+ {
+ fprintf (stderr, "Did not become owner of name: %d\n", ret);
+ exit(1);
+ }
+ else
+ {
+ fprintf (stderr, "Successfully requested dbus name\n");
+ }
+ }
+
+
_gconf_init_i18n ();
setlocale (LC_ALL, "");
textdomain (GETTEXT_PACKAGE);
@@ -859,9 +897,168 @@
static GSList* main_loops = NULL;
static guint timeout_id = 0;
+static guint dbus_timeout_id = 0;
static gboolean need_log_cleanup = FALSE;
+static void
+gconfd_handle_dbus_set_request(DBusMessage* message)
+{
+ DBusMessage* reply;
+ DBusMessageIter args;
+ GConfDatabase *db;
+ GConfValue *value;
+ char* key = NULL;
+ GError *error = NULL;
+ ConfigValue *cvalue;
+
+ fprintf(stderr, "handling dbus set request\n");
+
+ if (!dbus_message_iter_init(message, &args))
+ {
+ fprintf(stderr, "Set message has no arguments\n");
+ }
+
+ dbus_message_iter_get_basic(&args, &key);
+ dbus_message_iter_next(&args);
+ value = gconf_dbus_message_iter_get_gconf_value(&args);
+ db = lookup_database(NULL);
+
+ cvalue = gconf_corba_value_from_gconf_value(value);
+
+ gconf_database_set(db,
+ key,
+ value,
+ cvalue,
+ &error);
+
+ //TODO: pass back the error if there is one?
+ reply = dbus_message_new_method_return(message);
+ dbus_connection_send(dbus_connection, reply, NULL);
+ dbus_connection_flush(dbus_connection);
+ dbus_message_unref(reply);
+
+ if (value)
+ gconf_value_free(value);
+
+ if (cvalue)
+ CORBA_free(cvalue);
+}
+
+static void
+dbus_get_reply(DBusMessage* message)
+{
+ DBusMessage* reply;
+ DBusMessageIter args;
+ char* key = NULL;
+ char* val = NULL;
+ char* schema_name = NULL;
+ GConfDatabase *db;
+ GConfValue *value;
+ gboolean is_default;
+ gboolean is_writable;
+ GError *error = NULL;
+
+ if (!dbus_message_iter_init(message, &args))
+ {
+ fprintf(stderr, "Get message has no arguments\n");
+ }
+ else
+ {
+ dbus_message_iter_get_basic(&args, &key);
+ }
+
+ if (key != NULL)
+ {
+ fprintf(stderr, "Get method called on key: %s\n", key);
+ }
+
+ db = lookup_database(NULL);
+ value = gconf_database_query_value(db,
+ key,
+ NULL,
+ TRUE,
+ &schema_name,
+ &is_default,
+ &is_writable,
+ &error);
+ if (error != NULL)
+ {
+ fprintf(stderr, "Error doing database query for '%s': %s\n",
+ key, error->message);
+ g_error_free(error);
+ value = NULL;
+ }
+
+ if (value != NULL)
+ {
+ val = gconf_value_to_string(value);
+ fprintf(stderr, "Got value from gconf: %s\n", val);
+ g_free(val);
+ }
+
+ reply = dbus_message_new_method_return(message);
+ dbus_message_iter_init_append(reply, &args);
+ gconf_dbus_message_iter_append_gconf_entry(&args,
+ key,
+ value,
+ is_default,
+ is_writable,
+ schema_name);
+
+ dbus_connection_send(dbus_connection, reply, NULL);
+ dbus_connection_flush(dbus_connection);
+ if (value)
+ gconf_value_free (value);
+ dbus_message_unref(reply);
+}
+
+
static gboolean
+dbus_message_timeout(gpointer data)
+{
+ DBusMessage* message;
+
+ if (dbus_connection == NULL)
+ {
+ fprintf(stderr, "dbus connection was null\n");
+ return TRUE;
+ }
+
+ while (TRUE)
+ {
+ dbus_connection_read_write(dbus_connection, 0);
+ message = dbus_connection_pop_message(dbus_connection);
+ if (message != NULL)
+ {
+ if (dbus_message_is_method_call(message,
+ "org.gnome.gconf",
+ "Get"))
+ {
+ dbus_get_reply(message);
+ }
+ else if (dbus_message_is_method_call(message,
+ "org.gnome.gconf",
+ "Set"))
+ {
+ gconfd_handle_dbus_set_request(message);
+ }
+ else
+ {
+ fprintf(stderr, "dbus message was not a recognized method call\n");
+ }
+
+ dbus_message_unref(message);
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
periodic_cleanup_timeout(gpointer data)
{
if (need_db_reload)
@@ -926,6 +1123,12 @@
timeout_id = g_timeout_add (timeout_len,
periodic_cleanup_timeout,
NULL);
+
+ timeout_len = 50; //.5 seconds
+ g_assert(dbus_timeout_id == 0);
+ dbus_timeout_id = g_timeout_add (timeout_len,
+ dbus_message_timeout,
+ NULL);
}
@@ -940,6 +1143,10 @@
g_assert(timeout_id != 0);
g_source_remove(timeout_id);
timeout_id = 0;
+
+ g_assert(dbus_timeout_id != 0);
+ g_source_remove(dbus_timeout_id);
+ dbus_timeout_id = 0;
}
g_main_loop_unref (loop);
@@ -1179,7 +1386,58 @@
while (tmp != NULL)
{
GConfDatabase *db = tmp->data;
+
+
+ GConfValue *value;
+ GError *error;
+ gboolean is_default;
+ gboolean is_writable;
+ gchar *schema_name;
+ error = NULL;
+ value = gconf_database_query_value (db,
+ key,
+ NULL,
+ TRUE,
+ &schema_name,
+ &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;
+ }
+
+ fprintf(stderr, "sending dbus signal PreferenceChanged\n");
+ dbus_uint32_t serial = 0;
+ DBusMessage* signal;
+ DBusMessageIter args;
+ signal = dbus_message_new_signal("/org/gnome/gconf",
+ "org.gnome.gconf",
+ "PreferenceChanged");
+ dbus_message_iter_init_append(signal, &args);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &key);
+ gconf_dbus_message_iter_append_gconf_entry(&args,
+ key,
+ value,
+ is_default,
+ is_writable,
+ schema_name);
+ dbus_connection_send(dbus_connection, signal, &serial);
+ dbus_connection_flush(dbus_connection);
+ dbus_message_unref(signal);
+
+ if (value)
+ gconf_value_free(value);
+
+ if (schema_name != NULL)
+ g_free(schema_name);
+
+
if (db != modified_db)
{
GList *tmp2;
@@ -1191,7 +1449,7 @@
if (gconf_sources_is_affected (db->sources, modified_source, key))
{
- GConfValue *value;
+ /*GConfValue *value;
ConfigValue *cvalue;
GError *error;
gboolean is_default;
@@ -1233,6 +1491,7 @@
is_writable,
FALSE);
CORBA_free (cvalue);
+ */
}
tmp2 = tmp2->next;
Index: gconf/gconf-dbus-utils.c
===================================================================
--- gconf/gconf-dbus-utils.c (revision 0)
+++ gconf/gconf-dbus-utils.c (revision 0)
@@ -0,0 +1,669 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+
+#include <config.h>
+#include <string.h>
+#define DBUS_API_SUBJECT_TO_CHANGE 1
+#include <dbus/dbus.h>
+#include "gconf-dbus-utils.h"
+#include "gconf-internals.h"
+
+#if 0
+GConfValue *
+gconf_value_from_dict (DBusMessageIter *iter,
+ const char *key)
+{
+ DBusMessageIter dict;
+ gchar *str;
+ gboolean found = FALSE;
+ GConfValue *value;
+
+ g_return_val_if_fail (iter != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ g_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_DICT);
+
+ dbus_message_iter_init_dict_iterator (iter, &dict);
+
+ while (1)
+ {
+ str = dbus_message_iter_get_dict_key (&dict);
+
+ if (str != NULL && strcmp (str, key) == 0)
+ {
+ dbus_free (str);
+ found = TRUE;
+ break;
+ }
+
+ dbus_free (str);
+
+ if (!dbus_message_iter_next (&dict))
+ break;
+ }
+
+ if (!found)
+ {
+ g_error ("Unknown dict key.");
+ return NULL;
+ }
+
+ switch (dbus_message_iter_get_arg_type (&dict))
+ {
+ case DBUS_TYPE_STRING:
+ {
+ gchar *str;
+ value = gconf_value_new (GCONF_VALUE_STRING);
+
+ str = dbus_message_iter_get_string (&dict);
+ gconf_value_set_string (value, str);
+ dbus_free (str);
+
+ return value;
+ }
+ case DBUS_TYPE_INT32:
+ {
+ dbus_int32_t val;
+
+ value = gconf_value_new (GCONF_VALUE_INT);
+
+ val = dbus_message_iter_get_int32 (&dict);
+ gconf_value_set_int (value, val);
+
+ return value;
+ }
+ case DBUS_TYPE_DOUBLE:
+ {
+ double val;
+
+ value = gconf_value_new (GCONF_VALUE_FLOAT);
+
+ val = dbus_message_iter_get_double (&dict);
+ gconf_value_set_float (value, val);
+
+ return value;
+ }
+ case DBUS_TYPE_BOOLEAN:
+ {
+ dbus_bool_t val;
+
+ value = gconf_value_new (GCONF_VALUE_BOOL);
+
+ val = dbus_message_iter_get_boolean (&dict);
+ gconf_value_set_bool (value, val);
+
+ return value;
+ }
+
+ case DBUS_TYPE_NIL:
+ return NULL;
+
+ default:
+ return NULL;
+ }
+}
+
+void
+set_dict_value_from_gconf_value (DBusMessageIter *dict,
+ const char *key,
+ GConfValue *value)
+{
+ dbus_message_iter_append_dict_key (dict, key);
+
+ if (value == NULL)
+ {
+ dbus_message_iter_append_nil (dict);
+ return;
+ }
+
+ switch (value->type)
+ {
+ case GCONF_VALUE_STRING:
+ dbus_message_iter_append_string (dict, gconf_value_get_string (value));
+ break;
+ case GCONF_VALUE_INT:
+ dbus_message_iter_append_int32 (dict, gconf_value_get_int (value));
+ break;
+ case GCONF_VALUE_FLOAT:
+ dbus_message_iter_append_double (dict, gconf_value_get_float (value));
+ break;
+ case GCONF_VALUE_BOOL:
+ dbus_message_iter_append_boolean (dict, gconf_value_get_bool (value));
+ break;
+
+ /* Note: This is only used for setting the values in a pair, and lists and
+ * pairs are not allowed inside a pair.
+ */
+ case GCONF_VALUE_PAIR:
+ case GCONF_VALUE_LIST:
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+void
+gconf_dbus_message_iter_append_gconf_schema (DBusMessageIter *iter,
+ const GConfSchema *schema)
+{
+ DBusMessageIter dict;
+ GConfValue *default_val;
+
+ if (!schema)
+ {
+ dbus_message_iter_append_nil (iter);
+ return;
+ }
+
+ dbus_message_iter_append_dict (iter, &dict);
+
+ dbus_message_iter_append_dict_key (&dict, "type");
+ dbus_message_iter_append_int32 (&dict, gconf_schema_get_type (schema));
+
+ dbus_message_iter_append_dict_key (&dict, "list_type");
+ dbus_message_iter_append_int32 (&dict, gconf_schema_get_list_type (schema));
+
+ dbus_message_iter_append_dict_key (&dict, "car_type");
+ dbus_message_iter_append_int32 (&dict, gconf_schema_get_car_type (schema));
+
+ dbus_message_iter_append_dict_key (&dict, "cdr_type");
+ dbus_message_iter_append_int32 (&dict, gconf_schema_get_cdr_type (schema));
+
+ dbus_message_iter_append_dict_key (&dict, "locale");
+ dbus_message_iter_append_string (&dict, gconf_schema_get_locale (schema) ?
+ gconf_schema_get_locale (schema) : "");
+
+ dbus_message_iter_append_dict_key (&dict, "short_desc");
+ dbus_message_iter_append_string (&dict, gconf_schema_get_short_desc (schema) ?
+ gconf_schema_get_short_desc (schema) : "");
+
+ dbus_message_iter_append_dict_key (&dict, "long_desc");
+ dbus_message_iter_append_string (&dict, gconf_schema_get_long_desc (schema) ?
+ gconf_schema_get_long_desc (schema) : "");
+
+ dbus_message_iter_append_dict_key (&dict, "owner");
+ dbus_message_iter_append_string (&dict, gconf_schema_get_owner (schema) ?
+ gconf_schema_get_owner (schema) : "");
+
+ default_val = gconf_schema_get_default_value (schema);
+
+ /* We don't need to do this, but it's much simpler */
+ if (default_val)
+ {
+ gchar *encoded = gconf_value_encode (default_val);
+ g_assert (encoded != NULL);
+
+ dbus_message_iter_append_dict_key (&dict, "default_value");
+ dbus_message_iter_append_string (&dict, encoded);
+
+ g_free (encoded);
+ }
+}
+
+GConfValue *
+gconf_dbus_create_gconf_value_from_dict (DBusMessageIter *dict)
+{
+ DBusMessageIter child_iter;
+ gchar *name;
+ GConfValue *value = NULL;
+
+ g_assert (dbus_message_iter_get_arg_type (dict) == DBUS_TYPE_DICT);
+
+ dbus_message_iter_init_dict_iterator (dict, &child_iter);
+ name = dbus_message_iter_get_dict_key (&child_iter);
+
+ /* Check if we've got a schema dict */
+ if (strcmp (name, "type") == 0)
+ {
+ dbus_int32_t type, list_type, car_type, cdr_type;
+ gchar *tmp;
+ GConfSchema *schema;
+
+ type = dbus_message_iter_get_int32 (&child_iter);
+ dbus_message_iter_next (&child_iter);
+
+ list_type = dbus_message_iter_get_int32 (&child_iter);
+ dbus_message_iter_next (&child_iter);
+
+ car_type = dbus_message_iter_get_int32 (&child_iter);
+ dbus_message_iter_next (&child_iter);
+
+ cdr_type = dbus_message_iter_get_int32 (&child_iter);
+ dbus_message_iter_next (&child_iter);
+
+ schema = gconf_schema_new ();
+
+ gconf_schema_set_type (schema, type);
+ gconf_schema_set_list_type (schema, list_type);
+ gconf_schema_set_car_type (schema, car_type);
+ gconf_schema_set_cdr_type (schema, cdr_type);
+
+ value = gconf_value_new (GCONF_VALUE_SCHEMA);
+ gconf_value_set_schema_nocopy (value, schema);
+
+ tmp = dbus_message_iter_get_string (&child_iter);
+ dbus_message_iter_next (&child_iter);
+ if (*tmp != '\0')
+ gconf_schema_set_locale (schema, tmp);
+ dbus_free (tmp);
+
+ tmp = dbus_message_iter_get_string (&child_iter);
+ dbus_message_iter_next (&child_iter);
+ if (*tmp != '\0')
+ gconf_schema_set_short_desc (schema, tmp);
+ dbus_free (tmp);
+
+ tmp = dbus_message_iter_get_string (&child_iter);
+ dbus_message_iter_next (&child_iter);
+ if (*tmp != '\0')
+ gconf_schema_set_long_desc (schema, tmp);
+ dbus_free (tmp);
+
+ tmp = dbus_message_iter_get_string (&child_iter);
+ dbus_message_iter_next (&child_iter);
+ if (*tmp != '\0')
+ gconf_schema_set_owner (schema, tmp);
+ dbus_free (tmp);
+
+ tmp = dbus_message_iter_get_string (&child_iter);
+ dbus_message_iter_next (&child_iter);
+
+ {
+ GConfValue *val;
+
+ val = gconf_value_decode (tmp);
+
+ if (val)
+ gconf_schema_set_default_value_nocopy (schema, val);
+ }
+
+ dbus_free (tmp);
+ }
+ else if (strcmp (name, "car") == 0)
+ {
+ value = gconf_value_new (GCONF_VALUE_PAIR);
+
+ gconf_value_set_car_nocopy (value, gconf_value_from_dict (dict, "car"));
+ gconf_value_set_cdr_nocopy (value, gconf_value_from_dict (dict, "cdr"));
+ }
+
+ dbus_free (name);
+
+ return value;
+}
+#endif
+
+void
+gconf_dbus_message_append_gconf_value (DBusMessage *message,
+ const GConfValue *value)
+{
+ DBusMessageIter iter;
+
+ dbus_message_iter_init_append (message, &iter);
+
+ gconf_dbus_message_iter_append_gconf_value (&iter, value);
+}
+
+void
+gconf_dbus_message_iter_append_gconf_value (DBusMessageIter *iter,
+ const GConfValue *value)
+{
+ if (value == NULL)
+ {
+ //TODO: this is a hack
+ gchar b = 0;
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &b);
+ return;
+ }
+
+ dbus_int32_t tempInt;
+ gdouble tempDouble;
+ dbus_bool_t tempBool;
+
+ switch (value->type)
+ {
+ case GCONF_VALUE_INT:
+ tempInt = gconf_value_get_int (value);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &tempInt);
+ break;
+ case GCONF_VALUE_STRING:
+ {
+ const char* str;
+ str = gconf_value_get_string (value);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &str);
+ break;
+ }
+ case GCONF_VALUE_FLOAT:
+ tempDouble = gconf_value_get_float (value);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &tempDouble);
+ break;
+ case GCONF_VALUE_BOOL:
+ tempBool = gconf_value_get_bool (value);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &tempBool);
+ break;
+ /*
+ //TODO: should we be able to send invalid values?
+ case GCONF_VALUE_INVALID:
+ dbus_message_iter_append_nil (iter);
+ break;
+ */
+ case GCONF_VALUE_LIST:
+ {
+ GSList* list;
+ DBusMessageIter sub;
+
+ list = gconf_value_get_list (value);
+
+ switch (gconf_value_get_list_type (value))
+ {
+ case GCONF_VALUE_STRING:
+ {
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "s", &sub);
+
+ while (list)
+ {
+ GConfValue *val = list->data;
+ const gchar *str = gconf_value_get_string(val);
+ dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &str);
+ list = list->next;
+ }
+
+ dbus_message_iter_close_container(iter, &sub);
+ break;
+ }
+ case GCONF_VALUE_INT:
+ {
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "i", &sub);
+
+ while (list)
+ {
+ GConfValue *val = list->data;
+ dbus_int32_t i = gconf_value_get_int(val);
+ dbus_message_iter_append_basic(&sub, DBUS_TYPE_INT32, &i);
+ list = list->next;
+ }
+
+ dbus_message_iter_close_container(iter, &sub);
+ break;
+ }
+ case GCONF_VALUE_FLOAT:
+ {
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "d", &sub);
+
+ while (list)
+ {
+ GConfValue *val = list->data;
+ gdouble d = gconf_value_get_float(val);
+ dbus_message_iter_append_basic(&sub, DBUS_TYPE_DOUBLE, &d);
+ list = list->next;
+ }
+
+ dbus_message_iter_close_container(iter, &sub);
+ break;
+ }
+ case GCONF_VALUE_BOOL:
+ {
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "b", &sub);
+
+ while (list)
+ {
+ GConfValue *val = list->data;
+ gboolean b = gconf_value_get_bool(val);
+ dbus_message_iter_append_basic(&sub, DBUS_TYPE_BOOLEAN, &b);
+ list = list->next;
+ }
+
+ dbus_message_iter_close_container(iter, &sub);
+ break;
+ }
+ default:
+ g_error ("unsupported gconf list value type %d", gconf_value_get_list_type (value));
+ }
+ break;
+ }
+ case GCONF_VALUE_PAIR:
+ {
+ //TODO: bad hack
+ gint p = 0;
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &p);
+ gconf_dbus_message_iter_append_gconf_value(iter, gconf_value_get_car(value));
+ gconf_dbus_message_iter_append_gconf_value(iter, gconf_value_get_cdr(value));
+ break;
+ }
+ /*
+ case GCONF_VALUE_SCHEMA:
+ gconf_dbus_message_iter_append_gconf_schema (iter, gconf_value_get_schema (value));
+ break;
+ */
+
+ default:
+ g_error ("unsupported gconf value type %d", value->type);
+ }
+}
+
+//This function advances the DBusMessageIter past the gconf value
+GConfValue *
+gconf_dbus_message_iter_get_gconf_value (DBusMessageIter *iter)
+{
+ int arg_type;
+ GConfValue *gval;
+ GConfValueType type = GCONF_VALUE_INVALID;
+
+ arg_type = dbus_message_iter_get_arg_type (iter);
+
+ switch (arg_type)
+ {
+ case DBUS_TYPE_BYTE:
+ //TODO: this is a hack
+ dbus_message_iter_next(iter);
+ return NULL;
+ case DBUS_TYPE_BOOLEAN:
+ type = GCONF_VALUE_BOOL;
+ break;
+ case DBUS_TYPE_INT32:
+ type = GCONF_VALUE_INT;
+ break;
+ case DBUS_TYPE_DOUBLE:
+ type = GCONF_VALUE_FLOAT;
+ break;
+ case DBUS_TYPE_STRING:
+ type = GCONF_VALUE_STRING;
+ break;
+ case DBUS_TYPE_ARRAY:
+ type = GCONF_VALUE_LIST;
+ break;
+ case DBUS_TYPE_INT16:
+ //TODO: bad hack
+ type = GCONF_VALUE_PAIR;
+ break;
+ default:
+ g_error ("unsupported arg type %d\n", arg_type);
+ }
+
+ g_assert (GCONF_VALUE_TYPE_VALID (type));
+
+ gval = gconf_value_new (type);
+
+ dbus_bool_t tempBool;
+ dbus_int32_t tempInt;
+ gdouble tempDouble;
+
+ switch (gval->type)
+ {
+ case GCONF_VALUE_BOOL:
+ dbus_message_iter_get_basic(iter, &tempBool);
+ dbus_message_iter_next(iter);
+ gconf_value_set_bool(gval, tempBool);
+ break;
+ case GCONF_VALUE_INT:
+ dbus_message_iter_get_basic(iter, &tempInt);
+ dbus_message_iter_next(iter);
+ gconf_value_set_int(gval, tempInt);
+ break;
+ case GCONF_VALUE_FLOAT:
+ dbus_message_iter_get_basic(iter, &tempDouble);
+ dbus_message_iter_next(iter);
+ gconf_value_set_float(gval, tempDouble);
+ break;
+ case GCONF_VALUE_STRING:
+ {
+ const char *str;
+ dbus_message_iter_get_basic(iter, &str);
+ dbus_message_iter_next(iter);
+ gconf_value_set_string (gval, str);
+ break;
+ }
+ case GCONF_VALUE_LIST:
+ {
+ GSList *list = NULL;
+ DBusMessageIter sub;
+
+ switch (dbus_message_iter_get_element_type(iter))
+ {
+ case DBUS_TYPE_STRING:
+ {
+ dbus_message_iter_recurse(iter, &sub);
+ while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID)
+ {
+ gchar *str;
+ dbus_message_iter_get_basic(&sub, &str);
+ GConfValue *val = gconf_value_new(GCONF_VALUE_STRING);
+ gconf_value_set_string(val, str);
+ list = g_slist_prepend(list, val);
+ dbus_message_iter_next(&sub);
+ }
+
+ list = g_slist_reverse(list);
+ gconf_value_set_list_type (gval, GCONF_VALUE_STRING);
+ gconf_value_set_list_nocopy (gval, list);
+ break;
+ }
+ case DBUS_TYPE_BOOLEAN:
+ {
+ dbus_message_iter_recurse(iter, &sub);
+ while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID)
+ {
+ gboolean b;
+ dbus_message_iter_get_basic(&sub, &b);
+ GConfValue *val = gconf_value_new(GCONF_VALUE_BOOL);
+ gconf_value_set_bool(val, b);
+ list = g_slist_prepend(list, val);
+ dbus_message_iter_next(&sub);
+ }
+
+ list = g_slist_reverse(list);
+ gconf_value_set_list_type (gval, GCONF_VALUE_BOOL);
+ gconf_value_set_list_nocopy (gval, list);
+ break;
+ }
+ case DBUS_TYPE_DOUBLE:
+ {
+ dbus_message_iter_recurse(iter, &sub);
+ while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID)
+ {
+ gdouble d;
+ dbus_message_iter_get_basic(&sub, &d);
+ GConfValue *val = gconf_value_new(GCONF_VALUE_FLOAT);
+ gconf_value_set_float(val, d);
+ list = g_slist_prepend(list, val);
+ dbus_message_iter_next(&sub);
+ }
+
+ list = g_slist_reverse(list);
+ gconf_value_set_list_type (gval, GCONF_VALUE_FLOAT);
+ gconf_value_set_list_nocopy (gval, list);
+ break;
+ }
+ case DBUS_TYPE_INT32:
+ {
+ dbus_message_iter_recurse(iter, &sub);
+ while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID)
+ {
+ dbus_int32_t i;
+ dbus_message_iter_get_basic(&sub, &i);
+ GConfValue *val = gconf_value_new(GCONF_VALUE_INT);
+ gconf_value_set_int(val, i);
+ list = g_slist_prepend(list, val);
+ dbus_message_iter_next(&sub);
+ }
+
+ list = g_slist_reverse(list);
+ gconf_value_set_list_type (gval, GCONF_VALUE_INT);
+ gconf_value_set_list_nocopy (gval, list);
+ break;
+ }
+ default:
+ g_error ("unknown list arg type %d", arg_type);
+ }
+ dbus_message_iter_next(iter);
+ break;
+ }
+ case GCONF_VALUE_PAIR:
+ {
+ //TODO: bad hack
+ //throw away marker
+ dbus_message_iter_next(iter);
+
+ GConfValue *car = gconf_dbus_message_iter_get_gconf_value(iter);
+ gconf_value_set_car_nocopy(gval, car);
+ GConfValue *cdr = gconf_dbus_message_iter_get_gconf_value(iter);
+ gconf_value_set_cdr_nocopy(gval, cdr);
+ break;
+ }
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ return gval;
+}
+
+void
+gconf_dbus_message_iter_append_gconf_entry (DBusMessageIter *args,
+ const gchar *key,
+ const GConfValue *value,
+ gboolean is_default,
+ gboolean is_writable,
+ const gchar *schema_name)
+{
+ dbus_message_iter_append_basic(args, DBUS_TYPE_STRING, &key);
+ gconf_dbus_message_iter_append_gconf_value(args, value);
+ dbus_message_iter_append_basic(args, DBUS_TYPE_BOOLEAN, &is_default);
+ dbus_message_iter_append_basic(args, DBUS_TYPE_BOOLEAN, &is_writable);
+
+ if (!schema_name)
+ {
+ schema_name = "";
+ }
+ dbus_message_iter_append_basic(args, DBUS_TYPE_STRING, &schema_name);
+
+}
+
+GConfEntry *
+gconf_dbus_message_iter_get_gconf_entry (DBusMessageIter *args)
+{
+ gchar *key;
+ GConfEntry *entry;
+ gboolean is_default;
+ gboolean is_writable;
+ gchar *schema_name;
+
+ dbus_message_iter_get_basic(args, &key);
+ dbus_message_iter_next(args);
+
+ GConfValue *value = gconf_dbus_message_iter_get_gconf_value(args);
+
+ dbus_message_iter_get_basic(args, &is_default);
+
+ dbus_message_iter_next(args);
+ dbus_message_iter_get_basic(args, &is_writable);
+
+ dbus_message_iter_next(args);
+ dbus_message_iter_get_basic(args, &schema_name);
+
+ entry = gconf_entry_new_nocopy(g_strdup (key), value);
+ gconf_entry_set_is_default(entry, is_default);
+ gconf_entry_set_is_default(entry, is_writable);
+ gconf_entry_set_schema_name(entry, schema_name);
+
+ return entry;
+}
+
Index: gconf/gconf-dbus-utils.h
===================================================================
--- gconf/gconf-dbus-utils.h (revision 0)
+++ gconf/gconf-dbus-utils.h (revision 0)
@@ -0,0 +1,90 @@
+/* GConf
+ * Copyright (C) 2003 Imendio HB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GCONF_DBUS_UTILS_H
+#define GCONF_DBUS_UTILS_H
+
+#include <glib.h>
+#define DBUS_API_SUBJECT_TO_CHANGE 1
+#include <dbus/dbus.h>
+#include <gconf/gconf.h>
+#include <gconf/gconf-value.h>
+
+/*
+#define GCONF_DBUS_SERVICE "org.gnome.GConf"
+
+#define GCONF_DBUS_SERVER_INTERFACE "org.gnome.GConf.Server"
+#define GCONF_DBUS_DATABASE_INTERFACE "org.gnome.GConf.Database"
+
+#define GCONF_DBUS_SERVER_OBJECT "/org/gnome/GConf/Server"
+
+#define GCONF_DBUS_SERVER_GET_DEFAULT_DB "GetDefaultDatabase"
+#define GCONF_DBUS_SERVER_GET_DB "GetDatabase"
+#define GCONF_DBUS_SERVER_SHUTDOWN "Shutdown"
+
+#define GCONF_DBUS_DATABASE_LOOKUP "Lookup"
+#define GCONF_DBUS_DATABASE_LOOKUP_EXTENDED "LookupExtended"
+#define GCONF_DBUS_DATABASE_SET "Set"
+#define GCONF_DBUS_DATABASE_UNSET "Unset"
+#define GCONF_DBUS_DATABASE_RECURSIVE_UNSET "RecursiveUnset"
+#define GCONF_DBUS_DATABASE_DIR_EXISTS "DirExists"
+#define GCONF_DBUS_DATABASE_GET_ALL_ENTRIES "AllEntries"
+#define GCONF_DBUS_DATABASE_GET_ALL_DIRS "AllDirs"
+#define GCONF_DBUS_DATABASE_SET_SCHEMA "SetSchema"
+#define GCONF_DBUS_DATABASE_ADD_NOTIFY "AddNotify"
+#define GCONF_DBUS_DATABASE_REMOVE_NOTIFY "RemoveNotify"
+
+#define GCONF_DBUS_LISTENER_NOTIFY "Notify"
+
+#define GCONF_DBUS_CLIENT_SERVICE "org.gnome.GConf.ClientService"
+#define GCONF_DBUS_CLIENT_OBJECT "/org/gnome/GConf/Client"
+#define GCONF_DBUS_CLIENT_INTERFACE "org.gnome.GConf.Client"
+
+#define GCONF_DBUS_UNSET_INCLUDING_SCHEMA_NAMES 0x1
+
+#define GCONF_DBUS_ERROR_FAILED "org.gnome.GConf.Error.Failed"
+#define GCONF_DBUS_ERROR_NO_PERMISSION "org.gnome.GConf.Error.NoPermission"
+#define GCONF_DBUS_ERROR_BAD_ADDRESS "org.gnome.GConf.Error.BadAddress"
+#define GCONF_DBUS_ERROR_BAD_KEY "org.gnome.GConf.Error.BadKey"
+#define GCONF_DBUS_ERROR_PARSE_ERROR "org.gnome.GConf.Error.ParseError"
+#define GCONF_DBUS_ERROR_CORRUPT "org.gnome.GConf.Error.Corrupt"
+#define GCONF_DBUS_ERROR_TYPE_MISMATCH "org.gnome.GConf.Error.TypeMismatch"
+#define GCONF_DBUS_ERROR_IS_DIR "org.gnome.GConf.Error.IsDir"
+#define GCONF_DBUS_ERROR_IS_KEY "org.gnome.GConf.Error.IsKey"
+#define GCONF_DBUS_ERROR_NO_WRITABLE_DATABASE "org.gnome.GConf.Error.NoWritableDatabase"
+#define GCONF_DBUS_ERROR_IN_SHUTDOWN "org.gnome.GConf.Error.InShutdown"
+#define GCONF_DBUS_ERROR_OVERRIDDEN "org.gnome.GConf.Error.Overriden"
+#define GCONF_DBUS_ERROR_LOCK_FAILED "org.gnome.GConf.Error.LockFailed"
+*/
+
+void gconf_dbus_message_append_gconf_value (DBusMessage *message,
+ const GConfValue *value);
+void gconf_dbus_message_iter_append_gconf_value (DBusMessageIter *iter,
+ const GConfValue *value);
+GConfValue *gconf_dbus_message_iter_get_gconf_value (DBusMessageIter *iter);
+void gconf_dbus_message_iter_append_gconf_entry (DBusMessageIter *args,
+ const gchar *key,
+ const GConfValue *value,
+ gboolean is_default,
+ gboolean is_writable,
+ const gchar *schema_name);
+GConfEntry *gconf_dbus_message_iter_get_gconf_entry (DBusMessageIter *iter);
+
+
+#endif/* GCONF_DBUS_UTILS_H */
Index: gconf/Makefile.am
===================================================================
--- gconf/Makefile.am (revision 2360)
+++ gconf/Makefile.am (working copy)
@@ -5,6 +5,7 @@
INCLUDES= \
-I$(top_srcdir) \
-I$(top_builddir) \
+ $(GCONF_DBUS_CFLAGS) \
$(DEPENDENT_WITH_XML_AND_GTK_CFLAGS) \
-DG_LOG_DOMAIN=\"GConf\" \
-DPREFIX=\""$(prefix)"\" \
@@ -74,7 +75,7 @@
gconfd.h \
gconfd.c
-gconfd_2_LDADD = $(EFENCE) $(INTLLIBS) $(DEPENDENT_LIBS) libgconf-$(MAJOR_VERSION).la
+gconfd_2_LDADD = $(EFENCE) $(INTLLIBS) $(DEPENDENT_LIBS) libgconf-$(MAJOR_VERSION).la $(GCONF_DBUS_LIBS)
# gconf_testclient_SOURCES = \
# testclient.c
@@ -84,7 +85,7 @@
gconftool_2_SOURCES = \
gconftool.c
-gconftool_2_LDADD = $(EFENCE) $(INTLLIBS) $(DEPENDENT_WITH_XML_LIBS) libgconf-$(MAJOR_VERSION).la
+gconftool_2_LDADD = $(EFENCE) $(INTLLIBS) $(DEPENDENT_WITH_XML_LIBS) libgconf-$(MAJOR_VERSION).la $(GCONF_DBUS_LIBS)
gconf_sanity_check_2_SOURCES = \
gconf-sanity-check.c
@@ -114,12 +115,13 @@
gconf.c \
gconf-client.c \
gconf-enum-types.c \
+ gconf-dbus-utils.c \
$(CORBA_SOURCECODE) \
$(WIN32_SOURCECODE)
libgconf_2_la_LDFLAGS = -version-info $(GCONF_CURRENT):$(GCONF_REVISION):$(GCONF_AGE) -no-undefined
-libgconf_2_la_LIBADD = $(INTLLIBS) $(DEPENDENT_LIBS)
+libgconf_2_la_LIBADD = $(INTLLIBS) $(DEPENDENT_LIBS) $(GCONF_DBUS_LIBS)
EXTRA_DIST=GConfX.idl default.path.in gconfmarshal.list regenerate-enum-header.sh regenerate-enum-footer.sh
Index: gconf/gconf.c
===================================================================
--- gconf/gconf.c (revision 2360)
+++ gconf/gconf.c (working copy)
@@ -35,6 +35,16 @@
#include <sys/time.h>
#include <unistd.h>
+#define DBUS_API_SUBJECT_TO_CHANGE 1
+#include <dbus/dbus.h>
+#include "gconf-dbus-utils.h"
+static DBusConnection *dbus_connection = NULL;
+static void ensure_dbus_connection();
+
+//TODO: I'm only having 1 dbus connection - this is the id for it
+// needs to be removed once the connection stuff is looked at
+#define CNXN_MAGIC_NUMBER 333
+
/* Returns TRUE if there was an error, frees exception, sets err */
static gboolean gconf_handle_corba_exception(CORBA_Environment* ev, GError** err);
/* just returns TRUE if there's an exception indicating the server is
@@ -740,87 +750,10 @@
gpointer user_data,
GError** err)
{
- ConfigDatabase db;
- ConfigListener cl;
- gulong id;
- CORBA_Environment ev;
GConfCnxn* cnxn;
- gint tries = 0;
- ConfigDatabase3_PropList properties;
-#define NUM_PROPERTIES 1
- ConfigStringProperty properties_buffer[1];
- g_return_val_if_fail(!gconf_engine_is_local(conf), 0);
+ cnxn = gconf_cnxn_new(conf, namespace_section, CNXN_MAGIC_NUMBER, func, user_data);
- CHECK_OWNER_USE (conf);
-
- if (gconf_engine_is_local(conf))
- {
- if (err)
- *err = gconf_error_new(GCONF_ERROR_LOCAL_ENGINE,
- _("Can't add notifications to a local configuration source"));
-
- return 0;
- }
-
- properties._buffer = properties_buffer;
- properties._length = NUM_PROPERTIES;
- properties._maximum = NUM_PROPERTIES;
- properties._release = CORBA_FALSE; /* don't free static buffer */
-
- properties._buffer[0].key = "name";
- properties._buffer[0].value = g_get_prgname ();
- if (properties._buffer[0].value == NULL)
- properties._buffer[0].value = "unknown";
-
- CORBA_exception_init(&ev);
-
- RETRY:
-
- db = gconf_engine_get_database (conf, TRUE, err);
-
- if (db == CORBA_OBJECT_NIL)
- return 0;
-
- cl = gconf_get_config_listener ();
-
- /* Should have aborted the program in this case probably */
- g_return_val_if_fail(cl != CORBA_OBJECT_NIL, 0);
-
- id = ConfigDatabase3_add_listener_with_properties (db,
- (gchar*)namespace_section,
- cl,
- &properties,
- &ev);
-
- if (ev._major == CORBA_SYSTEM_EXCEPTION &&
- CORBA_exception_id (&ev) &&
- strcmp (CORBA_exception_id (&ev), "IDL:CORBA/BAD_OPERATION:1.0") == 0)
- {
- CORBA_exception_free (&ev);
- CORBA_exception_init (&ev);
-
- id = ConfigDatabase_add_listener(db,
- (gchar*)namespace_section,
- cl, &ev);
- }
-
- if (gconf_server_broken(&ev))
- {
- if (tries < MAX_RETRIES)
- {
- ++tries;
- CORBA_exception_free(&ev);
- gconf_engine_detach (conf);
- goto RETRY;
- }
- }
-
- if (gconf_handle_corba_exception(&ev, err))
- return 0;
-
- cnxn = gconf_cnxn_new(conf, namespace_section, id, func, user_data);
-
ctable_insert(conf->ctable, cnxn);
return cnxn->client_id;
@@ -831,49 +764,14 @@
guint client_id)
{
GConfCnxn* gcnxn;
- CORBA_Environment ev;
- ConfigDatabase db;
- gint tries = 0;
CHECK_OWNER_USE (conf);
-
- if (gconf_engine_is_local(conf))
- return;
-
- CORBA_exception_init(&ev);
- RETRY:
-
- db = gconf_engine_get_database (conf, TRUE, NULL);
-
- if (db == CORBA_OBJECT_NIL)
- return;
-
gcnxn = ctable_lookup_by_client_id(conf->ctable, client_id);
g_return_if_fail(gcnxn != NULL);
- ConfigDatabase_remove_listener(db,
- gcnxn->server_id,
- &ev);
- if (gconf_server_broken(&ev))
- {
- if (tries < MAX_RETRIES)
- {
- ++tries;
- CORBA_exception_free(&ev);
- gconf_engine_detach (conf);
- goto RETRY;
- }
- }
-
- if (gconf_handle_corba_exception(&ev, NULL))
- {
- ; /* do nothing */
- }
-
-
/* We want to do this even if the CORBA fails, so if we restart gconfd and
reinstall listeners we don't reinstall this one. */
ctable_remove(conf->ctable, gcnxn);
@@ -891,147 +789,90 @@
gchar **schema_name_p,
GError **err)
{
- GConfValue* val;
- ConfigValue* cv;
- CORBA_Environment ev;
- ConfigDatabase db;
- gint tries = 0;
- CORBA_boolean is_default = FALSE;
- CORBA_boolean is_writable = TRUE;
- CORBA_char *corba_schema_name = NULL;
+ GConfEntry* entry;
+ GConfValue* value;
+ DBusMessage* message;
+ DBusMessage* reply;
+ DBusMessageIter args;
+ DBusError dbusError;
g_return_val_if_fail(conf != NULL, NULL);
g_return_val_if_fail(key != NULL, NULL);
- g_return_val_if_fail(err == NULL || *err == NULL, NULL);
+ //TODO: setting GError on error
+ //g_return_val_if_fail(err == NULL || *err == NULL, NULL);
CHECK_OWNER_USE (conf);
if (!gconf_key_check(key, err))
return NULL;
- if (gconf_engine_is_local(conf))
- {
- gchar** locale_list;
- gboolean tmp_is_default = FALSE;
- gboolean tmp_is_writable = TRUE;
- gchar *tmp_schema_name = NULL;
-
- locale_list = gconf_split_locale(locale);
-
- val = gconf_sources_query_value(conf->local_sources,
- key,
- (const gchar**)locale_list,
- use_schema_default,
- &tmp_is_default,
- &tmp_is_writable,
- schema_name_p ? &tmp_schema_name : NULL,
- err);
+ fprintf(stderr, "Doing remote query for %s\n", key);
- if (locale_list != NULL)
- g_strfreev(locale_list);
-
- if (is_default_p)
- *is_default_p = tmp_is_default;
-
- if (is_writable_p)
- *is_writable_p = tmp_is_writable;
-
- if (schema_name_p)
- *schema_name_p = tmp_schema_name;
- else
- g_free (tmp_schema_name);
-
- return val;
- }
-
- g_assert(!gconf_engine_is_local(conf));
-
- CORBA_exception_init(&ev);
-
- RETRY:
-
- db = gconf_engine_get_database (conf, TRUE, err);
-
- if (db == CORBA_OBJECT_NIL)
+ ensure_dbus_connection();
+ dbus_error_init(&dbusError);
+
+ message = dbus_message_new_method_call ("org.gnome.gconf",
+ "/org/gnome/gconf",
+ "org.gnome.gconf",
+ "Get");
+
+ dbus_message_iter_init_append(message, &args);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &key);
+
+ reply = dbus_connection_send_with_reply_and_block(dbus_connection,
+ message,
+ -1,
+ &dbusError);
+ if (reply == NULL)
{
- g_return_val_if_fail(err == NULL || *err != NULL, NULL);
-
+ fprintf(stderr, "failed getting reply: %s\n", dbusError.message);
+ dbus_error_free(&dbusError);
return NULL;
}
- if (schema_name_p)
- *schema_name_p = NULL;
-
-
- corba_schema_name = NULL;
- cv = ConfigDatabase2_lookup_with_schema_name (db,
- (gchar*)key, (gchar*)
- (locale ? locale : gconf_current_locale()),
- use_schema_default,
- &corba_schema_name,
- &is_default,
- &is_writable,
- &ev);
-
- if (ev._major == CORBA_SYSTEM_EXCEPTION &&
- CORBA_exception_id (&ev) &&
- strcmp (CORBA_exception_id (&ev), "IDL:CORBA/BAD_OPERATION:1.0") == 0)
+
+ if (!dbus_message_iter_init(reply, &args))
{
- CORBA_exception_free (&ev);
- CORBA_exception_init (&ev);
-
- cv = ConfigDatabase_lookup_with_locale(db,
- (gchar*)key, (gchar*)
- (locale ? locale : gconf_current_locale()),
- use_schema_default,
- &is_default,
- &is_writable,
- &ev);
+ fprintf(stderr, "Get reply has no arguments\n");
+ return NULL;
}
+
+ entry = gconf_dbus_message_iter_get_gconf_entry(&args);
+ value = gconf_entry_get_value(entry);
+ dbus_message_unref(reply);
+ dbus_message_unref(message);
- if (gconf_server_broken(&ev))
+ if (value != NULL)
{
- if (tries < MAX_RETRIES)
- {
- ++tries;
- CORBA_exception_free(&ev);
- gconf_engine_detach (conf);
- goto RETRY;
- }
+ gchar* retval = gconf_value_to_string(value);
+ fprintf (stderr, "Result of get call: %s\n", retval);
+ g_free(retval);
}
-
- if (gconf_handle_corba_exception(&ev, err))
+ else
{
- /* NOTE: don't free cv since we got an exception! */
- return NULL;
+ fprintf(stderr, "Result of get call: (null)\n");
}
- else
+
+ if (is_default_p)
+ *is_default_p = gconf_entry_get_is_default(entry);
+ if (is_writable_p)
+ *is_writable_p = gconf_entry_get_is_writable(entry);
+
+ const gchar* schema_name = gconf_entry_get_schema_name(entry);
+ if (schema_name && schema_name[0] != '/')
{
- val = gconf_value_from_corba_value(cv);
- CORBA_free(cv);
-
- if (is_default_p)
- *is_default_p = !!is_default;
- if (is_writable_p)
- *is_writable_p = !!is_writable;
-
- /* we can't get a null pointer through corba
- * so the server sent us an empty string
- */
- if (corba_schema_name && corba_schema_name[0] != '/')
- {
- CORBA_free (corba_schema_name);
- corba_schema_name = NULL;
- }
-
- if (schema_name_p)
- *schema_name_p = g_strdup (corba_schema_name);
-
- if (corba_schema_name)
- CORBA_free (corba_schema_name);
-
- return val;
+ gconf_entry_set_schema_name(entry, NULL);
}
+
+ if (schema_name_p)
+ *schema_name_p = g_strdup(gconf_entry_get_schema_name(entry));
+
+ if (value)
+ value = gconf_value_copy(value);
+
+ gconf_entry_free(entry);
+
+ return value;
}
@@ -1196,10 +1037,8 @@
gconf_engine_set (GConfEngine* conf, const gchar* key,
const GConfValue* value, GError** err)
{
- ConfigValue* cv;
- CORBA_Environment ev;
- ConfigDatabase db;
- gint tries = 0;
+ DBusMessage* message;
+ DBusMessageIter args;
g_return_val_if_fail(conf != NULL, FALSE);
g_return_val_if_fail(key != NULL, FALSE);
@@ -1218,66 +1057,25 @@
if (!gconf_value_validate (value, err))
return FALSE;
-
- if (gconf_engine_is_local(conf))
- {
- GError* error = NULL;
-
- gconf_sources_set_value(conf->local_sources, key, value, NULL, &error);
- if (error != NULL)
- {
- if (err)
- *err = error;
- else
- {
- g_error_free(error);
- }
- return FALSE;
- }
-
- return TRUE;
- }
- g_assert(!gconf_engine_is_local(conf));
-
- CORBA_exception_init(&ev);
+ fprintf(stderr, "Doing remote set for %s\n", key);
- RETRY:
+ ensure_dbus_connection();
+
+ message = dbus_message_new_method_call ("org.gnome.gconf",
+ "/org/gnome/gconf",
+ "org.gnome.gconf",
+ "Set");
+
+ dbus_message_iter_init_append(message, &args);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &key);
+ gconf_dbus_message_iter_append_gconf_value(&args, value);
+
+ dbus_connection_send(dbus_connection, message, NULL);
+ dbus_connection_flush(dbus_connection);
+ dbus_message_unref(message);
- db = gconf_engine_get_database (conf, TRUE, err);
-
- if (db == CORBA_OBJECT_NIL)
- {
- g_return_val_if_fail(err == NULL || *err != NULL, FALSE);
-
- return FALSE;
- }
-
- cv = gconf_corba_value_from_gconf_value (value);
-
- ConfigDatabase_set(db,
- (gchar*)key, cv,
- &ev);
-
- CORBA_free(cv);
-
- if (gconf_server_broken(&ev))
- {
- if (tries < MAX_RETRIES)
- {
- ++tries;
- CORBA_exception_free(&ev);
- gconf_engine_detach (conf);
- goto RETRY;
- }
- }
-
- if (gconf_handle_corba_exception(&ev, err))
- return FALSE;
-
- g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
-
return TRUE;
}
@@ -3624,3 +3422,103 @@
return NULL;
}
+static void
+dbus_preference_changed(DBusMessage* message)
+{
+ char* key = NULL;
+ GConfCnxn* cnxn;
+ GConfEngine* engine;
+ DBusMessageIter args;
+
+ GConfEntry* entry;
+
+ if (!dbus_message_iter_init(message, &args))
+ {
+ fprintf(stderr, "PreferenceChanged signal has no arguments\n");
+ return;
+ }
+
+ dbus_message_iter_get_basic(&args, &key);
+ dbus_message_iter_next(&args);
+
+ fprintf(stderr, "dbus_preference_changed: %s\n", key);
+
+ entry = gconf_dbus_message_iter_get_gconf_entry(&args);
+
+ engine = gconf_engine_get_default();
+
+ cnxn = ctable_lookup_by_server_id(engine->ctable, CNXN_MAGIC_NUMBER);
+ gconf_cnxn_notify(cnxn, entry);
+
+ gconf_entry_free (entry);
+}
+
+
+static gboolean
+dbus_message_timeout(gpointer data)
+{
+ DBusMessage* message;
+
+ while (TRUE)
+ {
+ dbus_connection_read_write(dbus_connection, 0);
+ message = dbus_connection_pop_message(dbus_connection);
+ if (message != NULL)
+ {
+ if (dbus_message_is_signal(message,
+ "org.gnome.gconf",
+ "PreferenceChanged"))
+ {
+ dbus_preference_changed(message);
+ }
+ //TODO: what other dbus messages should we listen to?
+ else
+ {
+ fprintf(stderr, "dbus message was not a PreferenceChanged signal\n");
+ }
+
+ dbus_message_unref(message);
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+static void
+ensure_dbus_connection()
+{
+ DBusError dbusError;
+ dbus_error_init(&dbusError);
+ if (dbus_connection == NULL) {
+ dbus_connection = dbus_bus_get (DBUS_BUS_SESSION, &dbusError);
+
+ //TODO: this is polling - it needs to be fixed
+ gulong timeout_len = 500; //.5 seconds
+ g_timeout_add (timeout_len,
+ dbus_message_timeout,
+ NULL);
+ if (!dbus_connection)
+ {
+ fprintf(stderr, "Couldn't connect to dbus: %s\n", dbusError.message);
+ dbus_error_free (&dbusError);
+ exit(1);
+ }
+ else
+ {
+ dbus_bus_add_match(dbus_connection,
+ "type='signal',interface='org.gnome.gconf'",
+ &dbusError);
+ if (dbus_error_is_set(&dbusError))
+ {
+ fprintf(stderr, "Match error: %s\n", dbusError.message);
+ exit(1);
+ }
+ }
+ }
+}
+
Index: tests/testgconf.c
===================================================================
--- tests/testgconf.c (revision 2360)
+++ tests/testgconf.c (working copy)
@@ -801,6 +801,70 @@
static void
+check_pair_storage(GConfEngine* conf)
+{
+ //TODO: needs more checks, also it probably leaks memory
+ GError* err = NULL;
+
+ GConfValue *value = gconf_value_new(GCONF_VALUE_PAIR);
+ GConfValue *car = gconf_value_new(GCONF_VALUE_INT);
+ gint i = 1;
+ gconf_value_set_int(car, i);
+
+ gchar *str = "hello";
+ GConfValue *cdr = gconf_value_new(GCONF_VALUE_STRING);
+ gconf_value_set_string(cdr, str);
+
+ gconf_value_set_car_nocopy(value, car);
+ gconf_value_set_cdr_nocopy(value, cdr);
+
+ if (!gconf_engine_set(conf, *keys, value, &err))
+ {
+ fprintf(stderr, "Failed to set key `%s' to pair: %s\n",
+ *keys, err->message);
+ g_error_free(err);
+ err = NULL;
+ }
+ else
+ {
+ GConfValue *retval = gconf_engine_get(conf, *keys, &err);
+
+ if (err != NULL)
+ {
+ check(retval == NULL, "NULL not returned though there was an error");
+
+ fprintf(stderr, "Failed to get key `%s': %s\n",
+ *keys, err->message);
+ g_error_free(err);
+ err = NULL;
+ }
+ else
+ {
+ GConfValue *retcar = gconf_value_get_car(retval);
+ GConfValue *retcdr = gconf_value_get_cdr(retval);
+ check(car->type == retcar->type,
+ "got wrong car type: %d set, %d got", car->type, retcar->type);
+
+ gint reti = gconf_value_get_int(retcar);
+ check(i == reti,
+ "got wrong car integer: %d set, %d got", i, reti);
+
+ check(cdr->type == retcdr->type,
+ "got wrong cdr type: %d set, %d got", cdr->type, retcdr->type);
+
+ const gchar *retstr = gconf_value_get_string(retcdr);
+
+ check (strcmp(str, retstr) == 0,
+ "got wrong cdr string: `%s' set, `%s' got", str, retstr);
+
+ gconf_value_free(value);
+ gconf_value_free(retval);
+ }
+ }
+}
+
+
+static void
check_list_storage(GConfEngine* conf)
{
GError* err = NULL;
@@ -981,6 +1045,10 @@
check_bool_storage(conf);
+ printf("\nChecking pair storage:");
+
+ check_pair_storage(conf);
+
gconf_engine_set_bool(conf, "/foo", TRUE, &err);
gconf_engine_unref(conf);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]