[Xfce4-commits] <xfce4-panel:devel> Add support for the 'old' 4.6 external plugins.

Nick Schermer noreply at xfce.org
Sat Nov 21 21:50:02 CET 2009


Updating branch refs/heads/devel
         to 8ab28949ac1b23fd11ddbbb216e8561a6fa511c5 (commit)
       from b6bbfcae74170fa8a674b8558e509a18ae6bb898 (commit)

commit 8ab28949ac1b23fd11ddbbb216e8561a6fa511c5
Author: Nick Schermer <nick at xfce.org>
Date:   Sat Nov 21 21:47:38 2009 +0100

    Add support for the 'old' 4.6 external plugins.

 libxfce4panel/Makefile.am                  |    2 +-
 libxfce4panel/libxfce4panel-deprecated.h   |  326 +++++++++++-
 libxfce4panel/libxfce4panel-enums.h        |    4 +-
 libxfce4panel/xfce-arrow-button.h          |    4 +-
 libxfce4panel/xfce-hvbox.h                 |    4 +-
 libxfce4panel/xfce-panel-convenience.h     |    4 +-
 libxfce4panel/xfce-panel-macros.h          |   10 +-
 libxfce4panel/xfce-panel-plugin-provider.h |    8 +-
 libxfce4panel/xfce-panel-plugin.h          |    8 +-
 panel/Makefile.am                          |    2 +
 panel/panel-application.c                  |    7 +-
 panel/panel-base-window.c                  |    4 +
 panel/panel-module.c                       |  302 ++++++-----
 panel/panel-module.h                       |    5 +-
 panel/panel-plugin-external-46.c           |  833 ++++++++++++++++++++++++++++
 panel/panel-plugin-external-46.h           |   50 ++
 panel/panel-window.c                       |   14 +-
 17 files changed, 1411 insertions(+), 176 deletions(-)

diff --git a/libxfce4panel/Makefile.am b/libxfce4panel/Makefile.am
index ce87e13..68dc148 100644
--- a/libxfce4panel/Makefile.am
+++ b/libxfce4panel/Makefile.am
@@ -28,6 +28,7 @@ libxfce4panel_headers = \
 	xfce-panel-convenience.h \
 	xfce-panel-macros.h \
 	xfce-panel-plugin.h \
+	xfce-panel-plugin-provider.h \
 	xfce-panel-image.h
 
 libxfce4panel_includedir = \
@@ -45,7 +46,6 @@ libxfce4panel_1_0_la_SOURCES = \
 	xfce-panel-convenience.c \
 	xfce-panel-plugin.c \
 	xfce-panel-plugin-provider.c \
-	xfce-panel-plugin-provider.h \
 	xfce-panel-image.c
 
 libxfce4panel_1_0_la_CFLAGS =	 \
diff --git a/libxfce4panel/libxfce4panel-deprecated.h b/libxfce4panel/libxfce4panel-deprecated.h
index bf5422d..423e429 100644
--- a/libxfce4panel/libxfce4panel-deprecated.h
+++ b/libxfce4panel/libxfce4panel-deprecated.h
@@ -16,14 +16,36 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+/* #if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION)
+#error "Only <libxfce4panel/libxfce4panel.h> can be included directly, this file may disappear or change contents"
+#endif */
+
 #ifndef __LIBXFCE4PANEL_DEPRECATED_H__
 #define __LIBXFCE4PANEL_DEPRECATED_H__
 
-//#ifndef XFCE_DISABLE_DEPRECATED
-
+/* #ifndef XFCE_DISABLE_DEPRECATED */
+#include <libxfce4panel/xfce-panel-plugin-provider.h>
+/* #endif *//* !XFCE_DISABLE_DEPRECATED */
 
 G_BEGIN_DECLS
 
+enum /*< skip >*/
+{
+  PANEL_CLIENT_EVENT_REMOVE,
+  PANEL_CLIENT_EVENT_SAVE,
+  PANEL_CLIENT_EVENT_SET_BACKGROUND_ALPHA,
+  PANEL_CLIENT_EVENT_SET_ORIENTATION,
+  PANEL_CLIENT_EVENT_SET_SCREEN_POSITION,
+  PANEL_CLIENT_EVENT_SET_SENSITIVE,
+  PANEL_CLIENT_EVENT_SET_SIZE,
+  PANEL_CLIENT_EVENT_SHOW_ABOUT,
+  PANEL_CLIENT_EVENT_SHOW_CONFIGURE
+};
+
+#define PANEL_CLIENT_EVENT_ATOM "XFCE4_PANEL_PLUGIN_46"
+
+/* #ifndef XFCE_DISABLE_DEPRECATED */
+
 #define panel_slice_alloc(block_size)            (g_slice_alloc ((block_size)))
 #define panel_slice_alloc0(block_size)           (g_slice_alloc0 ((block_size)))
 #define panel_slice_free1(block_size, mem_block) G_STMT_START{ g_slice_free1 ((block_size), (mem_block)); }G_STMT_END
@@ -40,11 +62,307 @@ G_BEGIN_DECLS
 #define _panel_return_if_fail(expr)          g_return_if_fail (expr)
 #define _panel_return_val_if_fail(expr, val) g_return_val_if_fail (expr, (val))
 
+#define xfce_create_panel_button        xfce_panel_create_button
+#define xfce_create_panel_toggle_button xfce_panel_create_toggle_button
+#define xfce_allow_panel_customization  xfce_panel_allow_customization
+
 #define _panel_g_type_register_simple(type_parent,type_name_static,class_size,class_init,instance_size,instance_init) \
     g_type_register_static_simple(type_parent,type_name_static,class_size,class_init,instance_size,instance_init, 0)
 
-G_END_DECLS
+#define XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL(construct_func)  \
+    XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL_FULL (construct_func, NULL, NULL)
+
+#define XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL_WITH_CHECK(construct_func ,check_func) \
+    XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL_FULL (construct_func, NULL, check_func)
+
+#define XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL_FULL(construct_func, preinit_func, check_func) \
+  static GdkAtom  _xpp_atom = GDK_NONE; \
+  static gdouble  _xpp_alpha = 1.00; \
+  static gboolean _xpp_composited = FALSE; \
+  \
+  static gboolean \
+  _xpp_client_event (GtkWidget       *plug, \
+                     GdkEventClient  *event, \
+                     XfcePanelPlugin *xpp) \
+  { \
+    XfcePanelPluginProvider *provider = XFCE_PANEL_PLUGIN_PROVIDER (xpp); \
+    gint                     value; \
+    gint                     message; \
+    \
+    g_return_val_if_fail (XFCE_IS_PANEL_PLUGIN (xpp), TRUE); \
+    g_return_val_if_fail (GTK_IS_PLUG (plug), TRUE); \
+    g_return_val_if_fail (_xpp_atom != GDK_NONE, TRUE); \
+    g_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (xpp), TRUE); \
+    \
+    if (event->message_type == _xpp_atom) \
+      { \
+        message = event->data.s[0]; \
+        value = event->data.s[1]; \
+        \
+        switch (message) \
+          { \
+            case PANEL_CLIENT_EVENT_REMOVE: \
+              xfce_panel_plugin_provider_remove (provider); \
+              break; \
+              \
+            case PANEL_CLIENT_EVENT_SAVE: \
+              xfce_panel_plugin_provider_save (provider); \
+              break; \
+              \
+            case PANEL_CLIENT_EVENT_SET_BACKGROUND_ALPHA: \
+              _xpp_alpha = value / 100.00; \
+              if (_xpp_composited) \
+                gtk_widget_queue_draw (plug); \
+              break; \
+              \
+            case PANEL_CLIENT_EVENT_SET_ORIENTATION: \
+              xfce_panel_plugin_provider_set_orientation (provider, value); \
+              break; \
+              \
+            case PANEL_CLIENT_EVENT_SET_SCREEN_POSITION: \
+              xfce_panel_plugin_provider_set_screen_position (provider, value); \
+              break; \
+              \
+            case PANEL_CLIENT_EVENT_SET_SENSITIVE: \
+              gtk_widget_set_sensitive (plug, value); \
+              break; \
+              \
+            case PANEL_CLIENT_EVENT_SET_SIZE: \
+              xfce_panel_plugin_provider_set_size (provider, value); \
+              break; \
+              \
+            case PANEL_CLIENT_EVENT_SHOW_ABOUT: \
+              xfce_panel_plugin_provider_show_about (provider); \
+              break; \
+              \
+            case PANEL_CLIENT_EVENT_SHOW_CONFIGURE: \
+              xfce_panel_plugin_provider_show_configure (provider); \
+              break; \
+              \
+            default: \
+              g_warning ("Received unknow client event %d", message); \
+              break; \
+          } \
+        \
+        return FALSE; \
+      } \
+    \
+    return TRUE; \
+  } \
+  \
+  static void \
+  _xpp_provider_signal (GtkWidget *xpp, \
+                        guint      message, \
+                        GtkWidget *plug) \
+  { \
+    GdkEventClient event; \
+    \
+    g_return_if_fail (GTK_IS_PLUG (plug)); \
+    g_return_if_fail (XFCE_IS_PANEL_PLUGIN (xpp)); \
+    g_return_if_fail (GDK_IS_WINDOW (plug->window)); \
+    g_return_if_fail (_xpp_atom != GDK_NONE); \
+    \
+    event.type = GDK_CLIENT_EVENT; \
+    event.window = plug->window; \
+    event.send_event = TRUE; \
+    event.message_type = _xpp_atom; \
+    event.data_format = 16; \
+    event.data.s[0] = message; \
+    event.data.s[1] = 0; \
+    \
+    gdk_error_trap_push (); \
+    gdk_event_send_client_message ((GdkEvent *) &event,  \
+        GDK_WINDOW_XID (gtk_plug_get_socket_window (GTK_PLUG (plug)))); \
+    gdk_flush (); \
+    if (gdk_error_trap_pop () != 0) \
+      g_warning ("Failed to send provider-signal %d", message); \
+  } \
+  \
+  static void \
+  _xpp_realize (XfcePanelPlugin *xpp) \
+  { \
+    g_return_if_fail (XFCE_IS_PANEL_PLUGIN (xpp)); \
+    \
+    g_signal_handlers_disconnect_by_func (G_OBJECT (xpp), \
+        G_CALLBACK (_xpp_realize), NULL); \
+    \
+    ((XfcePanelPluginFunc) construct_func) (xpp); \
+  } \
+  \
+  static gboolean \
+  _xpp_expose_event (GtkWidget      *plug, \
+                     GdkEventExpose *event) \
+  { \
+    cairo_t  *cr; \
+    GdkColor *color; \
+    \
+    if (_xpp_composited \
+        && GTK_WIDGET_DRAWABLE (plug) \
+        && _xpp_alpha < 1.00) \
+      { \
+        cr = gdk_cairo_create (plug->window); \
+        cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); \
+        \
+        color = &(plug->style->bg[GTK_STATE_NORMAL]); \
+        cairo_set_source_rgba (cr, \
+                               color->red / 65535.00, \
+                               color->green / 65535.00, \
+                               color->blue / 65535.00, \
+                               _xpp_alpha); \
+        \
+        cairo_rectangle (cr, event->area.x, event->area.y, \
+                         event->area.width, event->area.height); \
+        \
+        cairo_fill (cr); \
+        cairo_destroy (cr); \
+      } \
+    \
+    return FALSE; \
+  } \
+  \
+  static void \
+  _xpp_plug_embedded (GtkPlug *plug) \
+  { \
+    g_return_if_fail (GTK_IS_PLUG (plug)); \
+    \
+    if (!gtk_plug_get_embedded (plug)) \
+      gtk_main_quit (); \
+  } \
+  \
+  static void \
+  _xpp_set_colormap (GtkWidget *plug) \
+  { \
+    GdkColormap *colormap = NULL; \
+    GdkScreen   *screen; \
+    gboolean     restore; \
+    \
+    g_return_if_fail (GTK_IS_WIDGET (plug)); \
+    \
+    restore = GTK_WIDGET_REALIZED (plug); \
+    if (restore) \
+      { \
+        gtk_widget_hide (plug); \
+        gtk_widget_unrealize (plug); \
+      } \
+    \
+    screen = gtk_widget_get_screen (plug); \
+    \
+    _xpp_composited = gtk_widget_is_composited (plug); \
+    \
+    if (_xpp_composited) \
+      colormap = gdk_screen_get_rgba_colormap (screen); \
+    \
+    if (colormap == NULL) \
+      { \
+        colormap = gdk_screen_get_rgb_colormap (screen); \
+        _xpp_composited = FALSE; \
+      } \
+    \
+    if (colormap != NULL) \
+      gtk_widget_set_colormap (plug, colormap); \
+    \
+    if (restore) \
+      { \
+        gtk_widget_realize (plug); \
+        gtk_widget_show (plug); \
+      } \
+    \
+    gtk_widget_queue_draw (plug); \
+  } \
+  \
+  gint \
+  main (gint argc, gchar **argv) \
+  { \
+    GtkWidget     *plug; \
+    GdkScreen     *screen; \
+    GtkWidget     *xpp; \
+    GError        *error = NULL; \
+    gchar         *opt_name = NULL; \
+    gchar         *opt_display_name = NULL; \
+    gint           opt_unique_id = -1; \
+    gchar         *opt_comment = NULL; \
+    gint           opt_socket_id = 0; \
+    gchar        **opt_arguments = NULL; \
+    GOptionEntry   option_entries[] = \
+    { \
+      { "name", 'n', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &opt_name, NULL, NULL }, \
+      { "display-name", 'd', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &opt_display_name, NULL, NULL }, \
+      { "comment", 'c', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &opt_comment, NULL, NULL }, \
+      { "unique-id", 'i', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_INT, &opt_unique_id, NULL, NULL }, \
+      { "socket-id", 's', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_INT, &opt_socket_id, NULL, NULL }, \
+      { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &opt_arguments, NULL, NULL }, \
+      { NULL } \
+    }; \
+    \
+    _xpp_atom = gdk_atom_intern_static_string (PANEL_CLIENT_EVENT_ATOM); \
+    \
+    if (preinit_func != NULL) \
+      { \
+        if (!((XfcePanelPluginPreInit) preinit_func) (argc, argv)) \
+          return 2; /* WRAPPER_EXIT_PREINIT */ \
+      } \
+    \
+    if (!gtk_init_with_args (&argc, &argv, "", option_entries, NULL, &error)) \
+      { \
+        g_critical ("Failed to initialize"); \
+        return 1 /* WRAPPER_EXIT_FAILURE */; \
+      } \
+    \
+    if (opt_unique_id == -1 || opt_name == NULL || opt_display_name == NULL \
+        || opt_comment == NULL || opt_socket_id == 0) \
+      { \
+        g_critical ("Missing argument(s)"); \
+        return 1 /* WRAPPER_EXIT_FAILURE */; \
+      } \
+    \
+    if (check_func != NULL) \
+      { \
+        screen = gdk_screen_get_default (); \
+        if (!((XfcePanelPluginCheck) check_func) (screen)) \
+          return 3; /* WRAPPER_EXIT_NO_PROVIDER */ \
+      } \
+    \
+    plug = gtk_plug_new (opt_socket_id); \
+    g_signal_connect (G_OBJECT (plug), "embedded", \
+        G_CALLBACK (_xpp_plug_embedded), NULL); \
+    g_signal_connect (G_OBJECT (plug), "expose-event", \
+        G_CALLBACK (_xpp_expose_event), NULL); \
+    g_signal_connect (G_OBJECT (plug), "composited-changed", \
+        G_CALLBACK (_xpp_set_colormap), NULL); \
+    \
+    gtk_widget_set_app_paintable (plug, TRUE); \
+    if (gtk_widget_is_composited (plug)) \
+      _xpp_set_colormap (plug); \
+    \
+    xpp = g_object_new (XFCE_TYPE_PANEL_PLUGIN, \
+                        "name", opt_name, \
+                        "unique-id", opt_unique_id, \
+                        "display-name", opt_display_name, \
+                        "comment", opt_comment,  \
+                        "arguments", opt_arguments, NULL); \
+    gtk_container_add (GTK_CONTAINER (plug), xpp); \
+    g_signal_connect_after (G_OBJECT (xpp), "realize", \
+        G_CALLBACK (_xpp_realize), NULL); \
+    g_signal_connect_after (G_OBJECT (xpp), "destroy", \
+        G_CALLBACK (gtk_main_quit), NULL); \
+    g_signal_connect (G_OBJECT (xpp), "provider-signal", \
+        G_CALLBACK (_xpp_provider_signal), plug); \
+    gtk_widget_show (xpp); \
+    \
+    g_signal_connect (G_OBJECT (plug), "client-event", \
+       G_CALLBACK (_xpp_client_event), xpp); \
+    gtk_widget_show (plug); \
+    \
+    gtk_main (); \
+    \
+    if (GTK_IS_WIDGET (plug)) \
+      gtk_widget_destroy (plug); \
+    \
+    return 0 /* WRAPPER_EXIT_SUCCESS */; \
+  }
 
-//#endif /* !XFCE_DISABLE_DEPRECATED */
+/* #endif *//* !XFCE_DISABLE_DEPRECATED */
+
+G_END_DECLS
 
 #endif /* !__LIBXFCE4PANEL_DEPRECATED_H__ */
diff --git a/libxfce4panel/libxfce4panel-enums.h b/libxfce4panel/libxfce4panel-enums.h
index 9fcaf07..dfbb811 100644
--- a/libxfce4panel/libxfce4panel-enums.h
+++ b/libxfce4panel/libxfce4panel-enums.h
@@ -17,9 +17,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION)&& !defined(XFCE_DISABLE_DEPRECATED)
+/* #if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION)
 #error "Only <libxfce4panel/libxfce4panel.h> can be included directly, this file may disappear or change contents"
-#endif
+#endif */
 
 #ifndef __LIBXFCE4PANEL_ENUMS_H__
 #define __LIBXFCE4PANEL_ENUMS_H__
diff --git a/libxfce4panel/xfce-arrow-button.h b/libxfce4panel/xfce-arrow-button.h
index 64beb48..0e9f3f1 100644
--- a/libxfce4panel/xfce-arrow-button.h
+++ b/libxfce4panel/xfce-arrow-button.h
@@ -17,9 +17,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION) && !defined(XFCE_DISABLE_DEPRECATED)
+/* #if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION)
 #error "Only <libxfce4panel/libxfce4panel.h> can be included directly, this file may disappear or change contents"
-#endif
+#endif */
 
 #ifndef __XFCE_ARROW_BUTTON_H__
 #define __XFCE_ARROW_BUTTON_H__
diff --git a/libxfce4panel/xfce-hvbox.h b/libxfce4panel/xfce-hvbox.h
index 986d1e6..7a08d8d 100644
--- a/libxfce4panel/xfce-hvbox.h
+++ b/libxfce4panel/xfce-hvbox.h
@@ -21,9 +21,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION) && !defined(XFCE_DISABLE_DEPRECATED)
+/* #if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION)
 #error "Only <libxfce4panel/libxfce4panel.h> can be included directly, this file may disappear or change contents"
-#endif
+#endif */
 
 #ifndef __XFCE_HVBOX_H__
 #define __XFCE_HVBOX_H__
diff --git a/libxfce4panel/xfce-panel-convenience.h b/libxfce4panel/xfce-panel-convenience.h
index f9eeda0..b5d7ecd 100644
--- a/libxfce4panel/xfce-panel-convenience.h
+++ b/libxfce4panel/xfce-panel-convenience.h
@@ -17,9 +17,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION) && !defined(XFCE_DISABLE_DEPRECATED)
+/* #if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION)
 #error "Only <libxfce4panel/libxfce4panel.h> can be included directly, this file may disappear or change contents"
-#endif
+#endif */
 
 #ifndef __XFCE_PANEL_CONVENIENCE_H__
 #define __XFCE_PANEL_CONVENIENCE_H__
diff --git a/libxfce4panel/xfce-panel-macros.h b/libxfce4panel/xfce-panel-macros.h
index deeb2b1..58f7d9c 100644
--- a/libxfce4panel/xfce-panel-macros.h
+++ b/libxfce4panel/xfce-panel-macros.h
@@ -16,9 +16,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION) && !defined(XFCE_DISABLE_DEPRECATED)
+/* #if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION)
 #error "Only <libxfce4panel/libxfce4panel.h> can be included directly, this file may disappear or change contents"
-#endif
+#endif */
 
 #ifndef __XFCE_PANEL_MACROS_H__
 #define __XFCE_PANEL_MACROS_H__
@@ -29,12 +29,6 @@
 
 G_BEGIN_DECLS
 
-typedef void (*XfcePanelPluginFunc) (XfcePanelPlugin *plugin);
-
-typedef gboolean (*XfcePanelPluginPreInit) (gint argc, gchar **argv);
-
-typedef gboolean (*XfcePanelPluginCheck) (GdkScreen *screen);
-
 typedef GTypeModule XfcePanelTypeModule;
 
 /* xfconf channel for plugins */
diff --git a/libxfce4panel/xfce-panel-plugin-provider.h b/libxfce4panel/xfce-panel-plugin-provider.h
index 4c2a048..2ac9c3c 100644
--- a/libxfce4panel/xfce-panel-plugin-provider.h
+++ b/libxfce4panel/xfce-panel-plugin-provider.h
@@ -26,7 +26,6 @@ G_BEGIN_DECLS
 
 typedef struct _XfcePanelPluginProviderIface  XfcePanelPluginProviderIface;
 typedef struct _XfcePanelPluginProvider       XfcePanelPluginProvider;
-typedef enum   _XfcePanelPluginProviderSignal XfcePanelPluginProviderSignal;
 
 #define XFCE_TYPE_PANEL_PLUGIN_PROVIDER           (xfce_panel_plugin_provider_get_type ())
 #define XFCE_PANEL_PLUGIN_PROVIDER(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_PANEL_PLUGIN_PROVIDER, XfcePanelPluginProvider))
@@ -48,7 +47,7 @@ struct _XfcePanelPluginProviderIface
   /*< private >*/
   GTypeInterface __parent__;
 
-  /*< public >*/
+  /*<public >*/
   const gchar *(*get_name)            (XfcePanelPluginProvider       *provider);
   gint         (*get_unique_id)       (XfcePanelPluginProvider       *provider);
   void         (*set_size)            (XfcePanelPluginProvider       *provider,
@@ -70,7 +69,7 @@ struct _XfcePanelPluginProviderIface
 
 /* signals send from the plugin to the panel (possibly
  * through the wrapper) */
-enum _XfcePanelPluginProviderSignal
+typedef enum /*< skip >*/
 {
   PROVIDER_SIGNAL_MOVE_PLUGIN = 0,
   PROVIDER_SIGNAL_EXPAND_PLUGIN,
@@ -88,7 +87,8 @@ enum _XfcePanelPluginProviderSignal
   PROVIDER_SIGNAL_SHOW_CONFIGURE,
   PROVIDER_SIGNAL_SHOW_ABOUT,
   PROVIDER_SIGNAL_FOCUS_PLUGIN
-};
+}
+XfcePanelPluginProviderSignal;
 
 
 
diff --git a/libxfce4panel/xfce-panel-plugin.h b/libxfce4panel/xfce-panel-plugin.h
index 4e430a4..27626cd 100644
--- a/libxfce4panel/xfce-panel-plugin.h
+++ b/libxfce4panel/xfce-panel-plugin.h
@@ -16,9 +16,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION) && !defined(XFCE_DISABLE_DEPRECATED)
+/* #if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION)
 #error "Only <libxfce4panel/libxfce4panel.h> can be included directly, this file may disappear or change contents"
-#endif
+#endif */
 
 #ifndef __XFCE_PANEL_PLUGIN_H__
 #define __XFCE_PANEL_PLUGIN_H__
@@ -33,6 +33,10 @@ typedef struct _XfcePanelPluginPrivate XfcePanelPluginPrivate;
 typedef struct _XfcePanelPluginClass   XfcePanelPluginClass;
 typedef struct _XfcePanelPlugin        XfcePanelPlugin;
 
+typedef void (*XfcePanelPluginFunc) (XfcePanelPlugin *plugin);
+typedef gboolean (*XfcePanelPluginPreInit) (gint argc, gchar **argv);
+typedef gboolean (*XfcePanelPluginCheck) (GdkScreen *screen);
+
 #define XFCE_TYPE_PANEL_PLUGIN            (xfce_panel_plugin_get_type ())
 #define XFCE_PANEL_PLUGIN(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_PANEL_PLUGIN, XfcePanelPlugin))
 #define XFCE_PANEL_PLUGIN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_PANEL_PLUGIN, XfcePanelPluginClass))
diff --git a/panel/Makefile.am b/panel/Makefile.am
index 1873c70..2c60281 100644
--- a/panel/Makefile.am
+++ b/panel/Makefile.am
@@ -43,6 +43,8 @@ xfce4_panel_SOURCES = \
 	panel-module-factory.h \
 	panel-plugin-external.c \
 	panel-plugin-external.h \
+	panel-plugin-external-46.c \
+	panel-plugin-external-46.h \
 	panel-preferences-dialog.c \
 	panel-preferences-dialog.h \
 	panel-window.c \
diff --git a/panel/panel-application.c b/panel/panel-application.c
index d3d4ebe..448e4a5 100644
--- a/panel/panel-application.c
+++ b/panel/panel-application.c
@@ -391,9 +391,10 @@ panel_application_plugin_move (GtkWidget        *item,
   /* set the drag context icon name */
   module = panel_module_get_from_plugin_provider (XFCE_PANEL_PLUGIN_PROVIDER (item));
   icon_name = panel_module_get_icon_name (module);
-  if (G_UNLIKELY (icon_name == NULL))
-    icon_name = GTK_STOCK_DND;
-  gtk_drag_set_icon_name (context, icon_name, 0, 0);
+  if (G_LIKELY (icon_name != NULL))
+    gtk_drag_set_icon_name (context, icon_name, 0, 0);
+  else
+    gtk_drag_set_icon_default (context);
 
   /* release the drag list */
   gtk_target_list_unref (target_list);
diff --git a/panel/panel-base-window.c b/panel/panel-base-window.c
index 9f4f990..f73937e 100644
--- a/panel/panel-base-window.c
+++ b/panel/panel-base-window.c
@@ -30,6 +30,7 @@
 #include <common/panel-private.h>
 #include <panel/panel-base-window.h>
 #include <panel/panel-plugin-external.h>
+#include <panel/panel-plugin-external-46.h>
 
 
 
@@ -547,6 +548,9 @@ panel_base_window_set_plugin_background_alpha (GtkWidget *widget,
   if (PANEL_IS_PLUGIN_EXTERNAL (widget))
     panel_plugin_external_set_background_alpha (PANEL_PLUGIN_EXTERNAL (widget),
         PANEL_BASE_WINDOW (user_data)->background_alpha);
+  else if (PANEL_IS_PLUGIN_EXTERNAL_46 (widget))
+    panel_plugin_external_46_set_background_alpha (PANEL_PLUGIN_EXTERNAL_46 (widget),
+        PANEL_BASE_WINDOW (user_data)->background_alpha);
 }
 
 
diff --git a/panel/panel-module.c b/panel/panel-module.c
index c1cfd06..fddaed0 100644
--- a/panel/panel-module.c
+++ b/panel/panel-module.c
@@ -32,6 +32,7 @@
 #include <panel/panel-module.h>
 #include <panel/panel-module-factory.h>
 #include <panel/panel-plugin-external.h>
+#include <panel/panel-plugin-external-46.h>
 
 #define PANEL_PLUGINS_LIB_DIR LIBDIR G_DIR_SEPARATOR_S "panel-plugins"
 
@@ -51,24 +52,23 @@ struct _PanelModuleClass
   GTypeModuleClass __parent__;
 };
 
-
+enum _PanelModuleRunMode
+{
+  UNKNOWN,    /* Unset */
+  INTERNAL,   /* plugin library will be loaded in the panel */
+  WRAPPER,    /* external library with comunication through PanelPluginExternal */
+  EXTERNAL_46 /* external executable with comunication through PanelPluginExternal46 */
+};
 
 struct _PanelModule
 {
   GTypeModule __parent__;
 
-  /* to plugin library */
-  GModule             *library;
-
-  PluginConstructFunc  construct_func;
-
-  /* plugin type */
-  GType                type;
-
-  /* whether to run the plugin in the wrapper */
-  guint                run_in_wrapper : 1;
+  /* module type */
+  PanelModuleRunMode   mode;
 
-  /* the library location */
+  /* filename to the library or executable
+   * for an old 4.6 executable */
   gchar               *filename;
 
   /* plugin information from the desktop file */
@@ -76,11 +76,14 @@ struct _PanelModule
   gchar               *comment;
   gchar               *icon_name;
 
-  /* whether this plugin is unique (only 1 running instance) */
+  /* unique handling */
+  guint                use_count;
   guint                is_unique : 1;
 
-  /* use count */
-  guint                use_count;
+  /* settings for an internal plugin */
+  GModule             *library;
+  PluginConstructFunc  construct_func; /* for non-gobject plugin */
+  GType                plugin_type; /* for gobject plugin */
 };
 
 
@@ -88,14 +91,14 @@ static GQuark module_quark = 0;
 
 
 
-G_DEFINE_TYPE (PanelModule, panel_module, G_TYPE_TYPE_MODULE);
+G_DEFINE_TYPE (PanelModule, panel_module, G_TYPE_TYPE_MODULE)
 
 
 
 static void
 panel_module_class_init (PanelModuleClass *klass)
 {
-  GObjectClass *gobject_class;
+  GObjectClass     *gobject_class;
   GTypeModuleClass *gtype_module_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
@@ -106,7 +109,6 @@ panel_module_class_init (PanelModuleClass *klass)
   gtype_module_class->load = panel_module_load;
   gtype_module_class->unload = panel_module_unload;
 
-  /* initialize the quark */
   module_quark = g_quark_from_static_string ("panel-module");
 }
 
@@ -115,17 +117,16 @@ panel_module_class_init (PanelModuleClass *klass)
 static void
 panel_module_init (PanelModule *module)
 {
-  /* initialize */
-  module->library = NULL;
-  module->construct_func = NULL;
-  module->type = G_TYPE_NONE;
+  module->mode = UNKNOWN;
   module->filename = NULL;
-  module->run_in_wrapper = TRUE;
   module->display_name = NULL;
   module->comment = NULL;
   module->icon_name = NULL;
-  module->is_unique = FALSE;
   module->use_count = 0;
+  module->is_unique = FALSE;
+  module->library = NULL;
+  module->construct_func = NULL;
+  module->plugin_type = G_TYPE_NONE;
 }
 
 
@@ -148,7 +149,6 @@ panel_module_finalize (GObject *object)
 {
   PanelModule *module = PANEL_MODULE (object);
 
-  /* cleanup */
   g_free (module->filename);
   g_free (module->display_name);
   g_free (module->comment);
@@ -169,7 +169,10 @@ panel_module_load (GTypeModule *type_module)
 
   panel_return_val_if_fail (PANEL_IS_MODULE (module), FALSE);
   panel_return_val_if_fail (G_IS_TYPE_MODULE (module), FALSE);
-  panel_return_val_if_fail (module->run_in_wrapper == FALSE, FALSE);
+  panel_return_val_if_fail (module->mode == INTERNAL, FALSE);
+  panel_return_val_if_fail (module->library == NULL, FALSE);
+  panel_return_val_if_fail (module->plugin_type == G_TYPE_NONE, FALSE);
+  panel_return_val_if_fail (module->construct_func == NULL, FALSE);
 
   /* open the module */
   module->library = g_module_open (module->filename, G_MODULE_BIND_LOCAL);
@@ -187,14 +190,14 @@ panel_module_load (GTypeModule *type_module)
       /* show warning */
       g_warning ("The plugin \"%s\" is marked as internal in the desktop file, "
                  "but the developer has defined an pre-init function, which is "
-                 "not supported for internal plugins. %s will force "
-                 "the plugin to run external.", module->filename, PACKAGE_NAME);
+                 "not supported for internal plugins. " PACKAGE_NAME " will force "
+                 "the plugin to run external.", module->filename);
 
       /* unload */
       panel_module_unload (type_module);
 
       /* from now on, run this plugin in a wrapper */
-      module->run_in_wrapper = TRUE;
+      module->mode = WRAPPER;
 
       return FALSE;
     }
@@ -203,7 +206,7 @@ panel_module_load (GTypeModule *type_module)
   if (g_module_symbol (module->library, "xfce_panel_module_init", (gpointer) &init_func))
     {
       /* initialize the plugin */
-      module->type = init_func (type_module, &make_resident);
+      module->plugin_type = init_func (type_module, &make_resident);
 
       /* whether to make this plugin resident or not */
       if (make_resident)
@@ -234,14 +237,17 @@ panel_module_unload (GTypeModule *type_module)
 
   panel_return_if_fail (PANEL_IS_MODULE (module));
   panel_return_if_fail (G_IS_TYPE_MODULE (module));
+  panel_return_if_fail (module->mode == INTERNAL);
+  panel_return_if_fail (module->library != NULL);
+  panel_return_if_fail (module->plugin_type != G_TYPE_NONE
+                        || module->construct_func != NULL);
 
-  /* close the module */
   g_module_close (module->library);
 
   /* reset plugin state */
   module->library = NULL;
   module->construct_func = NULL;
-  module->type = G_TYPE_NONE;
+  module->plugin_type = G_TYPE_NONE;
 }
 
 
@@ -260,7 +266,7 @@ panel_module_plugin_destroyed (gpointer  user_data,
   module->use_count--;
 
   /* unuse the library if the plugin runs internal */
-  if (module->run_in_wrapper == FALSE)
+  if (module->mode == INTERNAL)
     g_type_module_unuse (G_TYPE_MODULE (module));
 
   /* emit signal unique signal in the factory */
@@ -278,85 +284,96 @@ panel_module_new_from_desktop_file (const gchar *filename,
   PanelModule *module = NULL;
   XfceRc      *rc;
   const gchar *module_name;
-  const gchar *value;
   gchar       *path;
+  const gchar *module_exec;
 
   panel_return_val_if_fail (IS_STRING (filename), NULL);
+  panel_return_val_if_fail (IS_STRING (name), NULL);
 
-  /* open the desktop file */
   rc = xfce_rc_simple_open (filename, TRUE);
-  if (G_LIKELY (rc != NULL && xfce_rc_has_group (rc, "Xfce Panel")))
+  if (G_UNLIKELY (rc == NULL))
+    {
+      g_critical ("Plugin %s: Unable to read from desktop file \"%s\"", name, filename);
+      return NULL;
+    }
+
+  if (!xfce_rc_has_group (rc, "Xfce Panel"))
     {
-      /* set the xfce panel group */
-      xfce_rc_set_group (rc, "Xfce Panel");
+      g_critical ("Plugin %s: Desktop file \"%s\" has no \"Xfce Panel\" group", name, filename);
+      xfce_rc_close (rc);
+      return NULL;
+    }
 
-      /* read library location from the desktop file */
-      module_name = xfce_rc_read_entry (rc, "X-XFCE-Module", NULL);
+  xfce_rc_set_group (rc, "Xfce Panel");
 
-      if (G_LIKELY (module_name != NULL))
+  /* read module location from the desktop file */
+  module_name = xfce_rc_read_entry_untranslated (rc, "X-XFCE-Module", NULL);
+  if (G_LIKELY (module_name != NULL))
+    {
+#ifndef NDEBUG
+      if (xfce_rc_has_entry (rc, "X-XFCE-Module-Path"))
         {
-          /* build the module path */
-          path = g_module_build_path (PANEL_PLUGINS_LIB_DIR, module_name);
-
-          /* test if the library exists */
-          if (G_LIKELY (g_file_test (path, G_FILE_TEST_EXISTS)))
-            {
-              /* create new module */
-              module = g_object_new (PANEL_TYPE_MODULE, NULL);
-
-              /* set library location */
-              module->filename = path;
-            }
-          else
-            {
-              /* cleanup */
-              g_free (path);
-            }
+          /* show a messsage if the old module path key still exists */
+          g_message ("Plugin %s: The \"X-XFCE-Module-Path\" key is ignored in \"%s\", "
+                     "the panel will look for the module in " PANEL_PLUGINS_LIB_DIR
+                     ", see bug #5455 why this decision was made", name, filename);
         }
+#endif
 
-      /* read the remaining information */
-      if (G_LIKELY (module != NULL))
+      path = g_module_build_path (PANEL_PLUGINS_LIB_DIR, module_name);
+      if (G_LIKELY (g_file_test (path, G_FILE_TEST_EXISTS)))
         {
-          /* set the module name */
-          g_type_module_set_name (G_TYPE_MODULE (module), name);
-
-          /* read the plugin name */
-          value = xfce_rc_read_entry (rc, "Name", name);
-          module->display_name = g_strdup (value);
-
-          /* read the plugin comment */
-          value = xfce_rc_read_entry (rc, "Comment", NULL);
-          module->comment = g_strdup (value);
-
-          /* read the plugin icon */
-          value = xfce_rc_read_entry (rc, "Icon", NULL);
-          module->icon_name = g_strdup (value);
-
-          /* whether the plugin is unique */
-          module->is_unique = xfce_rc_read_bool_entry (rc, "X-XFCE-Unique", FALSE);
-
-          /* whether to force the plugin to run external */
-          if (G_UNLIKELY (force_external))
-            module->run_in_wrapper = TRUE;
+          /* create new module */
+          module = g_object_new (PANEL_TYPE_MODULE, NULL);
+          module->filename = path;
+
+          /* run mode of the module, by default everything runs in
+           * the wrapper, unless defined otherwise */
+          if (force_external || !xfce_rc_read_bool_entry (rc, "X-XFCE-Internal", FALSE))
+            module->mode = WRAPPER;
           else
-            module->run_in_wrapper = !xfce_rc_read_bool_entry (rc, "X-XFCE-Internal", FALSE);
+            module->mode = INTERNAL;
         }
-      else if (xfce_rc_has_entry (rc, "X-XFCE-Exec"))
+      else
         {
-          /* old external plugin, not usable anymore */
-          g_message ("The plugin from desktop file \"%s\" should "
-                     "be ported to an internal plugin", filename);
+          g_critical ("Plugin %s: There was no module found at \"%s\"",
+                      name, path);
+          g_free (path);
+        }
+    }
+  else
+    {
+      /* yeah, we support ancient shizzle too... */
+      module_exec = xfce_rc_read_entry_untranslated (rc, "X-XFCE-Exec", NULL);
+      if (module_exec != NULL
+          && g_path_is_absolute (module_exec)
+          && g_file_test (module_exec, G_FILE_TEST_EXISTS))
+        {
+          module = g_object_new (PANEL_TYPE_MODULE, NULL);
+          module->filename = g_strdup (module_exec);
+          module->mode = EXTERNAL_46;
         }
       else
         {
-          /* print warning */
-          g_warning ("Failed to create a plugin from desktop file \"%s\"", filename);
+          g_critical ("Plugin %s: There was no executable found at \"%s\"",
+                      name, module_exec);
         }
+    }
 
-      /* close rc file */
-      xfce_rc_close (rc);
+  /* read the remaining information */
+  if (G_LIKELY (module != NULL))
+    {
+      g_type_module_set_name (G_TYPE_MODULE (module), name);
+      panel_assert (module->mode != UNKNOWN);
+
+      module->display_name = g_strdup (xfce_rc_read_entry (rc, "Name", name));
+      module->comment = g_strdup (xfce_rc_read_entry (rc, "Comment", NULL));
+      module->icon_name = g_strdup (xfce_rc_read_entry_untranslated (rc, "Icon", NULL));
+      module->is_unique = xfce_rc_read_bool_entry (rc, "X-XFCE-Unique", FALSE);
     }
 
+  xfce_rc_close (rc);
+
   return module;
 }
 
@@ -368,58 +385,65 @@ panel_module_new_plugin (PanelModule  *module,
                          gint          unique_id,
                          gchar       **arguments)
 {
-  GtkWidget   *plugin = NULL;
-  const gchar *name;
+  GtkWidget *plugin = NULL;
 
   panel_return_val_if_fail (PANEL_IS_MODULE (module), NULL);
   panel_return_val_if_fail (G_IS_TYPE_MODULE (module), NULL);
   panel_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
   panel_return_val_if_fail (unique_id != -1, NULL);
+  panel_return_val_if_fail (module->mode != UNKNOWN, NULL);
 
   /* return null if the module is not usable (unique and already used) */
-  if (G_UNLIKELY (panel_module_is_usable (module) == FALSE))
+  if (G_UNLIKELY (!panel_module_is_usable (module)))
     return NULL;
 
-  /* get the internal plugin name */
-  name = panel_module_get_name (module);
-
-  if (module->run_in_wrapper)
-    {
-      /* create external plugin */
-      force_in_wrapper:
-      plugin = panel_plugin_external_new (module, unique_id, arguments);
-    }
-  else
+  switch (module->mode)
     {
-      /* increase the module use count */
-      if (g_type_module_use (G_TYPE_MODULE (module)))
-        {
-          if (module->type != G_TYPE_NONE)
-            {
-              plugin = g_object_new (module->type,
-                                     "name", name,
-                                     "unique-id", unique_id,
-                                     "display-name", module->display_name,
-                                     "comment", module->comment,
-                                     "arguments", arguments,
-                                     NULL);
-            }
-          else if (module->construct_func != NULL)
-            {
-              /* create a new panel plugin */
-              plugin = (*module->construct_func) (name,
-                                                  unique_id,
-                                                  module->display_name,
-                                                  module->comment,
-                                                  arguments,
-                                                  screen);
-            }
-        }
-      else if (module->run_in_wrapper)
-        {
-          /* pre-init function found during plugin use */
-          goto force_in_wrapper;
-        }
+      case INTERNAL:
+        if (g_type_module_use (G_TYPE_MODULE (module)))
+          {
+            if (module->plugin_type != G_TYPE_NONE)
+              {
+                /* plugin is build as an object, to use its gtype */
+                plugin = g_object_new (module->plugin_type,
+                                       "name", panel_module_get_name (module),
+                                       "unique-id", unique_id,
+                                       "display-name", module->display_name,
+                                       "comment", module->comment,
+                                       "arguments", arguments,
+                                       NULL);
+              }
+            else if (module->construct_func != NULL)
+              {
+                /* create plugin using the 'old style' construct function */
+                plugin = (*module->construct_func) (panel_module_get_name (module),
+                                                    unique_id,
+                                                    module->display_name,
+                                                    module->comment,
+                                                    arguments,
+                                                    screen);
+              }
+
+            if (G_LIKELY (plugin != NULL))
+              break;
+            else
+              g_type_module_unuse (G_TYPE_MODULE (module));
+          }
+
+        /* fall-through (make wrapper plugin), probably a plugin with
+         * preinit_func which is not supported for internal plugins */
+
+      case WRAPPER:
+        plugin = panel_plugin_external_new (module, unique_id, arguments);
+        break;
+
+      case EXTERNAL_46:
+        plugin = panel_plugin_external_46_new (module, unique_id, arguments);
+        break;
+
+      default:
+        panel_assert_not_reached ();
+        break;
     }
 
   if (G_LIKELY (plugin != NULL))
@@ -438,11 +462,6 @@ panel_module_new_plugin (PanelModule  *module,
       /* add link to the module */
       g_object_set_qdata (G_OBJECT (plugin), module_quark, module);
     }
-  else if (module->run_in_wrapper == FALSE)
-    {
-      /* decrease the use count since loading failed somehow */
-      g_type_module_unuse (G_TYPE_MODULE (module));
-    }
 
   return plugin;
 }
@@ -476,7 +495,8 @@ panel_module_get_display_name (PanelModule *module)
 {
   panel_return_val_if_fail (PANEL_IS_MODULE (module), NULL);
   panel_return_val_if_fail (G_IS_TYPE_MODULE (module), NULL);
-  panel_return_val_if_fail (g_utf8_validate (module->display_name, -1, NULL), NULL);
+  panel_return_val_if_fail (module->display_name == NULL
+                            || g_utf8_validate (module->display_name, -1, NULL), NULL);
 
   return module->display_name;
 }
@@ -487,7 +507,8 @@ const gchar *
 panel_module_get_comment (PanelModule *module)
 {
   panel_return_val_if_fail (PANEL_IS_MODULE (module), NULL);
-  panel_return_val_if_fail (g_utf8_validate (module->comment, -1, NULL), NULL);
+  panel_return_val_if_fail (module->comment == NULL
+                            || g_utf8_validate (module->comment, -1, NULL), NULL);
 
   return module->comment;
 }
@@ -498,7 +519,8 @@ const gchar *
 panel_module_get_icon_name (PanelModule *module)
 {
   panel_return_val_if_fail (PANEL_IS_MODULE (module), NULL);
-  panel_return_val_if_fail (g_utf8_validate (module->icon_name, -1, NULL), NULL);
+  panel_return_val_if_fail (module->icon_name == NULL
+                            || g_utf8_validate (module->icon_name, -1, NULL), NULL);
 
   return module->icon_name;
 }
diff --git a/panel/panel-module.h b/panel/panel-module.h
index 2efd5d5..ee1459a 100644
--- a/panel/panel-module.h
+++ b/panel/panel-module.h
@@ -25,8 +25,9 @@
 
 G_BEGIN_DECLS
 
-typedef struct _PanelModuleClass PanelModuleClass;
-typedef struct _PanelModule      PanelModule;
+typedef struct _PanelModuleClass  PanelModuleClass;
+typedef struct _PanelModule       PanelModule;
+typedef enum   _PanelModuleRunMode PanelModuleRunMode;
 
 #define PANEL_TYPE_MODULE            (panel_module_get_type ())
 #define PANEL_MODULE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_MODULE, PanelModule))
diff --git a/panel/panel-plugin-external-46.c b/panel/panel-plugin-external-46.c
new file mode 100644
index 0000000..308d98c
--- /dev/null
+++ b/panel/panel-plugin-external-46.c
@@ -0,0 +1,833 @@
+/*
+ * Copyright (C) 2009 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+
+#include <exo/exo.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <libxfce4util/libxfce4util.h>
+
+#include <common/panel-private.h>
+
+#include <libxfce4panel/libxfce4panel.h>
+#include <libxfce4panel/xfce-panel-plugin-provider.h>
+
+#include <panel/panel-marshal.h>
+#include <panel/panel-module.h>
+#include <panel/panel-plugin-external-46.h>
+#include <panel/panel-window.h>
+
+/* Number of automatic plugin restarts before the
+ * panel asks the users what to do. This code is
+ * disabled when debugging is enabled. */
+#ifndef NDEBUG
+#define N_RESTART_TRIES (0)
+#else
+#define N_RESTART_TRIES (2)
+#endif
+
+
+
+static void         panel_plugin_external_46_provider_init         (XfcePanelPluginProviderIface *iface);
+static void         panel_plugin_external_46_finalize              (GObject                      *object);
+static void         panel_plugin_external_46_get_property          (GObject                      *object,
+                                                                    guint                         prop_id,
+                                                                    GValue                       *value,
+                                                                    GParamSpec                   *pspec);
+static void         panel_plugin_external_46_set_property          (GObject                      *object,
+                                                                    guint                         prop_id,
+                                                                    const GValue                 *value,
+                                                                    GParamSpec                   *pspec);
+static void         panel_plugin_external_46_realize               (GtkWidget                    *widget);
+static gboolean     panel_plugin_external_46_client_event          (GtkWidget                    *widget,
+                                                                    GdkEventClient               *event);
+static gboolean     panel_plugin_external_46_plug_removed          (GtkSocket                    *socket);
+static void         panel_plugin_external_46_plug_added            (GtkSocket                    *socket);
+static void         panel_plugin_external_46_send_client_event     (PanelPluginExternal46        *external,
+                                                                    gint                          message,
+                                                                    gint                          value);
+static void         panel_plugin_external_46_queue_add             (PanelPluginExternal46        *external,
+                                                                    gint                          message,
+                                                                    gint                          value);
+static const gchar *panel_plugin_external_46_get_name              (XfcePanelPluginProvider      *provider);
+static gint         panel_plugin_external_46_get_unique_id         (XfcePanelPluginProvider      *provider);
+static void         panel_plugin_external_46_set_size              (XfcePanelPluginProvider      *provider,
+                                                                    gint                          size);
+static void         panel_plugin_external_46_set_orientation       (XfcePanelPluginProvider      *provider,
+                                                                    GtkOrientation                orientation);
+static void         panel_plugin_external_46_set_screen_position   (XfcePanelPluginProvider      *provider,
+                                                                    XfceScreenPosition            screen_position);
+static void         panel_plugin_external_46_save                  (XfcePanelPluginProvider      *provider);
+static gboolean     panel_plugin_external_46_get_show_configure    (XfcePanelPluginProvider      *provider);
+static void         panel_plugin_external_46_show_configure        (XfcePanelPluginProvider      *provider);
+static gboolean     panel_plugin_external_46_get_show_about        (XfcePanelPluginProvider      *provider);
+static void         panel_plugin_external_46_show_about            (XfcePanelPluginProvider      *provider);
+static void         panel_plugin_external_46_remove                (XfcePanelPluginProvider      *provider);
+static gboolean     panel_plugin_external_46_remote_event          (XfcePanelPluginProvider      *provider,
+                                                                    const gchar                  *name,
+                                                                    const GValue                 *value);
+static void         panel_plugin_external_46_set_sensitive         (PanelPluginExternal46        *external);
+static void         panel_plugin_external_46_child_watch           (GPid                          pid,
+                                                                    gint                          status,
+                                                                    gpointer                      user_data);
+static void         panel_plugin_external_46_child_watch_destroyed (gpointer                      user_data);
+
+
+
+struct _PanelPluginExternal46Class
+{
+  GtkSocketClass __parent__;
+};
+
+struct _PanelPluginExternal46
+{
+  GtkSocket  __parent__;
+
+  /* plugin information */
+  gint              unique_id;
+
+  /* the module */
+  PanelModule      *module;
+
+  /* whether the plug is embedded */
+  guint             plug_embedded : 1;
+
+  /* dbus message queue */
+  GSList           *queue;
+
+  /* counter to count the number of restarts */
+  guint             n_restarts;
+
+  /* some info we store here */
+  guint             show_configure : 1;
+  guint             show_about : 1;
+
+  /* child watch data */
+  GPid              pid;
+  guint             watch_id;
+};
+
+enum
+{
+  PROP_0,
+  PROP_MODULE,
+  PROP_UNIQUE_ID
+};
+
+typedef struct
+{
+  gint message;
+  gint value;
+}
+QueueItem;
+
+
+
+static GdkAtom panel_atom = GDK_NONE;
+
+
+
+G_DEFINE_TYPE_WITH_CODE (PanelPluginExternal46, panel_plugin_external_46, GTK_TYPE_SOCKET,
+  G_IMPLEMENT_INTERFACE (XFCE_TYPE_PANEL_PLUGIN_PROVIDER, panel_plugin_external_46_provider_init))
+
+
+
+static void
+panel_plugin_external_46_class_init (PanelPluginExternal46Class *klass)
+{
+  GObjectClass   *gobject_class;
+  GtkWidgetClass *gtkwidget_class;
+  GtkSocketClass *gtksocket_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = panel_plugin_external_46_finalize;
+  gobject_class->set_property = panel_plugin_external_46_set_property;
+  gobject_class->get_property = panel_plugin_external_46_get_property;
+
+  gtkwidget_class = GTK_WIDGET_CLASS (klass);
+  gtkwidget_class->realize = panel_plugin_external_46_realize;
+  gtkwidget_class->client_event = panel_plugin_external_46_client_event;
+
+  gtksocket_class = GTK_SOCKET_CLASS (klass);
+  gtksocket_class->plug_removed = panel_plugin_external_46_plug_removed;
+  gtksocket_class->plug_added = panel_plugin_external_46_plug_added;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_UNIQUE_ID,
+                                   g_param_spec_int ("unique-id", NULL, NULL,
+                                                     -1, G_MAXINT, -1,
+                                                     G_PARAM_READWRITE
+                                                     | G_PARAM_STATIC_STRINGS
+                                                     | G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_MODULE,
+                                   g_param_spec_object ("module", NULL, NULL,
+                                                        PANEL_TYPE_MODULE,
+                                                        G_PARAM_READWRITE
+                                                        | G_PARAM_STATIC_STRINGS
+                                                        | G_PARAM_CONSTRUCT_ONLY));
+
+  panel_atom = gdk_atom_intern_static_string (PANEL_CLIENT_EVENT_ATOM);
+}
+
+
+
+static void
+panel_plugin_external_46_init (PanelPluginExternal46 *external)
+{
+  /* initialize */
+  external->unique_id = -1;
+  external->module = NULL;
+  external->queue = NULL;
+  external->plug_embedded = FALSE;
+  external->n_restarts = 0;
+  external->show_configure = FALSE;
+  external->show_about = FALSE;
+
+  /* signal to pass gtk_widget_set_sensitive() changes to the remote window */
+  g_signal_connect (G_OBJECT (external), "notify::sensitive",
+      G_CALLBACK (panel_plugin_external_46_set_sensitive), NULL);
+}
+
+
+
+static void
+panel_plugin_external_46_provider_init (XfcePanelPluginProviderIface *iface)
+{
+  iface->get_name = panel_plugin_external_46_get_name;
+  iface->get_unique_id = panel_plugin_external_46_get_unique_id;
+  iface->set_size = panel_plugin_external_46_set_size;
+  iface->set_orientation = panel_plugin_external_46_set_orientation;
+  iface->set_screen_position = panel_plugin_external_46_set_screen_position;
+  iface->save = panel_plugin_external_46_save;
+  iface->get_show_configure = panel_plugin_external_46_get_show_configure;
+  iface->show_configure = panel_plugin_external_46_show_configure;
+  iface->get_show_about = panel_plugin_external_46_get_show_about;
+  iface->show_about = panel_plugin_external_46_show_about;
+  iface->remove = panel_plugin_external_46_remove;
+  iface->remote_event = panel_plugin_external_46_remote_event;
+}
+
+
+
+static void
+panel_plugin_external_46_finalize (GObject *object)
+{
+  PanelPluginExternal46 *external = PANEL_PLUGIN_EXTERNAL_46 (object);
+  GSList                *li;
+
+  if (external->watch_id != 0)
+    {
+      /* remove the child watch and don't leave zomies */
+      g_source_remove (external->watch_id);
+      g_child_watch_add (external->pid, (GChildWatchFunc) g_spawn_close_pid, NULL);
+    }
+
+  if (external->queue != NULL)
+    {
+      for (li = external->queue; li != NULL; li = li->next)
+        g_slice_free (QueueItem, li->data);
+      g_slist_free (external->queue);
+    }
+
+  g_object_unref (G_OBJECT (external->module));
+
+  (*G_OBJECT_CLASS (panel_plugin_external_46_parent_class)->finalize) (object);
+}
+
+
+
+static void
+panel_plugin_external_46_get_property (GObject    *object,
+                                       guint       prop_id,
+                                       GValue     *value,
+                                       GParamSpec *pspec)
+{
+  PanelPluginExternal46 *external = PANEL_PLUGIN_EXTERNAL_46 (object);
+
+  switch (prop_id)
+    {
+      case PROP_UNIQUE_ID:
+        g_value_set_int (value, external->unique_id);
+        break;
+
+      case PROP_MODULE:
+        g_value_set_object (value, external->module);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+
+
+static void
+panel_plugin_external_46_set_property (GObject      *object,
+                                       guint         prop_id,
+                                       const GValue *value,
+                                       GParamSpec   *pspec)
+{
+  PanelPluginExternal46 *external = PANEL_PLUGIN_EXTERNAL_46 (object);
+
+  switch (prop_id)
+    {
+      case PROP_UNIQUE_ID:
+        external->unique_id = g_value_get_int (value);
+        break;
+
+      case PROP_MODULE:
+        external->module = g_value_dup_object (value);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+
+
+static void
+panel_plugin_external_46_realize (GtkWidget *widget)
+{
+  PanelPluginExternal46  *external = PANEL_PLUGIN_EXTERNAL_46 (widget);
+  gchar               **argv;
+  GError               *error = NULL;
+  gboolean              succeed;
+  gchar                *socket_id, *unique_id;
+  GdkScreen            *screen;
+  GPid                  pid;
+
+  /* realize the socket first */
+  (*GTK_WIDGET_CLASS (panel_plugin_external_46_parent_class)->realize) (widget);
+
+  /* get the socket id and unique id in a string */
+  socket_id = g_strdup_printf ("%d", gtk_socket_get_id (GTK_SOCKET (widget)));
+  unique_id = g_strdup_printf ("%d", external->unique_id);
+
+  /* setup the basic argv */
+  argv = g_new0 (gchar *, 12);
+  argv[0]  = (gchar *) panel_module_get_filename (external->module);
+  argv[1]  = (gchar *) "-n";
+  argv[2]  = (gchar *) panel_module_get_name (external->module);
+  argv[3]  = (gchar *) "-i";
+  argv[4]  = (gchar *) unique_id;
+  argv[5]  = (gchar *) "-d";
+  argv[6]  = (gchar *) panel_module_get_display_name (external->module);
+  argv[7]  = (gchar *) "-c";
+  argv[8]  = (gchar *) panel_module_get_comment (external->module);
+  argv[9] = (gchar *) "-s";
+  argv[10] = (gchar *) socket_id;
+
+  /* get the widget screen */
+  screen = gtk_widget_get_screen (widget);
+
+  /* spawn the proccess */
+  succeed = gdk_spawn_on_screen (screen, NULL, argv, NULL,
+                                 G_SPAWN_DO_NOT_REAP_CHILD, NULL,
+                                 NULL, &pid, &error);
+
+  if (G_LIKELY (succeed))
+    {
+      /* watch the child */
+      external->pid = pid;
+      external->watch_id = g_child_watch_add_full (G_PRIORITY_LOW, pid,
+                                                   panel_plugin_external_46_child_watch, external,
+                                                   panel_plugin_external_46_child_watch_destroyed);
+    }
+  else
+    {
+      g_critical ("Failed to spawn plugin: %s", error->message);
+      g_error_free (error);
+    }
+
+  /* cleanup */
+  g_free (socket_id);
+  g_free (unique_id);
+}
+
+
+
+static gboolean
+panel_plugin_external_46_client_event (GtkWidget      *widget,
+                                       GdkEventClient *event)
+{
+  PanelPluginExternal46 *external = PANEL_PLUGIN_EXTERNAL_46 (widget);
+  gint                   provider_signal;
+
+  if (event->message_type == panel_atom)
+    {
+      provider_signal = event->data.s[0];
+
+      switch (provider_signal)
+        {
+          case PROVIDER_SIGNAL_REMOVE_PLUGIN:
+            /* we're forced removing the plugin, don't ask for a restart */
+            external->plug_embedded = FALSE;
+
+            /* destroy ourselfs, unrealize will close the plugin */
+            gtk_widget_destroy (GTK_WIDGET (external));
+            break;
+
+          case PROVIDER_SIGNAL_SHOW_CONFIGURE:
+            external->show_configure = TRUE;
+            break;
+
+          case PROVIDER_SIGNAL_SHOW_ABOUT:
+            external->show_about = TRUE;
+            break;
+
+          default:
+            /* other signals are handled in panel-applications.c */
+            xfce_panel_plugin_provider_emit_signal (XFCE_PANEL_PLUGIN_PROVIDER (external),
+                                                    provider_signal);
+            break;
+        }
+
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+
+
+static gboolean
+panel_plugin_external_46_plug_removed (GtkSocket *socket)
+{
+  PanelPluginExternal46 *external = PANEL_PLUGIN_EXTERNAL_46 (socket);
+  GtkWidget             *dialog;
+  gint                   response;
+  PanelWindow           *window;
+
+  /* leave when the plugin was removed on purpose */
+  if (external->plug_embedded == FALSE)
+    return FALSE;
+
+  /* plug has been removed */
+  external->plug_embedded = FALSE;
+
+  /* unrealize and hide the socket */
+  gtk_widget_unrealize (GTK_WIDGET (socket));
+  gtk_widget_hide (GTK_WIDGET (socket));
+
+  if (external->watch_id != 0)
+    {
+      /* remove the child watch and don't leave zomies */
+      g_source_remove (external->watch_id);
+      g_child_watch_add (external->pid, (GChildWatchFunc) g_spawn_close_pid, NULL);
+    }
+
+  /* increase the restart counter */
+  external->n_restarts++;
+
+  /* check if we ask the user what to do */
+  if (external->n_restarts > N_RESTART_TRIES)
+    {
+      /* create dialog */
+      dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (socket))),
+                                       GTK_DIALOG_DESTROY_WITH_PARENT,
+                                       GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
+                                       _("Plugin \"%s\" unexpectedly left the building, do you want to restart it?"),
+                                       panel_module_get_display_name (external->module));
+      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), _("If you press Execute "
+                                                "the panel will try to restart the plugin otherwise it "
+                                                "will be permanently removed from the panel."));
+      gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_EXECUTE, GTK_RESPONSE_OK,
+                              GTK_STOCK_REMOVE, GTK_RESPONSE_CLOSE, NULL);
+      gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+      gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+
+      /* wait for the user's choise */
+      response = gtk_dialog_run (GTK_DIALOG (dialog));
+      gtk_widget_destroy (dialog);
+
+      /* reset the restart counter */
+      external->n_restarts = 0;
+    }
+  else
+    {
+      /* pretend the user clicked the yes button */
+      response = GTK_RESPONSE_OK;
+
+      /* print a message we did an autorestart */
+      g_message ("Automatically restarting plugin %s-%d, try %d",
+                 panel_module_get_name (external->module),
+                 external->unique_id, external->n_restarts);
+  }
+
+  /* handle the response */
+  if (response == GTK_RESPONSE_OK)
+    {
+      /* get the plugin panel */
+      window = PANEL_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (socket)));
+      panel_return_val_if_fail (PANEL_IS_WINDOW (window), FALSE);
+
+      /* send panel information to the plugin */
+      panel_window_set_povider_info (window, GTK_WIDGET (external));
+
+      /* show the socket again (realize will spawn the plugin) */
+      gtk_widget_show (GTK_WIDGET (socket));
+
+      /* don't process other events */
+      return TRUE;
+    }
+  else
+    {
+      /* emit a remove signal, so we can cleanup the plugin configuration (in panel-application) */
+      xfce_panel_plugin_provider_emit_signal (XFCE_PANEL_PLUGIN_PROVIDER (external),
+                                              PROVIDER_SIGNAL_REMOVE_PLUGIN);
+
+      /* destroy the socket */
+      gtk_widget_destroy (GTK_WIDGET (socket));
+    }
+
+  return FALSE;
+}
+
+
+
+static void
+panel_plugin_external_46_plug_added (GtkSocket *socket)
+{
+  PanelPluginExternal46 *external = PANEL_PLUGIN_EXTERNAL_46 (socket);
+  GSList                *li;
+  QueueItem             *item;
+
+  /* plug has been added */
+  external->plug_embedded = TRUE;
+
+  if (external->queue != NULL)
+    {
+      external->queue = g_slist_reverse (external->queue);
+
+      for (li = external->queue; li != NULL; li = li->next)
+        {
+          item = li->data;
+
+          panel_plugin_external_46_send_client_event (external, item->message, item->value);
+
+          g_slice_free (QueueItem, item);
+        }
+
+      g_slist_free (external->queue);
+    }
+}
+
+
+
+static void
+panel_plugin_external_46_send_client_event (PanelPluginExternal46 *external,
+                                            gint                   message,
+                                            gint                   value)
+{
+  GdkEventClient event;
+
+  panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (external));
+  panel_return_if_fail (panel_atom != GDK_NONE);
+  panel_return_if_fail (GDK_IS_WINDOW (GTK_WIDGET (external)->window));
+
+  event.type = GDK_CLIENT_EVENT;
+  event.window = GTK_WIDGET (external)->window;
+  event.send_event = TRUE;
+  event.message_type = panel_atom;
+  event.data_format = 16;
+  event.data.s[0] = message;
+  event.data.s[1] = value;
+  event.data.s[2] = 0;
+
+  gdk_error_trap_push ();
+  gdk_event_send_client_message ((GdkEvent *) &event,
+      GDK_WINDOW_XID (gtk_socket_get_plug_window (GTK_SOCKET (external))));
+  gdk_flush ();
+  if (gdk_error_trap_pop () != 0)
+    g_warning ("Failed to send client event %d", message);
+}
+
+
+
+static void
+panel_plugin_external_46_queue_add (PanelPluginExternal46 *external,
+                                    gint                   message,
+                                    gint                   value)
+{
+  QueueItem *item;
+
+  panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (external));
+
+  if (external->plug_embedded)
+    {
+      /* directly send the message */
+      panel_plugin_external_46_send_client_event (external, message, value);
+    }
+  else
+    {
+      /* queue the message until the plug is embedded */
+      item = g_slice_new0 (QueueItem);
+      item->message = message;
+      item->value = value;
+
+      external->queue = g_slist_prepend (external->queue, item);
+    }
+}
+
+
+
+static const gchar *
+panel_plugin_external_46_get_name (XfcePanelPluginProvider *provider)
+{
+  panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (provider), NULL);
+  panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), NULL);
+
+  return panel_module_get_name (PANEL_PLUGIN_EXTERNAL_46 (provider)->module);
+}
+
+
+
+static gint
+panel_plugin_external_46_get_unique_id (XfcePanelPluginProvider *provider)
+{
+  panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (provider), -1);
+  panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), -1);
+
+  return PANEL_PLUGIN_EXTERNAL_46 (provider)->unique_id;
+}
+
+
+
+static void
+panel_plugin_external_46_set_size (XfcePanelPluginProvider *provider,
+                                   gint                     size)
+{
+  panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (provider));
+  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
+
+  panel_plugin_external_46_queue_add (PANEL_PLUGIN_EXTERNAL_46 (provider),
+                                      PANEL_CLIENT_EVENT_SET_SIZE,
+                                      size);
+}
+
+
+
+static void
+panel_plugin_external_46_set_orientation (XfcePanelPluginProvider *provider,
+                                          GtkOrientation           orientation)
+{
+  panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (provider));
+  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
+
+  panel_plugin_external_46_queue_add (PANEL_PLUGIN_EXTERNAL_46 (provider),
+                                      PANEL_CLIENT_EVENT_SET_ORIENTATION,
+                                      orientation);
+}
+
+
+
+static void
+panel_plugin_external_46_set_screen_position (XfcePanelPluginProvider *provider,
+                                              XfceScreenPosition       screen_position)
+{
+  panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (provider));
+  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
+
+  panel_plugin_external_46_queue_add (PANEL_PLUGIN_EXTERNAL_46 (provider),
+                                      PANEL_CLIENT_EVENT_SET_SCREEN_POSITION,
+                                      screen_position);
+}
+
+
+
+static void
+panel_plugin_external_46_save (XfcePanelPluginProvider *provider)
+{
+  panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (provider));
+  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
+
+  panel_plugin_external_46_queue_add (PANEL_PLUGIN_EXTERNAL_46 (provider),
+                                      PANEL_CLIENT_EVENT_SAVE,
+                                      FALSE);
+}
+
+
+
+static gboolean
+panel_plugin_external_46_get_show_configure (XfcePanelPluginProvider *provider)
+{
+  panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (provider), FALSE);
+  panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), FALSE);
+
+  return PANEL_PLUGIN_EXTERNAL_46 (provider)->show_configure;
+}
+
+
+
+static void
+panel_plugin_external_46_show_configure (XfcePanelPluginProvider *provider)
+{
+  panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (provider));
+  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
+
+  panel_plugin_external_46_queue_add (PANEL_PLUGIN_EXTERNAL_46 (provider),
+                                      PANEL_CLIENT_EVENT_SHOW_CONFIGURE,
+                                      FALSE);
+}
+
+
+
+static gboolean
+panel_plugin_external_46_get_show_about (XfcePanelPluginProvider *provider)
+{
+  panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (provider), FALSE);
+  panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), FALSE);
+
+  return PANEL_PLUGIN_EXTERNAL_46 (provider)->show_about;
+}
+
+
+
+static void
+panel_plugin_external_46_show_about (XfcePanelPluginProvider *provider)
+{
+  panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (provider));
+  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
+
+  panel_plugin_external_46_queue_add (PANEL_PLUGIN_EXTERNAL_46 (provider),
+                                      PANEL_CLIENT_EVENT_SHOW_ABOUT,
+                                      FALSE);
+}
+
+
+
+static void
+panel_plugin_external_46_remove (XfcePanelPluginProvider *provider)
+{
+  panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (provider));
+  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
+
+  panel_plugin_external_46_queue_add (PANEL_PLUGIN_EXTERNAL_46 (provider),
+                                      PANEL_CLIENT_EVENT_REMOVE,
+                                      FALSE);
+}
+
+
+
+static gboolean
+panel_plugin_external_46_remote_event (XfcePanelPluginProvider *provider,
+                                       const gchar             *name,
+                                       const GValue            *value)
+{
+  panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (provider), TRUE);
+  panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), TRUE);
+
+  g_warning ("Plugin %s is compiled as an Xfce 4.6 binary. It needs to be "
+             "ported to the new library plugin framework to be able to use "
+             "remote events.", panel_plugin_external_46_get_name (provider));
+
+  return TRUE;
+}
+
+
+
+static void
+panel_plugin_external_46_set_sensitive (PanelPluginExternal46 *external)
+{
+  panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (external));
+
+  panel_plugin_external_46_queue_add (external,
+                                      PANEL_CLIENT_EVENT_SET_SENSITIVE,
+                                      GTK_WIDGET_IS_SENSITIVE (external));
+}
+
+
+
+static void
+panel_plugin_external_46_child_watch (GPid     pid,
+                                   gint     status,
+                                   gpointer user_data)
+{
+  PanelPluginExternal46 *external = PANEL_PLUGIN_EXTERNAL_46 (user_data);
+
+  panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (external));
+  panel_return_if_fail (external->pid == pid);
+
+  switch (WEXITSTATUS (status))
+    {
+      case WRAPPER_EXIT_FAILURE:
+      case WRAPPER_EXIT_NO_PROVIDER:
+      case WRAPPER_EXIT_PREINIT:
+        /* wait until everything is settled, then destroy the
+         * external plugin so it is removed from the configuration */
+        exo_gtk_object_destroy_later (GTK_OBJECT (external));
+        break;
+    }
+
+  /* close the pid */
+  g_spawn_close_pid (pid);
+}
+
+
+
+static void
+panel_plugin_external_46_child_watch_destroyed (gpointer user_data)
+{
+  PANEL_PLUGIN_EXTERNAL_46 (user_data)->watch_id = 0;
+}
+
+
+
+GtkWidget *
+panel_plugin_external_46_new (PanelModule  *module,
+                              gint          unique_id,
+                              gchar       **arguments)
+{
+  panel_return_val_if_fail (PANEL_IS_MODULE (module), NULL);
+  panel_return_val_if_fail (unique_id != -1, NULL);
+/* TODO arguments */
+  return g_object_new (PANEL_TYPE_PLUGIN_EXTERNAL_46,
+                       "module", module,
+                       "unique-id", unique_id, NULL);
+}
+
+
+
+void
+panel_plugin_external_46_set_background_alpha (PanelPluginExternal46 *external,
+                                               gdouble              alpha)
+{
+  panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (external));
+
+  panel_plugin_external_46_queue_add (external,
+                                      PANEL_CLIENT_EVENT_SET_BACKGROUND_ALPHA,
+                                      rint (alpha * 100.0));
+}
diff --git a/panel/panel-plugin-external-46.h b/panel/panel-plugin-external-46.h
new file mode 100644
index 0000000..f5cb4c2
--- /dev/null
+++ b/panel/panel-plugin-external-46.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __PANEL_PLUGIN_EXTERNAL_46_H__
+#define __PANEL_PLUGIN_EXTERNAL_46_H__
+
+#include <gtk/gtk.h>
+#include <libxfce4panel/libxfce4panel.h>
+#include <libxfce4panel/xfce-panel-plugin-provider.h>
+#include <panel/panel-module.h>
+
+G_BEGIN_DECLS
+
+typedef struct _PanelPluginExternal46Class PanelPluginExternal46Class;
+typedef struct _PanelPluginExternal46      PanelPluginExternal46;
+
+#define PANEL_TYPE_PLUGIN_EXTERNAL_46            (panel_plugin_external_46_get_type ())
+#define PANEL_PLUGIN_EXTERNAL_46(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_PLUGIN_EXTERNAL_46, PanelPluginExternal46))
+#define PANEL_PLUGIN_EXTERNAL_46_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), PANEL_TYPE_PLUGIN_EXTERNAL_46, PanelPluginExternal46Class))
+#define PANEL_IS_PLUGIN_EXTERNAL_46(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PANEL_TYPE_PLUGIN_EXTERNAL_46))
+#define PANEL_IS_PLUGIN_EXTERNAL_46_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_PLUGIN_EXTERNAL_46))
+#define PANEL_PLUGIN_EXTERNAL_46_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), PANEL_TYPE_PLUGIN_EXTERNAL_46, PanelPluginExternal46Class))
+
+GType      panel_plugin_external_46_get_type             (void) G_GNUC_CONST;
+
+GtkWidget *panel_plugin_external_46_new                  (PanelModule            *module,
+                                                          gint                    unique_id,
+                                                          gchar                 **arguments) G_GNUC_MALLOC;
+
+void       panel_plugin_external_46_set_background_alpha (PanelPluginExternal46   *external,
+                                                          gdouble                 alpha);
+
+G_END_DECLS
+
+#endif /* !__PANEL_PLUGIN_EXTERNAL_46_H__ */
diff --git a/panel/panel-window.c b/panel/panel-window.c
index 0f3ae92..5d52813 100644
--- a/panel/panel-window.c
+++ b/panel/panel-window.c
@@ -38,6 +38,7 @@
 #include <panel/panel-dialogs.h>
 #include <panel/panel-dbus-service.h>
 #include <panel/panel-plugin-external.h>
+#include <panel/panel-plugin-external-46.h>
 
 
 
@@ -2139,10 +2140,15 @@ panel_window_set_povider_info (PanelWindow *window,
   panel_window_set_plugin_orientation (provider, window);
   panel_window_set_plugin_screen_position (provider, window);
 
-  if (PANEL_IS_PLUGIN_EXTERNAL (provider)
-      && PANEL_BASE_WINDOW (window)->background_alpha < 1.0)
-    panel_plugin_external_set_background_alpha (PANEL_PLUGIN_EXTERNAL (provider),
-        PANEL_BASE_WINDOW (window)->background_alpha);
+  if (PANEL_BASE_WINDOW (window)->background_alpha < 1.0)
+    {
+      if (PANEL_IS_PLUGIN_EXTERNAL (provider))
+        panel_plugin_external_set_background_alpha (PANEL_PLUGIN_EXTERNAL (provider),
+            PANEL_BASE_WINDOW (window)->background_alpha);
+      else if (PANEL_IS_PLUGIN_EXTERNAL_46 (provider))
+        panel_plugin_external_46_set_background_alpha (PANEL_PLUGIN_EXTERNAL_46 (provider),
+            PANEL_BASE_WINDOW (window)->background_alpha);
+    }
 }
 
 



More information about the Xfce4-commits mailing list