/*
* nautilus-freedesktop-dbus: Implementation for the org.freedesktop DBus file-management interfaces
*
* Nautilus 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.
*
* Nautilus 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, see .
*
* Authors: Akshay Gupta
* Federico Mena Quintero
*/
#include "nautilus-freedesktop-dbus.h"
/* We share the same debug domain as nautilus-dbus-manager */
#define DEBUG_FLAG NAUTILUS_DEBUG_DBUS
#include "nautilus-debug.h"
#include "nautilus-application.h"
#include "nautilus-file.h"
#include "nautilus-freedesktop-generated.h"
#include "nautilus-properties-window.h"
#include
struct _NautilusFreedesktopDBus
{
GObject parent;
/* Id from g_dbus_own_name() */
guint owner_id;
/* Our DBus implementation skeleton */
NautilusFreedesktopFileManager1 *skeleton;
GDBusConnection *connection;
};
enum
{
PROP_0,
PROP_CONNECTION,
};
G_DEFINE_TYPE (NautilusFreedesktopDBus, nautilus_freedesktop_dbus, G_TYPE_OBJECT);
static gboolean
skeleton_handle_show_items_cb (NautilusFreedesktopFileManager1 *object,
GDBusMethodInvocation *invocation,
const gchar * const *uris,
const gchar *startup_id,
gpointer data)
{
NautilusApplication *application;
int i;
application = NAUTILUS_APPLICATION (g_application_get_default ());
for (i = 0; uris[i] != NULL; i++)
{
g_autoptr (GFile) file = NULL;
g_autoptr (GFile) parent = NULL;
file = g_file_new_for_uri (uris[i]);
parent = g_file_get_parent (file);
if (parent != NULL)
{
nautilus_application_open_location (application, parent, file, startup_id);
}
else
{
nautilus_application_open_location (application, file, NULL, startup_id);
}
}
nautilus_freedesktop_file_manager1_complete_show_items (object, invocation);
return TRUE;
}
static gboolean
skeleton_handle_show_folders_cb (NautilusFreedesktopFileManager1 *object,
GDBusMethodInvocation *invocation,
const gchar * const *uris,
const gchar *startup_id,
gpointer data)
{
NautilusApplication *application;
int i;
application = NAUTILUS_APPLICATION (g_application_get_default ());
for (i = 0; uris[i] != NULL; i++)
{
g_autoptr (GFile) file = NULL;
file = g_file_new_for_uri (uris[i]);
nautilus_application_open_location (application, file, NULL, startup_id);
}
nautilus_freedesktop_file_manager1_complete_show_folders (object, invocation);
return TRUE;
}
static void
properties_window_on_finished (gpointer user_data)
{
g_application_release (g_application_get_default ());
}
static gboolean
skeleton_handle_show_item_properties_cb (NautilusFreedesktopFileManager1 *object,
GDBusMethodInvocation *invocation,
const gchar * const *uris,
const gchar *startup_id,
gpointer data)
{
GList *files;
int i;
files = NULL;
for (i = 0; uris[i] != NULL; i++)
{
files = g_list_prepend (files, nautilus_file_get_by_uri (uris[i]));
}
files = g_list_reverse (files);
g_application_hold (g_application_get_default ());
nautilus_properties_window_present (files, NULL, startup_id,
properties_window_on_finished, NULL);
nautilus_file_list_free (files);
nautilus_freedesktop_file_manager1_complete_show_item_properties (object, invocation);
return TRUE;
}
static void
name_acquired_cb (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
DEBUG ("Acquired the name %s on the session message bus\n", name);
}
static void
name_lost_cb (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
DEBUG ("Lost (or failed to acquire) the name %s on the session message bus\n", name);
}
static void
nautilus_freedesktop_dbus_dispose (GObject *object)
{
NautilusFreedesktopDBus *fdb = (NautilusFreedesktopDBus *) object;
if (fdb->owner_id != 0)
{
g_bus_unown_name (fdb->owner_id);
fdb->owner_id = 0;
}
if (fdb->skeleton != NULL)
{
g_object_unref (fdb->skeleton);
fdb->skeleton = NULL;
}
g_clear_object (&fdb->connection);
G_OBJECT_CLASS (nautilus_freedesktop_dbus_parent_class)->dispose (object);
}
static void
nautilus_freedesktop_dbus_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NautilusFreedesktopDBus *fdb = NAUTILUS_FREEDESKTOP_DBUS (object);
switch (prop_id)
{
case PROP_CONNECTION:
{
g_set_object (&fdb->connection, g_value_get_object (value));
}
break;
default:
{
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
break;
}
}
static void
nautilus_freedesktop_dbus_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NautilusFreedesktopDBus *fdb = NAUTILUS_FREEDESKTOP_DBUS (object);
switch (prop_id)
{
case PROP_CONNECTION:
{
g_value_set_object (value, fdb->connection);
}
break;
default:
{
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
break;
}
}
static void
nautilus_freedesktop_dbus_class_init (NautilusFreedesktopDBusClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = nautilus_freedesktop_dbus_dispose;
object_class->get_property = nautilus_freedesktop_dbus_get_property;
object_class->set_property = nautilus_freedesktop_dbus_set_property;
g_object_class_install_property (object_class,
PROP_CONNECTION,
g_param_spec_object ("connection",
"Connection",
"GDBus connection property",
G_TYPE_DBUS_CONNECTION,
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE));
}
static void
nautilus_freedesktop_dbus_init (NautilusFreedesktopDBus *fdb)
{
fdb->skeleton = nautilus_freedesktop_file_manager1_skeleton_new ();
}
void
nautilus_freedesktop_dbus_set_open_locations (NautilusFreedesktopDBus *fdb,
const gchar **locations)
{
g_return_if_fail (NAUTILUS_IS_FREEDESKTOP_DBUS (fdb));
nautilus_freedesktop_file_manager1_set_open_locations (fdb->skeleton, locations);
}
/**
* nautilus_freedesktop_dbus_set_open_windows_with_locations:
* fdb: The skeleton for the dbus interface
* locations: Mapping of windows to locations open in each window
*
* This allows the application to publish the locations that are open in each window.
* It is used by shell extensions like dash-to-dock/ubuntu-dock to match special dock
* icons to the windows where the icon's location is open. For example, the Trash or
* a removable device.
*/
void
nautilus_freedesktop_dbus_set_open_windows_with_locations (NautilusFreedesktopDBus *fdb,
GVariant *locations)
{
g_return_if_fail (NAUTILUS_IS_FREEDESKTOP_DBUS (fdb));
nautilus_freedesktop_file_manager1_set_open_windows_with_locations (fdb->skeleton,
locations);
}
NautilusFreedesktopDBus *
nautilus_freedesktop_dbus_new (GDBusConnection *connection)
{
return g_object_new (NAUTILUS_TYPE_FREEDESKTOP_DBUS,
"connection", connection,
NULL);
}
/* Tries to own the org.freedesktop.FileManager1 service name */
gboolean
nautilus_freedesktop_dbus_register (NautilusFreedesktopDBus *fdb,
GError **error)
{
gboolean success;
success = g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (fdb->skeleton),
fdb->connection,
NAUTILUS_FDO_DBUS_PATH,
error);
if (success)
{
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);
}
fdb->owner_id = g_bus_own_name_on_connection (fdb->connection,
NAUTILUS_FDO_DBUS_NAME,
G_BUS_NAME_OWNER_FLAGS_NONE,
name_acquired_cb,
name_lost_cb,
fdb,
NULL);
return success;
}
void
nautilus_freedesktop_dbus_unregister (NautilusFreedesktopDBus *fdb)
{
if (fdb->owner_id != 0)
{
g_bus_unown_name (fdb->owner_id);
fdb->owner_id = 0;
}
g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (fdb->skeleton));
g_signal_handlers_disconnect_by_data (fdb->skeleton, fdb);
}