2
* Copyright (C) 2008-2009 Nick Schermer <nick@xfce.org>
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.
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.
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.
27
#include <dbus/dbus.h>
28
#include <dbus/dbus-glib.h>
29
#include <dbus/dbus-glib-lowlevel.h>
30
#include <common/panel-private.h>
31
#include <common/panel-dbus.h>
32
#include <libxfce4util/libxfce4util.h>
33
#include <libxfce4ui/libxfce4ui.h>
34
#include <libxfce4panel/libxfce4panel.h>
36
#include <panel/panel-dbus-service.h>
37
#include <panel/panel-application.h>
38
#include <panel/panel-preferences-dialog.h>
39
#include <panel/panel-item-dialog.h>
40
#include <panel/panel-module-factory.h>
44
static void panel_dbus_service_finalize (GObject *object);
45
static gboolean panel_dbus_service_display_preferences_dialog (PanelDBusService *service,
48
static gboolean panel_dbus_service_display_items_dialog (PanelDBusService *service,
51
static gboolean panel_dbus_service_save (PanelDBusService *service,
53
static gboolean panel_dbus_service_add_new_item (PanelDBusService *service,
54
const gchar *plugin_name,
57
static void panel_dbus_service_plugin_event_free (gpointer data);
58
static gboolean panel_dbus_service_plugin_event (PanelDBusService *service,
59
const gchar *plugin_name,
63
static gboolean panel_dbus_service_terminate (PanelDBusService *service,
69
/* include the dbus glue generated by dbus-binding-tool */
70
#include <panel/panel-dbus-service-infos.h>
74
struct _PanelDBusServiceClass
76
GObjectClass __parent__;
79
struct _PanelDBusService
83
/* the dbus connection */
84
DBusGConnection *connection;
86
/* queue for remote-events */
87
GHashTable *remote_events;
89
/* whether the service is owner of the name */
104
/* shared boolean for restart or quit */
105
static gboolean dbus_exit_restart = FALSE;
109
G_DEFINE_TYPE (PanelDBusService, panel_dbus_service, G_TYPE_OBJECT)
114
panel_dbus_service_class_init (PanelDBusServiceClass *klass)
116
GObjectClass *gobject_class;
118
gobject_class = G_OBJECT_CLASS (klass);
119
gobject_class->finalize = panel_dbus_service_finalize;
121
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
122
&dbus_glib_panel_dbus_service_object_info);
128
panel_dbus_service_init (PanelDBusService *service)
130
GError *error = NULL;
131
DBusConnection *connection;
134
service->is_owner = FALSE;
135
service->remote_events = NULL;
137
service->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
138
if (G_LIKELY (service->connection != NULL))
140
/* TODO handle error */
141
connection = dbus_g_connection_get_connection (service->connection);
142
result = dbus_bus_request_name (connection, PANEL_DBUS_NAME, DBUS_NAME_FLAG_DO_NOT_QUEUE, NULL);
143
if (result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
145
/* yes we own the name */
146
service->is_owner = TRUE;
148
/* register this object */
149
dbus_g_connection_register_g_object (service->connection,
156
g_warning ("Failed to connect to the D-BUS session bus: %s", error->message);
157
g_error_free (error);
164
panel_dbus_service_finalize (GObject *object)
166
PanelDBusService *service = PANEL_DBUS_SERVICE (object);
167
DBusConnection *connection;
169
if (G_LIKELY (service->connection != NULL))
171
/* release the org.xfce.Panel name */
172
connection = dbus_g_connection_get_connection (service->connection);
173
dbus_bus_release_name (connection, PANEL_DBUS_NAME, NULL);
174
dbus_g_connection_flush (service->connection);
176
dbus_g_connection_unref (service->connection);
179
if (service->remote_events != NULL)
181
panel_return_if_fail (g_hash_table_size (service->remote_events) == 0);
182
g_hash_table_destroy (service->remote_events);
185
(*G_OBJECT_CLASS (panel_dbus_service_parent_class)->finalize) (object);
191
panel_dbus_service_display_preferences_dialog (PanelDBusService *service,
195
PanelApplication *application;
197
panel_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), FALSE);
198
panel_return_val_if_fail (error == NULL || *error == NULL, FALSE);
200
/* show the preferences dialog */
201
application = panel_application_get ();
202
panel_preferences_dialog_show (panel_application_get_nth_window (application, active));
203
g_object_unref (G_OBJECT (application));
211
panel_dbus_service_display_items_dialog (PanelDBusService *service,
215
PanelApplication *application;
217
panel_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), FALSE);
218
panel_return_val_if_fail (error == NULL || *error == NULL, FALSE);
220
/* show the items dialog */
221
application = panel_application_get ();
222
panel_item_dialog_show (panel_application_get_nth_window (application, active));
223
g_object_unref (G_OBJECT (application));
231
panel_dbus_service_save (PanelDBusService *service,
234
PanelApplication *application;
236
panel_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), FALSE);
237
panel_return_val_if_fail (error == NULL || *error == NULL, FALSE);
239
/* save the configuration */
240
application = panel_application_get ();
241
panel_application_save (application, TRUE);
242
g_object_unref (G_OBJECT (application));
250
panel_dbus_service_add_new_item (PanelDBusService *service,
251
const gchar *plugin_name,
255
PanelApplication *application;
257
panel_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), FALSE);
258
panel_return_val_if_fail (error == NULL || *error == NULL, FALSE);
259
panel_return_val_if_fail (plugin_name != NULL, FALSE);
261
application = panel_application_get ();
263
/* add new plugin (with or without arguments) */
264
if (arguments && *arguments != NULL)
265
panel_application_add_new_item (application, plugin_name, arguments);
267
panel_application_add_new_item (application, plugin_name, NULL);
269
g_object_unref (G_OBJECT (application));
277
panel_dbus_service_plugin_event_free (gpointer data)
279
PluginEvent *event = data;
281
g_value_unset (&event->value);
282
g_free (event->name);
283
g_slist_free (event->plugins);
284
g_slice_free (PluginEvent, event);
290
panel_dbus_service_plugin_event_result (XfcePanelPluginProvider *prev_provider,
293
PanelDBusService *service)
297
XfcePanelPluginProvider *provider;
301
g_signal_handlers_disconnect_by_func (G_OBJECT (prev_provider),
302
G_CALLBACK (panel_dbus_service_plugin_event_result), service);
304
event = g_hash_table_lookup (service->remote_events, &handle);
305
if (G_LIKELY (event != NULL))
307
panel_assert (event->handle == handle);
310
for (li = event->plugins, new_handle = 0; li != NULL; li = lnext, new_handle = 0)
314
event->plugins = g_slist_delete_link (event->plugins, li);
317
/* maybe the plugin has been destroyed */
318
if (!XFCE_PANEL_PLUGIN_PROVIDER (provider))
321
new_result = xfce_panel_plugin_provider_remote_event (provider, event->name,
322
&event->value, &new_handle);
324
if (new_handle > 0 && lnext != NULL)
326
/* steal the old value */
327
g_hash_table_steal (service->remote_events, &handle);
329
/* update handle and insert again */
330
event->handle = new_handle;
331
g_hash_table_insert (service->remote_events, &event->handle, event);
332
g_signal_connect (G_OBJECT (provider), "remote-event-result",
333
G_CALLBACK (panel_dbus_service_plugin_event_result), service);
335
/* leave and wait for reply */
340
/* we're done, remove from hash table below */
346
/* handle can be removed */
347
g_hash_table_remove (service->remote_events, &handle);
354
panel_dbus_service_plugin_event (PanelDBusService *service,
355
const gchar *plugin_name,
360
GSList *plugins, *li, *lnext;
361
PanelModuleFactory *factory;
366
panel_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), FALSE);
367
panel_return_val_if_fail (error == NULL || *error == NULL, FALSE);
368
panel_return_val_if_fail (plugin_name != NULL, FALSE);
369
panel_return_val_if_fail (name != NULL, FALSE);
370
panel_return_val_if_fail (G_IS_VALUE (value), FALSE);
372
/* send the event to all matching plugins, break if one of the
373
* plugins returns TRUE in this remote-event handler */
374
factory = panel_module_factory_get ();
375
plugins = panel_module_factory_get_plugins (factory, plugin_name);
377
for (li = plugins, handle = 0; li != NULL; li = lnext, handle = 0)
381
panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (li->data), FALSE);
382
result = xfce_panel_plugin_provider_remote_event (li->data, name, value, &handle);
384
if (handle > 0 && lnext != NULL)
386
event = g_slice_new0 (PluginEvent);
387
event->handle = handle;
388
event->name = g_strdup (name);
389
event->plugins = g_slist_copy (lnext);
390
g_value_init (&event->value, G_VALUE_TYPE (value));
391
g_value_copy (value, &event->value);
393
/* create hash table if needed */
394
if (service->remote_events == NULL)
395
service->remote_events = g_hash_table_new_full (g_int_hash, g_int_equal, NULL,
396
panel_dbus_service_plugin_event_free);
398
g_hash_table_insert (service->remote_events, &event->handle, event);
399
g_signal_connect (G_OBJECT (li->data), "remote-event-result",
400
G_CALLBACK (panel_dbus_service_plugin_event_result), service);
402
/* we're going to wait until the plugin replied */
407
/* plugin returned %TRUE, so abort the event notification */
412
g_slist_free (plugins);
413
g_object_unref (G_OBJECT (factory));
421
panel_dbus_service_terminate (PanelDBusService *service,
425
panel_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), FALSE);
426
panel_return_val_if_fail (error == NULL || *error == NULL, FALSE);
428
panel_dbus_service_exit_panel (restart);
436
panel_dbus_service_get (void)
438
static PanelDBusService *service = NULL;
440
if (G_LIKELY (service != NULL))
442
g_object_ref (G_OBJECT (service));
446
service = g_object_new (PANEL_TYPE_DBUS_SERVICE, NULL);
447
g_object_add_weak_pointer (G_OBJECT (service), (gpointer) &service);
456
panel_dbus_service_is_owner (PanelDBusService *service)
458
panel_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), FALSE);
459
return service->is_owner;
465
panel_dbus_service_exit_panel (gboolean restart)
467
XfceSMClient *sm_client;
469
sm_client = xfce_sm_client_get ();
470
xfce_sm_client_set_restart_style (sm_client, XFCE_SM_CLIENT_RESTART_NORMAL);
472
dbus_exit_restart = !!restart;
480
panel_dbus_service_get_restart (void)
482
return dbus_exit_restart;