corba -> dbus



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]