[farsight2/master] Import simplified version of the Farsight1 plugin infrastructure

Olivier Crête olivier.crete at collabora.co.uk
Tue Dec 23 15:19:19 PST 2008


---
 configure.ac                         |    8 +
 docs/libs/farsight-libs-docs.sgml    |    4 +
 docs/libs/farsight-libs-sections.txt |   17 ++
 gst-libs/gst/farsight/Makefile.am    |    2 +
 gst-libs/gst/farsight/fs-plugin.c    |  326 ++++++++++++++++++++++++++++++++++
 gst-libs/gst/farsight/fs-plugin.h    |  113 ++++++++++++
 6 files changed, 470 insertions(+), 0 deletions(-)
 create mode 100644 gst-libs/gst/farsight/fs-plugin.c
 create mode 100644 gst-libs/gst/farsight/fs-plugin.h

diff --git a/configure.ac b/configure.ac
index ea7c2d0..59dbd2c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -131,6 +131,14 @@ AG_GST_CHECK_FEATURE(EXTERNAL, [enable building of plug-ins with external deps],
   ])
 AM_CONDITIONAL(BUILD_EXTERNAL, test "x$BUILD_EXTERNAL" = "xyes")
 
+dnl *** path for our local plugins ***
+
+dnl set the plugindir where plugins should be installed
+AS_AC_EXPAND(FS2_PLUGIN_PATH, ${libdir}/farsight-$FS2_MAJORMINOR)
+AC_SUBST(FS2_PLUGIN_PATH)
+AC_DEFINE_UNQUOTED(FS2_PLUGIN_PATH, "${FS2_PLUGIN_PATH}", [The path were plugins are installed and search by default])
+
+
 dnl *** checks for platform ***
 
 dnl * hardware/architecture *
diff --git a/docs/libs/farsight-libs-docs.sgml b/docs/libs/farsight-libs-docs.sgml
index fb9f12f..8af5a42 100644
--- a/docs/libs/farsight-libs-docs.sgml
+++ b/docs/libs/farsight-libs-docs.sgml
@@ -28,4 +28,8 @@
     <xi:include href="xml/fs-transmitter.xml"/>
     <xi:include href="xml/fs-stream-transmitter.xml"/>
   </chapter>
+  <chapter>
+    <title>Farsight Plugins infrastructure</title>
+    <xi:include href="xml/fs-plugin.xml"/>
+  </chapter>
 </book>
diff --git a/docs/libs/farsight-libs-sections.txt b/docs/libs/farsight-libs-sections.txt
index cc420eb..6d6f908 100644
--- a/docs/libs/farsight-libs-sections.txt
+++ b/docs/libs/farsight-libs-sections.txt
@@ -179,6 +179,23 @@ FsStreamTransmitterPrivate
 fs_stream_transmitter_get_type
 </SECTION>
 
+<SECTION>
+<FILE>fs-plugin</FILE>
+<TITLE>FsPlugin</TITLE>
+fs_plugin_create_valist
+FS_INIT_PLUGIN
+<SUBSECTION Standard>
+FsPlugin
+FsPluginClass
+FS_IS_PLUGIN
+FS_IS_PLUGIN_CLASS
+FS_PLUGIN
+FS_PLUGIN_CLASS
+FS_PLUGIN_GET_CLASS
+FS_TYPE_PLUGIN
+FsPluginPrivate
+fs_plugin_get_type
+</SECTION>
 
 <SECTION>
 <FILE>fs-marshal</FILE>
diff --git a/gst-libs/gst/farsight/Makefile.am b/gst-libs/gst/farsight/Makefile.am
index 96a8c9c..bbbed0f 100644
--- a/gst-libs/gst/farsight/Makefile.am
+++ b/gst-libs/gst/farsight/Makefile.am
@@ -10,6 +10,7 @@ libgstfarsightinclude_HEADERS = \
 		fs-conference-iface.h \
 		fs-transmitter.h \
 		fs-stream-transmitter.h \
+		fs-plugin.h \
 		fs-marshal.h
 
 lib_LTLIBRARIES = libgstfarsight- at GST_MAJORMINOR@.la
@@ -28,6 +29,7 @@ libgstfarsight_ at GST_MAJORMINOR@_la_SOURCES = \
 		fs-conference-iface.c \
 		fs-transmitter.c \
 		fs-stream-transmitter.c \
+		fs-plugin.c \
 		fs-marshal.c
 
 EXTRA_libgstfarsight_ at GST_MAJORMINOR@_la_SOURCES = fs-marshal.list
diff --git a/gst-libs/gst/farsight/fs-plugin.c b/gst-libs/gst/farsight/fs-plugin.c
new file mode 100644
index 0000000..84819e2
--- /dev/null
+++ b/gst-libs/gst/farsight/fs-plugin.c
@@ -0,0 +1,326 @@
+/*
+ * fs-plugin.c - Source for farsight plugin infrastructure
+ *
+ * Farsight Voice+Video library
+ * Copyright (c) 2005 INdT.
+ *   @author Andre Moreira Magalhaes <andre.magalhaes at indt.org.br>
+ * Copyright 2005-2007 Collabora Ltd.
+ * Copyright 2005-2007 Nokia Corp.
+ *   @author Rob Taylor <rob.taylor at collabora.co.uk>
+ *   @author: Olivier Crete <olivier.crete at collabora.co.uk>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser 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 "fs-plugin.h"
+
+#include <string.h>
+
+/**
+ * SECTION:fs-plugin
+ * @short_description: A class for defining Farsight plugins
+ *
+ * This class is a generic class to load GType plugins based on their name.
+ * With this simple class, you can only have one type per plugin.
+ */
+
+#define FS_PLUGIN_GET_PRIVATE(o)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_PLUGIN, FsPluginPrivate))
+
+static gboolean fs_plugin_load (GTypeModule *module);
+static void fs_plugin_unload (GTypeModule *module);
+
+
+static gchar **search_paths = NULL;
+
+GList *plugins = NULL;
+
+static GObjectClass *parent_class = NULL;
+
+struct _FsPluginPrivate
+{
+  GModule *handle;
+  gboolean disposed;
+};
+
+
+static void fs_plugin_class_init (FsPluginClass * klass);
+static void fs_plugin_init (FsPlugin * plugin);
+static void fs_plugin_dispose (GObject * object);
+static void fs_plugin_finalize (GObject * object);
+
+
+GType
+fs_plugin_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (FsPluginClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) fs_plugin_class_init,
+      NULL,
+      NULL,
+      sizeof (FsPlugin),
+      0,
+      (GInstanceInitFunc) fs_plugin_init
+    };
+
+    type = g_type_register_static (G_TYPE_TYPE_MODULE,
+        "FsPlugin", &info, 0);
+  }
+
+  return type;
+}
+
+static void
+fs_plugin_search_path_init ()
+{
+  const gchar *env;
+
+  if (search_paths)
+    return;
+
+  env = g_getenv ("FS_PLUGIN_PATH");
+
+  if (env == NULL)
+    {
+      search_paths = g_new (gchar *, 2);
+      search_paths[0] = g_strdup (FS2_PLUGIN_PATH);
+      search_paths[1] = NULL;
+      return;
+    }
+  else
+    {
+      gchar *path;
+
+      path = g_strjoin (":", env, FS2_PLUGIN_PATH, NULL);
+      search_paths = g_strsplit (path, ":", -1);
+      g_free (path);
+    }
+}
+
+static void
+fs_plugin_class_init (FsPluginClass * klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+  GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (klass);
+
+  gobject_class->dispose = fs_plugin_dispose;
+  gobject_class->finalize = fs_plugin_finalize;
+
+  parent_class = g_type_class_peek_parent(klass);
+
+  module_class->load = fs_plugin_load;
+  module_class->unload = fs_plugin_unload;
+
+  g_type_class_add_private (klass, sizeof (FsPluginPrivate));
+
+  /* Calling from class initializer so it only gets init'ed once */
+  fs_plugin_search_path_init ();
+}
+
+
+
+static void
+fs_plugin_init (FsPlugin * plugin)
+{
+  /* member init */
+  plugin->priv = FS_PLUGIN_GET_PRIVATE (plugin);
+  plugin->priv->handle = NULL;
+  plugin->priv->disposed = FALSE;
+}
+
+
+static void
+fs_plugin_dispose (GObject * object)
+{
+  FsPlugin *plugin = FS_PLUGIN (object);
+
+  if (plugin->priv->disposed) {
+    /* If dispose did already run, return. */
+    return;
+  }
+
+  /* Make sure dispose does not run twice. */
+  plugin->priv->disposed = TRUE;
+
+  parent_class->dispose (object);
+}
+
+static void
+fs_plugin_finalize (GObject * object)
+{
+  parent_class->finalize (object);
+}
+
+static gboolean fs_plugin_load (GTypeModule *module)
+{
+  FsPlugin *plugin = FS_PLUGIN(module);
+  gchar **search_path = NULL;
+  gchar *path=NULL;
+
+  gboolean (*fs_init_plugin) (FsPlugin *);
+
+  g_return_val_if_fail (plugin != NULL, FALSE);
+  g_return_val_if_fail (plugin->name != NULL && plugin->name[0] != '\0', FALSE);
+
+  for (search_path = search_paths; *search_path; search_path++) {
+    g_debug("looking for plugins in %s", *search_path);
+
+    path = g_module_build_path(*search_path, plugin->name);
+
+    plugin->priv->handle = g_module_open (path, G_MODULE_BIND_LOCAL);
+    g_debug ("opening module %s: %s\n", path,
+      (plugin->priv->handle != NULL) ? "succeeded" : g_module_error ());
+    g_free (path);
+
+    if (!plugin->priv->handle) {
+      continue;
+    }
+
+    else if (!g_module_symbol (plugin->priv->handle,
+                          "fs_init_plugin",
+                          (gpointer) & fs_init_plugin)) {
+      g_module_close (plugin->priv->handle);
+      plugin->priv->handle = NULL;
+      g_warning ("could not find init function in plugin\n");
+      continue;
+    }
+
+    else
+      break;
+  }
+
+  if (!plugin->priv->handle) {
+    return FALSE;
+  }
+
+
+  if (!fs_init_plugin (plugin)) {
+    /* TODO error handling (init error or no info defined) */
+    g_warning ("init error or no info defined");
+    goto err_close_module;
+  }
+
+  return TRUE;
+
+ err_close_module:
+  g_module_close (plugin->priv->handle);
+  return FALSE;
+
+}
+
+static void
+fs_plugin_unload (GTypeModule *module)
+{
+  FsPlugin *plugin = NULL;
+
+  g_return_if_fail (module != NULL);
+
+  plugin = FS_PLUGIN (module);
+
+  g_debug("Unloading plugin %s", plugin->name);
+
+  if (plugin->unload != NULL)
+    plugin->unload (plugin);
+
+  if (plugin->priv->handle != NULL)
+    g_module_close (plugin->priv->handle);
+}
+
+static FsPlugin *
+fs_plugin_get_by_name (const gchar * name, const gchar * type_suffix)
+{
+  gchar *fullname;
+  FsPlugin *plugin = NULL;
+  GList *plugin_item;
+
+  g_return_val_if_fail (name != NULL, NULL);
+  g_return_val_if_fail (type_suffix != NULL, NULL);
+
+  fullname = g_strdup_printf ("%s-%s",name,type_suffix);
+
+  for (plugin_item = plugins;
+       plugin_item;
+       plugin_item = g_list_next(plugin_item))  {
+    plugin = plugin_item->data;
+    if (plugin->name == NULL || plugin->name[0] == 0)
+      continue;
+    if (!strcmp (plugin->name, fullname)) {
+      break;
+    }
+
+  }
+  g_free (fullname);
+
+  if (plugin_item)
+    return plugin;
+
+  return NULL;
+}
+
+
+/**
+ * fs_plugin_create_valist:
+ * @name: The name of the plugin to load
+ * @type_suffix: The type of plugin to load (normally "transmitter")
+ * @first_property_name: The name of the first property to be set on the
+ *   object
+ * @var_args: The rest of the arguments
+ *
+ * Loads the appropriate plugin if necessary and creates a GObject of
+ * the requested type
+ *
+ * Returns: The object created (or NULL if there is an error)
+ **/
+
+GObject *
+fs_plugin_create_valist (const gchar *name, const gchar *type_suffix,
+  const gchar *first_property_name, va_list var_args)
+{
+  GObject *object;
+  FsPlugin *plugin;
+
+  g_return_val_if_fail (name != NULL, NULL);
+  g_return_val_if_fail (type_suffix != NULL, NULL);
+
+  plugin = fs_plugin_get_by_name (name, type_suffix);
+
+  if (!plugin) {
+    plugin = g_object_new (FS_TYPE_PLUGIN, NULL);
+    if (!plugin)
+      return NULL;
+    plugin->name = g_strdup_printf ("%s-%s",name,type_suffix);
+    g_type_module_set_name (G_TYPE_MODULE (plugin), plugin->name);
+    plugins = g_list_append(plugins, plugin);
+  }
+
+  if (!g_type_module_use (G_TYPE_MODULE (plugin)))
+    return NULL;
+
+  object = g_object_new_valist (plugin->type, first_property_name, var_args);
+
+  g_type_module_unuse(G_TYPE_MODULE(plugin));
+
+  return object;
+}
diff --git a/gst-libs/gst/farsight/fs-plugin.h b/gst-libs/gst/farsight/fs-plugin.h
new file mode 100644
index 0000000..20820c7
--- /dev/null
+++ b/gst-libs/gst/farsight/fs-plugin.h
@@ -0,0 +1,113 @@
+/*
+ * fs-plugin.h - Header for farsight plugin infrastructure
+ *
+ * Farsight Voice+Video library
+ * Copyright (c) 2005 INdT.
+ *   @author: Andre Moreira Magalhaes <andre.magalhaes at indt.org.br>
+ * Copyright (c) 2005-2007 Collabora Ltd.
+ * Copyright (c) 2005-2007 Nokia Corp.
+ *   @author: Rob Taylor <rob.taylor at collabora.co.uk>
+ *   @author: Olivier Crete <olivier.crete at collabora.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser 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 __FS_PLUGIN_H__
+#define __FS_PLUGIN_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gmodule.h>
+#include <gst/gst.h>
+
+#include <stdarg.h>
+
+G_BEGIN_DECLS
+
+
+/* TYPE MACROS */
+#define FS_TYPE_PLUGIN \
+  (fs_plugin_get_type())
+#define FS_PLUGIN(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_PLUGIN, FsPlugin))
+#define FS_PLUGIN_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_PLUGIN, FsPluginClass))
+#define FS_IS_PLUGIN(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_PLUGIN))
+#define FS_IS_PLUGIN_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_PLUGIN))
+#define FS_PLUGIN_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_PLUGIN, FsPluginClass))
+
+typedef struct _FsPlugin FsPlugin;
+typedef struct _FsPluginClass FsPluginClass;
+typedef struct _FsPluginPrivate FsPluginPrivate;
+
+struct _FsPlugin
+{
+  GTypeModule parent;
+
+  /*< private >*/
+
+  GType  type;
+
+  gchar *name;			/* name of the plugin */
+
+  /* callbacks */
+  /* This function is called when the last instance of the plugin is
+   * unloaded. It can be useful to deallocate resources common for all
+   * instances of the plugin. */
+  void (*unload) (FsPlugin * plugin);
+
+  FsPluginPrivate *priv;
+};
+
+struct _FsPluginClass
+{
+  GTypeModuleClass parent_class;
+
+};
+
+GType fs_plugin_get_type (void);
+
+
+GObject *fs_plugin_create_valist (const gchar *name,
+                                  const gchar *type_suffix,
+                                  const gchar *first_property_name,
+                                  va_list var_args);
+
+
+/**
+ * FS_INIT_PLUGIN:
+ * @type: The #GType that this plugin provides
+ * @unload: a function of type void (*unload) (FsPlugin * plugin) to be called
+ * when the plugin is unloaded
+ *
+ * This macro is used to declare Farsight plugins and must be used once
+ * in any farsight plugin.
+ */
+
+#define FS_INIT_PLUGIN(type,unload)                             \
+    G_MODULE_EXPORT GType fs_init_plugin(FsPlugin *plugin) {    \
+      plugin->name = name;                                      \
+      plugin->type = type;                                      \
+      plugin->unload = unload;                                  \
+      return type;                                              \
+    }
+
+
+G_END_DECLS
+#endif
+
-- 
1.5.6.5




More information about the farsight-commits mailing list