From d1715e4fdef385cea4eda116090311dcff9fcd18 Mon Sep 17 00:00:00 2001 From: Stefano Karapetsas Date: Sat, 23 Feb 2013 22:02:09 +0100 Subject: Add support for freedesktop.org File Manager DBus Interface http://www.freedesktop.org/wiki/Specifications/file-manager-interface Most of code is adapted from Nautilus: http://git.gnome.org/browse/nautilus/tree/src/nautilus-freedesktop-dbus.c Closes https://github.com/mate-desktop/mate-file-manager/issues/3 --- src/Makefile.am | 16 +++ src/caja-application.c | 36 +++++++ src/caja-application.h | 5 +- src/caja-freedesktop-dbus.c | 245 ++++++++++++++++++++++++++++++++++++++++++++ src/caja-freedesktop-dbus.h | 42 ++++++++ 5 files changed, 343 insertions(+), 1 deletion(-) create mode 100644 src/caja-freedesktop-dbus.c create mode 100644 src/caja-freedesktop-dbus.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 28c97fc1..84ee8b5f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,6 +43,19 @@ LDADD = \ $(POPT_LIBS) \ $(NULL) +dbus_freedesktop_built_sources = \ + caja-freedesktop-generated.c \ + caja-freedesktop-generated.h + +$(dbus_freedesktop_built_sources) : Makefile.am $(top_srcdir)/data/freedesktop-dbus-interfaces.xml + gdbus-codegen \ + --interface-prefix org.freedesktop. \ + --c-namespace CajaFreedesktop \ + --c-generate-object-manager \ + --generate-c-code caja-freedesktop-generated \ + $(top_srcdir)/data/freedesktop-dbus-interfaces.xml \ + $(NULL) + @INTLTOOL_DESKTOP_RULE@ desktop_in_files=mate-network-scheme.desktop.in @@ -55,6 +68,7 @@ scheme_DATA = mate-network-scheme.desktop BUILT_SOURCES = \ caja-src-marshal.c \ caja-src-marshal.h \ + $(dbus_freedesktop_built_sources) \ $(NULL) caja_SOURCES = \ @@ -76,6 +90,8 @@ caja_SOURCES = \ caja-emblem-sidebar.h \ caja-file-management-properties.c \ caja-file-management-properties.h \ + caja-freedesktop-dbus.c \ + caja-freedesktop-dbus.h \ caja-history-sidebar.c \ caja-history-sidebar.h \ caja-image-properties-page.c \ diff --git a/src/caja-application.c b/src/caja-application.c index f70fbae7..b4f180f5 100644 --- a/src/caja-application.c +++ b/src/caja-application.c @@ -55,6 +55,7 @@ #include "libcaja-private/caja-file-operations.h" #include "caja-window-private.h" #include "caja-window-manage-views.h" +#include "caja-freedesktop-dbus.h" #include #include #include @@ -107,6 +108,9 @@ static GList *caja_application_spatial_window_list; /* The saving of the accelerator map was requested */ static gboolean save_of_accel_map_requested = FALSE; +/* File Manager DBus Interface */ +static CajaFreedesktopDBus *fdb_manager = NULL; + static void desktop_changed_callback (gpointer user_data); static void desktop_location_changed_callback (gpointer user_data); static void mount_removed_callback (GVolumeMonitor *monitor, @@ -370,6 +374,12 @@ caja_application_finalize (GObject *object) application->proxy = NULL; } + if (fdb_manager != NULL) + { + g_object_unref (fdb_manager); + fdb_manager = NULL; + } + G_OBJECT_CLASS (caja_application_parent_class)->finalize (object); } @@ -846,6 +856,29 @@ open_windows (CajaApplication *application, } } +void +caja_application_open_location (CajaApplication *application, + GFile *location, + GFile *selection, + const char *startup_id) +{ + CajaWindow *window; + GList *sel_list = NULL; + + window = caja_application_create_navigation_window (application, startup_id, gdk_screen_get_default ()); + + if (selection != NULL) { + sel_list = g_list_prepend (NULL, g_object_ref (selection)); + } + + caja_window_slot_open_location_full (caja_window_get_active_slot (window), location, + 0, CAJA_WINDOW_OPEN_FLAG_NEW_WINDOW, sel_list, NULL, NULL); + + if (sel_list != NULL) { + caja_file_list_free (sel_list); + } +} + static UniqueResponse message_received_cb (UniqueApp *unique_app, gint command, @@ -985,6 +1018,9 @@ caja_application_startup (CajaApplication *application, g_signal_connect (application->unique_app, "message-received", G_CALLBACK (message_received_cb), application); } + /* Start the File Manager DBus Interface */ + fdb_manager = caja_freedesktop_dbus_new (application); + /* Monitor the preference to show or hide the desktop */ g_signal_connect_swapped (mate_background_preferences, "changed::" MATE_BG_KEY_SHOW_DESKTOP, diff --git a/src/caja-application.h b/src/caja-application.h index 426f2c09..0ad62f07 100644 --- a/src/caja-application.h +++ b/src/caja-application.h @@ -105,6 +105,9 @@ void caja_application_close_all_spatial_windows (void); void caja_application_open_desktop (CajaApplication *application); void caja_application_close_desktop (void); gboolean caja_application_save_accel_map (gpointer data); - +void caja_application_open_location (CajaApplication *application, + GFile *location, + GFile *selection, + const char *startup_id); #endif /* CAJA_APPLICATION_H */ diff --git a/src/caja-freedesktop-dbus.c b/src/caja-freedesktop-dbus.c new file mode 100644 index 00000000..1ce79c8f --- /dev/null +++ b/src/caja-freedesktop-dbus.c @@ -0,0 +1,245 @@ +/* + * caja-freedesktop-dbus: Implementation for the org.freedesktop DBus file-management interfaces + * + * Caja is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Caja 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * Authors: Akshay Gupta + * Federico Mena Quintero + * Stefano Karapetsas + */ + +#include + +#include "caja-application.h" +#include "caja-freedesktop-dbus.h" +#include "caja-freedesktop-generated.h" + +#include + +#include "file-manager/fm-properties-window.h" + +#include + +struct _CajaFreedesktopDBus { + GObject parent; + + /* Id from g_dbus_own_name() */ + guint owner_id; + + /* DBus paraphernalia */ + GDBusObjectManagerServer *object_manager; + + /* Our DBus implementation skeleton */ + CajaFreedesktopFileManager1 *skeleton; + + /* Caja application */ + CajaApplication *application; +}; + +struct _CajaFreedesktopDBusClass { + GObjectClass parent_class; +}; + +G_DEFINE_TYPE (CajaFreedesktopDBus, caja_freedesktop_dbus, G_TYPE_OBJECT); + +static gboolean +skeleton_handle_show_items_cb (CajaFreedesktopFileManager1 *object, + GDBusMethodInvocation *invocation, + const gchar *const *uris, + const gchar *startup_id, + CajaFreedesktopDBus *fdb) +{ + CajaApplication *application; + int i; + + application = CAJA_APPLICATION (fdb->application); + + for (i = 0; uris[i] != NULL; i++) { + GFile *file; + GFile *parent; + + file = g_file_new_for_uri (uris[i]); + parent = g_file_get_parent (file); + + if (parent != NULL) { + caja_application_open_location (application, parent, file, startup_id); + g_object_unref (parent); + } else { + caja_application_open_location (application, file, NULL, startup_id); + } + + g_object_unref (file); + } + + caja_freedesktop_file_manager1_complete_show_items (object, invocation); + return TRUE; +} + +static gboolean +skeleton_handle_show_folders_cb (CajaFreedesktopFileManager1 *object, + GDBusMethodInvocation *invocation, + const gchar *const *uris, + const gchar *startup_id, + CajaFreedesktopDBus *fdb) +{ + CajaApplication *application; + int i; + + application = CAJA_APPLICATION (fdb->application); + + for (i = 0; uris[i] != NULL; i++) { + GFile *file; + + file = g_file_new_for_uri (uris[i]); + + caja_application_open_location (application, file, NULL, startup_id); + + g_object_unref (file); + } + + caja_freedesktop_file_manager1_complete_show_folders (object, invocation); + return TRUE; +} + +static gboolean +skeleton_handle_show_item_properties_cb (CajaFreedesktopFileManager1 *object, + GDBusMethodInvocation *invocation, + const gchar *const *uris, + const gchar *startup_id, + CajaFreedesktopDBus *fdb) +{ + CajaApplication *application; + CajaWindow *window; + GList *files; + int i; + + application = CAJA_APPLICATION (fdb->application); + files = NULL; + + for (i = 0; uris[i] != NULL; i++) { + files = g_list_prepend (files, caja_file_get_by_uri (uris[i])); + } + + files = g_list_reverse (files); + + if (uris[0] != NULL) { + GFile *file; + file = g_file_new_for_uri (uris[i]); + window = caja_application_get_spatial_window (application, + NULL, + startup_id, + file, + gdk_screen_get_default (), + NULL); + fm_properties_window_present (files, window); + g_object_unref (file); + } + + caja_file_list_free (files); + + caja_freedesktop_file_manager1_complete_show_item_properties (object, invocation); + return TRUE; +} + +static void +bus_acquired_cb (GDBusConnection *conn, + const gchar *name, + CajaFreedesktopDBus *fdb) +{ + caja_debug_log (FALSE, CAJA_DEBUG_LOG_DOMAIN_USER, "Bus acquired at %s", name); + + fdb->object_manager = g_dbus_object_manager_server_new (CAJA_FDO_DBUS_PATH); + + fdb->skeleton = caja_freedesktop_file_manager1_skeleton_new (); + + g_signal_connect (fdb->skeleton, "handle-show-items", + G_CALLBACK (skeleton_handle_show_items_cb), fdb); + g_signal_connect (fdb->skeleton, "handle-show-folders", + G_CALLBACK (skeleton_handle_show_folders_cb), fdb); + g_signal_connect (fdb->skeleton, "handle-show-item-properties", + G_CALLBACK (skeleton_handle_show_item_properties_cb), fdb); + + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (fdb->skeleton), conn, CAJA_FDO_DBUS_PATH, NULL); + + g_dbus_object_manager_server_set_connection (fdb->object_manager, conn); +} + +static void +name_acquired_cb (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + caja_debug_log (FALSE, CAJA_DEBUG_LOG_DOMAIN_USER, "Acquired the name %s on the session message bus\n", name); +} + +static void +name_lost_cb (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + caja_debug_log (FALSE, CAJA_DEBUG_LOG_DOMAIN_USER, "Lost (or failed to acquire) the name %s on the session message bus\n", name); +} + +static void +caja_freedesktop_dbus_dispose (GObject *object) +{ + CajaFreedesktopDBus *fdb = (CajaFreedesktopDBus *) object; + + if (fdb->owner_id != 0) { + g_bus_unown_name (fdb->owner_id); + fdb->owner_id = 0; + } + + if (fdb->skeleton != NULL) { + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (fdb->skeleton)); + g_object_unref (fdb->skeleton); + fdb->skeleton = NULL; + } + + g_clear_object (&fdb->object_manager); + + G_OBJECT_CLASS (caja_freedesktop_dbus_parent_class)->dispose (object); +} + +static void +caja_freedesktop_dbus_class_init (CajaFreedesktopDBusClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = caja_freedesktop_dbus_dispose; +} + +static void +caja_freedesktop_dbus_init (CajaFreedesktopDBus *fdb) +{ + fdb->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + CAJA_FDO_DBUS_NAME, + G_BUS_NAME_OWNER_FLAGS_NONE, + bus_acquired_cb, + name_acquired_cb, + name_lost_cb, + fdb, + NULL); +} + +/* Tries to own the org.freedesktop.FileManager1 service name */ +CajaFreedesktopDBus * +caja_freedesktop_dbus_new (CajaApplication *application) +{ + CajaFreedesktopDBus *fdb = g_object_new (caja_freedesktop_dbus_get_type (), NULL); + fdb->application = application; + return fdb; +} diff --git a/src/caja-freedesktop-dbus.h b/src/caja-freedesktop-dbus.h new file mode 100644 index 00000000..a3ac1504 --- /dev/null +++ b/src/caja-freedesktop-dbus.h @@ -0,0 +1,42 @@ +/* + * caja-freedesktop-dbus: Implementation for the org.freedesktop DBus file-management interfaces + * + * Caja is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Caja 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * Authors: Akshay Gupta + * Federico Mena Quintero + * Stefano Karapetsas + */ + + +#ifndef __CAJA_FREEDESKTOP_DBUS_H__ +#define __CAJA_FREEDESKTOP_DBUS_H__ + +#include + +#include "caja-application.h" + +#define CAJA_FDO_DBUS_IFACE "org.freedesktop.FileManager1" +#define CAJA_FDO_DBUS_NAME "org.freedesktop.FileManager1" +#define CAJA_FDO_DBUS_PATH "/org/freedesktop/FileManager1" + +typedef struct _CajaFreedesktopDBus CajaFreedesktopDBus; +typedef struct _CajaFreedesktopDBusClass CajaFreedesktopDBusClass; + +GType caja_freedesktop_dbus_get_type (void); +CajaFreedesktopDBus * caja_freedesktop_dbus_new (CajaApplication *application); + +#endif /* __CAJA_FREEDESKTOP_DBUS_H__ */ -- cgit v1.2.1