[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