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 }