[Xfce4-commits] <xfce4-panel:master> Support remote event replies from the wrapper.

Nick Schermer noreply at xfce.org
Thu Mar 11 20:40:01 CET 2010


Updating branch refs/heads/master
         to d168066d3dc8ae112df6b33e8164394c8d6c0087 (commit)
       from 8a1c651625c0c069da8aef7486ce8f1eaef819d6 (commit)

commit d168066d3dc8ae112df6b33e8164394c8d6c0087
Author: Nick Schermer <nick at xfce.org>
Date:   Thu Mar 11 20:35:54 2010 +0100

    Support remote event replies from the wrapper.
    
    Because of the dbus signal we cannot return the reply
    of the remote event, so add a method and handle ids to
    reply to the panel.
    When an implementation of the panel plugin provider returns
    a handle, the dbus service waits for the reply before it
    continues.

 common/panel-dbus.h                        |   43 +++---
 libxfce4panel/Makefile.am                  |    2 +
 libxfce4panel/xfce-panel-plugin-provider.c |   17 ++-
 libxfce4panel/xfce-panel-plugin-provider.h |    6 +-
 libxfce4panel/xfce-panel-plugin.c          |    6 +-
 panel/Makefile.am                          |   12 ++-
 panel/panel-dbus-client.c                  |    3 +-
 panel/panel-dbus-service.c                 |  141 +++++++++++++++++++--
 panel/panel-marshal.list                   |    2 +
 panel/panel-plugin-external-46.c           |    6 +-
 panel/panel-plugin-external-infos.xml      |   35 ++++--
 panel/panel-plugin-external.c              |  191 ++++++++++++++++------------
 wrapper/main.c                             |  163 +++++++++++++++---------
 13 files changed, 431 insertions(+), 196 deletions(-)

diff --git a/common/panel-dbus.h b/common/panel-dbus.h
index e53b15c..611456c 100644
--- a/common/panel-dbus.h
+++ b/common/panel-dbus.h
@@ -27,34 +27,33 @@
 #define PANEL_DBUS_WRAPPER_INTERFACE PANEL_DBUS_INTERFACE ".Wrapper"
 
 /* internal signals send over dbus */
-#define SIGNAL_PREFIX                   '_'
-#define SIGNAL_PREFIX_S                 "_"
-#define SIGNAL_SET_SIZE                 SIGNAL_PREFIX_S "a"
-#define SIGNAL_SET_ORIENTATION          SIGNAL_PREFIX_S "b"
-#define SIGNAL_SET_SCREEN_POSITION      SIGNAL_PREFIX_S "c"
-#define SIGNAL_SET_LOCKED               SIGNAL_PREFIX_S "d"
-#define SIGNAL_SAVE                     SIGNAL_PREFIX_S "e"
-#define SIGNAL_SHOW_CONFIGURE           SIGNAL_PREFIX_S "f"
-#define SIGNAL_SHOW_ABOUT               SIGNAL_PREFIX_S "g"
-#define SIGNAL_REMOVED                  SIGNAL_PREFIX_S "h"
-#define SIGNAL_WRAPPER_SET_SENSITIVE    SIGNAL_PREFIX_S "i"
-#define SIGNAL_WRAPPER_BACKGROUND_ALPHA SIGNAL_PREFIX_S "j"
-#define SIGNAL_WRAPPER_QUIT             SIGNAL_PREFIX_S "k"
+#define SIGNAL_SET_SIZE                 "a"
+#define SIGNAL_SET_ORIENTATION          "b"
+#define SIGNAL_SET_SCREEN_POSITION      "c"
+#define SIGNAL_SET_LOCKED               "d"
+#define SIGNAL_SAVE                     "e"
+#define SIGNAL_SHOW_CONFIGURE           "f"
+#define SIGNAL_SHOW_ABOUT               "g"
+#define SIGNAL_REMOVED                  "h"
+#define SIGNAL_WRAPPER_SET_SENSITIVE    "i"
+#define SIGNAL_WRAPPER_BACKGROUND_ALPHA "j"
+#define SIGNAL_WRAPPER_QUIT             "k"
 
 /* special types for dbus communication */
-#define PANEL_TYPE_DBUS_SET_MESSAGE dbus_g_type_get_struct ("GValueArray", \
-                                                            G_TYPE_STRING, \
-                                                            G_TYPE_VALUE, \
-                                                            G_TYPE_UINT, \
-                                                            G_TYPE_INVALID)
-#define PANEL_TYPE_DBUS_SET_SIGNAL  dbus_g_type_get_collection ("GPtrArray", \
-                                                                PANEL_TYPE_DBUS_SET_MESSAGE)
+#define PANEL_TYPE_DBUS_SET_MESSAGE \
+  dbus_g_type_get_struct ("GValueArray", \
+                          G_TYPE_STRING, \
+                          G_TYPE_VALUE, \
+                          G_TYPE_INVALID)
+
+#define PANEL_TYPE_DBUS_SET_SIGNAL \
+  dbus_g_type_get_collection ("GPtrArray", \
+                              PANEL_TYPE_DBUS_SET_MESSAGE)
 
 enum
 {
   DBUS_SET_PROPERTY,
-  DBUS_SET_VALUE,
-  DBUS_SET_REPLY_ID
+  DBUS_SET_VALUE
 };
 
 #endif /* !__PANEL_DBUS_H__ */
diff --git a/libxfce4panel/Makefile.am b/libxfce4panel/Makefile.am
index 5deed3e..1a0fb7b 100644
--- a/libxfce4panel/Makefile.am
+++ b/libxfce4panel/Makefile.am
@@ -77,6 +77,7 @@ pkgconfig_DATA = libxfce4panel-$(LIBXFCE4PANEL_VERSION_API).pc
 # Build sources
 #
 if MAINTAINER_MODE
+
 libxfce4panel-marshal.h: libxfce4panel-marshal.list Makefile
 	$(AM_V_GEN) glib-genmarshal --prefix=_libxfce4panel_marshal --internal --header $< > $@
 
@@ -117,6 +118,7 @@ BUILT_SOURCES = \
 CLEANFILES = \
 	actual-abi \
 	expected-abi
+
 endif
 
 EXTRA_DIST = \
diff --git a/libxfce4panel/xfce-panel-plugin-provider.c b/libxfce4panel/xfce-panel-plugin-provider.c
index 073c474..4875762 100644
--- a/libxfce4panel/xfce-panel-plugin-provider.c
+++ b/libxfce4panel/xfce-panel-plugin-provider.c
@@ -211,13 +211,26 @@ xfce_panel_plugin_provider_removed (XfcePanelPluginProvider *provider)
 gboolean
 xfce_panel_plugin_provider_remote_event (XfcePanelPluginProvider *provider,
                                          const gchar             *name,
-                                         const GValue            *value)
+                                         const GValue            *value,
+                                         guint                   *handle)
 {
+  const GValue *real_value = value;
+
   panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), TRUE);
   panel_return_val_if_fail (name != NULL, TRUE);
   panel_return_val_if_fail (value == NULL || G_IS_VALUE (value), TRUE);
 
-  return (*XFCE_PANEL_PLUGIN_PROVIDER_GET_INTERFACE (provider)->remote_event) (provider, name, value);
+  if (XFCE_PANEL_PLUGIN_PROVIDER_GET_INTERFACE (provider)->remote_event != NULL)
+    {
+      if (real_value != NULL
+          && G_VALUE_HOLDS_UCHAR (real_value)
+          && g_value_get_uchar == '\0')
+        real_value = NULL;
+
+      return (*XFCE_PANEL_PLUGIN_PROVIDER_GET_INTERFACE (provider)->remote_event) (provider, name, real_value, handle);
+    }
+
+  return FALSE;
 }
 
 
diff --git a/libxfce4panel/xfce-panel-plugin-provider.h b/libxfce4panel/xfce-panel-plugin-provider.h
index 3f230ee..b43be8d 100644
--- a/libxfce4panel/xfce-panel-plugin-provider.h
+++ b/libxfce4panel/xfce-panel-plugin-provider.h
@@ -64,7 +64,8 @@ struct _XfcePanelPluginProviderInterface
   void         (*removed)             (XfcePanelPluginProvider       *provider);
   gboolean     (*remote_event)        (XfcePanelPluginProvider       *provider,
                                        const gchar                   *name,
-                                       const GValue                  *value);
+                                       const GValue                  *value,
+                                       guint                         *handle);
   void         (*set_locked)          (XfcePanelPluginProvider       *provider,
                                        gboolean                       locked);
 };
@@ -149,7 +150,8 @@ void                  xfce_panel_plugin_provider_removed             (XfcePanelP
 
 gboolean              xfce_panel_plugin_provider_remote_event        (XfcePanelPluginProvider       *provider,
                                                                       const gchar                   *name,
-                                                                      const GValue                  *value);
+                                                                      const GValue                  *value,
+                                                                      guint                         *handle);
 
 void                  xfce_panel_plugin_provider_set_locked          (XfcePanelPluginProvider       *provider,
                                                                       gboolean                       locked);
diff --git a/libxfce4panel/xfce-panel-plugin.c b/libxfce4panel/xfce-panel-plugin.c
index 2c64550..9c3a712 100644
--- a/libxfce4panel/xfce-panel-plugin.c
+++ b/libxfce4panel/xfce-panel-plugin.c
@@ -95,7 +95,8 @@ static void          xfce_panel_plugin_show_about             (XfcePanelPluginPr
 static void          xfce_panel_plugin_removed                (XfcePanelPluginProvider          *provider);
 static gboolean      xfce_panel_plugin_remote_event           (XfcePanelPluginProvider          *provider,
                                                                const gchar                      *name,
-                                                               const GValue                     *value);
+                                                               const GValue                     *value,
+                                                               guint                            *handle);
 static void          xfce_panel_plugin_set_locked             (XfcePanelPluginProvider          *provider,
                                                                gboolean                          locked);
 static void          xfce_panel_plugin_take_window_notify     (gpointer                          data,
@@ -1346,7 +1347,8 @@ xfce_panel_plugin_removed (XfcePanelPluginProvider *provider)
 static gboolean
 xfce_panel_plugin_remote_event (XfcePanelPluginProvider *provider,
                                 const gchar             *name,
-                                const GValue            *value)
+                                const GValue            *value,
+                                guint                   *handle)
 {
   gboolean stop_emission;
 
diff --git a/panel/Makefile.am b/panel/Makefile.am
index 28ee69f..5183c32 100644
--- a/panel/Makefile.am
+++ b/panel/Makefile.am
@@ -15,6 +15,8 @@ bin_PROGRAMS = \
 xfce4_panel_built_sources = \
 	panel-dbus-service-infos.h \
 	panel-dbus-client-infos.h \
+	panel-marshal.c \
+	panel-marshal.h \
 	panel-plugin-external-infos.h \
 	panel-preferences-dialog-ui.h
 
@@ -80,6 +82,13 @@ xfce4_panel_DEPENDENCIES = \
 
 if MAINTAINER_MODE
 
+panel-marshal.h: panel-marshal.list Makefile
+	$(AM_V_GEN) glib-genmarshal --prefix=_panel_marshal --internal --header $< > $@
+
+panel-marshal.c: panel-marshal.list Makefile
+	$(AM_V_GEN) echo "#include <panel/panel-marshal.h>" > $@ \
+	&& glib-genmarshal --prefix=_panel_marshal --body $< >> $@
+
 panel-dbus-service-infos.h: $(srcdir)/panel-dbus-service-infos.xml Makefile
 	$(AM_V_GEN) dbus-binding-tool --prefix=panel_dbus_service --mode=glib-server $< > $@
 
@@ -110,6 +119,7 @@ endif
 EXTRA_DIST = \
 	panel-dbus-service-infos.xml \
 	panel-plugin-external-infos.xml \
-	panel-preferences-dialog.glade
+	panel-preferences-dialog.glade \
+	panel-marshal.list
 
 # vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/panel/panel-dbus-client.c b/panel/panel-dbus-client.c
index 176119c..caff76c 100644
--- a/panel/panel-dbus-client.c
+++ b/panel/panel-dbus-client.c
@@ -220,8 +220,7 @@ panel_dbus_client_plugin_event (const gchar  *plugin_event,
 
   if (!(n_tokens == 2 || n_tokens == N_TOKENS)
       || exo_str_is_empty (tokens[PLUGIN_NAME])
-      || exo_str_is_empty (tokens[NAME])
-      || *tokens[NAME] == SIGNAL_PREFIX)
+      || exo_str_is_empty (tokens[NAME]))
     {
       g_set_error_literal (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
                            _("Invalid plugin event syntax specified. "
diff --git a/panel/panel-dbus-service.c b/panel/panel-dbus-service.c
index faf2c4b..d2ce717 100644
--- a/panel/panel-dbus-service.c
+++ b/panel/panel-dbus-service.c
@@ -54,6 +54,7 @@ static gboolean  panel_dbus_service_add_new_item               (PanelDBusService
                                                                 const gchar        *plugin_name,
                                                                 gchar             **arguments,
                                                                 GError            **error);
+static void      panel_dbus_service_plugin_event_free          (gpointer            data);
 static gboolean  panel_dbus_service_plugin_event               (PanelDBusService  *service,
                                                                 const gchar       *plugin_name,
                                                                 const gchar       *name,
@@ -81,8 +82,20 @@ struct _PanelDBusService
 
   /* the dbus connection */
   DBusGConnection *connection;
+
+  /* queue for remote-events */
+  GHashTable      *remote_events;
 };
 
+typedef struct
+{
+  guint   handle;
+  gchar  *name;
+  GValue  value;
+  GSList *plugins;
+}
+PluginEvent;
+
 
 
 /* shared boolean for restart or quit */
@@ -114,6 +127,9 @@ panel_dbus_service_init (PanelDBusService *service)
   GError         *error = NULL;
   DBusConnection *connection;
 
+  service->remote_events = g_hash_table_new_full (g_int_hash, g_int_equal, NULL,
+                                                  panel_dbus_service_plugin_event_free);
+
   service->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
   if (G_LIKELY (service->connection != NULL))
     {
@@ -141,6 +157,8 @@ panel_dbus_service_finalize (GObject *object)
   PanelDBusService *service = PANEL_DBUS_SERVICE (object);
   DBusConnection   *connection;
 
+  panel_return_if_fail (g_hash_table_size (service->remote_events) == 0);
+
   if (G_LIKELY (service->connection != NULL))
     {
       /* release the org.xfce.Panel name */
@@ -151,6 +169,8 @@ panel_dbus_service_finalize (GObject *object)
       dbus_g_connection_unref (service->connection);
     }
 
+  g_hash_table_destroy (service->remote_events);
+
   (*G_OBJECT_CLASS (panel_dbus_service_parent_class)->finalize) (object);
 }
 
@@ -242,6 +262,82 @@ panel_dbus_service_add_new_item (PanelDBusService  *service,
 
 
 
+static void
+panel_dbus_service_plugin_event_free (gpointer data)
+{
+  PluginEvent *event = data;
+
+  g_value_unset (&event->value);
+  g_free (event->name);
+  g_slist_free (event->plugins);
+  g_slice_free (PluginEvent, event);
+}
+
+
+
+static void
+panel_dbus_service_plugin_event_result (XfcePanelPluginProvider *prev_provider,
+                                        guint                    handle,
+                                        gboolean                 result,
+                                        PanelDBusService        *service)
+{
+  PluginEvent             *event;
+  GSList                  *li, *lnext;
+  XfcePanelPluginProvider *provider;
+  guint                    new_handle;
+  gboolean                 new_result;
+
+  g_signal_handlers_disconnect_by_func (G_OBJECT (prev_provider),
+      G_CALLBACK (panel_dbus_service_plugin_event_result), service);
+
+  event = g_hash_table_lookup (service->remote_events, &handle);
+  if (G_LIKELY (event != NULL))
+    {
+      panel_assert (event->handle == handle);
+      if (!result)
+        {
+          for (li = event->plugins, new_handle = 0; li != NULL; li = lnext, new_handle = 0)
+            {
+              lnext = li->next;
+              provider = li->data;
+              event->plugins = g_slist_delete_link (event->plugins, li);
+
+              /* maybe the plugin has been destroyed */
+              if (!XFCE_PANEL_PLUGIN_PROVIDER (provider))
+                continue;
+
+              new_result = xfce_panel_plugin_provider_remote_event (provider, event->name,
+                                                                    &event->value, &new_handle);
+
+              if (new_handle > 0 && lnext != NULL)
+                {
+                  /* steal the old value */
+                  g_hash_table_steal (service->remote_events, &handle);
+
+                  /* update handle and insert again */
+                  event->handle = new_handle;
+                  g_hash_table_insert (service->remote_events, &event->handle, event);
+                  g_signal_connect (G_OBJECT (provider), "remote-event-result",
+                      G_CALLBACK (panel_dbus_service_plugin_event_result), service);
+
+                  /* leave and wait for reply */
+                  return;
+                }
+              else if (new_result)
+                {
+                  /* we're done, remove from hash table below */
+                  break;
+                }
+            }
+        }
+
+      /* handle can be removed */
+      g_hash_table_remove (service->remote_events, &handle);
+    }
+}
+
+
+
 static gboolean
 panel_dbus_service_plugin_event (PanelDBusService  *service,
                                  const gchar       *plugin_name,
@@ -249,9 +345,11 @@ panel_dbus_service_plugin_event (PanelDBusService  *service,
                                  const GValue      *value,
                                  GError           **error)
 {
-  GSList             *plugins, *li;
+  GSList             *plugins, *li, *lnext;
   PanelModuleFactory *factory;
-  const GValue       *real_value = value;
+  PluginEvent        *event;
+  guint               handle;
+  gboolean            result;
 
   panel_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), FALSE);
   panel_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@@ -259,22 +357,41 @@ panel_dbus_service_plugin_event (PanelDBusService  *service,
   panel_return_val_if_fail (name != NULL, FALSE);
   panel_return_val_if_fail (G_IS_VALUE (value), FALSE);
 
-  /* if no type and value is send with the signal we send a char type
-   * with nul value */
-  if (G_VALUE_HOLDS_UCHAR (value)
-      && g_value_get_uchar (value) == '\0')
-    real_value = NULL;
-
   /* send the event to all matching plugins, break if one of the
-   * plugins return TRUE in this remote-event handler */
+   * plugins returns TRUE in this remote-event handler */
   factory = panel_module_factory_get ();
   plugins = panel_module_factory_get_plugins (factory, plugin_name);
-  for (li = plugins; li != NULL; li = li->next)
+
+  for (li = plugins, handle = 0; li != NULL; li = lnext, handle = 0)
     {
+      lnext = li->next;
+
       panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (li->data), FALSE);
-      if (xfce_panel_plugin_provider_remote_event (li->data, name, real_value))
-        break;
+      result = xfce_panel_plugin_provider_remote_event (li->data, name, value, &handle);
+
+      if (handle > 0 && lnext != NULL)
+        {
+          event = g_slice_new0 (PluginEvent);
+          event->handle = handle;
+          event->name = g_strdup (name);
+          event->plugins = g_slist_copy (lnext);
+          g_value_init (&event->value, G_VALUE_TYPE (value));
+          g_value_copy (value, &event->value);
+
+          g_hash_table_insert (service->remote_events, &event->handle, event);
+          g_signal_connect (G_OBJECT (li->data), "remote-event-result",
+              G_CALLBACK (panel_dbus_service_plugin_event_result), service);
+
+          /* we're going to wait until the plugin replied */
+          break;
+        }
+      else if (result)
+        {
+          /* plugin returned %TRUE, so abort the event notification */
+          break;
+        }
     }
+
   g_slist_free (plugins);
   g_object_unref (G_OBJECT (factory));
 
diff --git a/panel/panel-marshal.list b/panel/panel-marshal.list
new file mode 100644
index 0000000..a86d2b7
--- /dev/null
+++ b/panel/panel-marshal.list
@@ -0,0 +1,2 @@
+VOID:UINT,BOOLEAN
+VOID:STRING,BOXED,UINT
diff --git a/panel/panel-plugin-external-46.c b/panel/panel-plugin-external-46.c
index fca8ccf..d75627e 100644
--- a/panel/panel-plugin-external-46.c
+++ b/panel/panel-plugin-external-46.c
@@ -86,7 +86,8 @@ static void         panel_plugin_external_46_show_about            (XfcePanelPlu
 static void         panel_plugin_external_46_removed               (XfcePanelPluginProvider          *provider);
 static gboolean     panel_plugin_external_46_remote_event          (XfcePanelPluginProvider          *provider,
                                                                     const gchar                      *name,
-                                                                    const GValue                     *value);
+                                                                    const GValue                     *value,
+                                                                    guint                            *handler_id);
 static void         panel_plugin_external_46_set_locked            (XfcePanelPluginProvider          *provider,
                                                                     gboolean                          locked);
 static void         panel_plugin_external_46_set_sensitive         (PanelPluginExternal46            *external);
@@ -757,7 +758,8 @@ panel_plugin_external_46_removed (XfcePanelPluginProvider *provider)
 static gboolean
 panel_plugin_external_46_remote_event (XfcePanelPluginProvider *provider,
                                        const gchar             *name,
-                                       const GValue            *value)
+                                       const GValue            *value,
+                                       guint                   *handle)
 {
   panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (provider), TRUE);
   panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), TRUE);
diff --git a/panel/panel-plugin-external-infos.xml b/panel/panel-plugin-external-infos.xml
index 87c0680..454a02f 100644
--- a/panel/panel-plugin-external-infos.xml
+++ b/panel/panel-plugin-external-infos.xml
@@ -9,31 +9,42 @@
                 value="wrapper_dbus" />
 
     <!--
-      property : Name of the property to set on the wrapper. This is used
-                 for both panel values (no reply required) and plugin
-                 event (require a reply from the plugin).
-      value    : GValue with the value for the property.
-      reply_id : 0 if no reply is needed, if bigger then 0, the id to
-                 return together with the Reply method.
+      s : property : Name of the property to set on the wrapper. This is used
+                     for both panel values (no reply required) and plugin
+                     event (require a reply from the plugin).
+      v : value    : GValue with the value for the property.
     -->
     <signal name="Set">
-      <arg name="values" type="a(svu)" />
+      <arg name="values" type="a(sv)" />
     </signal>
 
     <!--
-      replay_id : The reply id given during the request.
-      value     : The return value for the reply.
+      name   : name of the event.
+      value  : GValue with the value of the name.
+      handle : unique id for the RemoteEventResult method.
     -->
-    <method name="Reply">
-      <arg name="reply_id" type="u" />
+    <signal name="RemoteEvent">
+      <arg name="name" type="s" />
       <arg name="value" type="v" />
-    </method>
+      <arg name="handle" type="u" />
+    </signal>
 
     <!--
       signal : A provider signal from XfcePanelPluginProviderSignal.
     -->
     <method name="ProviderSignal">
+      <annotation name="org.freedesktop.DBus.Method.NoReply" value="true" />
       <arg name="signal" type="u" />
     </method>
+
+    <!--
+      handle : the id send to the RemoteEvent signal.
+      result : result of the call.
+    -->
+    <method name="RemoteEventResult">
+      <annotation name="org.freedesktop.DBus.Method.NoReply" value="true" />
+      <arg name="handle" type="u" />
+      <arg name="result" type="b" />
+    </method>
   </interface>
 </node>
diff --git a/panel/panel-plugin-external.c b/panel/panel-plugin-external.c
index 14eec04..c6c214f 100644
--- a/panel/panel-plugin-external.c
+++ b/panel/panel-plugin-external.c
@@ -43,6 +43,7 @@
 #include <panel/panel-plugin-external.h>
 #include <panel/panel-window.h>
 #include <panel/panel-dialogs.h>
+#include <panel/panel-marshal.h>
 
 
 
@@ -50,63 +51,64 @@
 
 
 
-static void         panel_plugin_external_provider_init         (XfcePanelPluginProviderInterface  *iface);
-static GObject     *panel_plugin_external_constructor           (GType                              type,
-                                                                 guint                              n_construct_params,
-                                                                 GObjectConstructParam             *construct_params);
-static void         panel_plugin_external_finalize              (GObject                           *object);
-static void         panel_plugin_external_get_property          (GObject                           *object,
-                                                                 guint                              prop_id,
-                                                                 GValue                            *value,
-                                                                 GParamSpec                        *pspec);
-static void         panel_plugin_external_set_property          (GObject                           *object,
-                                                                 guint                              prop_id,
-                                                                 const GValue                      *value,
-                                                                 GParamSpec                        *pspec);
-static void         panel_plugin_external_realize               (GtkWidget                         *widget);
-static void         panel_plugin_external_unrealize             (GtkWidget                         *widget);
-static gboolean     panel_plugin_external_plug_removed          (GtkSocket                         *socket);
-static void         panel_plugin_external_plug_added            (GtkSocket                         *socket);
-static gboolean     panel_plugin_external_dbus_reply            (PanelPluginExternal               *external,
-                                                                 guint                              reply_id,
-                                                                 const GValue                      *value,
-                                                                 GError                           **error);
-static gboolean     panel_plugin_external_dbus_provider_signal  (PanelPluginExternal               *external,
-                                                                 XfcePanelPluginProviderSignal      provider_signal,
-                                                                 GError                           **error);
-static void         panel_plugin_external_dbus_set              (PanelPluginExternal               *external,
-                                                                 gboolean                           force);
-static void         panel_plugin_external_queue_add             (PanelPluginExternal               *external,
-                                                                 gboolean                           force,
-                                                                 const gchar                       *property,
-                                                                 const GValue                      *value);
-static void         panel_plugin_external_queue_add_noop        (PanelPluginExternal               *external,
-                                                                 gboolean                           force,
-                                                                 const gchar                       *property);
-static const gchar *panel_plugin_external_get_name              (XfcePanelPluginProvider           *provider);
-static gint         panel_plugin_external_get_unique_id         (XfcePanelPluginProvider           *provider);
-static void         panel_plugin_external_set_size              (XfcePanelPluginProvider           *provider,
-                                                                 gint                               size);
-static void         panel_plugin_external_set_orientation       (XfcePanelPluginProvider           *provider,
-                                                                 GtkOrientation                     orientation);
-static void         panel_plugin_external_set_screen_position   (XfcePanelPluginProvider           *provider,
-                                                                 XfceScreenPosition                 screen_position);
-static void         panel_plugin_external_save                  (XfcePanelPluginProvider           *provider);
-static gboolean     panel_plugin_external_get_show_configure    (XfcePanelPluginProvider           *provider);
-static void         panel_plugin_external_show_configure        (XfcePanelPluginProvider           *provider);
-static gboolean     panel_plugin_external_get_show_about        (XfcePanelPluginProvider           *provider);
-static void         panel_plugin_external_show_about            (XfcePanelPluginProvider           *provider);
-static void         panel_plugin_external_removed               (XfcePanelPluginProvider           *provider);
-static gboolean     panel_plugin_external_remote_event          (XfcePanelPluginProvider           *provider,
-                                                                 const gchar                       *name,
-                                                                 const GValue                      *value);
-static void         panel_plugin_external_set_locked            (XfcePanelPluginProvider           *provider,
-                                                                 gboolean                           locked);
-static void         panel_plugin_external_set_sensitive         (PanelPluginExternal               *external);
-static void         panel_plugin_external_child_watch           (GPid                               pid,
-                                                                 gint                               status,
-                                                                 gpointer                           user_data);
-static void         panel_plugin_external_child_watch_destroyed (gpointer                           user_data);
+static void         panel_plugin_external_provider_init            (XfcePanelPluginProviderInterface  *iface);
+static GObject     *panel_plugin_external_constructor              (GType                              type,
+                                                                    guint                              n_construct_params,
+                                                                    GObjectConstructParam             *construct_params);
+static void         panel_plugin_external_finalize                 (GObject                           *object);
+static void         panel_plugin_external_get_property             (GObject                           *object,
+                                                                    guint                              prop_id,
+                                                                    GValue                            *value,
+                                                                    GParamSpec                        *pspec);
+static void         panel_plugin_external_set_property             (GObject                           *object,
+                                                                    guint                              prop_id,
+                                                                    const GValue                      *value,
+                                                                    GParamSpec                        *pspec);
+static void         panel_plugin_external_realize                  (GtkWidget                         *widget);
+static void         panel_plugin_external_unrealize                (GtkWidget                         *widget);
+static gboolean     panel_plugin_external_plug_removed             (GtkSocket                         *socket);
+static void         panel_plugin_external_plug_added               (GtkSocket                         *socket);
+static gboolean     panel_plugin_external_dbus_provider_signal     (PanelPluginExternal               *external,
+                                                                    XfcePanelPluginProviderSignal      provider_signal,
+                                                                    GError                           **error);
+static gboolean     panel_plugin_external_dbus_remote_event_result (PanelPluginExternal               *external,
+                                                                    guint                              handle,
+                                                                    gboolean                           result,
+                                                                    GError                           **error);
+static void         panel_plugin_external_dbus_set                 (PanelPluginExternal               *external,
+                                                                    gboolean                           force);
+static void         panel_plugin_external_queue_add                (PanelPluginExternal               *external,
+                                                                    gboolean                           force,
+                                                                    const gchar                       *property,
+                                                                    const GValue                      *value);
+static void         panel_plugin_external_queue_add_noop           (PanelPluginExternal               *external,
+                                                                    gboolean                           force,
+                                                                    const gchar                       *property);
+static const gchar *panel_plugin_external_get_name                 (XfcePanelPluginProvider           *provider);
+static gint         panel_plugin_external_get_unique_id            (XfcePanelPluginProvider           *provider);
+static void         panel_plugin_external_set_size                 (XfcePanelPluginProvider           *provider,
+                                                                    gint                               size);
+static void         panel_plugin_external_set_orientation          (XfcePanelPluginProvider           *provider,
+                                                                    GtkOrientation                     orientation);
+static void         panel_plugin_external_set_screen_position      (XfcePanelPluginProvider           *provider,
+                                                                    XfceScreenPosition                 screen_position);
+static void         panel_plugin_external_save                     (XfcePanelPluginProvider           *provider);
+static gboolean     panel_plugin_external_get_show_configure       (XfcePanelPluginProvider           *provider);
+static void         panel_plugin_external_show_configure           (XfcePanelPluginProvider           *provider);
+static gboolean     panel_plugin_external_get_show_about           (XfcePanelPluginProvider           *provider);
+static void         panel_plugin_external_show_about               (XfcePanelPluginProvider           *provider);
+static void         panel_plugin_external_removed                  (XfcePanelPluginProvider           *provider);
+static gboolean     panel_plugin_external_remote_event             (XfcePanelPluginProvider           *provider,
+                                                                    const gchar                       *name,
+                                                                    const GValue                      *value,
+                                                                    guint                             *handler_id);
+static void         panel_plugin_external_set_locked               (XfcePanelPluginProvider           *provider,
+                                                                    gboolean                           locked);
+static void         panel_plugin_external_set_sensitive            (PanelPluginExternal               *external);
+static void         panel_plugin_external_child_watch              (GPid                               pid,
+                                                                    gint                               status,
+                                                                    gpointer                           user_data);
+static void         panel_plugin_external_child_watch_destroyed    (gpointer                           user_data);
 
 
 
@@ -159,6 +161,8 @@ enum
 enum
 {
   SET,
+  REMOTE_EVENT,
+  REMOTE_EVENT_RESULT,
   LAST_SIGNAL
 };
 
@@ -203,6 +207,24 @@ panel_plugin_external_class_init (PanelPluginExternalClass *klass)
                   G_TYPE_NONE, 1,
                   PANEL_TYPE_DBUS_SET_SIGNAL);
 
+  external_signals[REMOTE_EVENT] =
+    g_signal_new (g_intern_static_string ("remote-event"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  _panel_marshal_VOID__STRING_BOXED_UINT,
+                  G_TYPE_NONE, 3,
+                  G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_UINT);
+
+  external_signals[REMOTE_EVENT_RESULT] =
+    g_signal_new (g_intern_static_string ("remote-event-result"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  _panel_marshal_VOID__UINT_BOOLEAN,
+                  G_TYPE_NONE, 2,
+                  G_TYPE_UINT, G_TYPE_BOOLEAN);
+
   g_object_class_install_property (gobject_class,
                                    PROP_UNIQUE_ID,
                                    g_param_spec_int ("unique-id",
@@ -573,20 +595,6 @@ panel_plugin_external_plug_added (GtkSocket *socket)
 
 
 static gboolean
-panel_plugin_external_dbus_reply (PanelPluginExternal  *external,
-                                  guint                 reply_id,
-                                  const GValue         *value,
-                                  GError              **error)
-{
-  panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL (external), FALSE);
-  panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (external), FALSE);
-
-  return TRUE;
-}
-
-
-
-static gboolean
 panel_plugin_external_dbus_provider_signal (PanelPluginExternal            *external,
                                             XfcePanelPluginProviderSignal   provider_signal,
                                             GError                        **error)
@@ -616,6 +624,22 @@ panel_plugin_external_dbus_provider_signal (PanelPluginExternal            *exte
 
 
 
+static gboolean
+panel_plugin_external_dbus_remote_event_result (PanelPluginExternal  *external,
+                                                guint                 handle,
+                                                gboolean              result,
+                                                GError              **error)
+{
+  panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL (external), FALSE);
+
+  g_signal_emit (G_OBJECT (external), external_signals[REMOTE_EVENT_RESULT], 0,
+                 handle, result);
+
+  return TRUE;
+}
+
+
+
 static void
 panel_plugin_external_dbus_set (PanelPluginExternal *external,
                                 gboolean             force)
@@ -657,7 +681,6 @@ panel_plugin_external_queue_add (PanelPluginExternal *external,
   dbus_g_type_struct_set (&message,
                           DBUS_SET_PROPERTY, property,
                           DBUS_SET_VALUE, value,
-                          DBUS_SET_REPLY_ID, 0,
                           G_MAXUINT);
 
   g_ptr_array_add (external->queue, g_value_get_boxed (&message));
@@ -846,26 +869,34 @@ panel_plugin_external_removed (XfcePanelPluginProvider *provider)
 static gboolean
 panel_plugin_external_remote_event (XfcePanelPluginProvider *provider,
                                     const gchar             *name,
-                                    const GValue            *value)
+                                    const GValue            *value,
+                                    guint                   *handle)
 {
-  GValue        noop_value = { 0, };
+  static guint  handle_counter = 0;
+  GValue        dummy_value = { 0, };
   const GValue *real_value = value;
 
   panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL (provider), TRUE);
   panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), TRUE);
   panel_return_val_if_fail (value == NULL || G_IS_VALUE (value), FALSE);
 
-  /* TODO handle the return value */
+  if (G_UNLIKELY (handle_counter > G_MAXUINT - 2))
+    handle_counter = 0;
+  *handle = ++handle_counter;
 
   if (value == NULL)
     {
-      g_value_init (&noop_value, G_TYPE_UCHAR);
-      g_value_set_uchar (&noop_value, '\0');
-      real_value = &noop_value;
+      /* we send a dummy value over dbus */
+      g_value_init (&dummy_value, G_TYPE_UCHAR);
+      g_value_set_uchar (&dummy_value, '\0');
+      real_value = &dummy_value;
     }
 
-  panel_plugin_external_queue_add (PANEL_PLUGIN_EXTERNAL (provider),
-                                   FALSE, name, real_value);
+  g_signal_emit (G_OBJECT (provider), external_signals[REMOTE_EVENT], 0,
+                 name, real_value, *handle);
+
+  if (real_value != value)
+    g_value_unset (&dummy_value);
 
   return TRUE;
 }
diff --git a/wrapper/main.c b/wrapper/main.c
index 00124c3..69e83d5 100644
--- a/wrapper/main.c
+++ b/wrapper/main.c
@@ -60,13 +60,11 @@ wrapper_gproxy_set (DBusGProxy              *dbus_gproxy,
                     const GPtrArray         *array,
                     XfcePanelPluginProvider *provider)
 {
-  WrapperPlug  *plug;
-  guint         i;
-  GValue       *value;
-  gchar        *property;
-  guint         reply_id;
-  GValue        msg = { 0, };
-  const GValue *real_value;
+  WrapperPlug *plug;
+  guint        i;
+  GValue      *value;
+  gchar       *property;
+  GValue       msg = { 0, };
 
   panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
 
@@ -78,53 +76,39 @@ wrapper_gproxy_set (DBusGProxy              *dbus_gproxy,
       if (!dbus_g_type_struct_get (&msg,
                                    DBUS_SET_PROPERTY, &property,
                                    DBUS_SET_VALUE, &value,
-                                   DBUS_SET_REPLY_ID, &reply_id,
                                    G_MAXUINT))
         {
           panel_assert_not_reached ();
           continue;
         }
 
-      if (G_LIKELY (*property == SIGNAL_PREFIX))
+      if (strcmp (property, SIGNAL_SET_SIZE) == 0)
+        xfce_panel_plugin_provider_set_size (provider, g_value_get_int (value));
+      else if (strcmp (property, SIGNAL_SET_ORIENTATION) == 0)
+        xfce_panel_plugin_provider_set_orientation (provider, g_value_get_uint (value));
+      else if (strcmp (property, SIGNAL_SET_SCREEN_POSITION) == 0)
+        xfce_panel_plugin_provider_set_screen_position (provider, g_value_get_uint (value));
+      else if (strcmp (property, SIGNAL_SET_LOCKED) == 0)
+        xfce_panel_plugin_provider_set_locked (provider, g_value_get_boolean (value));
+      else if (strcmp (property, SIGNAL_WRAPPER_BACKGROUND_ALPHA) == 0)
         {
-          if (strcmp (property, SIGNAL_SET_SIZE) == 0)
-            xfce_panel_plugin_provider_set_size (provider, g_value_get_int (value));
-          else if (strcmp (property, SIGNAL_SET_ORIENTATION) == 0)
-            xfce_panel_plugin_provider_set_orientation (provider, g_value_get_uint (value));
-          else if (strcmp (property, SIGNAL_SET_SCREEN_POSITION) == 0)
-            xfce_panel_plugin_provider_set_screen_position (provider, g_value_get_uint (value));
-          else if (strcmp (property, SIGNAL_SET_LOCKED) == 0)
-            xfce_panel_plugin_provider_set_locked (provider, g_value_get_boolean (value));
-          else if (strcmp (property, SIGNAL_WRAPPER_BACKGROUND_ALPHA) == 0)
-            {
-              plug = g_object_get_qdata (G_OBJECT (provider), plug_quark);
-              wrapper_plug_set_background_alpha (plug, g_value_get_double (value));
-            }
-          else if (strcmp (property, SIGNAL_SAVE) == 0)
-            xfce_panel_plugin_provider_save (provider);
-          else if (strcmp (property, SIGNAL_SHOW_CONFIGURE) == 0)
-            xfce_panel_plugin_provider_show_configure (provider);
-          else if (strcmp (property, SIGNAL_SHOW_ABOUT) == 0)
-            xfce_panel_plugin_provider_show_about (provider);
-          else if (strcmp (property, SIGNAL_REMOVED) == 0)
-            xfce_panel_plugin_provider_removed (provider);
-          else if (strcmp (property, SIGNAL_WRAPPER_SET_SENSITIVE) == 0)
-            gtk_widget_set_sensitive (GTK_WIDGET (provider), g_value_get_boolean (value));
-          else if (strcmp (property, SIGNAL_WRAPPER_QUIT) == 0)
-            gtk_main_quit ();
-          else
-            panel_assert_not_reached ();
+          plug = g_object_get_qdata (G_OBJECT (provider), plug_quark);
+          wrapper_plug_set_background_alpha (plug, g_value_get_double (value));
         }
+      else if (strcmp (property, SIGNAL_SAVE) == 0)
+        xfce_panel_plugin_provider_save (provider);
+      else if (strcmp (property, SIGNAL_SHOW_CONFIGURE) == 0)
+        xfce_panel_plugin_provider_show_configure (provider);
+      else if (strcmp (property, SIGNAL_SHOW_ABOUT) == 0)
+        xfce_panel_plugin_provider_show_about (provider);
+      else if (strcmp (property, SIGNAL_REMOVED) == 0)
+        xfce_panel_plugin_provider_removed (provider);
+      else if (strcmp (property, SIGNAL_WRAPPER_SET_SENSITIVE) == 0)
+        gtk_widget_set_sensitive (GTK_WIDGET (provider), g_value_get_boolean (value));
+      else if (strcmp (property, SIGNAL_WRAPPER_QUIT) == 0)
+        gtk_main_quit ();
       else
-        {
-          if (G_VALUE_HOLDS_UCHAR (value)
-              && g_value_get_uchar (value) == '\0')
-            real_value = NULL;
-          else
-            real_value = value;
-
-          xfce_panel_plugin_provider_remote_event (provider, property, real_value);
-        }
+        panel_assert_not_reached ();
 
       g_free (property);
       g_value_unset (value);
@@ -135,16 +119,66 @@ wrapper_gproxy_set (DBusGProxy              *dbus_gproxy,
 
 
 static void
-wrapper_gproxy_provider_signal_callback (DBusGProxy *proxy,
-                                         GError     *error,
-                                         gpointer    user_data)
+wrapper_gproxy_remote_event (DBusGProxy              *dbus_gproxy,
+                             const gchar             *name,
+                             const GValue            *value,
+                             guint                    handle,
+                             XfcePanelPluginProvider *provider)
 {
-  if (G_UNLIKELY (error != NULL))
+  const GValue *real_value;
+  gboolean      result;
+
+  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
+
+  if (G_VALUE_HOLDS_UCHAR (value)
+     && g_value_get_uchar (value) == '\0')
+    real_value = NULL;
+  else
+    real_value = value;
+
+  result = xfce_panel_plugin_provider_remote_event (provider, name, real_value, NULL);
+
+  wrapper_dbus_remote_event_result (dbus_gproxy, handle, result, NULL);
+}
+
+
+
+static void
+wrapper_marshal_VOID__STRING_BOXED_UINT (GClosure     *closure,
+                                         GValue       *return_value G_GNUC_UNUSED,
+                                         guint         n_param_values,
+                                         const GValue *param_values,
+                                         gpointer      invocation_hint G_GNUC_UNUSED,
+                                         gpointer      marshal_data)
+{
+  typedef void (*GMarshalFunc_VOID__STRING_BOXED_UINT) (gpointer     data1,
+                                                        gpointer     arg_1,
+                                                        gpointer     arg_2,
+                                                        guint        arg_3,
+                                                        gpointer     data2);
+  register GMarshalFunc_VOID__STRING_BOXED_UINT callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+
+  g_return_if_fail (n_param_values == 4);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
     {
-      g_warning ("Failed to send provider signal %d: %s",
-                 GPOINTER_TO_UINT (user_data), error->message);
-      g_error_free (error);
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
     }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+  callback = (GMarshalFunc_VOID__STRING_BOXED_UINT) (marshal_data ? marshal_data : cc->callback);
+
+  callback (data1,
+            g_value_peek_pointer (param_values + 1),
+            g_value_peek_pointer (param_values + 2),
+            g_value_get_uint (param_values + 3),
+            data2);
 }
 
 
@@ -157,9 +191,7 @@ wrapper_gproxy_provider_signal (XfcePanelPluginProvider       *provider,
   panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
 
   /* send the provider signal to the panel */
-  wrapper_dbus_provider_signal_async (dbus_gproxy, provider_signal,
-                                      wrapper_gproxy_provider_signal_callback,
-                                      GUINT_TO_POINTER (provider_signal));
+  wrapper_dbus_provider_signal (dbus_gproxy, provider_signal, NULL);
 }
 
 
@@ -297,12 +329,21 @@ main (gint argc, gchar **argv)
       g_signal_connect (G_OBJECT (provider), "provider-signal",
           G_CALLBACK (wrapper_gproxy_provider_signal), dbus_gproxy);
 
-      /* connect dbus signal to set provider properties send from the panel */
-      dbus_g_proxy_add_signal (dbus_gproxy, "Set", PANEL_TYPE_DBUS_SET_SIGNAL, G_TYPE_INVALID);
+      /* connect to service signals */
+      dbus_g_proxy_add_signal (dbus_gproxy, "Set",
+          PANEL_TYPE_DBUS_SET_SIGNAL, G_TYPE_INVALID);
       dbus_g_proxy_connect_signal (dbus_gproxy, "Set",
           G_CALLBACK (wrapper_gproxy_set), g_object_ref (provider),
           (GClosureNotify) g_object_unref);
 
+      dbus_g_object_register_marshaller (wrapper_marshal_VOID__STRING_BOXED_UINT,
+          G_TYPE_NONE, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_UINT, G_TYPE_INVALID);
+      dbus_g_proxy_add_signal (dbus_gproxy, "RemoteEvent",
+          G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_UINT, G_TYPE_INVALID);
+      dbus_g_proxy_connect_signal (dbus_gproxy, "RemoteEvent",
+          G_CALLBACK (wrapper_gproxy_remote_event), g_object_ref (provider),
+          (GClosureNotify) g_object_unref);
+
       /* show the plugin */
       gtk_widget_show (GTK_WIDGET (provider));
 
@@ -311,8 +352,12 @@ main (gint argc, gchar **argv)
 
       /* disconnect signals */
       if (!gproxy_destroyed)
-        dbus_g_proxy_disconnect_signal (dbus_gproxy, "Set",
-            G_CALLBACK (wrapper_gproxy_set), provider);
+        {
+          dbus_g_proxy_disconnect_signal (dbus_gproxy, "Set",
+              G_CALLBACK (wrapper_gproxy_set), provider);
+          dbus_g_proxy_disconnect_signal (dbus_gproxy, "RemoteEvent",
+              G_CALLBACK (wrapper_gproxy_remote_event), provider);
+        }
 
       /* destroy the plug and provider */
       if (plug != NULL)



More information about the Xfce4-commits mailing list