[nautilus-actions] Implement GDBus high-level API



commit 8c5cd5af989eae3bd7ac36009f4a70052461b93c
Author: Pierre Wieser <pwieser trychlos org>
Date:   Sat Jan 28 17:58:34 2012 +0100

    Implement GDBus high-level API

 ChangeLog                               |   21 ++
 src/plugin-tracker/Makefile.am          |   30 +++-
 src/plugin-tracker/na-tracker-dbus.c    |  260 -----------------------
 src/plugin-tracker/na-tracker-dbus.h    |   85 --------
 src/plugin-tracker/na-tracker-dbus.xml  |    2 +-
 src/plugin-tracker/na-tracker-gdbus.xml |   26 +++
 src/plugin-tracker/na-tracker-plugin.c  |    2 +-
 src/plugin-tracker/na-tracker.c         |  354 ++++++++++++++++++++++++++-----
 src/plugin-tracker/na-tracker.h         |   43 +++-
 src/utils/Makefile.am                   |   22 ++-
 src/utils/nautilus-actions-run.c        |   70 ++++++-
 11 files changed, 493 insertions(+), 422 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 34271b6..f6aedc2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
 2012-01-28 Pierre Wieser <pwieser trychlos org>
 
+	* src/plugin-tracker/na-tracker-gdbus.xml: New file.
+
+	* src/plugin-tracker/Makefile.am: Generate code for GDBus.
+
+	* src/plugin-tracker/na-tracker-dbus.c:
+	* src/plugin-tracker/na-tracker-dbus.h: Removed files.
+
+	* src/plugin-tracker/na-tracker-dbus.xml: Updated accordingly.
+
+	* src/plugin-tracker/na-tracker.c:
+	* src/plugin-tracker/na-tracker.h:
+	Implement GDBus server high-level API.
+	Rename GType macro name.
+
+	* src/plugin-tracker/na-tracker-plugin.c
+	(nautilus_module_list_types): Updated to new GType macro name.
+
+	* src/utils/Makefile.am: Generate code for GDBus.
+
+	* src/utils/nautilus-actions-run.c: Implement GDBus client high-level API.
+
 	* m4/na-check-for-gdbus.m4: Requires GIO 2.30 (GDBusObjectManagerServer).
 
 	* docs/reference/nautilus-actions-sections.txt: Update reference manual.
diff --git a/src/plugin-tracker/Makefile.am b/src/plugin-tracker/Makefile.am
index cc5c6de..9fa4a9b 100644
--- a/src/plugin-tracker/Makefile.am
+++ b/src/plugin-tracker/Makefile.am
@@ -37,19 +37,38 @@ nautilus_extensiondir = $(NAUTILUS_EXTENSIONS_DIR)
 
 nautilus_extension_LTLIBRARIES = libnautilus-actions-tracker.la
 
-BUILT_SOURCES = \
-	na-tracker-dbus-glue.h										\
+BUILT_SOURCES =
+
+if HAVE_GDBUS
+BUILT_SOURCES += \
+	na-tracker-gdbus.c											\
+	na-tracker-gdbus.h											\
 	$(NULL)
 
-na-tracker-dbus-glue.h: na-tracker-dbus.xml
+na-tracker-gdbus.c na-tracker-gdbus.h: na-tracker-gdbus.xml
+	gdbus-codegen \
+		--interface-prefix org.nautilus_actions.DBus.Tracker.	\
+		--generate-c-code na-tracker-gdbus						\
+		--c-namespace NA_Tracker								\
+		--c-generate-object-manager								\
+		--generate-docbook na-tracker-gdbus-docs				\
+		$<
+endif
+
+if HAVE_DBUS_GLIB
+BUILT_SOURCES += \
+	na-tracker-dbus-glib.h										\
+	$(NULL)
+
+na-tracker-dbus-glib.h: na-tracker-dbus.xml
 	dbus-binding-tool --mode=glib-server --prefix=na_tracker_dbus $< > $@
+endif
 
 libnautilus_actions_tracker_la_SOURCES = \
 	na-tracker.c												\
 	na-tracker.h												\
-	na-tracker-dbus.c											\
-	na-tracker-dbus.h											\
 	na-tracker-plugin.c											\
+	$(BUILT_SOURCES)											\
 	$(NULL)
 
 libnautilus_actions_tracker_la_LIBADD = \
@@ -65,6 +84,7 @@ libnautilus_actions_tracker_la_LDFLAGS = \
 
 EXTRA_DIST = \
 	na-tracker-dbus.xml											\
+	na-tracker-gdbus.xml										\
 	$(NULL)
 
 CLEANFILES = \
diff --git a/src/plugin-tracker/na-tracker-dbus.xml b/src/plugin-tracker/na-tracker-dbus.xml
index 5e53d2f..36cff3e 100644
--- a/src/plugin-tracker/na-tracker-dbus.xml
+++ b/src/plugin-tracker/na-tracker-dbus.xml
@@ -3,7 +3,7 @@
   <interface name="org.nautilus_actions.DBus.Tracker.Properties1">
     <method name="GetSelectedPaths">
       <arg type="as" name="paths" direction="out" />
-      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="na_tracker_dbus_get_selected_paths" />
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="na_tracker_get_selected_paths" />
     </method>
   </interface>
 </node>
diff --git a/src/plugin-tracker/na-tracker-gdbus.xml b/src/plugin-tracker/na-tracker-gdbus.xml
new file mode 100644
index 0000000..b16d6b3
--- /dev/null
+++ b/src/plugin-tracker/na-tracker-gdbus.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<node>
+  <!--
+    org.nautilus_actions.DBus.Tracker.Properties1:
+    @short_description: Tracker properties
+    @since: 3.2
+    
+    This interface tracks the items currently selected in the Nautilus
+    file manager user interface. and is able to retrieve them through
+    DBus.
+  -->
+  <interface name="org.nautilus_actions.DBus.Tracker.Properties1">
+  
+    <!--
+      GetSelectedPaths:
+      @since: 3.2
+
+      This method is used to retrieve through DBus the list of the currently
+      selected items in the Nautilus file manager user interface.
+    -->
+    <method name="GetSelectedPaths">
+      <arg type="as" name="paths" direction="out" />
+    </method>
+
+  </interface>
+</node>
diff --git a/src/plugin-tracker/na-tracker-plugin.c b/src/plugin-tracker/na-tracker-plugin.c
index 10074a2..94090e4 100644
--- a/src/plugin-tracker/na-tracker-plugin.c
+++ b/src/plugin-tracker/na-tracker-plugin.c
@@ -80,7 +80,7 @@ nautilus_module_list_types( const GType **types, int *num_types )
 
 	g_debug( "%s: types=%p, num_types=%p", thisfn, ( void * ) types, ( void * ) num_types );
 
-	type_list[0] = NA_TRACKER_TYPE;
+	type_list[0] = NA_TYPE_TRACKER;
 	*types = type_list;
 	*num_types = 1;
 }
diff --git a/src/plugin-tracker/na-tracker.c b/src/plugin-tracker/na-tracker.c
index efd24f0..d770ccd 100644
--- a/src/plugin-tracker/na-tracker.c
+++ b/src/plugin-tracker/na-tracker.c
@@ -32,8 +32,14 @@
 #include <config.h>
 #endif
 
-#include <dbus/dbus-glib.h>
+#ifdef HAVE_GDBUS
+#include <gio/gio.h>
+#include "na-tracker-gdbus.h"
+#else
+# ifdef HAVE_DBUS_GLIB
 #include <dbus/dbus-glib-bindings.h>
+# endif
+#endif
 
 #include <libnautilus-extension/nautilus-extension-types.h>
 #include <libnautilus-extension/nautilus-file-info.h>
@@ -42,7 +48,10 @@
 #include <api/na-dbus.h>
 
 #include "na-tracker.h"
-#include "na-tracker-dbus.h"
+
+#ifdef HAVE_DBUS_GLIB
+#include "na-tracker-dbus-glib.h"
+#endif
 
 /* private class data
  */
@@ -53,22 +62,36 @@ struct _NATrackerClassPrivate {
 /* private instance data
  */
 struct _NATrackerPrivate {
-	gboolean       dispose_has_run;
-	NATrackerDBus *tracker;
+	gboolean                  dispose_has_run;
+#ifdef HAVE_GDBUS
+	guint                     owner_id;	/* the identifier returns by g_bus_own_name */
+	GDBusObjectManagerServer *server;
+#endif
+	GList                    *selected;
 };
 
 static GObjectClass *st_parent_class = NULL;
 static GType         st_module_type = 0;
 
-static void           class_init( NATrackerClass *klass );
-static void           instance_init( GTypeInstance *instance, gpointer klass );
-static NATrackerDBus *initialize_dbus_connection( void );
-static void           instance_dispose( GObject *object );
-static void           instance_finalize( GObject *object );
+static void    class_init( NATrackerClass *klass );
+static void    instance_init( GTypeInstance *instance, gpointer klass );
+static void    initialize_dbus_connection( NATracker *tracker );
+#ifdef HAVE_GDBUS
+static void    on_bus_acquired( GDBusConnection *connection, const gchar *name, NATracker *tracker );
+static void    on_name_acquired( GDBusConnection *connection, const gchar *name, NATracker *tracker );
+static void    on_name_lost( GDBusConnection *connection, const gchar *name, NATracker *tracker );
+static gboolean on_properties1_get_selected_paths( NATrackerProperties1 *tracker_properties, GDBusMethodInvocation *invocation, NATracker *tracker );
+#endif
+static void    instance_dispose( GObject *object );
+static void    instance_finalize( GObject *object );
+
+static void    menu_provider_iface_init( NautilusMenuProviderIface *iface );
+static GList  *menu_provider_get_background_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *folder );
+static GList  *menu_provider_get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files );
 
-static void           menu_provider_iface_init( NautilusMenuProviderIface *iface );
-static GList         *menu_provider_get_background_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *folder );
-static GList         *menu_provider_get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files );
+static void    set_uris( NATracker *tracker, GList *files );
+static gchar **get_selected_paths( NATracker *tracker );
+static GList  *free_selected( GList *selected );
 
 GType
 na_tracker_get_type( void )
@@ -138,18 +161,34 @@ instance_init( GTypeInstance *instance, gpointer klass )
 
 	self->private = g_new0( NATrackerPrivate, 1 );
 	self->private->dispose_has_run = FALSE;
-	self->private->tracker = initialize_dbus_connection();
+
+	initialize_dbus_connection( self );
 }
 
 /*
- * initialize the DBus connection at class init time
+ * initialize the DBus connection at instanciation time
  * & instantiate the object which will do effective tracking
  */
-static NATrackerDBus *
-initialize_dbus_connection( void )
+static void
+initialize_dbus_connection( NATracker *tracker )
 {
+#ifdef HAVE_GDBUS
+	NATrackerPrivate *priv = tracker->private;
+
+	priv->owner_id = g_bus_own_name(
+			G_BUS_TYPE_SESSION,
+			NAUTILUS_ACTIONS_DBUS_SERVICE,
+			G_BUS_NAME_OWNER_FLAGS_REPLACE,
+			( GBusAcquiredCallback ) on_bus_acquired,
+			( GBusNameAcquiredCallback ) on_name_acquired,
+			( GBusNameLostCallback ) on_name_lost,
+			tracker,
+			NULL );
+
+#else /* HAVE_GDBUS */
+
+# ifdef HAVE_DBUS_GLIB
 	static const gchar *thisfn = "na_tracker_initialize_dbus_connection";
-	NATrackerDBus *tracker;
 	DBusGConnection *connection;
 	GError *error;
 	DBusGProxy *proxy;
@@ -157,13 +196,12 @@ initialize_dbus_connection( void )
 
 	/* get a connection on session DBus
 	 */
-	tracker = NULL;
 	error = NULL;
 	connection = dbus_g_bus_get( DBUS_BUS_SESSION, &error );
 	if( !connection ){
 		g_warning( "%s: unable to get a connection on session DBus: %s", thisfn, error->message );
 		g_error_free( error );
-		return( NULL );
+		return;
 	}
 	g_debug( "%s: connection is ok", thisfn );
 
@@ -174,7 +212,7 @@ initialize_dbus_connection( void )
 	if( !proxy ){
 		g_warning( "%s: unable to get a proxy for the connection", thisfn );
 		dbus_g_connection_unref( connection );
-		return( NULL );
+		return;
 	}
 	g_debug( "%s: proxy is ok", thisfn );
 
@@ -187,43 +225,132 @@ initialize_dbus_connection( void )
 				thisfn, NAUTILUS_ACTIONS_DBUS_SERVICE, error->message );
 		g_error_free( error );
 		dbus_g_connection_unref( connection );
-		return( NULL );
+		return;
 	}
 	g_debug( "%s: well known name registration is ok", thisfn );
 
 	if( request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER ){
 		g_warning("%s: got result code %u from requesting name (not the primary owner of the name)", thisfn, request_name_ret );
 		dbus_g_connection_unref( connection );
-		return( NULL );
+		return;
 	}
 	g_debug( "%s: primary owner check is ok", thisfn );
 
 	/* allocate the tracking object and register it
 	 * instantiation takes care of installing introspection infos
 	 */
-	tracker = g_object_new( NA_TRACKER_DBUS_TYPE, NULL );
+	dbus_g_object_type_install_info( NA_TYPE_TRACKER, &dbus_glib_na_tracker_dbus_object_info );
 	dbus_g_connection_register_g_object( connection, NAUTILUS_ACTIONS_DBUS_TRACKER_PATH, G_OBJECT( tracker ));
 
 	g_debug( "%s: registering tracker path is ok", thisfn );
-	return( tracker );
+# endif /* HAVE_DBUS_GLIB */
+#endif
+}
+
+#ifdef HAVE_GDBUS
+static void
+on_bus_acquired( GDBusConnection *connection, const gchar *name, NATracker *tracker )
+{
+	static const gchar *thisfn = "na_tracker_on_bus_acquired";
+	NATrackerObjectSkeleton *tracker_object;
+	NATrackerProperties1 *tracker_properties1;
+
+	/*NATrackerDBus *tracker_object;*/
+
+	g_debug( "%s: connection=%p, name=%s, tracker=%p",
+			thisfn,
+			( void * ) connection,
+			name,
+			( void * ) tracker );
+
+	/* create a new org.freedesktop.DBus.ObjectManager rooted at
+	 *  /org/nautilus_actions/DBus/Tracker
+	 */
+	tracker->private->server = g_dbus_object_manager_server_new( NAUTILUS_ACTIONS_DBUS_TRACKER_PATH );
+
+	/* create a new D-Bus object at the path
+	 *  /org/nautilus_actions/DBus/Tracker
+	 *  (which must be same or below than that of object manager server)
+	 */
+	tracker_object = na_tracker_object_skeleton_new( NAUTILUS_ACTIONS_DBUS_TRACKER_PATH );
+
+	/* make a newly created object export the interface
+	 *  org.nautilus_actions.DBus.Tracker.Properties1
+	 *  and attach it to the D-Bus object, which takes its own reference on it
+	 */
+	tracker_properties1 = na_tracker_properties1_skeleton_new();
+	na_tracker_object_skeleton_set_properties1( tracker_object, tracker_properties1 );
+	g_object_unref( tracker_properties1 );
+
+	/* handle GetSelectedPaths method invocation on the .Properties1 interface
+	 */
+	g_signal_connect(
+			tracker_properties1,
+			"handle-get-selected-paths",
+			G_CALLBACK( on_properties1_get_selected_paths ),
+			tracker );
+
+	/* last export the DBus object on the object manager server
+	 * (which takes its own reference on it)
+	 */
+	g_dbus_object_manager_server_export( tracker->private->server, G_DBUS_OBJECT_SKELETON( tracker_object ));
+	g_object_unref( tracker_object );
+
+	/* and connect the object manager server to the D-Bus session
+	 */
+	g_dbus_object_manager_server_set_connection( tracker->private->server, connection );
 }
 
 static void
+on_name_acquired( GDBusConnection *connection, const gchar *name, NATracker *tracker )
+{
+	static const gchar *thisfn = "na_tracker_on_name_acquired";
+
+	g_debug( "%s: connection=%p, name=%s, tracker=%p",
+			thisfn,
+			( void * ) connection,
+			name,
+			( void * ) tracker );
+}
+
+static void
+on_name_lost( GDBusConnection *connection, const gchar *name, NATracker *tracker )
+{
+	static const gchar *thisfn = "na_tracker_on_name_lost";
+
+	g_debug( "%s: connection=%p, name=%s, tracker=%p",
+			thisfn,
+			( void * ) connection,
+			name,
+			( void * ) tracker );
+}
+#endif /* HAVE_GDBUS */
+
+static void
 instance_dispose( GObject *object )
 {
 	static const gchar *thisfn = "na_tracker_instance_dispose";
-	NATracker *self;
+	NATrackerPrivate *priv;
 
 	g_debug( "%s: object=%p", thisfn, ( void * ) object );
 	g_return_if_fail( NA_IS_TRACKER( object ));
-	self = NA_TRACKER( object );
 
-	if( !self->private->dispose_has_run ){
+	priv = NA_TRACKER( object )->private;
 
-		self->private->dispose_has_run = TRUE;
+	if( !priv->dispose_has_run ){
 
-		g_object_unref( self->private->tracker );
-		self->private->tracker = NULL;
+		priv->dispose_has_run = TRUE;
+
+#ifdef HAVE_GDBUS
+		if( priv->owner_id ){
+			g_bus_unown_name( priv->owner_id );
+		}
+		if( priv->server ){
+			g_object_unref( priv->server );
+		}
+#endif
+
+		priv->selected = free_selected( priv->selected );
 
 		/* chain up to the parent class */
 		if( G_OBJECT_CLASS( st_parent_class )->dispose ){
@@ -259,31 +386,32 @@ menu_provider_iface_init( NautilusMenuProviderIface *iface )
 
 	iface->get_background_items = menu_provider_get_background_items;
 	iface->get_file_items = menu_provider_get_file_items;
-
-#ifdef HAVE_NAUTILUS_MENU_PROVIDER_GET_TOOLBAR_ITEMS
-	iface->get_toolbar_items = NULL;
-#endif
 }
 
 static GList *
 menu_provider_get_background_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *folder )
 {
 	static const gchar *thisfn = "na_tracker_menu_provider_get_background_items";
-	NATracker *self;
+	NATracker *tracker;
 	gchar *uri;
 	GList *selected;
 
-	uri = nautilus_file_info_get_uri( folder );
-	g_debug( "%s: provider=%p, window=%p, folder=%s", thisfn, ( void * ) provider, ( void * ) window, uri );
-	g_free( uri );
-
 	g_return_val_if_fail( NA_IS_TRACKER( provider ), NULL );
-	self = NA_TRACKER( provider );
 
-	if( !self->private->dispose_has_run && self->private->tracker ){
+	tracker = NA_TRACKER( provider );
+
+	if( !tracker->private->dispose_has_run ){
+
+		uri = nautilus_file_info_get_uri( folder );
+		g_debug( "%s: provider=%p, window=%p, folder=%s",
+				thisfn,
+				( void * ) provider,
+				( void * ) window,
+				uri );
+		g_free( uri );
 
 		selected = g_list_prepend( NULL, folder );
-		na_tracker_dbus_set_uris( self->private->tracker, selected );
+		set_uris( tracker, selected );
 		g_list_free( selected );
 	}
 
@@ -300,18 +428,146 @@ static GList *
 menu_provider_get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files )
 {
 	static const gchar *thisfn = "na_tracker_menu_provider_get_file_items";
-	NATracker *self;
-
-	g_debug( "%s: provider=%p, window=%p, files=%p, count=%d",
-			thisfn, ( void * ) provider, ( void * ) window, ( void * ) files, g_list_length( files ));
+	NATracker *tracker;
 
 	g_return_val_if_fail( NA_IS_TRACKER( provider ), NULL );
-	self = NA_TRACKER( provider );
 
-	if( !self->private->dispose_has_run && self->private->tracker ){
+	tracker = NA_TRACKER( provider );
+
+	if( !tracker->private->dispose_has_run ){
 
-		na_tracker_dbus_set_uris( self->private->tracker, files );
+		g_debug( "%s: provider=%p, window=%p, files=%p, count=%d",
+				thisfn,
+				( void * ) provider,
+				( void * ) window,
+				( void * ) files, g_list_length( files ));
+
+		set_uris( tracker, files );
 	}
 
 	return( NULL );
 }
+
+/*
+ * set_uris:
+ * @tracker: this #NATracker instance.
+ * @files: the list of currently selected items.
+ *
+ * Maintains our own list of uris.
+ */
+static void
+set_uris( NATracker *tracker, GList *files )
+{
+	NATrackerPrivate *priv;
+
+	priv = tracker->private;
+
+	priv->selected = free_selected( tracker->private->selected );
+	priv->selected = nautilus_file_info_list_copy( files );
+}
+
+#ifdef HAVE_GDBUS
+/*
+ * Returns: %TRUE if the method has been handled.
+ */
+static gboolean
+on_properties1_get_selected_paths( NATrackerProperties1 *tracker_properties, GDBusMethodInvocation *invocation, NATracker *tracker )
+{
+	gchar **paths;
+
+	g_return_val_if_fail( NA_IS_TRACKER( tracker ), FALSE );
+
+	paths = get_selected_paths( tracker );
+
+	na_tracker_properties1_complete_get_selected_paths(
+			tracker_properties,
+			invocation,
+			( const gchar * const * ) paths );
+
+	return( TRUE );
+}
+#endif
+
+#ifdef HAVE_DBUS_GLIB
+/**
+ * na_tracker_get_selected_paths:
+ * @tracker: this #NATracker object.
+ * @paths: the location in which copy the strings to be sent.
+ * @error: the location of a GError.
+ *
+ * Sends on session D-Bus the list of currently selected items, as two
+ * strings for each item :
+ * - the uri
+ * - the mimetype as returned by NautilusFileInfo.
+ *
+ * This is required as some particular items are only known by Nautilus
+ * (e.g. computer), and standard GLib functions are not able to retrieve
+ * their mimetype.
+ *
+ * Exported as GetSelectedPaths method on Tracker.Properties1 interface.
+ *
+ * Returns: %TRUE if the method has been handled.
+ */
+gboolean
+na_tracker_get_selected_paths( NATracker *tracker, char ***paths, GError **error )
+{
+	g_return_val_if_fail( NA_IS_TRACKER( tracker ), FALSE );
+
+	*error = NULL;
+	*paths = get_selected_paths( tracker );
+
+	return( TRUE );
+}
+#endif
+
+/*
+ * get_selected_paths:
+ * @tracker: this #NATracker object.
+ *
+ * Sends on session D-Bus the list of currently selected items, as two
+ * strings for each item :
+ * - the uri
+ * - the mimetype as returned by NautilusFileInfo.
+ *
+ * This is required as some particular items are only known by Nautilus
+ * (e.g. computer), and standard GLib functions are not able to retrieve
+ * their mimetype.
+ *
+ * Exported as GetSelectedPaths method on Tracker.Properties1 interface.
+ */
+static gchar **
+get_selected_paths( NATracker *tracker )
+{
+	static const gchar *thisfn = "na_tracker_get_selected_paths";
+	NATrackerPrivate *priv;
+	gchar **paths;
+	GList *it;
+	int count;
+	gchar **iter;
+
+	paths = NULL;
+	priv = tracker->private;
+
+	g_debug( "%s: tracker=%p", thisfn, ( void * ) tracker );
+
+	count = 2 * g_list_length( priv->selected );
+	paths = ( char ** ) g_new0( gchar *, 1+count );
+	iter = paths;
+
+	for( it = priv->selected ; it ; it = it->next ){
+		*iter = nautilus_file_info_get_uri(( NautilusFileInfo * ) it->data );
+		iter++;
+		*iter = nautilus_file_info_get_mime_type(( NautilusFileInfo * ) it->data );
+		iter++;
+	}
+
+	return( paths );
+}
+
+static GList *
+free_selected( GList *selected )
+{
+	nautilus_file_info_list_free( selected );
+
+	return( NULL );
+}
diff --git a/src/plugin-tracker/na-tracker.h b/src/plugin-tracker/na-tracker.h
index 92e7618..1d1d957 100644
--- a/src/plugin-tracker/na-tracker.h
+++ b/src/plugin-tracker/na-tracker.h
@@ -36,24 +36,39 @@
  * @short_description: #NATracker class definition.
  * @include: tracker/na-tracker.h
  *
- * There is only one #NATracker object in the process. As any Nautilus
+ * The #NATracker object is instanciated when Nautilus file manager loads
+ * this plugin (this is the normal behavior of Nautilus to instanciate one
+ * object of each plugin type).
+ *
+ * There is so only one #NATracker object in the process. As any Nautilus
  * extension, it is instantiated when the module is loaded by the file
- * manager at startup time.
+ * manager, usually at startup time.
+ *
+ * glib-dbus
+ *
+ * The #NATracker object initiates a connection on the session D-Bus, takes
+ * ownership of our well-known name, and then register itself as the object
+ * which serves our object path (so installing introspection infos).
  *
- * The #NATracker object initiates the DBus connection, and allocates
- * the object responsable of effective tracking.
+ * GDBus
+ *
+ * The #NATracker object instanciates and keeps a new GDBusObjectManagerServer
+ * rooted on our D-Bus path.
+ * It then allocates an object at this same path, and another object which
+ * implements the .Properties1 interface. Last connects to the method signal
+ * before connecting the server to the session D-Bus.
  */
 
 #include <glib-object.h>
 
 G_BEGIN_DECLS
 
-#define NA_TRACKER_TYPE                ( na_tracker_get_type())
-#define NA_TRACKER( object )           ( G_TYPE_CHECK_INSTANCE_CAST(( object ), NA_TRACKER_TYPE, NATracker ))
-#define NA_TRACKER_CLASS( klass )      ( G_TYPE_CHECK_CLASS_CAST(( klass ), NA_TRACKER_TYPE, NATrackerClass ))
-#define NA_IS_TRACKER( object )        ( G_TYPE_CHECK_INSTANCE_TYPE(( object ), NA_TRACKER_TYPE ))
-#define NA_IS_TRACKER_CLASS( klass )   ( G_TYPE_CHECK_CLASS_TYPE(( klass ), NA_TRACKER_TYPE ))
-#define NA_TRACKER_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), NA_TRACKER_TYPE, NATrackerClass ))
+#define NA_TYPE_TRACKER                ( na_tracker_get_type())
+#define NA_TRACKER( object )           ( G_TYPE_CHECK_INSTANCE_CAST(( object ), NA_TYPE_TRACKER, NATracker ))
+#define NA_TRACKER_CLASS( klass )      ( G_TYPE_CHECK_CLASS_CAST(( klass ), NA_TYPE_TRACKER, NATrackerClass ))
+#define NA_IS_TRACKER( object )        ( G_TYPE_CHECK_INSTANCE_TYPE(( object ), NA_TYPE_TRACKER ))
+#define NA_IS_TRACKER_CLASS( klass )   ( G_TYPE_CHECK_CLASS_TYPE(( klass ), NA_TYPE_TRACKER ))
+#define NA_TRACKER_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), NA_TYPE_TRACKER, NATrackerClass ))
 
 typedef struct _NATrackerPrivate       NATrackerPrivate;
 
@@ -73,8 +88,12 @@ typedef struct {
 }
 	NATrackerClass;
 
-GType na_tracker_get_type( void );
-void  na_tracker_register_type( GTypeModule *module );
+GType    na_tracker_get_type          ( void );
+void     na_tracker_register_type     ( GTypeModule *module );
+
+#ifdef HAVE_DBUS_GLIB
+gboolean na_tracker_get_selected_paths( NATracker *tracker, char ***paths, GError **error );
+#endif
 
 G_END_DECLS
 
diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
index 11bad4f..626cc6b 100644
--- a/src/utils/Makefile.am
+++ b/src/utils/Makefile.am
@@ -70,17 +70,37 @@ nautilus_actions_print_LDADD = \
 	$(NA_UTILS_LDADD)											\
 	$(NULL)
 
-BUILT_SOURCES = \
+BUILT_SOURCES =
+
+if HAVE_GDBUS
+BUILT_SOURCES += \
+	nautilus-actions-run-bindings.c								\
+	nautilus-actions-run-bindings.h								\
+	$(NULL)
+
+nautilus-actions-run-bindings.c nautilus-actions-run-bindings.h: $(top_srcdir)/src/plugin-tracker/na-tracker-gdbus.xml
+	gdbus-codegen \
+		--interface-prefix org.nautilus_actions.DBus.Tracker.	\
+		--generate-c-code nautilus-actions-run-bindings			\
+		--c-namespace NA_Tracker								\
+		--c-generate-object-manager								\
+		$<
+endif
+
+if HAVE_DBUS_GLIB
+BUILT_SOURCES += \
 	nautilus-actions-run-bindings.h								\
 	$(NULL)
 
 nautilus-actions-run-bindings.h: $(top_srcdir)/src/plugin-tracker/na-tracker-dbus.xml
 	dbus-binding-tool --mode=glib-client $< > $@
+endif
 
 nautilus_actions_run_SOURCES = \
 	nautilus-actions-run.c										\
 	console-utils.c												\
 	console-utils.h												\
+	$(BUILT_SOURCES)											\
 	$(NULL)
 
 nautilus_actions_run_LDADD = \
diff --git a/src/utils/nautilus-actions-run.c b/src/utils/nautilus-actions-run.c
index 0d4d99b..105ca7d 100644
--- a/src/utils/nautilus-actions-run.c
+++ b/src/utils/nautilus-actions-run.c
@@ -250,7 +250,7 @@ get_action( const gchar *id )
 }
 
 /*
- * the DBus.Tracker.Status interface returns a list of strings
+ * the DBus.Tracker.Properties1 interface returns a list of strings
  * where each selected item brings up both its URI and its Nautilus
  * mime type.
  *
@@ -261,17 +261,69 @@ targets_from_selection( void )
 {
 	static const gchar *thisfn = "nautilus_actions_run_targets_from_selection";
 	GList *selection;
-	DBusGConnection *connection;
-	DBusGProxy *proxy;
 	GError *error;
 	gchar **paths;
 
+	g_debug( "%s", thisfn );
+
+	selection = NULL;
 	error = NULL;
-	proxy = NULL;
 	paths = NULL;
 
-	connection = dbus_g_bus_get( DBUS_BUS_SESSION, &error );
+#ifdef HAVE_GDBUS
+	GDBusObjectManager *manager;
+	gchar *name_owner;
+	GDBusObject *object;
+	GDBusInterface *iface;
+
+	manager = na_tracker_object_manager_client_new_for_bus_sync(
+			G_BUS_TYPE_SESSION,
+			G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
+			NAUTILUS_ACTIONS_DBUS_SERVICE,
+			NAUTILUS_ACTIONS_DBUS_TRACKER_PATH,
+			NULL,
+			&error );
+
+	if( !manager ){
+		g_printerr( "%s: unable to allocate an ObjectManagerClient: %s", thisfn, error->message );
+		g_error_free( error );
+		return( NULL );
+	}
+
+	name_owner = g_dbus_object_manager_client_get_name_owner( G_DBUS_OBJECT_MANAGER_CLIENT( manager ));
+	g_debug( "%s: name_owner=%s", thisfn, name_owner );
+	g_free( name_owner );
+
+	object = g_dbus_object_manager_get_object( manager, NAUTILUS_ACTIONS_DBUS_TRACKER_PATH );
+	if( !object ){
+		g_printerr( "%s: unable to get object at %s path", thisfn, NAUTILUS_ACTIONS_DBUS_TRACKER_PATH );
+		g_object_unref( manager );
+		return( NULL );
+	}
+
+	iface = g_dbus_object_get_interface( object, NAUTILUS_ACTIONS_DBUS_TRACKER_IFACE );
+	if( !iface ){
+		g_printerr( "%s: unable to get %s interface", thisfn, NAUTILUS_ACTIONS_DBUS_TRACKER_IFACE );
+		g_object_unref( object );
+		g_object_unref( manager );
+		return( NULL );
+	}
+
+	/* note that @iface is really a GDBusProxy instance
+	 * and additionally also a NATrackerProperties1 instance
+	 */
+	na_tracker_properties1_call_get_selected_paths_sync(
+			NA_TRACKER_PROPERTIES1( iface ),
+			&paths,
+			NULL,
+			&error );
 
+#else
+# ifdef HAVE_DBUS_GLIB
+	DBusGConnection *connection;
+	DBusGProxy *proxy = NULL;
+
+	connection = dbus_g_bus_get( DBUS_BUS_SESSION, &error );
 	if( !connection ){
 		if( error ){
 			g_printerr( _( "Error: unable to get a connection to session DBus: %s" ), error->message );
@@ -305,13 +357,15 @@ targets_from_selection( void )
 	}
 	g_debug( "%s: function call is ok", thisfn );
 
+	/* TODO: unref proxy */
+	dbus_g_connection_unref( connection );
+# endif
+#endif
+
 	selection = get_selection_from_strv(( const gchar ** ) paths, TRUE );
 
 	g_strfreev( paths );
 
-	/* TODO: unref proxy */
-	dbus_g_connection_unref( connection );
-
 	return( selection );
 }
 



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