[clutter/wip/actor-content: 3/33] Add a module-based ImageLoader class
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/wip/actor-content: 3/33] Add a module-based ImageLoader class
- Date: Wed, 18 May 2011 11:10:40 +0000 (UTC)
commit 54826e8945f8546b82ad05c8b63b3a0e53949046
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Mon Dec 6 17:39:56 2010 +0000
Add a module-based ImageLoader class
The ImageLoader is an abstract class that can be implemented through GIO
extension points.
clutter/Makefile.am | 14 ++
clutter/clutter-image-loader.c | 153 +++++++++++++++++++++
clutter/clutter-image-loader.h | 101 ++++++++++++++
clutter/clutter-main.c | 67 +++++++++
clutter/clutter-private.h | 2 +
clutter/clutter.h | 1 +
clutter/image-loaders/clutter-image-loader-null.c | 68 +++++++++
clutter/image-loaders/clutter-image-loader-null.h | 19 +++
configure.ac | 7 +-
9 files changed, 427 insertions(+), 5 deletions(-)
---
diff --git a/clutter/Makefile.am b/clutter/Makefile.am
index 53e4ab6..5d24f6e 100644
--- a/clutter/Makefile.am
+++ b/clutter/Makefile.am
@@ -18,6 +18,7 @@ INCLUDES = \
-I$(top_srcdir)/clutter/$(CLUTTER_WINSYS_BASE) \
-I$(top_srcdir)/clutter/cally \
-I$(top_srcdir)/clutter/evdev \
+ -I$(top_srcdir)/clutter/image-loaders \
-I$(top_builddir) \
-I$(top_builddir)/clutter \
$(NULL)
@@ -97,6 +98,7 @@ source_h = \
$(srcdir)/clutter-flow-layout.h \
$(srcdir)/clutter-frame-source.h \
$(srcdir)/clutter-group.h \
+ $(srcdir)/clutter-image-loader.h \
$(srcdir)/clutter-image.h \
$(srcdir)/clutter-input-device.h \
$(srcdir)/clutter-interval.h \
@@ -181,6 +183,7 @@ source_c = \
$(srcdir)/clutter-flow-layout.c \
$(srcdir)/clutter-frame-source.c \
$(srcdir)/clutter-group.c \
+ $(srcdir)/clutter-image-loader.c \
$(srcdir)/clutter-image.c \
$(srcdir)/clutter-input-device.c \
$(srcdir)/clutter-interval.c \
@@ -583,6 +586,15 @@ cally_include_HEADERS = $(cally_sources_h)
pc_files += cally/cally-$(CLUTTER_API_VERSION).pc
EXTRA_DIST += cally/cally.pc.in
+# image loader backends
+imageloader_sources_c = \
+ $(srcdir)/image-loaders/clutter-image-loader-null.c \
+ $(NULL)
+
+imageloader_sources_h = \
+ $(srcdir)/image-loaders/clutter-image-loader-null.h \
+ $(NULL)
+
# general build rules:
# you should not need to modify anything below this point
@@ -627,6 +639,8 @@ libclutter_ CLUTTER_SONAME_INFIX@_ CLUTTER_API_VERSION@_la_SOURCES = \
$(backend_source_h) \
$(backend_source_c_priv) \
$(backend_source_h_priv) \
+ $(imageloader_sources_c) \
+ $(imageloader_sources_h) \
$(source_c) \
$(source_h) \
$(source_c_priv) \
diff --git a/clutter/clutter-image-loader.c b/clutter/clutter-image-loader.c
new file mode 100644
index 0000000..287ddae
--- /dev/null
+++ b/clutter/clutter-image-loader.c
@@ -0,0 +1,153 @@
+#include "config.h"
+
+#include "clutter-image-loader.h"
+
+#include <string.h>
+#include <gio/gio.h>
+
+#include "clutter-private.h"
+
+G_DEFINE_ABSTRACT_TYPE (ClutterImageLoader, clutter_image_loader, G_TYPE_OBJECT);
+
+static void
+clutter_image_loader_class_init (ClutterImageLoaderClass *klass)
+{
+}
+
+static void
+clutter_image_loader_init (ClutterImageLoader *loader)
+{
+}
+
+static gpointer
+get_default_image_loader (gpointer data)
+{
+ ClutterImageLoaderClass *chosen_class;
+ ClutterImageLoaderClass **ret = data;
+ GIOExtensionPoint *ep;
+ GList *extensions, *l;
+
+ _clutter_io_modules_ensure_loaded ();
+
+ ep = g_io_extension_point_lookup (CLUTTER_IMAGE_LOADER_EXTENSION_POINT_NAME);
+
+ extensions = g_io_extension_point_get_extensions (ep);
+
+ chosen_class = NULL;
+ for (l = extensions; l != NULL; l = l->next)
+ {
+ GIOExtension *extension = l->data;
+ ClutterImageLoaderClass *klass;
+
+ klass = CLUTTER_IMAGE_LOADER_CLASS (g_io_extension_ref_class (extension));
+
+ if (klass->is_supported ())
+ {
+ chosen_class = klass;
+ break;
+ }
+ else
+ g_type_class_unref (klass);
+ }
+
+ if (chosen_class)
+ {
+ *ret = chosen_class;
+ return (gpointer) G_TYPE_FROM_CLASS (chosen_class);
+ }
+ else
+ return (gpointer) G_TYPE_INVALID;
+}
+
+ClutterImageLoader *
+_clutter_image_loader_new (void)
+{
+ static GOnce once_init = G_ONCE_INIT;
+ GTypeClass *type_class = NULL;
+ ClutterImageLoader *loader;
+ GType type = G_TYPE_INVALID;
+
+ g_once (&once_init, get_default_image_loader, &type_class);
+ type = (GType) once_init.retval;
+ if (type == G_TYPE_INVALID)
+ {
+ g_critical ("Unable to load the default image loader. Check the "
+ "compilation options of Clutter.");
+ return NULL;
+ }
+
+ loader = g_object_new (type, NULL);
+
+ if (type_class != NULL)
+ g_type_class_unref (type_class);
+
+ return loader;
+}
+
+void
+_clutter_image_loader_get_image_size (ClutterImageLoader *loader,
+ gint *width,
+ gint *height)
+{
+ g_return_if_fail (CLUTTER_IS_IMAGE_LOADER (loader));
+
+ CLUTTER_IMAGE_LOADER_GET_CLASS (loader)->get_image_size (loader,
+ width,
+ height);
+}
+
+CoglHandle
+_clutter_image_loader_get_texture_handle (ClutterImageLoader *loader)
+{
+ g_return_val_if_fail (CLUTTER_IS_IMAGE_LOADER (loader), NULL);
+
+ return CLUTTER_IMAGE_LOADER_GET_CLASS (loader)->get_texture_handle (loader);
+}
+
+gboolean
+_clutter_image_loader_load_stream (ClutterImageLoader *loader,
+ GInputStream *stream,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (CLUTTER_IS_IMAGE_LOADER (loader), FALSE);
+ g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
+ g_return_val_if_fail (cancellable == NULL ||
+ G_IS_CANCELLABLE (cancellable), FALSE);
+
+
+ return CLUTTER_IMAGE_LOADER_GET_CLASS (loader)->load_stream (loader, stream,
+ cancellable,
+ error);
+}
+
+void
+_clutter_image_loader_load_stream_async (ClutterImageLoader *loader,
+ GInputStream *stream,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (CLUTTER_IS_IMAGE_LOADER (loader));
+ g_return_if_fail (G_IS_INPUT_STREAM (stream));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (callback != NULL);
+
+ CLUTTER_IMAGE_LOADER_GET_CLASS (loader)->load_stream_async (loader, stream,
+ cancellable,
+ callback,
+ user_data);
+}
+
+gboolean
+_clutter_image_loader_load_stream_finish (ClutterImageLoader *loader,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (CLUTTER_IS_IMAGE_LOADER (loader), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ return CLUTTER_IMAGE_LOADER_GET_CLASS (loader)->load_stream_finish (loader,
+ result,
+ error);
+}
diff --git a/clutter/clutter-image-loader.h b/clutter/clutter-image-loader.h
new file mode 100644
index 0000000..02b014f
--- /dev/null
+++ b/clutter/clutter-image-loader.h
@@ -0,0 +1,101 @@
+#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
+#error "Only <clutter/clutter.h> can be included directly."
+#endif
+
+#ifndef __CLUTTER_IMAGE_LOADER_H__
+#define __CLUTTER_IMAGE_LOADER_H__
+
+#include <glib-object.h>
+#include <gio/gio.h>
+#include <cogl/cogl.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_IMAGE_LOADER (clutter_image_loader_get_type ())
+#define CLUTTER_IMAGE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_IMAGE_LOADER, ClutterImageLoader))
+#define CLUTTER_IS_IMAGE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_IMAGE_LOADER))
+#define CLUTTER_IMAGE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_IMAGE_LOADER, ClutterImageLoaderClass))
+#define CLUTTER_IS_IMAGE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_IMAGE_LOADER))
+#define CLUTTER_IMAGE_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_IMAGE_LOADER, ClutterImageLoaderClass))
+
+#define CLUTTER_IMAGE_LOADER_EXTENSION_POINT_NAME "clutter-image-loader"
+
+typedef struct _ClutterImageLoader ClutterImageLoader;
+typedef struct _ClutterImageLoaderClass ClutterImageLoaderClass;
+
+struct _ClutterImageLoader
+{
+ GObject parent_instance;
+};
+
+struct _ClutterImageLoaderClass
+{
+ GObjectClass parent_class;
+
+ gboolean (* is_supported) (void);
+
+ gboolean (* load_stream) (ClutterImageLoader *loader,
+ GInputStream *stream,
+ GCancellable *cancellable,
+ GError **error);
+
+ void (* load_stream_async) (ClutterImageLoader *loader,
+ GInputStream *stream,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (* load_stream_finish) (ClutterImageLoader *loader,
+ GAsyncResult *result,
+ GError **error);
+
+ void (* get_image_size) (ClutterImageLoader *loader,
+ gint *width,
+ gint *height);
+
+ CoglHandle (* get_texture_handle) (ClutterImageLoader *loader);
+
+ void (* _clutter_image_loader__1) (void);
+ void (* _clutter_image_loader__2) (void);
+ void (* _clutter_image_loader__3) (void);
+ void (* _clutter_image_loader__4) (void);
+ void (* _clutter_image_loader__5) (void);
+ void (* _clutter_image_loader__6) (void);
+ void (* _clutter_image_loader__7) (void);
+ void (* _clutter_image_loader__8) (void);
+ void (* _clutter_image_loader__9) (void);
+ void (* _clutter_image_loader_10) (void);
+ void (* _clutter_image_loader_11) (void);
+ void (* _clutter_image_loader_12) (void);
+ void (* _clutter_image_loader_13) (void);
+};
+
+GType clutter_image_loader_get_type (void) G_GNUC_CONST;
+
+/*
+ * private
+ */
+
+ClutterImageLoader * _clutter_image_loader_new (void);
+
+void _clutter_image_loader_get_image_size (ClutterImageLoader *loader,
+ gint *width,
+ gint *height);
+CoglHandle _clutter_image_loader_get_texture_handle (ClutterImageLoader *loader);
+
+gboolean _clutter_image_loader_load_stream (ClutterImageLoader *loader,
+ GInputStream *stream,
+ GCancellable *cancellable,
+ GError **error);
+
+void _clutter_image_loader_load_stream_async (ClutterImageLoader *loader,
+ GInputStream *stream,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean _clutter_image_loader_load_stream_finish (ClutterImageLoader *loader,
+ GAsyncResult *result,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __CLUTTER_IMAGE_LOADER_H__ */
diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c
index b7a63f4..71ba1a7 100644
--- a/clutter/clutter-main.c
+++ b/clutter/clutter-main.c
@@ -92,6 +92,7 @@
#include <stdlib.h>
#include <glib/gi18n-lib.h>
+#include <gio/gio.h>
#include <locale.h>
#include "clutter-actor.h"
@@ -101,6 +102,7 @@
#include "clutter-event.h"
#include "clutter-feature.h"
#include "clutter-frame-source.h"
+#include "clutter-image-loader.h"
#include "clutter-main.h"
#include "clutter-master-clock.h"
#include "clutter-private.h"
@@ -3091,3 +3093,68 @@ _clutter_context_pop_shader_stack (ClutterActor *actor)
return _clutter_context_peek_shader_stack ();
}
+
+/*
+ * Clutter modules
+ */
+
+G_LOCK_DEFINE_STATIC (registered_extensions);
+G_LOCK_DEFINE_STATIC (loaded_dirs);
+
+void
+_clutter_io_modules_ensure_extensions_registered (void)
+{
+ static gboolean registered_extensions = FALSE;
+ GIOExtensionPoint *ep;
+
+ G_LOCK (registered_extensions);
+
+ if (!registered_extensions)
+ {
+ registered_extensions = TRUE;
+
+ /* register the extension points we expose */
+
+ ep = g_io_extension_point_register (CLUTTER_IMAGE_LOADER_EXTENSION_POINT_NAME);
+ g_io_extension_point_set_required_type (ep, CLUTTER_TYPE_IMAGE_LOADER);
+ }
+
+ G_UNLOCK (registered_extensions);
+}
+
+void
+_clutter_io_modules_ensure_loaded (void)
+{
+ static gboolean loaded_dirs = FALSE;
+ const gchar *module_path;
+
+ _clutter_io_modules_ensure_extensions_registered ();
+
+ G_LOCK (loaded_dirs);
+
+ if (!loaded_dirs)
+ {
+ loaded_dirs = TRUE;
+
+ g_io_modules_scan_all_in_directory (CLUTTER_MODULEDIR);
+
+ module_path = g_getenv ("CLUTTER_EXTRA_MODULES");
+
+ if (module_path)
+ {
+ gchar **paths;
+ int i;
+
+ paths = g_strsplit (module_path, ":", 0);
+
+ for (i = 0; paths[i] != NULL; i++)
+ g_io_modules_scan_all_in_directory (paths[i]);
+
+ g_strfreev (paths);
+ }
+
+ /* XXX Initialize types from built-in "modules" here XXX */
+ }
+
+ G_UNLOCK (loaded_dirs);
+}
diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h
index a9fc004..92c3cdd 100644
--- a/clutter/clutter-private.h
+++ b/clutter/clutter-private.h
@@ -238,6 +238,8 @@ typedef enum _ClutterCullResult
CLUTTER_CULL_RESULT_PARTIAL
} ClutterCullResult;
+void _clutter_io_modules_ensure_loaded (void);
+
G_END_DECLS
#endif /* __CLUTTER_PRIVATE_H__ */
diff --git a/clutter/clutter.h b/clutter/clutter.h
index fae0766..1baf56e 100644
--- a/clutter/clutter.h
+++ b/clutter/clutter.h
@@ -74,6 +74,7 @@
#include "clutter-flow-layout.h"
#include "clutter-frame-source.h"
#include "clutter-group.h"
+#include "clutter-image-loader.h"
#include "clutter-image.h"
#include "clutter-input-device.h"
#include "clutter-interval.h"
diff --git a/clutter/image-loaders/clutter-image-loader-null.c b/clutter/image-loaders/clutter-image-loader-null.c
new file mode 100644
index 0000000..150fbc1
--- /dev/null
+++ b/clutter/image-loaders/clutter-image-loader-null.c
@@ -0,0 +1,68 @@
+#include "config.h"
+
+#include "clutter-image-loader-null.h"
+
+#include <cogl/cogl.h>
+#include <gio/gio.h>
+
+struct _ClutterImageLoaderNull
+{
+ ClutterImageLoader parent_instance;
+};
+
+#define clutter_image_loader_null_get_type _clutter_image_loader_null_get_type
+G_DEFINE_TYPE_WITH_CODE (ClutterImageLoaderNull,
+ clutter_image_loader_null,
+ CLUTTER_TYPE_IMAGE_LOADER,
+ g_io_extension_point_implement (CLUTTER_IMAGE_LOADER_EXTENSION_POINT_NAME,
+ g_define_type_id,
+ "null",
+ 0));
+
+static void
+clutter_image_loader_null_finalize (GObject *gobject)
+{
+ G_OBJECT_CLASS (clutter_image_loader_null_parent_class)->finalize (gobject);
+}
+
+static gboolean
+clutter_image_loader_null_is_supported (void)
+{
+ return FALSE;
+}
+
+static void
+clutter_image_loader_null_get_image_size (ClutterImageLoader *loader,
+ gint *width,
+ gint *height)
+{
+ if (width)
+ *width = 0;
+
+ if (height)
+ *height = 0;
+}
+
+static CoglHandle
+clutter_image_loader_null_get_texture_handle (ClutterImageLoader *loader)
+{
+ return COGL_INVALID_HANDLE;
+}
+
+static void
+clutter_image_loader_null_class_init (ClutterImageLoaderNullClass *klass)
+{
+ ClutterImageLoaderClass *loader_class = CLUTTER_IMAGE_LOADER_CLASS (klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = clutter_image_loader_null_finalize;
+
+ loader_class->is_supported = clutter_image_loader_null_is_supported;
+ loader_class->get_image_size = clutter_image_loader_null_get_image_size;
+ loader_class->get_texture_handle = clutter_image_loader_null_get_texture_handle;
+}
+
+static void
+clutter_image_loader_null_init (ClutterImageLoaderNull *loader)
+{
+}
diff --git a/clutter/image-loaders/clutter-image-loader-null.h b/clutter/image-loaders/clutter-image-loader-null.h
new file mode 100644
index 0000000..8ecded4
--- /dev/null
+++ b/clutter/image-loaders/clutter-image-loader-null.h
@@ -0,0 +1,19 @@
+#ifndef __CLUTTER_IMAGE_LOADER_NULL_H__
+#define __CLUTTER_IMAGE_LOADER_NULL_H__
+
+#include <clutter/clutter-image-loader.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_IMAGE_LOADER_NULL (_clutter_image_loader_null_get_type ())
+#define CLUTTER_IMAGE_LOADER_NULL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_IMAGE_LOADER_NULL, ClutterImageLoaderNull))
+#define CLUTTER_IS_IMAGE_LOADER_NULL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_IMAGE_LOADER_NULL))
+
+typedef struct _ClutterImageLoaderNull ClutterImageLoaderNull;
+typedef struct _ClutterImageLoaderClass ClutterImageLoaderNullClass;
+
+GType _clutter_image_loader_null_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __CLUTTER_IMAGE_LOADER_NULL_H__ */
diff --git a/configure.ac b/configure.ac
index 01d69b1..62e2084 100644
--- a/configure.ac
+++ b/configure.ac
@@ -139,7 +139,7 @@ AC_SUBST([XCOMPOSITE_REQ_VERSION], [xcomposite_req_version])
AM_PATH_GLIB_2_0([glib_req_version],
[],
[AC_MSG_ERROR([glib-2.0 is required])],
- [gobject gthread gmodule-no-export])
+ [gobject gthread gmodule-no-export gio])
# Check for -Bsymbolic-functions to avoid intra-library PLT jumps
AC_ARG_ENABLE([Bsymbolic],
@@ -486,9 +486,6 @@ AC_SUBST([CLUTTER_FLAVOUR])
CLUTTER_COGL=undefined
AC_SUBST([CLUTTER_COGL])
-dnl === Image loading backend =================================================
-IMAGE_PC_FILES=""
-
dnl === X11 checks, only for X11-based backends ===============================
X11_PC_FILES=""
x11_tests=no
@@ -819,7 +816,7 @@ dnl === Dependencies, compiler flags and linker libraries =====================
# strip leading space
BACKEND_PC_FILES=${BACKEND_PC_FILES#* }
-CLUTTER_REQUIRES="$CLUTTER_BASE_PC_FILES $IMAGE_PC_FILES $BACKEND_PC_FILES"
+CLUTTER_REQUIRES="$CLUTTER_BASE_PC_FILES $BACKEND_PC_FILES"
PKG_CHECK_MODULES(CLUTTER_DEPS, [$CLUTTER_REQUIRES])
AC_SUBST(CLUTTER_REQUIRES)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]