1 /*
2 * Copyright (C) 2013 Nick Schermer <nick@xfce.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program 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
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <libxfce4ui/libxfce4ui.h>
24
25 #include <src/appfinder-gdbus.h>
26 #include <src/appfinder-private.h>
27
28
29
30 #define APPFINDER_DBUS_SERVICE "org.xfce.Appfinder"
31 #define APPFINDER_DBUS_INTERFACE APPFINDER_DBUS_SERVICE
32 #define APPFINDER_DBUS_PATH "/org/xfce/Appfinder"
33 #define APPFINDER_DBUS_METHOD_OPEN "OpenWindow"
34 #define APPFINDER_DBUS_METHOD_QUIT "Quit"
35
36
37
38 static const gchar appfinder_gdbus_introspection_xml[] =
39 "<node>"
40 "<interface name='" APPFINDER_DBUS_INTERFACE "'>"
41 "<method name='" APPFINDER_DBUS_METHOD_OPEN "'>"
42 "<arg type='b' name='expanded' direction='in'/>"
43 "<arg type='s' name='startup-id' direction='in'/>"
44 "</method>"
45 "<method name='" APPFINDER_DBUS_METHOD_QUIT "'/>"
46 "</interface>"
47 "</node>";
48
49
50
51 static void
appfinder_gdbus_method_call(GDBusConnection * connection,const gchar * sender,const gchar * object_path,const gchar * interface_name,const gchar * method_name,GVariant * parameters,GDBusMethodInvocation * invocation,gpointer user_data)52 appfinder_gdbus_method_call (GDBusConnection *connection,
53 const gchar *sender,
54 const gchar *object_path,
55 const gchar *interface_name,
56 const gchar *method_name,
57 GVariant *parameters,
58 GDBusMethodInvocation *invocation,
59 gpointer user_data)
60 {
61 gboolean expanded;
62 gchar *startup_id = NULL;
63
64 g_return_if_fail (!g_strcmp0 (object_path, APPFINDER_DBUS_PATH));
65 g_return_if_fail (!g_strcmp0 (interface_name, APPFINDER_DBUS_INTERFACE));
66
67 APPFINDER_DEBUG ("received dbus method %s", method_name);
68
69 if (g_strcmp0 (method_name, APPFINDER_DBUS_METHOD_OPEN) == 0)
70 {
71 /* get paramenters */
72 g_variant_get (parameters, "(bs)", &expanded, &startup_id);
73
74 appfinder_window_new (startup_id, expanded);
75
76 /* everything went fine */
77 g_dbus_method_invocation_return_value (invocation, NULL);
78
79 g_free (startup_id);
80 }
81 else if (g_strcmp0 (method_name, APPFINDER_DBUS_METHOD_QUIT) == 0)
82 {
83 /* close all windows and quit */
84 g_printerr ("%s: %s.\n", PACKAGE_NAME, _("Forced to quit"));
85
86 gtk_main_quit ();
87 }
88 else
89 {
90 g_dbus_method_invocation_return_error (invocation,
91 G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD,
92 "Unknown method for DBus service " APPFINDER_DBUS_SERVICE);
93 }
94 }
95
96
97
98 static const GDBusInterfaceVTable appfinder_gdbus_vtable =
99 {
100 appfinder_gdbus_method_call,
101 NULL, /* get property */
102 NULL /* set property */
103 };
104
105
106
107 static void
appfinder_gdbus_bus_acquired(GDBusConnection * connection,const gchar * name,gpointer user_data)108 appfinder_gdbus_bus_acquired (GDBusConnection *connection,
109 const gchar *name,
110 gpointer user_data)
111 {
112 guint register_id;
113 GDBusNodeInfo *info;
114 GError *error = NULL;
115
116 info = g_dbus_node_info_new_for_xml (appfinder_gdbus_introspection_xml, NULL);
117 g_assert (info != NULL);
118 g_assert (*info->interfaces != NULL);
119
120 register_id = g_dbus_connection_register_object (connection,
121 APPFINDER_DBUS_PATH,
122 *info->interfaces, /* first iface */
123 &appfinder_gdbus_vtable,
124 user_data,
125 NULL,
126 &error);
127
128 APPFINDER_DEBUG ("registered interface with id %d", register_id);
129
130 if (register_id == 0)
131 {
132 g_message ("Failed to register object: %s", error->message);
133 g_error_free (error);
134 }
135
136 g_dbus_node_info_unref (info);
137 }
138
139
140
141 gboolean
appfinder_gdbus_service(GError ** error)142 appfinder_gdbus_service (GError **error)
143 {
144 guint owner_id;
145
146 owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
147 APPFINDER_DBUS_SERVICE,
148 G_BUS_NAME_OWNER_FLAGS_NONE,
149 appfinder_gdbus_bus_acquired,
150 NULL,
151 NULL,
152 NULL,
153 NULL);
154
155 return (owner_id != 0);
156 }
157
158
159
160 gboolean
appfinder_gdbus_quit(GError ** error)161 appfinder_gdbus_quit (GError **error)
162 {
163 GVariant *reply;
164 GDBusConnection *connection;
165 GError *err = NULL;
166 gboolean result;
167
168 connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
169 if (G_UNLIKELY (connection == NULL))
170 return FALSE;
171
172 reply = g_dbus_connection_call_sync (connection,
173 APPFINDER_DBUS_SERVICE,
174 APPFINDER_DBUS_PATH,
175 APPFINDER_DBUS_INTERFACE,
176 APPFINDER_DBUS_METHOD_QUIT,
177 NULL,
178 NULL,
179 G_DBUS_CALL_FLAGS_NO_AUTO_START,
180 2000,
181 NULL,
182 &err);
183
184 g_object_unref (connection);
185
186 result = (reply != NULL);
187 if (G_LIKELY (result))
188 g_variant_unref (reply);
189 else
190 g_propagate_error (error, err);
191
192 return result;
193 }
194
195
196
197 gboolean
appfinder_gdbus_open_window(gboolean expanded,const gchar * startup_id,GError ** error)198 appfinder_gdbus_open_window (gboolean expanded,
199 const gchar *startup_id,
200 GError **error)
201 {
202 GVariant *reply;
203 GDBusConnection *connection;
204 GError *err = NULL;
205 gboolean result;
206
207 connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
208 if (G_UNLIKELY (connection == NULL))
209 return FALSE;
210
211 if (startup_id == NULL)
212 startup_id = "";
213
214 reply = g_dbus_connection_call_sync (connection,
215 APPFINDER_DBUS_SERVICE,
216 APPFINDER_DBUS_PATH,
217 APPFINDER_DBUS_INTERFACE,
218 APPFINDER_DBUS_METHOD_OPEN,
219 g_variant_new ("(bs)",
220 expanded,
221 startup_id),
222 NULL,
223 G_DBUS_CALL_FLAGS_NO_AUTO_START,
224 2000,
225 NULL,
226 &err);
227
228 g_object_unref (connection);
229
230 result = (reply != NULL);
231 if (G_LIKELY (result))
232 g_variant_unref (reply);
233 else
234 g_propagate_error (error, err);
235
236 return result;
237 }
238