[gvfs/gdbus-core: 5/17] gdbus: Monitoring port



commit 10d1e182522c44388b2b435553d6fc47f940b43a
Author: Tomas Bzatek <tbzatek redhat com>
Date:   Fri Apr 13 15:11:36 2012 +0200

    gdbus: Monitoring port

 client/gdaemonfilemonitor.c |  306 ++++++++++++++++++++++++++++++-------------
 common/dbus-interfaces.xml  |   25 ++++
 daemon/gvfsmonitor.c        |  281 +++++++++++++++++++++++-----------------
 3 files changed, 398 insertions(+), 214 deletions(-)
---
diff --git a/client/gdaemonfilemonitor.c b/client/gdaemonfilemonitor.c
index dea5152..b3d519e 100644
--- a/client/gdaemonfilemonitor.c
+++ b/client/gdaemonfilemonitor.c
@@ -27,9 +27,9 @@
 #include <gio/gio.h>
 #include <gvfsdaemondbus.h>
 #include <gvfsdaemonprotocol.h>
-#include "gvfsdbusutils.h"
 #include "gmountspec.h"
 #include "gdaemonfile.h"
+#include <gvfsdbus.h>
 
 #define OBJ_PATH_PREFIX "/org/gtk/vfs/client/filemonitor/"
 
@@ -37,9 +37,6 @@
 static volatile gint path_counter = 1;
 
 static gboolean g_daemon_file_monitor_cancel (GFileMonitor* monitor);
-static DBusHandlerResult g_daemon_file_monitor_dbus_filter (DBusConnection     *connection,
-							    DBusMessage        *message,
-							    void               *user_data);
 
 
 struct _GDaemonFileMonitor
@@ -49,6 +46,7 @@ struct _GDaemonFileMonitor
   char *object_path;
   char *remote_obj_path;
   char *remote_id;
+  GDBusConnection *connection;
 };
 
 G_DEFINE_TYPE (GDaemonFileMonitor, g_daemon_file_monitor, G_TYPE_FILE_MONITOR)
@@ -62,6 +60,9 @@ g_daemon_file_monitor_finalize (GObject* object)
 
   _g_dbus_unregister_vfs_filter (daemon_monitor->object_path);
   
+  if (daemon_monitor->connection)
+    g_object_unref (daemon_monitor->connection);
+
   g_free (daemon_monitor->object_path);
   g_free (daemon_monitor->remote_id);
   g_free (daemon_monitor->remote_obj_path);
@@ -81,6 +82,69 @@ g_daemon_file_monitor_class_init (GDaemonFileMonitorClass* klass)
   file_monitor_class->cancel = g_daemon_file_monitor_cancel;
 }
 
+static gboolean
+handle_changed (GVfsDBusMonitorClient *object,
+                GDBusMethodInvocation *invocation,
+                guint arg_event_type,
+                GVariant *arg_mount_spec,
+                const gchar *arg_file_path,
+                GVariant *arg_other_mount_spec,
+                const gchar *arg_other_file_path,
+                gpointer user_data)
+{
+  GDaemonFileMonitor* monitor = user_data;
+  GMountSpec *spec1, *spec2;
+  GFile *file1, *file2;
+
+  g_print ("handle_changed: daemon_monitor = %p\n", monitor);
+
+  spec1 = g_mount_spec_from_dbus (arg_mount_spec);
+  file1 = g_daemon_file_new (spec1, arg_file_path);
+  g_mount_spec_unref (spec1);
+
+  file2 = NULL;
+  
+  if (strlen (arg_other_file_path) > 0)
+    {
+      spec2 = g_mount_spec_from_dbus (arg_other_mount_spec);
+      file2 = g_daemon_file_new (spec2, arg_other_file_path);
+      g_mount_spec_unref (spec2);
+    }
+
+  g_file_monitor_emit_event (G_FILE_MONITOR (monitor),
+                             file1, file2,
+                             arg_event_type);
+  
+  gvfs_dbus_monitor_client_complete_changed (object, invocation);
+  
+  return TRUE;
+}
+
+static GDBusInterfaceSkeleton *
+register_vfs_filter_cb (GDBusConnection *connection,
+                        const char *obj_path,
+                        gpointer callback_data)
+{
+  GError *error;
+  GVfsDBusMonitorClient *skeleton;
+
+  skeleton = gvfs_dbus_monitor_client_skeleton_new ();
+  g_signal_connect (skeleton, "handle-changed", G_CALLBACK (handle_changed), callback_data);
+
+  error = NULL;
+  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton),
+                                         connection,
+                                         obj_path,
+                                         &error))
+    {
+      g_warning ("Error registering path: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+    }
+
+  return G_DBUS_INTERFACE_SKELETON (skeleton);
+}
+
 static void
 g_daemon_file_monitor_init (GDaemonFileMonitor* daemon_monitor)
 {
@@ -89,128 +153,182 @@ g_daemon_file_monitor_init (GDaemonFileMonitor* daemon_monitor)
   id = g_atomic_int_add (&path_counter, 1);
 
   daemon_monitor->object_path = g_strdup_printf (OBJ_PATH_PREFIX"%d", id);
-  
+  g_print ("g_daemon_file_monitor_init: daemon_monitor = %p, object_path = '%s'\n", daemon_monitor, daemon_monitor->object_path);
+
   _g_dbus_register_vfs_filter (daemon_monitor->object_path,
-			       g_daemon_file_monitor_dbus_filter,
+                               register_vfs_filter_cb,
 			       G_OBJECT (daemon_monitor));
 }
 
+
+typedef void (*ProxyCreated) (GVfsDBusMonitor *proxy, gpointer user_data);
+
+typedef struct {
+  GDaemonFileMonitor* monitor;
+  ProxyCreated cb;
+  GDBusConnection *connection;
+} AsyncProxyCreate;
+
+static void
+async_proxy_create_free (AsyncProxyCreate *data)
+{
+  g_object_unref (data->monitor);
+  if (data->connection)
+    g_object_unref (data->connection);
+  g_free (data);
+}
+
+static void
+subscribe_cb (GVfsDBusMonitor *proxy,
+              GAsyncResult *res,
+              AsyncProxyCreate *data)
+{
+  GError *error = NULL;
+
+  g_print ("gdaemonfilemonitor.c: subscribe_cb()\n");
+  if (! gvfs_dbus_monitor_call_subscribe_finish (proxy, res, &error))
+    {
+      g_printerr ("Error calling org.gtk.vfs.Monitor.Subscribe(): %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+    }
+  
+  /* monitor subscription successful, let's keep the connection open and listen for the changes */
+  data->monitor->connection = g_object_ref (data->connection);
+  _g_dbus_connect_vfs_filters (data->monitor->connection);
+  
+  async_proxy_create_free (data);
+}
+
+static void
+subscribe_proxy_created_cb (GVfsDBusMonitor *proxy,
+                            gpointer user_data)
+{
+  AsyncProxyCreate *data = user_data;
+
+  gvfs_dbus_monitor_call_subscribe (proxy,
+                                    data->monitor->object_path,
+                                    NULL,
+                                    (GAsyncReadyCallback) subscribe_cb,
+                                    data);
+  
+  g_object_unref (proxy);
+}
+
+static void
+async_proxy_new_cb (GObject *source_object,
+                    GAsyncResult *res,
+                    gpointer user_data)
+{
+  AsyncProxyCreate *data = user_data;
+  GVfsDBusMonitor *proxy;
+  GError *error = NULL;
+
+  proxy = gvfs_dbus_monitor_proxy_new_finish (res, &error);
+  g_print ("gdaemonfilemonitor.c: async_proxy_new_cb, proxy = %p\n", proxy);
+  if (proxy == NULL)
+    {
+      g_printerr ("Error creating proxy: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+      async_proxy_create_free (data);
+      return;
+    }
+  
+  data->cb(proxy, data);
+}
+
+static void
+async_got_connection_cb (GDBusConnection *connection,
+                         GError *io_error,
+                         gpointer callback_data)
+{
+  AsyncProxyCreate *data = callback_data;
+  
+  g_print ("gdaemonfilemonitor.c: async_got_connection_cb, connection = %p\n", connection);
+
+  data->connection = g_object_ref (connection);
+  gvfs_dbus_monitor_proxy_new (connection,
+                               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+                               data->monitor->remote_id,
+                               data->monitor->remote_obj_path,
+                               NULL,
+                               async_proxy_new_cb,
+                               data);
+}
+
 GFileMonitor*
 g_daemon_file_monitor_new (const char *remote_id,
 				const char *remote_obj_path)
 {
   GDaemonFileMonitor* daemon_monitor;
-  DBusMessage *message;
+  AsyncProxyCreate *data;
   
   daemon_monitor = g_object_new (G_TYPE_DAEMON_FILE_MONITOR, NULL);
 
   daemon_monitor->remote_id = g_strdup (remote_id);
   daemon_monitor->remote_obj_path = g_strdup (remote_obj_path);
 
-  message =
-    dbus_message_new_method_call (daemon_monitor->remote_id,
-				  daemon_monitor->remote_obj_path,
-				  G_VFS_DBUS_MONITOR_INTERFACE,
-				  G_VFS_DBUS_MONITOR_OP_SUBSCRIBE);
-
-  _g_dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH,
-			       &daemon_monitor->object_path, 0);
-
-  _g_vfs_daemon_call_async (message,
-			    NULL, NULL,
-			    NULL);
-
-  dbus_message_unref (message);
+  data = g_new0 (AsyncProxyCreate, 1);
+  data->monitor = g_object_ref (daemon_monitor);
+  data->cb = subscribe_proxy_created_cb;
+  
+  _g_dbus_connection_get_for_async (daemon_monitor->remote_id,
+                                    async_got_connection_cb,
+                                    data,
+                                    NULL);
   
   return G_FILE_MONITOR (daemon_monitor);
 }
 
-static DBusHandlerResult
-g_daemon_file_monitor_dbus_filter (DBusConnection     *connection,
-				   DBusMessage        *message,
-				   void               *user_data)
+static void
+unsubscribe_cb (GVfsDBusMonitor *proxy,
+                GAsyncResult *res,
+                AsyncProxyCreate *data)
 {
-  GDaemonFileMonitor *monitor = G_DAEMON_FILE_MONITOR (user_data);
-  const char *member;
-  guint32 event_type;
-  DBusMessageIter iter;
-  GMountSpec *spec1, *spec2;
-  char *path1, *path2;
-  GFile *file1, *file2;
-  
-  member = dbus_message_get_member (message);
+  GError *error = NULL;
 
-  if (strcmp (member, G_VFS_DBUS_MONITOR_CLIENT_OP_CHANGED) == 0)
+  g_print ("gdaemonfilemonitor.c: unsubscribe_cb()\n");
+  if (! gvfs_dbus_monitor_call_unsubscribe_finish (proxy, res, &error))
     {
-      dbus_message_iter_init (message, &iter);
-      
-      if (!_g_dbus_message_iter_get_args (&iter, NULL,
-					  DBUS_TYPE_UINT32, &event_type,
-					  0))
-	return DBUS_HANDLER_RESULT_HANDLED;
-      
-      spec1 = g_mount_spec_from_dbus (&iter);
-      if (!_g_dbus_message_iter_get_args (&iter, NULL,
-					  G_DBUS_TYPE_CSTRING, &path1,
-					  0))
-	{
-	  g_mount_spec_unref (spec1);
-	  return DBUS_HANDLER_RESULT_HANDLED;
-	}
-
-      file1 = g_daemon_file_new (spec1, path1);
-      
-      g_mount_spec_unref (spec1);
-      g_free (path1);
-
-      file2 = NULL;
-      
-      spec2 = g_mount_spec_from_dbus (&iter);
-      if (spec2) {
-	if (_g_dbus_message_iter_get_args (&iter, NULL,
-					   G_DBUS_TYPE_CSTRING, &path2,
-					   0))
-	  {
-	    file2 = g_daemon_file_new (spec2, path2);
-
-	    g_free (path2);
-	  }
-	
-	g_mount_spec_unref (spec2);
-      }
-
-      g_file_monitor_emit_event (G_FILE_MONITOR (monitor),
-				 file1, file2,
-				 event_type);
-      
-      return DBUS_HANDLER_RESULT_HANDLED;
+      g_printerr ("Error calling org.gtk.vfs.Monitor.Unsubscribe(): %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
     }
-
-  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+  
+  async_proxy_create_free (data);
 }
 
+static void
+unsubscribe_proxy_created_cb (GVfsDBusMonitor *proxy,
+                              gpointer user_data)
+{
+  AsyncProxyCreate *data = user_data;
+
+  gvfs_dbus_monitor_call_unsubscribe (proxy,
+                                      data->monitor->object_path,
+                                      NULL,
+                                      (GAsyncReadyCallback) unsubscribe_cb,
+                                      data);
+  
+  g_object_unref (proxy);
+}
 
 static gboolean
 g_daemon_file_monitor_cancel (GFileMonitor* monitor)
 {
   GDaemonFileMonitor *daemon_monitor = G_DAEMON_FILE_MONITOR (monitor);
-  DBusMessage *message;
-  
-  message =
-    dbus_message_new_method_call (daemon_monitor->remote_id,
-				  daemon_monitor->remote_obj_path,
-				  G_VFS_DBUS_MONITOR_INTERFACE,
-				  G_VFS_DBUS_MONITOR_OP_UNSUBSCRIBE);
-
-  _g_dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH,
-			       &daemon_monitor->object_path, 0);
+  AsyncProxyCreate *data;
   
-  _g_vfs_daemon_call_async (message,
-			    NULL, NULL, 
-			    NULL);
-  
-  dbus_message_unref (message);
+  data = g_new0 (AsyncProxyCreate, 1);
+  data->monitor = g_object_ref (daemon_monitor);
+  data->cb = unsubscribe_proxy_created_cb;
   
+  _g_dbus_connection_get_for_async (daemon_monitor->remote_id,
+                                    async_got_connection_cb,
+                                    data,
+                                    NULL);
+
   return TRUE;
 }
 
diff --git a/common/dbus-interfaces.xml b/common/dbus-interfaces.xml
index 238bf27..8ad16ce 100644
--- a/common/dbus-interfaces.xml
+++ b/common/dbus-interfaces.xml
@@ -342,5 +342,30 @@
     </method>
   </interface>
 
+  <!--
+      org.gtk.vfs.Monitor
+  -->
+  <interface name='org.gtk.vfs.Monitor'>
+    <method name="Subscribe">
+      <arg type='o' name='object_path' direction='in'/>
+    </method>
+    <method name="Unsubscribe">
+      <arg type='o' name='object_path' direction='in'/>
+    </method>
+  </interface>
+
+  <!--
+      org.gtk.vfs.MonitorClient
+  -->
+  <interface name='org.gtk.vfs.MonitorClient'>
+    <method name="Changed">
+      <arg type='u' name='event_type' direction='in'/>
+      <arg type='(aya{sv})' name='mount_spec' direction='in'/>
+      <arg type='ay' name='file_path' direction='in'/>
+      <arg type='(aya{sv})' name='other_mount_spec' direction='in'/>
+      <arg type='ay' name='other_file_path' direction='in'/>
+    </method>
+  </interface>
+
 </node>
 
diff --git a/daemon/gvfsmonitor.c b/daemon/gvfsmonitor.c
index 8c9b38f..d8ac4bf 100644
--- a/daemon/gvfsmonitor.c
+++ b/daemon/gvfsmonitor.c
@@ -34,23 +34,19 @@
 #include <glib-object.h>
 #include <glib/gi18n.h>
 #include <gvfsmonitor.h>
-#include <gio/gunixinputstream.h>
-#include <gio/gunixoutputstream.h>
 #include <gvfsdaemonprotocol.h>
 #include <gvfsdaemonutils.h>
 #include <gvfsjobcloseread.h>
 #include <gvfsjobclosewrite.h>
+#include <gvfsdbus.h>
 
 #define OBJ_PATH_PREFIX "/org/gtk/vfs/daemon/dirmonitor/"
 
-/* TODO: Real P_() */
-#define P_(_x) (_x)
-
 
 /* TODO: Handle a connection dying and unregister its subscription */
 
 typedef struct {
-  DBusConnection *connection;
+  GDBusConnection *connection;
   char *id;
   char *object_path;
 } Subscriber;
@@ -135,7 +131,7 @@ g_vfs_monitor_init (GVfsMonitor *monitor)
 
 static gboolean
 matches_subscriber (Subscriber *subscriber,
-		    DBusConnection *connection,
+		    GDBusConnection *connection,
 		    const char *object_path,
 		    const char *dbus_id)
 {
@@ -152,105 +148,92 @@ unsubscribe (GVfsMonitor *monitor,
 {
   monitor->priv->subscribers = g_list_remove (monitor->priv->subscribers, subscriber);
   
-  dbus_connection_unref (subscriber->connection);
+  g_object_unref (subscriber->connection);
   g_free (subscriber->id);
   g_free (subscriber->object_path);
   g_free (subscriber);
   g_object_unref (monitor);
 }
 
-static DBusHandlerResult
-vfs_monitor_message_callback (DBusConnection  *connection,
-			      DBusMessage     *message,
-			      void            *user_data)
+static gboolean
+handle_subscribe (GVfsDBusMonitor *object,
+                  GDBusMethodInvocation *invocation,
+                  const gchar *arg_object_path,
+                  GVfsMonitor *monitor)
 {
-  GVfsMonitor *monitor = user_data;
-  char *object_path;
-  DBusError derror;
-  GList *l;
   Subscriber *subscriber;
-  DBusMessage *reply;
+
+  g_print ("handle_subscribe: adding connection %p\n", g_dbus_method_invocation_get_connection (invocation));
+  
+  subscriber = g_new0 (Subscriber, 1);
+  subscriber->connection = g_object_ref (g_dbus_method_invocation_get_connection (invocation));
+  subscriber->id = g_strdup (g_dbus_method_invocation_get_sender (invocation));
+  subscriber->object_path = g_strdup (arg_object_path);
+
+  g_object_ref (monitor);
+  monitor->priv->subscribers = g_list_prepend (monitor->priv->subscribers, subscriber);
+  
+  gvfs_dbus_monitor_complete_subscribe (object, invocation);
   
-  if (dbus_message_is_method_call (message,
-				   G_VFS_DBUS_MONITOR_INTERFACE,
-				   G_VFS_DBUS_MONITOR_OP_SUBSCRIBE))
+  return TRUE;
+}
+
+static gboolean
+handle_unsubscribe (GVfsDBusMonitor *object,
+                    GDBusMethodInvocation *invocation,
+                    const gchar *arg_object_path,
+                    GVfsMonitor *monitor)
+{
+  Subscriber *subscriber;
+  GList *l;
+
+  g_print ("handle_unsubscribe\n");
+
+  g_object_ref (monitor); /* Keep alive during possible last remove */
+  for (l = monitor->priv->subscribers; l != NULL; l = l->next)
     {
-      dbus_error_init (&derror);
-      if (!dbus_message_get_args (message, &derror, 
-				  DBUS_TYPE_OBJECT_PATH, &object_path,
-				  0))
-	{
-	  reply = dbus_message_new_error (message,
-					  derror.name,
-					  derror.message);
-	  dbus_error_free (&derror);
-
-	  dbus_connection_send (connection, reply, NULL);
-	  dbus_message_unref (reply);
-	}
-      else
-	{
-	  subscriber = g_new0 (Subscriber, 1);
-	  subscriber->connection = dbus_connection_ref (connection);
-	  subscriber->id = g_strdup (dbus_message_get_sender (message));
-	  subscriber->object_path = g_strdup (object_path);
-
-	  g_object_ref (monitor);
-	  monitor->priv->subscribers = g_list_prepend (monitor->priv->subscribers, subscriber);
-
-	  reply = dbus_message_new_method_return (message);
-	  dbus_connection_send (connection, reply, NULL);
-	  dbus_message_unref (reply);
-	}
-
-      return DBUS_HANDLER_RESULT_HANDLED;
+      subscriber = l->data;
+
+      if (matches_subscriber (subscriber,
+                              g_dbus_method_invocation_get_connection (invocation),
+                              arg_object_path,
+                              g_dbus_method_invocation_get_sender (invocation)))
+        {
+          unsubscribe (monitor, subscriber);
+          break;
+        }
     }
-  else if (dbus_message_is_method_call (message,
-					G_VFS_DBUS_MONITOR_INTERFACE,
-					G_VFS_DBUS_MONITOR_OP_UNSUBSCRIBE))
+  g_object_unref (monitor);
+
+  gvfs_dbus_monitor_complete_unsubscribe (object, invocation);
+
+  return TRUE;
+}
+
+static GDBusInterfaceSkeleton *
+register_path_cb (GDBusConnection *conn,
+                  const char *obj_path,
+                  gpointer data)
+{
+  GError *error;
+  GVfsDBusMonitor *skeleton;
+  
+  skeleton = gvfs_dbus_monitor_skeleton_new ();
+  g_signal_connect (skeleton, "handle-subscribe", G_CALLBACK (handle_subscribe), data);
+  g_signal_connect (skeleton, "handle-unsubscribe", G_CALLBACK (handle_unsubscribe), data);
+  
+  error = NULL;
+  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton),
+                                         conn,
+                                         obj_path,
+                                         &error))
     {
-      dbus_error_init (&derror);
-      if (!dbus_message_get_args (message, &derror, 
-				  DBUS_TYPE_OBJECT_PATH, &object_path,
-				  0))
-	{
-	  reply = dbus_message_new_error (message,
-					  derror.name,
-					  derror.message);
-	  dbus_error_free (&derror);
-
-	  dbus_connection_send (connection, reply, NULL);
-	  dbus_message_unref (reply);
-	}
-      else
-	{
-	  g_object_ref (monitor); /* Keep alive during possible last remove */
-	  for (l = monitor->priv->subscribers; l != NULL; l = l->next)
-	    {
-	      subscriber = l->data;
-
-	      if (matches_subscriber (subscriber,
-				      connection,
-				      object_path,
-				      dbus_message_get_sender (message)))
-		{
-		  unsubscribe (monitor, subscriber);
-		  break;
-		}
-	    }
-
-	  reply = dbus_message_new_method_return (message);
-	  dbus_connection_send (connection, reply, NULL);
-	  dbus_message_unref (reply);
-
-	  g_object_unref (monitor);
-	}
-      
-      return DBUS_HANDLER_RESULT_HANDLED;
+      g_warning ("Error registering path: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
     }
-      
-  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-  
+
+  return G_DBUS_INTERFACE_SKELETON (skeleton);
 }
 
 GVfsMonitor *
@@ -271,7 +254,7 @@ g_vfs_monitor_new (GVfsBackend *backend)
 
   g_vfs_daemon_register_path (monitor->priv->daemon,
 			      monitor->priv->object_path,
-			      vfs_monitor_message_callback,
+			      register_path_cb,
 			      monitor);
 
   return monitor;  
@@ -283,6 +266,72 @@ g_vfs_monitor_get_object_path (GVfsMonitor *monitor)
   return monitor->priv->object_path;
 }
 
+
+typedef struct {
+  GVfsMonitor *monitor;
+  GFileMonitorEvent event_type;
+  gchar *file_path;
+  gchar *other_file_path;
+} EmitEventData;
+
+static void
+emit_event_data_free (EmitEventData *data)
+{
+  g_object_unref (data->monitor);
+  g_free (data->file_path);
+  g_free (data->other_file_path);
+  g_free (data);
+}
+
+static void
+changed_cb (GVfsDBusMonitorClient *proxy,
+            GAsyncResult *res,
+            EmitEventData *data)
+{
+  GError *error = NULL;
+
+  g_print ("gvfsmonitor.c: changed_cb()\n");
+  if (! gvfs_dbus_monitor_client_call_changed_finish (proxy, res, &error))
+    {
+      g_printerr ("Error calling org.gtk.vfs.MonitorClient.Changed(): %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+    }
+  
+  emit_event_data_free (data);
+}
+
+static void
+got_proxy_cb (GObject *source_object,
+              GAsyncResult *res,
+              EmitEventData *data)
+{
+  GError *error = NULL;
+  GVfsDBusMonitorClient *proxy;
+  
+  g_print ("gvfsmonitor.c: got_proxy_cb()\n");
+  proxy = gvfs_dbus_monitor_client_proxy_new_finish (res, &error);
+  if (proxy == NULL)
+    {
+      g_printerr ("Error creating proxy: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+      emit_event_data_free (data);
+      return;
+    }
+  
+  gvfs_dbus_monitor_client_call_changed (proxy,
+                                         data->event_type,
+                                         g_mount_spec_to_dbus (data->monitor->priv->mount_spec),
+                                         data->file_path,
+                                         g_mount_spec_to_dbus (data->monitor->priv->mount_spec),
+                                         data->other_file_path ? data->other_file_path : "",
+                                         NULL,
+                                         (GAsyncReadyCallback) changed_cb,
+                                         data);
+  g_object_unref (proxy);
+}
+
 void
 g_vfs_monitor_emit_event (GVfsMonitor       *monitor,
 			  GFileMonitorEvent  event_type,
@@ -291,37 +340,29 @@ g_vfs_monitor_emit_event (GVfsMonitor       *monitor,
 {
   GList *l;
   Subscriber *subscriber;
-  DBusMessage *message;
-  DBusMessageIter iter;
-  guint32 event_type_dbus;
   
+  g_print ("g_vfs_monitor_emit_event: file_path = '%s', other_file_path = '%s'\n", file_path, other_file_path);
+
   for (l = monitor->priv->subscribers; l != NULL; l = l->next)
     {
+      EmitEventData *data;
+      
       subscriber = l->data;
 
-      message =
-	dbus_message_new_method_call (subscriber->id,
-				      subscriber->object_path,
-				      G_VFS_DBUS_MONITOR_CLIENT_INTERFACE,
-				      G_VFS_DBUS_MONITOR_CLIENT_OP_CHANGED);
-
-      dbus_message_iter_init_append (message, &iter);
-      event_type_dbus = event_type;
-      dbus_message_iter_append_basic (&iter,
-				      DBUS_TYPE_UINT32,
-				      &event_type_dbus);
-      g_mount_spec_to_dbus (&iter, monitor->priv->mount_spec);
-      _g_dbus_message_iter_append_cstring (&iter, file_path);
-
-      if (other_file_path)
-	{
-	  g_mount_spec_to_dbus (&iter, monitor->priv->mount_spec);
-	  _g_dbus_message_iter_append_cstring (&iter, other_file_path);
-	}
-
-      dbus_message_set_no_reply (message, FALSE);
+      data = g_new0 (EmitEventData, 1);
+      data->monitor = g_object_ref (monitor);
+      data->event_type = event_type;
+      data->file_path = g_strdup (file_path);
+      data->other_file_path = g_strdup (other_file_path);
+
+      g_print ("  subscriber %p: object_path = '%s', name = '%s'\n", subscriber, subscriber->object_path, subscriber->id);
       
-      dbus_connection_send (subscriber->connection, message, NULL);
-      dbus_message_unref (message);
+      gvfs_dbus_monitor_client_proxy_new (subscriber->connection,
+                                          G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+                                          subscriber->id,
+                                          subscriber->object_path,
+                                          NULL,
+                                          (GAsyncReadyCallback) got_proxy_cb,
+                                          data);
     }
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]