[Goodies-dev] Simple program to load panel plugin

Jean-François Wauthy pollux at xfce.org
Sun Aug 17 11:08:59 CEST 2008


Le samedi 16 août 2008 à 21:42 +0200, Jean-François Wauthy a écrit :

> Also it does not support internal plugins
> at this point but if there is interest for that it won't be a problem
> for me to write the need code.
> 

I've implemented support for internal plugins as well now. For command
line help, simply run the executable with --help.

Nick, Jasper, I think it would be interesting to include it in SVN. Also
I didn't find a way to remove a plugin from the container without some
confirmation dialog showing up.
-- 
Jean-François Wauthy <pollux at xfce.org>
-------------- next part --------------
diff --git a/configure.in.in b/configure.in.in
index ef403f9..e958692 100644
--- a/configure.in.in
+++ b/configure.in.in
@@ -267,6 +267,7 @@ plugins/showdesktop/Makefile
 plugins/systray/Makefile
 plugins/tasklist/Makefile
 plugins/windowlist/Makefile
+plugin-dev-container/Makefile
 mcs-plugin/Makefile
 po/Makefile.in
 docs/Makefile
diff --git a/plugin-dev-container/Makefile.am b/plugin-dev-container/Makefile.am
new file mode 100644
index 0000000..5c06495
--- /dev/null
+++ b/plugin-dev-container/Makefile.am
@@ -0,0 +1,41 @@
+# $Id$
+
+INCLUDES = 								\
+	-I$(top_srcdir)							\
+	-I$(top_builddir)						\
+	-DG_LOG_DOMAIN=\"plugin-dev-container\"				\
+	-DDATADIR=\"$(datadir)\"					\
+	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"				\
+	$(PLATFORM_CPPFLAGS)
+
+bin_PROGRAMS = 								\
+	plugin-dev-container
+
+plugin_dev_container_headers =						\
+	container-window.h
+
+plugin_dev_container_SOURCES =						\
+	$(plugin_dev_container_headers)					\
+	container-window.c						\
+	main.c								
+
+plugin_dev_container_CFLAGS =						\
+	$(GMODULE_CFLAGS)						\
+	$(LIBXFCE4UTIL_CFLAGS)                                          \
+	$(LIBXFCEGUI4_CFLAGS)						\
+	$(PLATFORM_CFLAGS)
+
+plugin_dev_container_LDFLAGS =						\
+	-no-undefined							\
+	$(PLATFORM_LDFLAGS)
+
+plugin_dev_container_LDADD =						\
+	$(top_builddir)/libxfce4panel/libxfce4panel.la			\
+	$(LIBXFCE4UTIL_LIBS)                                            \
+	$(LIBXFCEGUI4_LIBS)                                             \
+	$(GMODULE_LIBS)							
+
+plugin_dev_container_DEPENDENCIES =					\
+	$(top_builddir)/libxfce4panel/libxfce4panel.la
+
+# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/plugin-dev-container/container-window.c b/plugin-dev-container/container-window.c
new file mode 100644
index 0000000..fb81195
--- /dev/null
+++ b/plugin-dev-container/container-window.c
@@ -0,0 +1,266 @@
+/* $Id$
+ *
+ * Copyright (c) 2008 Jean-François Wauthy <pollux 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include <libxfce4panel/xfce-panel-enums.h>
+#include <libxfce4panel/xfce-panel-external-item.h>
+#include <libxfce4panel/xfce-panel-internal-plugin.h>
+#include <libxfce4panel/xfce-panel-item-iface.h>
+#include <libxfce4panel/xfce-panel-plugin-iface.h>
+
+#include "container-window.h"
+
+#define CONTAINER_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_CONTAINER_WINDOW, ContainerWindowPrivate))
+
+typedef struct {
+  GtkWidget *spin;
+  GtkWidget *container;
+  GtkWidget *plugin;
+} ContainerWindowPrivate;
+
+/* prototypes */
+static void container_window_class_init (ContainerWindowClass *);
+static void container_window_init (ContainerWindow *);
+
+static gboolean cb_delete_window (ContainerWindow * win, GdkEvent * event, ContainerWindowPrivate *priv);
+static void cb_button_resize_clicked (GtkButton *button, ContainerWindowPrivate *priv);
+static void cb_button_save_clicked (GtkButton *button, ContainerWindowPrivate *priv);
+
+/* global */
+static GtkWindowClass *parent_class = NULL;
+
+/*************************/
+/* ContainerWindow class */
+/*************************/
+GtkType
+container_window_get_type (void)
+{
+  static GtkType container_window_type = 0;
+
+  if (!container_window_type) {
+    static const GTypeInfo container_window_info = {
+      sizeof (ContainerWindowClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) container_window_class_init,
+      NULL,
+      NULL,
+      sizeof (ContainerWindow),
+      0,
+      (GInstanceInitFunc) container_window_init
+    };
+
+    container_window_type = g_type_register_static (GTK_TYPE_WINDOW, "ContainerWindow", &container_window_info, 0);
+  }
+
+  return container_window_type;
+}
+
+static void
+container_window_class_init (ContainerWindowClass * klass)
+{
+  g_type_class_add_private (klass, sizeof (ContainerWindowPrivate));
+
+  parent_class = g_type_class_peek_parent (klass);
+}
+
+static void
+container_window_init (ContainerWindow * window)
+{
+  ContainerWindowPrivate *priv = CONTAINER_WINDOW_GET_PRIVATE (window);
+
+  GtkWidget *hbox, *vbox, *button, *separator;
+  GtkWidget *hbox2, *image;
+
+  gtk_container_set_border_width (GTK_CONTAINER (window), 5);
+  gtk_window_set_title (GTK_WINDOW (window), "Panel-plugin development container");
+  g_signal_connect (G_OBJECT (window), "delete-event", G_CALLBACK (cb_delete_window), priv);
+
+  hbox = gtk_hbox_new (FALSE, 5);
+  gtk_widget_show (hbox);
+
+  vbox = gtk_vbox_new (TRUE, 0);
+  gtk_widget_show (vbox);
+
+  /* resize button */
+  hbox2 = gtk_hbox_new (FALSE, 0);
+  gtk_widget_show (hbox2);
+
+  priv->spin = gtk_spin_button_new_with_range (1, 5000, 1);
+  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (priv->spin), FALSE);
+  gtk_widget_show (priv->spin);
+  gtk_box_pack_start (GTK_BOX (hbox2), priv->spin, FALSE, FALSE, 0);
+
+  button = gtk_button_new_with_label ("_Resize");
+  g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (cb_button_resize_clicked), priv);
+
+  image = gtk_image_new_from_stock (GTK_STOCK_FULLSCREEN, GTK_ICON_SIZE_BUTTON);
+  gtk_widget_show (image);
+  gtk_button_set_image (GTK_BUTTON (button), image);
+
+  gtk_box_pack_start (GTK_BOX (hbox2), button, TRUE, TRUE, 0);
+  gtk_widget_show (button); 
+
+  gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 2);
+
+  /* save button */
+  button = gtk_button_new_from_stock (GTK_STOCK_SAVE);
+  g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (cb_button_save_clicked), priv);
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  gtk_widget_show (button);
+  
+  gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 2);
+
+  /* separator */
+  separator = gtk_vseparator_new ();
+  gtk_widget_show (separator);
+  gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, FALSE, 0);
+
+  /* container */
+  priv->container = gtk_alignment_new (0.5, 0.5, 0, 0);
+  gtk_widget_show (priv->container);
+  gtk_box_pack_start (GTK_BOX (hbox), priv->container, FALSE, FALSE, 0);
+
+  gtk_container_add (GTK_CONTAINER (window), hbox);
+}
+
+/*************/
+/* Callbacks */
+/*************/
+static gboolean
+cb_delete_window (ContainerWindow * win, GdkEvent * event, ContainerWindowPrivate *priv)
+{
+  gtk_main_quit ();
+
+  return FALSE;
+}
+
+static void
+cb_button_resize_clicked (GtkButton *button, ContainerWindowPrivate *priv)
+{
+  xfce_panel_item_set_size (XFCE_PANEL_ITEM (priv->plugin), gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->spin)));
+}
+
+static void
+cb_button_save_clicked (GtkButton *button, ContainerWindowPrivate *priv)
+{
+  xfce_panel_item_save (XFCE_PANEL_ITEM (priv->plugin));
+}
+
+/************/
+/* Internal */
+/************/
+typedef struct {
+  GModule              *gmodule;
+  XfcePanelPluginFunc   construct;
+  XfcePanelPluginCheck  check;
+} InternalPlugin;
+
+/* adapted from panel/panel-item-manager.c */
+static gboolean
+load_module (const gchar *file, InternalPlugin *plugin)
+{
+  gpointer symbol;
+  XfcePanelPluginFunc (*get_construct) (void);
+  XfcePanelPluginCheck (*get_check) (void);
+
+  /* try to open the module */
+  plugin->gmodule = g_module_open (file, G_MODULE_BIND_LOCAL);
+
+  /* check */
+  if (G_UNLIKELY (plugin->gmodule == NULL)) {
+    /* show a warning */
+    g_critical ("Could not open module %s: %s",
+		file, g_module_error ());
+
+    return FALSE;
+  }
+
+  /* check */
+  if (G_UNLIKELY (!g_module_symbol (plugin->gmodule,
+				    "xfce_panel_plugin_get_construct",
+				    &symbol))) {
+    /* show a warning */
+    g_critical ("Could not open symbol in module %s: %s",
+		file, g_module_error ());
+
+    /* close the module */
+    g_module_close (plugin->gmodule);
+    plugin->gmodule = NULL;
+    
+    return FALSE;
+  }
+
+  get_construct    = symbol;
+  plugin->construct = get_construct ();
+
+  /* check of the check function ^_^ */
+  if (g_module_symbol (plugin->gmodule, "xfce_panel_plugin_get_check", &symbol)) {
+    get_check    = symbol;
+    plugin->check = get_check ();
+  } else {
+    plugin->check = NULL;
+  }
+
+  return TRUE;
+}
+
+/***************/
+/* Public API */
+/**************/
+
+GtkWidget *
+container_window_new (gboolean is_external, const gchar *name, const gchar *file, gint size)
+{
+  GtkWidget *obj = NULL;
+
+  obj = g_object_new (container_window_get_type (), NULL);
+
+  if (obj) {
+    ContainerWindowPrivate *priv = CONTAINER_WINDOW_GET_PRIVATE (obj);
+
+    if (is_external) {
+      priv->plugin = xfce_external_panel_item_new (name, "container-dev-plugin", "Plugin in development container", file, size, XFCE_SCREEN_POSITION_NONE);
+    } else {
+      InternalPlugin plugin;
+
+      if (!load_module (file, &plugin)) {
+	g_object_unref (obj);
+	return NULL;
+      }
+
+      priv->plugin = xfce_internal_panel_plugin_new (name, "container-dev-plugin", "Plugin in development container", size, XFCE_SCREEN_POSITION_NONE, plugin.construct);
+    }
+
+    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->spin), size);
+
+    if (priv->plugin) {
+      gtk_container_add (GTK_CONTAINER (priv->container), priv->plugin);
+      gtk_widget_show (priv->plugin);
+    }
+  }
+
+  return obj;
+}
+
diff --git a/plugin-dev-container/container-window.h b/plugin-dev-container/container-window.h
new file mode 100644
index 0000000..75fe91e
--- /dev/null
+++ b/plugin-dev-container/container-window.h
@@ -0,0 +1,53 @@
+/* $Id$
+ *
+ * Copyright (c) 2008 Jean-François Wauthy <pollux 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __CONTAINER_WINDOW_H__
+#define __CONTAINER_WINDOW_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_CONTAINER_WINDOW            (container_window_get_type ())
+#define CONTAINER_WINDOW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CONTAINER_WINDOW, ContainerWindow))
+#define CONTAINER_WINDOW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CONTAINER_WINDOW, ContainerWindowClass))
+#define IS_CONTAINER_WINDOW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CONTAINER_WINDOW))
+#define IS_CONTAINER_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CONTAINER_WINDOW))
+#define CONTAINER_WINDOW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CONTAINER_WINDOW, ContainerWindowClass))
+
+typedef struct 
+{
+  GtkWindow window;
+} ContainerWindow;
+
+typedef struct 
+{
+  GtkWindowClass parent_class;
+} ContainerWindowClass;
+
+GtkType container_window_get_type (void);
+
+GtkWidget *container_window_new (gboolean is_external, const gchar *name, const gchar *file, gint size);
+
+G_END_DECLS
+#endif
diff --git a/plugin-dev-container/main.c b/plugin-dev-container/main.c
new file mode 100644
index 0000000..b8a853e
--- /dev/null
+++ b/plugin-dev-container/main.c
@@ -0,0 +1,94 @@
+/* $Id$
+ *
+ * Copyright (c) 2008 Jean-François Wauthy <pollux 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
+
+#include "container-window.h"
+
+/* globals */
+static gboolean opt_internal = FALSE;
+static gchar *opt_file = NULL;
+static gint opt_size = 24;
+
+/* command line options */
+static GOptionEntry option_entries[] =
+{
+    { "internal", 'i', 0, G_OPTION_ARG_NONE, &opt_internal, "The plugin is an internal plugin", NULL },
+    { "file",     'f', 0, G_OPTION_ARG_FILENAME, &opt_file, "The path to the plugin binary file", NULL },
+    { "size",     's', 0, G_OPTION_ARG_INT, &opt_size,      "The size of the panel plugin at startup", NULL},
+    { NULL }
+};
+
+/* main program */
+gint
+main (gint argc, gchar **argv)
+{
+  GtkWidget *mainwin;
+  GError *error = NULL;
+
+  /* translation domain */
+  xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+
+  /* application name */
+  g_set_application_name (PACKAGE_NAME);
+
+  /* initialize gtk */
+  if (!gtk_init_with_args (&argc, &argv, "", option_entries, GETTEXT_PACKAGE, &error)) {
+    g_print ("%s: %s\n", PACKAGE_NAME, error ? error->message : _("Failed to open display"));
+    
+    if (error != NULL)
+      g_error_free (error);
+    
+    return EXIT_FAILURE;
+  }
+
+  if (G_UNLIKELY (opt_file == NULL)) {
+    g_error ("A path to a plugin must be provided");
+
+    return EXIT_FAILURE;
+  }
+  
+  mainwin = container_window_new (!opt_internal, "test", opt_file, opt_size);
+
+  gtk_widget_show (mainwin);
+
+  gtk_main ();
+
+  g_free (opt_file);
+
+  return EXIT_SUCCESS;
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: Ceci est une partie de message num?riquement sign?e
URL: <http://mail.xfce.org/pipermail/goodies-dev/attachments/20080817/58770bcb/attachment.pgp>


More information about the Goodies-dev mailing list