1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright © 2010 Red Hat, Inc
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Authors: Colin Walters <walters@verbum.org>
23 #define G_APPLICATION_IFACE "org.gtk.Application"
26 application_dbus_method_call (GDBusConnection *connection,
28 const gchar *object_path,
29 const gchar *interface_name,
30 const gchar *method_name,
32 GDBusMethodInvocation *invocation,
35 GApplication *app = G_APPLICATION (user_data);
37 if (method_name == NULL && *method_name == '\0')
40 if (strcmp (method_name, "Quit") == 0)
42 GVariant *platform_data;
44 g_variant_get (parameters, "(@a{sv})", &platform_data);
46 g_dbus_method_invocation_return_value (invocation, NULL);
48 g_application_quit_with_data (app, platform_data);
50 g_variant_unref (platform_data);
52 else if (strcmp (method_name, "ListActions") == 0)
55 GApplicationAction *value;
56 GVariantBuilder builder;
58 g_variant_builder_init (&builder, G_VARIANT_TYPE ("(a{s(sb)})"));
59 g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{s(sb)}"));
60 g_hash_table_iter_init (&iter, app->priv->actions);
61 while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&value))
62 g_variant_builder_add (&builder, "{s(sb)}",
64 value->description ? value->description : "",
66 g_variant_builder_close (&builder);
68 g_dbus_method_invocation_return_value (invocation,
69 g_variant_builder_end (&builder));
71 else if (strcmp (method_name, "InvokeAction") == 0)
73 const char *action_name;
74 GVariant *platform_data;
75 GApplicationAction *action;
77 g_variant_get (parameters, "(&s@a{sv})", &action_name, &platform_data);
79 action = g_hash_table_lookup (app->priv->actions, action_name);
83 char *errmsg = g_strdup_printf ("Invalid action: %s", action_name);
84 g_dbus_method_invocation_return_dbus_error (invocation, G_APPLICATION_IFACE ".InvalidAction", errmsg);
86 g_variant_unref (platform_data);
90 g_signal_emit (app, application_signals[ACTION_WITH_DATA],
91 g_quark_from_string (action_name), action_name, platform_data);
93 g_dbus_method_invocation_return_value (invocation, NULL);
94 g_variant_unref (platform_data);
96 else if (strcmp (method_name, "Activate") == 0)
99 GVariant *platform_data;
101 g_variant_get (parameters, "(@aay@a{sv})", &args, &platform_data);
103 g_signal_emit (app, application_signals[PREPARE_ACTIVATION], 0, args, platform_data);
105 g_variant_unref (args);
106 g_variant_unref (platform_data);
108 g_dbus_method_invocation_return_value (invocation, NULL);
112 static const GDBusArgInfo application_quit_in_args[] =
122 static const GDBusArgInfo * const application_quit_in_args_p[] = {
123 &application_quit_in_args[0],
127 static const GDBusArgInfo application_list_actions_out_args[] =
137 static const GDBusArgInfo * const application_list_actions_out_args_p[] = {
138 &application_list_actions_out_args[0],
142 static const GDBusArgInfo application_invoke_action_in_args[] =
158 static const GDBusArgInfo * const application_invoke_action_in_args_p[] = {
159 &application_invoke_action_in_args[0],
160 &application_invoke_action_in_args[1],
164 static const GDBusMethodInfo application_quit_method_info =
168 (GDBusArgInfo **) &application_quit_in_args_p,
173 static const GDBusMethodInfo application_list_actions_method_info =
178 (GDBusArgInfo **) &application_list_actions_out_args_p,
182 static const GDBusMethodInfo application_invoke_action_method_info =
186 (GDBusArgInfo **) &application_invoke_action_in_args_p,
191 static const GDBusArgInfo application_activate_in_args[] =
207 static const GDBusArgInfo * const application_activate_in_args_p[] = {
208 &application_activate_in_args[0],
209 &application_activate_in_args[1],
213 static const GDBusMethodInfo application_activate_method_info =
217 (GDBusArgInfo **) &application_activate_in_args_p,
222 static const GDBusMethodInfo * const application_dbus_method_info_p[] =
224 &application_quit_method_info,
225 &application_list_actions_method_info,
226 &application_invoke_action_method_info,
227 &application_activate_method_info,
231 static const GDBusSignalInfo application_dbus_signal_info[] =
241 static const GDBusSignalInfo * const application_dbus_signal_info_p[] = {
242 &application_dbus_signal_info[0],
246 static const GDBusInterfaceInfo application_dbus_interface_info =
250 (GDBusMethodInfo **) application_dbus_method_info_p,
251 (GDBusSignalInfo **) application_dbus_signal_info_p,
255 static GDBusInterfaceVTable application_dbus_vtable =
257 application_dbus_method_call,
263 application_path_from_appid (const gchar *appid)
265 gchar *appid_path, *iter;
268 appid_path = g_strconcat ("/", appid, NULL);
269 for (iter = appid_path; *iter; iter++)
279 _g_application_platform_init (GApplication *app,
280 GCancellable *cancellable,
283 if (app->priv->session_bus == NULL)
284 app->priv->session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, cancellable, error);
285 if (!app->priv->session_bus)
288 if (!app->priv->dbus_path)
289 app->priv->dbus_path = application_path_from_appid (app->priv->appid);
294 _g_application_platform_register (GApplication *app,
296 GCancellable *cancellable,
299 GVariant *request_result;
300 guint32 request_status;
302 guint registration_id;
304 registration_id = g_dbus_connection_register_object (app->priv->session_bus,
305 app->priv->dbus_path,
306 &application_dbus_interface_info,
307 &application_dbus_vtable,
311 if (registration_id == 0)
314 request_result = g_dbus_connection_call_sync (app->priv->session_bus,
315 "org.freedesktop.DBus",
316 "/org/freedesktop/DBus",
317 "org.freedesktop.DBus",
319 g_variant_new ("(su)", app->priv->appid, 0x4),
320 NULL, 0, -1, cancellable, error);
322 if (request_result == NULL)
328 if (g_variant_is_of_type (request_result, G_VARIANT_TYPE ("(u)")))
329 g_variant_get (request_result, "(u)", &request_status);
333 g_variant_unref (request_result);
335 *unique = (request_status == 1 || request_status == 4);
340 app->priv->is_remote = FALSE;
342 else if (app->priv->default_quit)
344 GVariantBuilder builder;
348 g_variant_builder_init (&builder, G_VARIANT_TYPE ("(aaya{sv})"));
349 g_variant_builder_add_value (&builder, app->priv->argv);
350 g_variant_builder_add_value (&builder, app->priv->platform_data);
351 message = g_variant_builder_end (&builder);
353 result = g_dbus_connection_call_sync (app->priv->session_bus,
355 app->priv->dbus_path,
359 NULL, 0, -1, NULL, NULL);
362 g_variant_unref (result);
369 g_dbus_connection_unregister_object (app->priv->session_bus, registration_id);
375 _g_application_platform_on_actions_changed (GApplication *app)
377 g_dbus_connection_emit_signal (app->priv->session_bus, NULL,
378 app->priv->dbus_path,
380 "ActionsChanged", NULL, NULL);
384 _g_application_platform_remote_invoke_action (GApplication *app,
386 GVariant *platform_data)
390 result = g_dbus_connection_call_sync (app->priv->session_bus,
392 app->priv->dbus_path,
395 g_variant_new ("(s@a{sv})",
398 NULL, 0, -1, NULL, NULL);
400 g_variant_unref (result);
404 _g_application_platform_remote_quit (GApplication *app,
405 GVariant *platform_data)
409 result = g_dbus_connection_call_sync (app->priv->session_bus,
411 app->priv->dbus_path,
414 g_variant_new ("(@a{sv})",
416 NULL, 0, -1, NULL, NULL);
418 g_variant_unref (result);