nautilus-3.6.3/src/nautilus-freedesktop-dbus.c

No issues found

  1 /*
  2  * nautilus-freedesktop-dbus: Implementation for the org.freedesktop DBus file-management interfaces
  3  *
  4  * Nautilus is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU General Public License as
  6  * published by the Free Software Foundation; either version 2 of the
  7  * License, or (at your option) any later version.
  8  *
  9  * Nautilus is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  * General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU General Public License
 15  * along with this program; if not, write to the Free Software
 16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 17  *
 18  * Authors: Akshay Gupta <kitallis@gmail.com>
 19  *          Federico Mena Quintero <federico@gnome.org>
 20  */
 21 
 22 #include <config.h>
 23 
 24 #include "nautilus-freedesktop-dbus.h"
 25 #include "nautilus-freedesktop-generated.h"
 26 
 27 /* We share the same debug domain as nautilus-dbus-manager */
 28 #define DEBUG_FLAG NAUTILUS_DEBUG_DBUS
 29 #include <libnautilus-private/nautilus-debug.h>
 30 
 31 #include "nautilus-properties-window.h"
 32 
 33 #include <gio/gio.h>
 34 
 35 
 36 typedef struct _NautilusFreedesktopDBus NautilusFreedesktopDBus;
 37 typedef struct _NautilusFreedesktopDBusClass NautilusFreedesktopDBusClass;
 38 
 39 struct _NautilusFreedesktopDBus {
 40 	GObject parent;
 41 
 42 	/* Parent application */
 43 	NautilusApplication *application;
 44 
 45 	/* Id from g_dbus_own_name() */
 46 	guint owner_id;
 47 
 48 	/* DBus paraphernalia */
 49 	GDBusConnection *connection;
 50 	GDBusObjectManagerServer *object_manager;
 51 
 52 	/* Our DBus implementation skeleton */
 53 	NautilusFreedesktopFileManager1 *skeleton;
 54 };
 55 
 56 struct _NautilusFreedesktopDBusClass {
 57 	GObjectClass parent_class;
 58 };
 59 
 60 enum {
 61 	PROP_APPLICATION = 1
 62 };
 63 
 64 #define SERVICE_TIMEOUT 5
 65 
 66 static GType nautilus_freedesktop_dbus_get_type (void) G_GNUC_CONST;
 67 G_DEFINE_TYPE (NautilusFreedesktopDBus, nautilus_freedesktop_dbus, G_TYPE_OBJECT);
 68 
 69 static NautilusFreedesktopDBus *singleton = NULL;
 70 
 71 static gboolean
 72 skeleton_handle_show_items_cb (NautilusFreedesktopFileManager1 *object,
 73 			       GDBusMethodInvocation *invocation,
 74 			       const gchar *const *uris,
 75 			       const gchar *startup_id,
 76 			       gpointer data)
 77 {
 78 	NautilusFreedesktopDBus *fdb = data;
 79 	int i;
 80 
 81 	for (i = 0; uris[i] != NULL; i++) {
 82 		GFile *file;
 83 		GFile *parent;
 84 
 85 		file = g_file_new_for_uri (uris[i]);
 86 		parent = g_file_get_parent (file);
 87 
 88 		if (parent != NULL) {
 89 			nautilus_application_open_location (fdb->application, parent, file, startup_id);
 90 			g_object_unref (parent);
 91 		} else {
 92 			nautilus_application_open_location (fdb->application, file, NULL, startup_id);
 93 		}
 94 
 95 		g_object_unref (file);
 96 	}
 97 
 98 	nautilus_freedesktop_file_manager1_complete_show_items (object, invocation);
 99 	return TRUE;
100 }
101 
102 static gboolean
103 skeleton_handle_show_folders_cb (NautilusFreedesktopFileManager1 *object,
104 				 GDBusMethodInvocation *invocation,
105 				 const gchar *const *uris,
106 				 const gchar *startup_id,
107 				 gpointer data)
108 {
109 	NautilusFreedesktopDBus *fdb = data;
110 	int i;
111 
112 	for (i = 0; uris[i] != NULL; i++) {
113 		GFile *file;
114 
115 		file = g_file_new_for_uri (uris[i]);
116 
117 		nautilus_application_open_location (fdb->application, file, NULL, startup_id);
118 
119 		g_object_unref (file);
120 	}
121 
122 	nautilus_freedesktop_file_manager1_complete_show_folders (object, invocation);
123 	return TRUE;
124 }
125 
126 static gboolean
127 skeleton_handle_show_item_properties_cb (NautilusFreedesktopFileManager1 *object,
128 					 GDBusMethodInvocation *invocation,
129 					 const gchar *const *uris,
130 					 const gchar *startup_id,
131 					 gpointer data)
132 {
133 	GList *files;
134 	int i;
135 
136 	files = NULL;
137 
138 	for (i = 0; uris[i] != NULL; i++) {
139 		files = g_list_prepend (files, nautilus_file_get_by_uri (uris[i]));
140         }
141 
142 	files = g_list_reverse (files);
143 
144 	nautilus_properties_window_present (files, NULL, startup_id);
145 
146 	nautilus_file_list_free (files);
147 
148 	nautilus_freedesktop_file_manager1_complete_show_item_properties (object, invocation);
149 	return TRUE;
150 }
151 
152 static gboolean
153 service_timeout_cb (gpointer data)
154 {
155 	NautilusFreedesktopDBus *fdb = data;
156 
157 	DEBUG ("Reached the DBus service timeout");
158 
159 	/* just unconditionally release here, as if an operation has been
160 	 * called, its progress handler will hold it alive for all the task duration.
161 	 */
162 	g_application_release (G_APPLICATION (fdb->application));
163 
164 	return FALSE;
165 }
166 
167 static void
168 bus_acquired_cb (GDBusConnection *conn,
169 		 const gchar     *name,
170 		 gpointer         user_data)
171 {
172 	NautilusFreedesktopDBus *fdb = user_data;
173 
174 	DEBUG ("Bus acquired at %s", name);
175 
176 	fdb->connection = g_object_ref (conn);
177 	fdb->object_manager = g_dbus_object_manager_server_new ("/org/freedesktop/FileManager1");
178 
179 	fdb->skeleton = nautilus_freedesktop_file_manager1_skeleton_new ();
180 
181 	g_signal_connect (fdb->skeleton, "handle-show-items",
182 			  G_CALLBACK (skeleton_handle_show_items_cb), fdb);
183 	g_signal_connect (fdb->skeleton, "handle-show-folders",
184 			  G_CALLBACK (skeleton_handle_show_folders_cb), fdb);
185 	g_signal_connect (fdb->skeleton, "handle-show-item-properties",
186 			  G_CALLBACK (skeleton_handle_show_item_properties_cb), fdb);
187 
188 	g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (fdb->skeleton), fdb->connection, "/org/freedesktop/FileManager1", NULL);
189 
190 	g_dbus_object_manager_server_set_connection (fdb->object_manager, fdb->connection);
191 
192 	g_timeout_add_seconds (SERVICE_TIMEOUT, service_timeout_cb, fdb);
193 }
194 
195 static void
196 name_acquired_cb (GDBusConnection *connection,
197 		  const gchar     *name,
198 		  gpointer         user_data)
199 {
200 	DEBUG ("Acquired the name %s on the session message bus\n", name);
201 }
202 
203 static void
204 name_lost_cb (GDBusConnection *connection,
205 	      const gchar     *name,
206 	      gpointer         user_data)
207 {
208 	DEBUG ("Lost (or failed to acquire) the name %s on the session message bus\n", name);
209 }
210 
211 static void
212 nautilus_freedesktop_dbus_dispose (GObject *object)
213 {
214 	NautilusFreedesktopDBus *fdb = (NautilusFreedesktopDBus *) object;
215 
216 	if (fdb->owner_id != 0) {
217 		g_bus_unown_name (fdb->owner_id);
218 		fdb->owner_id = 0;
219 	}
220 
221 	if (fdb->skeleton != NULL) {
222 		g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (fdb->skeleton));
223 		g_object_unref (fdb->skeleton);
224 		fdb->skeleton = NULL;
225 	}
226 
227 	g_clear_object (&fdb->object_manager);
228 	g_clear_object (&fdb->connection);
229 	fdb->application = NULL;
230 
231 	G_OBJECT_CLASS (nautilus_freedesktop_dbus_parent_class)->dispose (object);
232 }
233 
234 static void
235 nautilus_freedesktop_dbus_constructed (GObject *object)
236 {
237 	NautilusFreedesktopDBus *fdb = (NautilusFreedesktopDBus *) object;
238 
239 	G_OBJECT_CLASS (nautilus_freedesktop_dbus_parent_class)->constructed (object);
240 
241 	g_application_hold (G_APPLICATION (fdb->application));
242 
243 	fdb->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
244 					"org.freedesktop.FileManager1",
245 					G_BUS_NAME_OWNER_FLAGS_NONE,
246 					bus_acquired_cb,
247 					name_acquired_cb,
248 					name_lost_cb,
249 					fdb,
250 					NULL);
251 }
252 
253 static void
254 nautilus_freedesktop_dbus_set_property (GObject *object,
255 					guint property_id,
256 					const GValue *value,
257 					GParamSpec *pspec)
258 {
259 	NautilusFreedesktopDBus *fdb = (NautilusFreedesktopDBus *) object;
260 
261 	switch (property_id) {
262 	case PROP_APPLICATION:
263 		fdb->application = g_value_get_object (value);
264 		break;
265 
266 	default:
267 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
268 		break;
269 	}
270 }
271 
272 
273 static void
274 nautilus_freedesktop_dbus_class_init (NautilusFreedesktopDBusClass *klass)
275 {
276 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
277 
278 	object_class->dispose		= nautilus_freedesktop_dbus_dispose;
279 	object_class->constructed	= nautilus_freedesktop_dbus_constructed;
280 	object_class->set_property	= nautilus_freedesktop_dbus_set_property;
281 
282 	g_object_class_install_property (object_class,
283 					 PROP_APPLICATION,
284 					 g_param_spec_object ("application",
285 							      "NautilusApplication instance",
286 							      "The owning NautilusApplication instance",
287 							      NAUTILUS_TYPE_APPLICATION,
288 							      G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
289 
290 }
291 
292 static void
293 nautilus_freedesktop_dbus_init (NautilusFreedesktopDBus *fdb)
294 {
295 	/* nothing */
296 }
297 
298 /* Tries to own the org.freedesktop.FileManager1 service name */
299 void
300 nautilus_freedesktop_dbus_start (NautilusApplication *app)
301 {	
302 	if (singleton != NULL) {
303 		return;
304 	}
305 
306 	singleton = g_object_new (nautilus_freedesktop_dbus_get_type (),
307 				  "application", app,
308 				  NULL);
309 }
310 
311 /* Releases the org.freedesktop.FileManager1 service name */
312 void
313 nautilus_freedesktop_dbus_stop (void)
314 {
315 	g_clear_object (&singleton);
316 }