[Xfce4-commits] <xfce4-panel:devel> Add support for the new api to the wrapper.

Nick Schermer nick at xfce.org
Tue Aug 11 20:30:17 CEST 2009


Updating branch refs/heads/devel
         to 248773ac8a1f5f029f924fadeb457075e71312d0 (commit)
       from 9ca2ad57ad5d7d909743396afde344eee4f79667 (commit)

commit 248773ac8a1f5f029f924fadeb457075e71312d0
Author: Nick Schermer <nick at xfce.org>
Date:   Sun Mar 15 15:30:17 2009 +0100

    Add support for the new api to the wrapper.

 wrapper/Makefile.am      |    2 +
 wrapper/main.c           |  155 ++++++++++++------------------
 wrapper/wrapper-module.c |  244 ++++++++++++++++++++++++++++++++++++++++++++++
 wrapper/wrapper-module.h |   51 ++++++++++
 4 files changed, 358 insertions(+), 94 deletions(-)

diff --git a/wrapper/Makefile.am b/wrapper/Makefile.am
index e28d0f6..5bb6484 100644
--- a/wrapper/Makefile.am
+++ b/wrapper/Makefile.am
@@ -22,6 +22,8 @@ xfce4_panel_wrapper_built_sources = \
 xfce4_panel_wrapper_SOURCES = \
 	$(xfce4_panel_wrapper_built_sources) \
 	main.c \
+	wrapper-module.c \
+	wrapper-module.h \
 	wrapper-plug.c \
 	wrapper-plug.h
 
diff --git a/wrapper/main.c b/wrapper/main.c
index cd6f5f8..3fcef6b 100644
--- a/wrapper/main.c
+++ b/wrapper/main.c
@@ -47,6 +47,7 @@
 
 #include <wrapper/wrapper-plug.h>
 #include <wrapper/wrapper-marshal.h>
+#include <wrapper/wrapper-module.h>
 #include <wrapper/wrapper-dbus-client-infos.h>
 
 
@@ -195,16 +196,16 @@ dbus_gproxy_dbus_filter (DBusConnection *connection,
 gint
 main (gint argc, gchar **argv)
 {
-  GError                  *error = NULL;
-  XfcePanelPluginProvider *provider;
-  GModule                 *module;
-  PluginConstructFunc      construct_func;
-  DBusGConnection         *dbus_gconnection;
-  DBusConnection          *dbus_connection;
-  DBusGProxy              *dbus_gproxy;
-  WrapperPlug             *plug;
+  GError           *error = NULL;
+  GtkWidget        *provider;
+  WrapperModule    *module = NULL;
+  gboolean          succeed = FALSE;
+  DBusGConnection *dbus_gconnection;
+  DBusConnection  *dbus_connection;
+  DBusGProxy      *dbus_gproxy = NULL;
+  WrapperPlug     *plug;
 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_NAME)
-  gchar                    process_name[16];
+  gchar            process_name[16];
 #endif
 
   /* set translation domain */
@@ -223,27 +224,20 @@ main (gint argc, gchar **argv)
   if (!gtk_init_with_args (&argc, &argv, _("[ARGUMENTS...]"),
                            option_entries, (gchar *) GETTEXT_PACKAGE, &error))
     {
-      /* print error */
-      g_critical ("Failed to initialize GTK+: %s",
-                  error ? error->message : "Unable to open display");
-
-      /* cleanup */
-      if (G_LIKELY (error != NULL))
-        g_error_free (error);
-
-      /* leave */
-      return EXIT_FAILURE;
+      /* set error if not set by gtk */
+      if (error == NULL)
+        g_set_error (&error, 0, 0, "Unable to open display \"%s\"", 
+                     gdk_get_display_arg_name ());
+      goto error;
     }
 
   /* check if the module exists */
-  if (!IS_STRING (opt_filename)
-      || g_file_test (opt_filename, G_FILE_TEST_EXISTS) == FALSE)
+  if (!IS_STRING (opt_filename) || !g_file_test (opt_filename, G_FILE_TEST_EXISTS))
     {
-      /* print error */
-      g_critical ("Unable to find plugin module \"%s\".", opt_filename);
-
-      /* leave */
-      return EXIT_FAILURE;
+      /* set error and leave */
+      g_set_error (&error, 0, 0,
+                   "Unable to find plugin module \"%s\"", opt_filename);
+      goto error;
     }
 
   /* check if all the other arguments are defined */
@@ -252,11 +246,10 @@ main (gint argc, gchar **argv)
       || opt_unique_id == -1
       || !IS_STRING (opt_display_name))
     {
-      /* print error */
-      g_critical ("One of the required arguments is missing.");
-
-      /* leave */
-      return EXIT_FAILURE;
+      /* set error and leave */
+      g_set_error (&error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                   "One of the required argument for the wrapper is missing");
+      goto error;
     }
 
 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_NAME)
@@ -264,27 +257,18 @@ main (gint argc, gchar **argv)
   g_snprintf (process_name, sizeof (process_name), "panel-%s-%d",
               wrapper_name, opt_unique_id);
   if (prctl (PR_SET_NAME, (gulong) process_name, 0, 0, 0) == -1)
-    g_critical ("Failed to set the process name to \"%s\".", process_name);
+    g_warning ("Failed to set the process name to \"%s\".", process_name);
 #endif
 
   /* try to connect to dbus */
   dbus_gconnection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
   if (G_UNLIKELY (dbus_gconnection == NULL))
-    {
-      /* print error */
-      g_critical ("Failed to connect to dbus: %s", error->message);
-
-      /* cleanup */
-      g_error_free (error);
-
-      /* leave */
-      return EXIT_FAILURE;
-    }
+    goto error;
 
   /* get the dbus connection from the gconnection */
   dbus_connection = dbus_g_connection_get_connection (dbus_gconnection);
 
-  /* hookup a filter to monitor panel craches */
+  /* hookup a filter to monitor panel segfaults */
   if (dbus_connection_add_filter (dbus_connection, dbus_gproxy_dbus_filter, NULL, NULL))
     dbus_bus_add_match (dbus_connection,
                         "type='signal',sender='" DBUS_SERVICE_DBUS
@@ -299,15 +283,11 @@ main (gint argc, gchar **argv)
                                            PANEL_DBUS_PLUGIN_INTERFACE);
   if (G_UNLIKELY (dbus_gproxy == NULL))
     {
-      /* print error */
-      g_critical ("Failed to create the dbus proxy: %s", error->message);
-
-      /* cleanup */
-      g_object_unref (G_OBJECT (dbus_gconnection));
-      g_error_free (error);
-
-      /* leave */
-      return EXIT_FAILURE;
+      /* set error and leave */
+      g_set_error (&error, 0, 0,
+                   "Failed to create the dbus proxy for interface \"%s\"",
+                   PANEL_DBUS_PLUGIN_INTERFACE);
+      goto error;
     }
 
   /* setup signal for property changes */
@@ -317,39 +297,15 @@ main (gint argc, gchar **argv)
   dbus_g_proxy_add_signal (dbus_gproxy, "PropertyChanged", G_TYPE_INT,
                            G_TYPE_INT, G_TYPE_VALUE, G_TYPE_INVALID);
 
-  /* load the module and link the function */
-  module = g_module_open (opt_filename, G_MODULE_BIND_LOCAL);
-  if (G_LIKELY (module))
-    {
-      /* get the contruct symbol */
-      if (!g_module_symbol (module, "__xpp_construct_obj", (gpointer) &construct_func)
-          && !g_module_symbol (module, "__xpp_construct", (gpointer) &construct_func))
-        {
-          /* print error */
-          g_critical ("Plugin \"%s-%d\" lacks a plugin register function",
-                      wrapper_name, opt_unique_id);
-
-          /* close the module */
-          g_module_close (module);
-
-          /* leave */
-          return EXIT_FAILURE;
-        }
-    }
-  else
-    {
-      /* print error */
-      g_critical ("Unable to load the plugin module \"%s\": %s.",
-                  wrapper_name, g_module_error ());
-
-      /* leave */
-      return EXIT_FAILURE;
-    }
-
-  /* contruct the panel plugin */
-  provider = (*construct_func) (wrapper_name, opt_unique_id, opt_display_name,
-                                opt_arguments, gdk_screen_get_default ());
-  if (G_LIKELY (provider))
+  /* create a new wrapper module */
+  module = wrapper_module_new (opt_filename);
+  
+  /* create the plugin provider */
+  provider = wrapper_module_new_provider (module,
+                                          gdk_screen_get_default (),
+                                          wrapper_name, opt_unique_id, 
+                                          opt_display_name, opt_arguments);
+  if (G_LIKELY (provider != NULL))
     {
       /* create quark */
       plug_quark = g_quark_from_static_string ("plug-quark");
@@ -372,6 +328,9 @@ main (gint argc, gchar **argv)
       gtk_container_add (GTK_CONTAINER (plug), GTK_WIDGET (provider));
       gtk_widget_show (GTK_WIDGET (plug));
       gtk_widget_show (GTK_WIDGET (provider));
+      
+      /* everything went fine */
+      succeed = TRUE;
 
       /* enter the main loop */
       gtk_main ();
@@ -385,19 +344,27 @@ main (gint argc, gchar **argv)
     }
   else
     {
-      /* print error */
-      g_critical ("Failed to contruct the plugin \"%s-%d\".",
-                  wrapper_name, opt_unique_id);
-
-      /* release the proxy */
-      g_object_unref (G_OBJECT (dbus_gproxy));
+      /* set error */
+      g_set_error (&error, 0, 0, "Failed to construct the provider object");
     }
 
+error:
   /* release the proxy */
-  g_object_unref (G_OBJECT (dbus_gproxy));
+  if (G_LIKELY (dbus_gproxy != NULL))
+    g_object_unref (G_OBJECT (dbus_gproxy));
 
   /* close the module */
-  g_module_close (module);
+  if (G_LIKELY (module != NULL))
+    g_object_unref (G_OBJECT (module));
+  
+  if (G_UNLIKELY (error != NULL))
+    {
+      /* print the critical error */
+      g_critical ("Wrapper %s-%d: %s.", wrapper_name, opt_unique_id, error->message);
+      
+      /* cleanup */
+      g_error_free (error);
+    }
 
-  return EXIT_SUCCESS;
+  return succeed ? EXIT_SUCCESS : EXIT_FAILURE;
 }
diff --git a/wrapper/wrapper-module.c b/wrapper/wrapper-module.c
new file mode 100644
index 0000000..e625841
--- /dev/null
+++ b/wrapper/wrapper-module.c
@@ -0,0 +1,244 @@
+/* $Id$ */
+/*
+ * 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_STRING_H
+#include <string.h>
+#endif
+
+#include <wrapper/wrapper-module.h>
+
+
+
+static void     wrapper_module_dispose  (GObject     *object);
+static void     wrapper_module_finalize (GObject     *object);
+static gboolean wrapper_module_load     (GTypeModule *type_module);
+static void     wrapper_module_unload   (GTypeModule *type_module);
+
+
+
+struct _WrapperModuleClass
+{
+  GTypeModuleClass __parent__;
+};
+
+struct _WrapperModule
+{
+  GTypeModule __parent__;
+
+  /* module filename */
+  gchar               *filename;
+
+  /* module library */
+  GModule             *library;
+
+  /* construct function */
+  PluginConstructFunc  construct_func;
+
+  /* module type */
+  GType                type;
+};
+
+
+
+G_DEFINE_TYPE (WrapperModule, wrapper_module, G_TYPE_TYPE_MODULE)
+
+
+
+static void
+wrapper_module_class_init (WrapperModuleClass *klass)
+{
+  GObjectClass     *gobject_class;
+  GTypeModuleClass *gtype_module_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->dispose = wrapper_module_dispose;
+  gobject_class->finalize = wrapper_module_finalize;
+
+  gtype_module_class = G_TYPE_MODULE_CLASS (klass);
+  gtype_module_class->load = wrapper_module_load;
+  gtype_module_class->unload = wrapper_module_unload;
+}
+
+
+
+static void
+wrapper_module_init (WrapperModule *module)
+{
+  module->filename = NULL;
+  module->library = NULL;
+  module->construct_func = NULL;
+  module->type = G_TYPE_NONE;
+}
+
+
+
+static void
+wrapper_module_dispose (GObject *object)
+{
+  /* do nothing */
+}
+
+
+
+static void
+wrapper_module_finalize (GObject *object)
+{
+  WrapperModule *module = WRAPPER_MODULE (object);
+
+  /* cleanup */
+  g_free (module->filename);
+
+  (*G_OBJECT_CLASS (wrapper_module_parent_class)->finalize) (object);
+}
+
+
+
+static gboolean
+wrapper_module_load (GTypeModule *type_module)
+{
+  WrapperModule        *module = WRAPPER_MODULE (type_module);
+  PluginInitializeFunc  init_func;
+
+  /* open the module */
+  module->library = g_module_open (module->filename, G_MODULE_BIND_LOCAL);
+  if (G_UNLIKELY (module->library == NULL))
+    {
+      /* print error and leave */
+      g_critical ("Failed to load module \"%s\": %s.", module->filename,
+                  g_module_error ());
+      return FALSE;
+    }
+
+  /* try to link the contruct function */
+  if (g_module_symbol (module->library, "__xpp_initialize",
+                       (gpointer) &init_func))
+    {
+      /* initialize the plugin */
+      module->type = init_func (type_module, NULL);
+    }
+  else if (!g_module_symbol (module->library, "__xpp_construct",
+                             (gpointer) &module->construct_func))
+    {
+      /* print critical warning */
+      g_critical ("Module \"%s\" lacks a plugin register function.",
+                  module->filename);
+
+      /* unload */
+      wrapper_module_unload (type_module);
+
+      return FALSE;
+    }
+
+  /* no need to unload modules in the wrapper, can only cause problems */
+  g_module_make_resident (module->library);
+
+  return TRUE;
+}
+
+
+
+static void
+wrapper_module_unload (GTypeModule *type_module)
+{
+  WrapperModule *module = WRAPPER_MODULE (type_module);
+
+  /* close the module */
+  g_module_close (module->library);
+
+  /* reset plugin state */
+  module->library = NULL;
+  module->construct_func = NULL;
+  module->type = G_TYPE_NONE;
+}
+
+
+
+static void
+wrapper_module_plugin_destroyed (gpointer  user_data,
+                                 GObject  *where_the_plugin_was)
+{
+  /* unused the module */
+  g_type_module_unuse (G_TYPE_MODULE (user_data));
+}
+
+
+
+WrapperModule *
+wrapper_module_new (const gchar *filename)
+{
+  WrapperModule *module;
+  
+  module = g_object_new (WRAPPER_TYPE_MODULE, NULL);
+  module->filename = g_strdup (filename);
+  
+  return module;
+}
+
+
+
+GtkWidget *
+wrapper_module_new_provider (WrapperModule  *module,
+                             GdkScreen      *screen,
+                             const gchar    *name,
+                             gint            unique_id,
+                             const gchar    *display_name,
+                             gchar         **arguments)
+{
+  GtkWidget *plugin = NULL;
+
+  /* increase the module use count */
+  if (g_type_module_use (G_TYPE_MODULE (module)))
+    {
+      if (module->type != G_TYPE_NONE)
+        {g_message ("New plugin from object");
+          /* create the object */
+          plugin = g_object_new (module->type,
+                                 "name", name,
+                                 "unique-id", unique_id,
+                                 "display-name", display_name,
+                                 "arguments", arguments, NULL);
+        }
+      else if (module->construct_func != NULL)
+        {g_message ("New plugin from construct function");
+          /* create a new panel plugin */
+          plugin = GTK_WIDGET ((*module->construct_func) (name, unique_id,
+                                                          display_name,
+                                                          arguments, screen));
+        }
+
+      if (G_LIKELY (plugin != NULL))
+        {
+          /* weak ref the plugin to unload the module */
+          g_object_weak_ref (G_OBJECT (plugin),
+                             wrapper_module_plugin_destroyed,
+                             module);
+        }
+      else
+        {
+          /* unuse the module */
+          g_type_module_unuse (G_TYPE_MODULE (module));
+        }
+    }
+
+  return plugin;
+}
diff --git a/wrapper/wrapper-module.h b/wrapper/wrapper-module.h
new file mode 100644
index 0000000..5d28eb9
--- /dev/null
+++ b/wrapper/wrapper-module.h
@@ -0,0 +1,51 @@
+/* $Id$ */
+/*
+ * 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 __WRAPPER_MODULE_H__
+#define __WRAPPER_MODULE_H__
+
+#include <gtk/gtk.h>
+#include <libxfce4panel/xfce-panel-plugin-provider.h>
+
+G_BEGIN_DECLS
+
+typedef struct _WrapperModuleClass WrapperModuleClass;
+typedef struct _WrapperModule      WrapperModule;
+
+#define WRAPPER_TYPE_MODULE            (wrapper_module_get_type ())
+#define WRAPPER_MODULE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), WRAPPER_TYPE_MODULE, WrapperModule))
+#define WRAPPER_MODULE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), WRAPPER_TYPE_MODULE, WrapperModuleClass))
+#define WRAPPER_IS_MODULE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WRAPPER_TYPE_MODULE))
+#define WRAPPER_IS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), WRAPPER_TYPE_MODULE))
+#define WRAPPER_MODULE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), WRAPPER_TYPE_MODULE, WrapperModuleClass))
+
+GType          wrapper_module_get_type     (void) G_GNUC_CONST;
+
+WrapperModule *wrapper_module_new          (const gchar *filename) G_GNUC_MALLOC;
+
+GtkWidget     *wrapper_module_new_provider (WrapperModule  *module,
+                                            GdkScreen      *screen,
+                                            const gchar    *name,
+                                            gint            unique_id,
+                                            const gchar    *display_name,
+                                            gchar         **arguments) G_GNUC_MALLOC;
+
+G_END_DECLS
+
+#endif /* !__WRAPPER_MODULE_H__ */



More information about the Xfce4-commits mailing list