Add a hook system for modules
authorMikko Rasa <mikko.rasa@movial.fi>
Tue, 28 Oct 2008 12:52:43 +0000 (14:52 +0200)
committerMikko Rasa <mikko.rasa@movial.fi>
Tue, 28 Oct 2008 12:52:43 +0000 (14:52 +0200)
Make modules global to a backend instead of component-specific
Refactor module registration to only create modules when needed
Add (still incomplete) GST-OMX QoS bridge module

13 files changed:
.gitignore
Makefile.am
modules/Makefile.am
modules/gstomx-qos-bridge.c [new file with mode: 0644]
src/octopus-backend-gst.c
src/octopus-backend-gst.h
src/octopus-backend.c
src/octopus-backend.h
src/octopus-marshals.spec
src/octopus-module-manager.c
src/octopus-module-manager.h
src/octopus-module.c
src/octopus-module.h

index ee338ca..f79d73c 100644 (file)
@@ -1,14 +1,17 @@
+*.la
+*.lo
 *.o
+.libs
 data/com.ixs.octopus.service
 data/octopus.pc
+player/octopus-dbus.h
+player/octopus-marshals.c
+player/octopus-marshals.h
+player/octopus-player
 src/octopus
 src/octopus-glue.h
-src/octopus-marshals.h
 src/octopus-marshals.c
-player/octopus-player
-player/octopus-dbus.h
-player/octopus-marshals.h
-player/octopus-marshals.c
+src/octopus-marshals.h
 
 # Matrix stuff
 meta/
index d970737..7c6715a 100644 (file)
@@ -2,6 +2,6 @@ if PLAYER
 PLAYER_DIR = player
 endif
 
-SUBDIRS = src data $(PLAYER_DIR)
+SUBDIRS = src data modules $(PLAYER_DIR)
 
 EXTRA_DIST = autogen.sh
index e69de29..3c3e0f6 100644 (file)
@@ -0,0 +1,7 @@
+pkglib_LTLIBRARIES = gstomx_qos_bridge.la
+
+gst_CFLAGS = $(glib_CFLAGS) $(gstreamer_CFLAGS)
+
+gstomx_qos_bridge_la_SOURCES = gstomx-qos-bridge.c
+gstomx_qos_bridge_la_CFLAGS = $(gst_CFLAGS)
+gstomx_qos_bridge_la_LDFLAGS = -module
diff --git a/modules/gstomx-qos-bridge.c b/modules/gstomx-qos-bridge.c
new file mode 100644 (file)
index 0000000..4d6661e
--- /dev/null
@@ -0,0 +1,169 @@
+#include "src/octopus-module.h"
+#include "src/octopus-module-manager.h"
+#include "src/octopus-backend-gst.h"
+
+#define GSTOMX_QOS_BRIDGE_TYPE             \
+        (gstomx_qos_bridge_get_type())
+#define GSTOMX_QOS_BRIDGE(obj)             \
+        (G_TYPE_CHECK_INSTANCE_CAST((obj), GSTOMX_QOS_BRIDGE_TYPE, GstOmxQosBridge))
+
+typedef struct _GstOmxQosBridge      GstOmxQosBridge;
+typedef struct _GstOmxQosBridgeClass GstOmxQosBridgeClass;
+
+struct _GstOmxQosBridge
+{
+  OctopusModule parent;
+};
+
+struct _GstOmxQosBridgeClass
+{
+  OctopusModuleClass parent;
+};
+
+GType
+gstomx_qos_bridge_get_type(void);
+static void
+backend_set(OctopusModule *module);
+static void
+init_hook(OctopusBackendGst *backend,
+          OctopusRoute      *route,
+          gpointer          user_data);
+static gint
+play_hook(OctopusBackendGst *backend,
+          OctopusRoute      *route,
+          gpointer          user_data);
+static void
+bus_watch(GstBus     *bus,
+          GstMessage *msg,
+          gpointer   user_data);
+void
+octopus_module_init(OctopusModuleManager *manager);
+
+G_DEFINE_TYPE(GstOmxQosBridge, gstomx_qos_bridge, OCTOPUS_TYPE_MODULE)
+
+static void
+gstomx_qos_bridge_class_init(GstOmxQosBridgeClass *klass)
+{
+  OctopusModuleClass *module_class;
+
+  module_class = OCTOPUS_MODULE_CLASS(klass);
+
+  module_class->backend_set = backend_set;
+}
+
+static void
+gstomx_qos_bridge_init(GstOmxQosBridge *bridge)
+{
+}
+
+/*
+ * OctopusModule implementation
+ */
+
+static void
+backend_set(OctopusModule *module)
+{
+  g_assert(OCTOPUS_IS_BACKEND_GST(module->backend));
+  g_signal_connect(G_OBJECT(module->backend), "hook-init", G_CALLBACK(init_hook), NULL);
+  g_signal_connect(G_OBJECT(module->backend), "hook-play", G_CALLBACK(play_hook), NULL);
+}
+
+static void
+init_hook(OctopusBackendGst *backend,
+          OctopusRoute      *route,
+          gpointer          user_data)
+{
+  OctopusRouteDataGst *data;
+  GstBus              *bus;
+
+  data = (OctopusRouteDataGst *)g_object_get_data(G_OBJECT(route), "data");
+  bus = gst_pipeline_get_bus(GST_PIPELINE(data->pipeline));
+  g_signal_connect(G_OBJECT(bus), "message", G_CALLBACK(bus_watch), route);
+}
+
+static gint
+play_hook(OctopusBackendGst *backend,
+          OctopusRoute      *route,
+          gpointer          user_data)
+{
+  OctopusRouteDataGst *data;
+
+  data = (OctopusRouteDataGst *)g_object_get_data(G_OBJECT(route), "data");
+  if(!data->ready) {
+    octopus_route_pause(route);
+    return 1;
+  }
+
+  return 0;
+}
+
+/*
+ * Private functions
+ */
+
+static gboolean
+check_resources(OctopusRoute *route)
+{
+  OctopusRouteDataGst *data;
+  GstIterator         *iter;
+  gpointer            elem;
+
+  data = (OctopusRouteDataGst *)g_object_get_data(G_OBJECT(route), "data");
+  iter = gst_bin_iterate_recurse(GST_BIN(data->pipeline));
+  while(gst_iterator_next(iter, &elem) == GST_ITERATOR_OK) {
+    if(g_object_class_find_property(G_OBJECT_GET_CLASS(elem), "omx-handle")) {
+      gpointer omx_handle;
+      gchar    *omx_comp_name;
+
+      g_object_get(G_OBJECT(elem), "omx-handle", &omx_handle, "component-name", &omx_comp_name, NULL);
+      g_debug("OpenMAX component: %s (%p)", omx_comp_name, omx_handle);
+      g_free(omx_comp_name);
+    }
+  }
+  gst_iterator_free(iter);
+
+  return rand()%2;
+}
+
+static void
+bus_watch(GstBus     *bus,
+          GstMessage *msg,
+          gpointer   user_data)
+{
+  OctopusRoute        *route;
+  OctopusRouteDataGst *data;
+  
+  route = OCTOPUS_ROUTE(user_data);
+  data = (OctopusRouteDataGst *)g_object_get_data(G_OBJECT(route), "data");
+  
+  if(GST_MESSAGE_TYPE(msg) == GST_MESSAGE_STATE_CHANGED)
+  {
+    GstElement *elem;
+    GstState   previous, state, pending;
+
+    elem = GST_ELEMENT(GST_MESSAGE_SRC(msg));
+    gst_message_parse_state_changed(msg, &previous, &state, &pending);
+    if(elem == data->pipeline && previous == GST_STATE_READY && state == GST_STATE_PAUSED && pending == GST_STATE_VOID_PENDING)
+    {
+      if(check_resources(route)) {
+        g_debug("Resources acquired, playback is GO");
+        octopus_route_play(route);
+      } else {
+        g_debug("No resources available, stopping the route");
+        octopus_route_stop(route);
+      }
+    }
+  }
+}
+
+/*
+ * Exported functions
+ */
+
+void
+octopus_module_init(OctopusModuleManager *manager)
+{
+  octopus_module_manager_register_module(manager, "gstomx_qos_bridge", GSTOMX_QOS_BRIDGE_TYPE);
+}
+
+// vim: filetype=c:expandtab:shiftwidth=2:tabstop=2:softtabstop=2
index e10ad1c..b86d5f8 100644 (file)
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  */
 #include <string.h>
-#include <gst/gst.h>
 #include <gst/interfaces/xoverlay.h>
 #include "octopus-backend-gst.h"
 #include "octopus-module.h"
 #include "octopus-module-manager.h"
 #include "octopus-route.h"
+#include "octopus-marshals.h"
 
-typedef struct _RouteDataGst RouteDataGst;
-
-struct _RouteDataGst
+enum
 {
-  GstElement *pipeline;
-  GstElement *fakesink;
-  gboolean   ready;
-  guint      timeout_tag;
+  HOOK_INIT,
+  HOOK_PLAY,
+  N_HOOKS
 };
 
+typedef OctopusRouteDataGst RouteDataGst;
+
+static gboolean
+hook_accumulator(GSignalInvocationHint *ihint,
+                 GValue                *ret_accu,
+                 const GValue          *handler_ret,
+                 gpointer              data);
 static gboolean
 validate_component(OctopusBackend   *backend,
                    OctopusComponent *comp);
@@ -82,13 +86,15 @@ pad_removed(GstElement *elem,
 static void
 no_more_pads(GstElement *elem,
              gpointer   user_data);
-static gboolean
+static void
 bus_watch(GstBus     *bus,
           GstMessage *msg,
           gpointer   user_data);
 static gboolean
 position_timer(gpointer);
 
+static guint hooks[N_HOOKS];
+
 G_DEFINE_TYPE(OctopusBackendGst, octopus_backend_gst, OCTOPUS_TYPE_BACKEND)
 
 static void
@@ -105,6 +111,26 @@ octopus_backend_gst_class_init(OctopusBackendGstClass *klass)
   backend->play_route = play_route;
   backend->pause_route = pause_route;
   backend->stop_route = stop_route;
+
+  hooks[HOOK_INIT] = 
+    g_signal_new ("hook-init",
+                  G_TYPE_FROM_CLASS(klass),
+                  G_SIGNAL_NO_RECURSE,
+                  0,
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__POINTER,
+                  G_TYPE_NONE,
+                  1, G_TYPE_POINTER);
+
+  hooks[HOOK_PLAY] = 
+    g_signal_new ("hook-play",
+                  G_TYPE_FROM_CLASS(klass),
+                  G_SIGNAL_NO_RECURSE,
+                  0,
+                  hook_accumulator, NULL,
+                  g_cclosure_user_marshal_INT__POINTER,
+                  G_TYPE_INT,
+                  1, G_TYPE_POINTER);
 }
 
 static void
@@ -124,6 +150,28 @@ octopus_backend_gst_init(OctopusBackendGst *backend)
  */
 
 static gboolean
+hook_accumulator(GSignalInvocationHint *ihint,
+                 GValue                *ret_accu,
+                 const GValue          *handler_ret,
+                 gpointer              data)
+{
+  gint old_ret;
+  gint ret;
+
+  ret = g_value_get_int(handler_ret);
+  if(ret<0) {
+    g_value_set_int(ret_accu, -1);
+    return FALSE;
+  }
+
+  old_ret = g_value_get_int(ret_accu);
+  if(ret>old_ret)
+    g_value_set_int(ret_accu, ret);
+
+  return TRUE;
+}
+
+static gboolean
 can_maybe_sink_caps(GstElementFactory *factory,
                     GstCaps *caps)
 {
@@ -218,7 +266,10 @@ init_route(OctopusBackend *backend,
   g_signal_connect(route, "endpoint-changed", G_CALLBACK(route_endpoint_changed), 0);
 
   bus = gst_pipeline_get_bus(GST_PIPELINE(data->pipeline));
-  gst_bus_add_watch(bus, bus_watch, route);
+  gst_bus_add_signal_watch(bus);
+  g_signal_connect(G_OBJECT(bus), "message", G_CALLBACK(bus_watch), route);
+
+  g_signal_emit(backend, hooks[HOOK_INIT], 0, route);
 
   return TRUE;
 }
@@ -241,8 +292,14 @@ play_route(OctopusBackend *backend,
 {
   RouteDataGst         *data;
   GstStateChangeReturn ret;
+  gint                 hook_ret;
 
   data = (RouteDataGst *)g_object_get_data(G_OBJECT(route), "data");
+
+  g_signal_emit(backend, hooks[HOOK_PLAY], 0, route, &hook_ret);
+  if(hook_ret)
+    return hook_ret > 0;
+
   if(!data->ready && !data->fakesink) {
     /* Keep the pipeline in an async state change while building it */
     data->fakesink = gst_element_factory_make("fakesink", NULL);
@@ -746,15 +803,17 @@ no_more_pads(GstElement *elem,
 
   route = OCTOPUS_ROUTE(user_data);
   data = (RouteDataGst *)g_object_get_data(G_OBJECT(route), "data");
+
+  data->ready = TRUE;
+
   if(data->fakesink) {
     gst_element_set_state(data->fakesink, GST_STATE_NULL);
     gst_bin_remove(GST_BIN(data->pipeline), data->fakesink);
     data->fakesink = NULL;
-    data->ready = TRUE;
   }
 }
 
-static gboolean
+static void
 bus_watch(GstBus     *bus,
           GstMessage *msg,
           gpointer   user_data)
@@ -786,9 +845,9 @@ bus_watch(GstBus     *bus,
   case GST_MESSAGE_STATE_CHANGED: {
     GstElement *elem;
     gchar      *name;
+    GstState   previous, state, pending;
 
-    GstState previous, state, pending;
-    gst_message_parse_state_changed (msg, &previous, &state, &pending);
+    gst_message_parse_state_changed(msg, &previous, &state, &pending);
     elem = GST_ELEMENT(GST_MESSAGE_SRC(msg));
     name = gst_element_get_name(elem);
     g_debug("GST STATE CHANGED: %s %s->%s, pending %s", name, gst_element_state_get_name(previous), gst_element_state_get_name(state), gst_element_state_get_name(pending));
@@ -804,11 +863,9 @@ bus_watch(GstBus     *bus,
     }
     break; }
 
-  default:;
+  default:
     g_debug("Unhandled GST message of type %d", GST_MESSAGE_TYPE(msg));
   }
-
-  return TRUE;
 }
 
 static gboolean
index b7213a7..c93b19c 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef _OCTOPUS_BACKEND_GST_H_
 #define _OCTOPUS_BACKEND_GST_H_
 
+#include <gst/gst.h>
 #include "octopus-backend.h"
 
 #define OCTOPUS_TYPE_BACKEND_GST             \
@@ -38,6 +39,7 @@
 typedef struct _OctopusBackendGst        OctopusBackendGst;
 typedef struct _OctopusBackendGstClass   OctopusBackendGstClass;
 typedef struct _OctopusBackendGstPrivate OctopusBackendGstPrivate;
+typedef struct _OctopusRouteDataGst      OctopusRouteDataGst;
 
 struct _OctopusBackendGst
 {
@@ -50,6 +52,15 @@ struct _OctopusBackendGstClass
   OctopusBackendClass parent;
 };
 
+struct _OctopusRouteDataGst
+{
+  GstElement *pipeline;
+  GstElement *fakesink;
+  gboolean   ready;
+  guint      timeout_tag;
+  GSList     *modules;
+};
+
 GType
 octopus_backend_gst_get_type(void);
 
index 70e0ad0..b3bcfeb 100644 (file)
@@ -32,6 +32,8 @@ enum
 };
 
 static void
+octopus_backend_finalize(GObject *object);
+static void
 set_property(GObject      *object,
              guint        prop_id,
              const GValue *value,
@@ -51,6 +53,7 @@ octopus_backend_class_init(OctopusBackendClass *klass)
 
   gobject_class = G_OBJECT_CLASS(klass);
 
+  gobject_class->finalize = octopus_backend_finalize;
   gobject_class->set_property = set_property;
   gobject_class->get_property = get_property;
 
@@ -72,6 +75,18 @@ octopus_backend_init(OctopusBackend *backend)
 }
 
 static void
+octopus_backend_finalize(GObject *object)
+{
+  OctopusBackend *backend;
+  GSList         *iter;
+
+  backend = OCTOPUS_BACKEND(object);
+
+  for(iter = backend->modules; iter; iter = iter->next)
+    g_object_unref((OctopusModule *)iter->data);
+}
+
+static void
 set_property(GObject      *object,
              guint        prop_id,
              const GValue *value,
@@ -205,14 +220,13 @@ octopus_backend_load_components(OctopusBackend *backend,
       component->name = g_strdup(parts[1]);
       new_comps = g_slist_prepend(new_comps, component);
       element = NULL;
+    } else if(!strcmp(parts[0], "module")) {
+      backend->modules = g_slist_append(backend->modules,
+        octopus_module_manager_create_module(backend->module_manager, parts[1], backend));
     } else if(component && !strcmp(parts[0], "element")) {
       element = g_new0(OctopusElement, 1);
       element->name = g_strdup(parts[1]);
       component->elements = g_slist_append(component->elements, element);
-    } else if(component && !strcmp(parts[0], "module")) {
-      element = g_new0(OctopusElement, 1);
-      element->name = g_strconcat("?", parts[1], NULL);
-      component->elements = g_slist_append(component->elements, element);
     } else if(component && !strcmp(parts[0], "dynamic")) {
       component->dynamic = TRUE;
     } else if(component && !strcmp(parts[0], "priority")) {
index 5374654..46d0516 100644 (file)
@@ -59,6 +59,7 @@ struct _OctopusBackend {
   gchar                        *name;
   struct _OctopusModuleManager *module_manager;
   GSList                       *components;
+  GSList                       *modules;
 };
 
 struct _OctopusBackendClass {
index a5365a4..cc72cd7 100644 (file)
@@ -1,3 +1,4 @@
 VOID:UINT,UINT
 VOID:UINT,STRING
 VOID:UINT,UINT,UINT
+INT:POINTER
index 79325bf..163c9a7 100644 (file)
 
 #include "octopus-module-manager.h"
 
+typedef struct _OctopusModuleInfo OctopusModuleInfo;
+
+struct _OctopusModuleInfo {
+  gchar *name;
+  GType type;
+};
+
 struct _OctopusModuleManagerPrivate {
   GSList *modules;
 };
@@ -35,6 +42,8 @@ static void
 octopus_module_manager_init      (OctopusModuleManager *module_manager);
 static void
 octopus_module_manager_finalize  (GObject *object);
+static void
+free_module_info(OctopusModuleInfo *info);
 static gboolean
 load_modules_from_directory      (OctopusModuleManager *object,
                                   const gchar          *dir_name);
@@ -78,12 +87,23 @@ octopus_module_manager_finalize(GObject *object)
   priv = manager->priv;
 
   for(iter = priv->modules; iter; iter = iter->next)
-    g_object_unref(iter->data);
+    free_module_info((OctopusModuleInfo *)iter->data);
   g_slist_free(priv->modules);
   g_free(priv);
 }
 
 /*
+ * Helper functions
+ */
+
+static void
+free_module_info(OctopusModuleInfo *info)
+{
+  g_free(info->name);
+  g_free(info);
+}
+
+/*
  * Private functions
  */
 
@@ -100,9 +120,7 @@ load_module (OctopusModuleManager *module_manager,
 
     if((gmod = g_module_open(filename, 0))
       && g_module_symbol(gmod, "octopus_module_init", (gpointer)&init)) {
-      if(init(module_manager)) {
-        g_debug("Module '%s' successfully loaded", filename);
-      } else {
+      if(!init(module_manager)) {
         g_warning("Module '%s' failed to initialize", filename);
         g_module_close(gmod);
       }
@@ -140,7 +158,9 @@ load_modules_from_directory (OctopusModuleManager *module_manager,
   info = gnome_vfs_file_info_new();
 
   while((result = gnome_vfs_directory_read_next(handle, info)) == GNOME_VFS_OK) {
-    if(info->type & GNOME_VFS_FILE_TYPE_REGULAR) {
+    if((info->type & GNOME_VFS_FILE_TYPE_REGULAR)
+        && g_str_has_suffix(info->name, ".so"))
+    {
       gchar *filename;
       filename = g_strconcat(dir_name, info->name, NULL);
       load_module(module_manager, filename);
@@ -159,28 +179,36 @@ load_modules_from_directory (OctopusModuleManager *module_manager,
 
 void
 octopus_module_manager_register_module(OctopusModuleManager *manager,
-                                       OctopusModule        *module)
+                                       const gchar          *name,
+                                       GType                module_type)
 {
-  manager->priv->modules = g_slist_prepend(manager->priv->modules, module);
+  OctopusModuleInfo *info;
+
+  info = g_new0(OctopusModuleInfo, 1);
+  info->name = g_strdup(name);
+  info->type = module_type;
+  manager->priv->modules = g_slist_prepend(manager->priv->modules, info);
+
+  g_debug("Registered module '%s'", name);
 }
 
 OctopusModule *
-octopus_module_manager_get_module(OctopusModuleManager *manager,
-                                  const gchar          *name)
+octopus_module_manager_create_module(OctopusModuleManager *manager,
+                                     const gchar          *name,
+                                     OctopusBackend       *backend)
 {
-  GSList        *iter;
-  OctopusModule *module = NULL;
+  GSList *iter;
+
+  g_debug("Creating module '%s'", name);
 
-  for(iter = manager->priv->modules; (!module && iter); iter = iter->next) {
-    gchar *mod_name;
+  for(iter = manager->priv->modules; iter; iter = iter->next) {
+    OctopusModuleInfo *info = (OctopusModuleInfo *)iter->data;
 
-    g_object_get(G_OBJECT(iter->data), "name", &mod_name, NULL);
-    if(!strcmp(mod_name, name))
-      module = (OctopusModule *)iter->data;
-    g_free(mod_name);
+    if(!strcmp(info->name, name))
+      return g_object_new(info->type, "backend", backend, NULL);
   }
 
-  return module;
+  return NULL;
 }
 
 
index e5f3c6a..dcdb6ea 100644 (file)
@@ -62,10 +62,12 @@ octopus_module_manager_get_type       (void);
 
 void
 octopus_module_manager_register_module(OctopusModuleManager *manager,
-                                       OctopusModule        *module);
+                                       const gchar          *name,
+                                       GType                module_type);
 OctopusModule *
-octopus_module_manager_get_module     (OctopusModuleManager *manager,
-                                       const gchar          *name);
+octopus_module_manager_create_module  (OctopusModuleManager *manager,
+                                       const gchar          *name,
+                                       OctopusBackend       *backend);
 
 G_END_DECLS
 
index 82273e9..1d3f9b7 100644 (file)
  */
 #include "octopus-module.h"
 
+enum
+{
+       PROP_BACKEND = 1
+};
+
+static void
+set_property(GObject      *object,
+             guint        prop_id,
+             const GValue *value,
+             GParamSpec   *pspec);
 static void 
 get_property(GObject    *object,
              guint      prop_id,
@@ -34,16 +44,48 @@ octopus_module_class_init(OctopusModuleClass *klass)
 
   gobject_class = G_OBJECT_CLASS(klass);
 
+  gobject_class->set_property = set_property;
   gobject_class->get_property = get_property;
+
+  g_object_class_install_property(gobject_class, PROP_BACKEND,
+    g_param_spec_pointer("backend", "Backend", "",
+      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
 octopus_module_init(OctopusModule *module)
 {
-       module->name = NULL;
+  module->backend = NULL;
 }
 
-static void 
+static void
+set_property(GObject      *object,
+             guint        prop_id,
+             const GValue *value,
+             GParamSpec   *pspec)
+{
+  OctopusModule *module;
+
+  g_assert(OCTOPUS_IS_MODULE(object));
+  module = (OctopusModule *)object;
+
+  switch(prop_id)
+  {
+  case PROP_BACKEND: {
+    OctopusModuleClass *klass;
+
+    module->backend = OCTOPUS_BACKEND(g_value_get_pointer(value));
+
+    klass = OCTOPUS_MODULE_GET_CLASS(module);
+    if(klass->backend_set)
+      klass->backend_set(module);
+    } break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+  };
+}
+
+static void
 get_property(GObject    *object,
              guint      prop_id,
              GValue     *value,
@@ -56,13 +98,12 @@ get_property(GObject    *object,
 
   switch(prop_id)
   {
+  case PROP_BACKEND:
+    g_value_set_pointer(value, module->backend);
+    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
   };
 }
 
-/*
- * Public API
- */
-
-/* To be done */
+// vim: filetype=c:expandtab:shiftwidth=2:tabstop=2:softtabstop=2
index 6f3320b..93ef495 100644 (file)
@@ -20,7 +20,7 @@
 #ifndef _OCTOPUS_MODULE_H_
 #define _OCTOPUS_MODULE_H_
 
-#include "octopus-route.h"
+#include "octopus-backend.h"
 
 #define OCTOPUS_TYPE_MODULE             \
         (octopus_module_get_type())
@@ -39,19 +39,19 @@ typedef struct _OctopusModule        OctopusModule;
 typedef struct _OctopusModuleClass   OctopusModuleClass;
 
 struct _OctopusModule {
-  GObject parent;
+  GObject        parent;
 
-  gchar   *name;
+  OctopusBackend *backend;
 };
 
 struct _OctopusModuleClass {
   GObjectClass parent;
+
+  void (*backend_set)(OctopusModule *);
 };
 
 GType
-octopus_module_get_type         (void);
-
-/* Module API TBD */
+octopus_module_get_type      (void);
 
 #endif