[clutter/wip/actor-content: 4/33] image-loader: Add stub for GdkPixbuf-based loader



commit d5c9f6959bdb92a268036bddea99d2e5d7d80434
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Mon Dec 6 18:10:24 2010 +0000

    image-loader: Add stub for GdkPixbuf-based loader
    
    Synchronous API only, for the moment.

 clutter/Makefile.am                                |   15 ++-
 clutter/clutter-main.c                             |   10 ++
 .../image-loaders/clutter-image-loader-pixbuf.c    |  150 ++++++++++++++++++++
 .../image-loaders/clutter-image-loader-pixbuf.h    |   19 +++
 configure.ac                                       |   28 ++++-
 5 files changed, 218 insertions(+), 4 deletions(-)
---
diff --git a/clutter/Makefile.am b/clutter/Makefile.am
index 5d24f6e..aecfbfb 100644
--- a/clutter/Makefile.am
+++ b/clutter/Makefile.am
@@ -40,7 +40,12 @@ AM_CPPFLAGS = \
 	$(CLUTTER_PROFILE_CFLAGS)		\
 	$(NULL)
 
-AM_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS) $(GCOV_CFLAGS)
+AM_CFLAGS = \
+	$(CLUTTER_CFLAGS) 	\
+	$(IMAGE_LOADER_CFLAGS) 	\
+	$(MAINTAINER_CFLAGS) 	\
+	$(GCOV_CFLAGS)		\
+	$(NULL)
 
 # these are the gir files we generate using g-ir-scanner
 INTROSPECTION_GIRS =
@@ -595,6 +600,11 @@ imageloader_sources_h = \
 	$(srcdir)/image-loaders/clutter-image-loader-null.h	\
 	$(NULL)
 
+if SUPPORT_GDK_PIXBUF
+imageloader_sources_c += $(srcdir)/image-loaders/clutter-image-loader-pixbuf.c
+imageloader_sources_h += $(srcdir)/image-loaders/clutter-image-loader-pixbuf.h
+endif
+
 # general build rules:
 # you should not need to modify anything below this point
 
@@ -629,7 +639,8 @@ lib_LTLIBRARIES += libclutter- CLUTTER_SONAME_INFIX@- CLUTTER_API_VERSION@.la
 
 libclutter_ CLUTTER_SONAME_INFIX@_ CLUTTER_API_VERSION@_la_LIBADD = \
 	$(CLUTTER_LIBS) \
-	$(CLUTTER_PROFILE_LIBS)
+	$(CLUTTER_PROFILE_LIBS) \
+	$(IMAGE_LOADER_LIBS)
 
 libclutter_ CLUTTER_SONAME_INFIX@_ CLUTTER_API_VERSION@_la_DEPENDENCIES = \
 	$(win32_resources)
diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c
index 71ba1a7..b96a6ec 100644
--- a/clutter/clutter-main.c
+++ b/clutter/clutter-main.c
@@ -116,6 +116,10 @@
 
 #include "cally.h" /* For accessibility support */
 
+#ifdef CLUTTER_IMAGE_LOADER_GDK_PIXBUF
+#include "image-loaders/clutter-image-loader-pixbuf.h"
+#endif
+
 /* main context */
 static ClutterMainContext *ClutterCntx       = NULL;
 
@@ -3134,6 +3138,8 @@ _clutter_io_modules_ensure_loaded (void)
 
   if (!loaded_dirs)
     {
+      volatile GType dummy_type;
+
       loaded_dirs = TRUE;
 
       g_io_modules_scan_all_in_directory (CLUTTER_MODULEDIR);
@@ -3154,6 +3160,10 @@ _clutter_io_modules_ensure_loaded (void)
         }
 
       /* XXX Initialize types from built-in "modules" here XXX */
+
+#ifdef CLUTTER_IMAGE_LOADER_GDK_PIXBUF
+      dummy_type = _clutter_image_loader_pixbuf_get_type ();
+#endif
     }
 
   G_UNLOCK (loaded_dirs);
diff --git a/clutter/image-loaders/clutter-image-loader-pixbuf.c b/clutter/image-loaders/clutter-image-loader-pixbuf.c
new file mode 100644
index 0000000..204e31c
--- /dev/null
+++ b/clutter/image-loaders/clutter-image-loader-pixbuf.c
@@ -0,0 +1,150 @@
+#include "config.h"
+
+#include "clutter-image-loader-pixbuf.h"
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gio/gio.h>
+#include <cogl/cogl.h>
+
+#include "clutter-debug.h"
+#include "clutter-image.h"
+#include "clutter-private.h"
+
+struct _ClutterImageLoaderPixbuf
+{
+  ClutterImageLoader parent_instance;
+
+  GdkPixbufLoader *loader;
+
+  gint image_width;
+  gint image_height;
+  gint rowstride;
+
+  CoglPixelFormat pixel_format;
+
+  CoglHandle texture;
+};
+
+#define clutter_image_loader_pixbuf_get_type    _clutter_image_loader_pixbuf_get_type
+G_DEFINE_TYPE_WITH_CODE (ClutterImageLoaderPixbuf,
+                         clutter_image_loader_pixbuf,
+                         CLUTTER_TYPE_IMAGE_LOADER,
+                         g_io_extension_point_implement (CLUTTER_IMAGE_LOADER_EXTENSION_POINT_NAME,
+                                                         g_define_type_id,
+                                                         "gdk-pixbuf",
+                                                         20));
+
+static void
+clutter_image_loader_pixbuf_dispose (GObject *gobject)
+{
+  ClutterImageLoaderPixbuf *loader;
+
+  loader = CLUTTER_IMAGE_LOADER_PIXBUF (gobject);
+
+  if (loader->loader != NULL)
+    {
+      gdk_pixbuf_loader_close (loader->loader, NULL);
+      g_object_unref (loader->loader);
+      loader->loader = NULL;
+    }
+
+  if (loader->texture != COGL_INVALID_HANDLE)
+    {
+      cogl_handle_unref (loader->texture);
+      loader->texture = COGL_INVALID_HANDLE;
+    }
+
+  G_OBJECT_CLASS (clutter_image_loader_pixbuf_parent_class)->dispose (gobject);
+}
+
+static gboolean
+clutter_image_loader_pixbuf_is_supported (void)
+{
+  return TRUE;
+}
+
+static gboolean
+clutter_image_loader_pixbuf_load_stream (ClutterImageLoader *loader,
+                                         GInputStream       *stream,
+                                         GCancellable       *cancellable,
+                                         GError            **error)
+{
+  ClutterImageLoaderPixbuf *self = CLUTTER_IMAGE_LOADER_PIXBUF (loader);
+  GdkPixbuf *pixbuf;
+
+  pixbuf = gdk_pixbuf_new_from_stream (stream, cancellable, error);
+  if (pixbuf == NULL)
+    return FALSE;
+
+  self->image_width = gdk_pixbuf_get_width (pixbuf);
+  self->image_height = gdk_pixbuf_get_height (pixbuf);
+  self->pixel_format = gdk_pixbuf_get_has_alpha (pixbuf)
+                     ? COGL_PIXEL_FORMAT_RGBA_8888
+                     : COGL_PIXEL_FORMAT_RGB_888;
+  self->rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+  CLUTTER_NOTE (MISC, "Image: %d x %d (rowstride: %d, has-alpha: %s)",
+                self->image_width,
+                self->image_height,
+                self->rowstride,
+                gdk_pixbuf_get_has_alpha (pixbuf) ? "yes" : "no");
+
+  self->texture = cogl_texture_new_from_data (self->image_width,
+                                              self->image_height,
+                                              COGL_TEXTURE_NONE,
+                                              self->pixel_format,
+                                              COGL_PIXEL_FORMAT_ANY,
+                                              self->rowstride,
+                                              gdk_pixbuf_get_pixels (pixbuf));
+
+  g_object_unref (pixbuf);
+
+  if (self->texture == COGL_INVALID_HANDLE &&
+      (error != NULL && *error == NULL))
+    g_set_error_literal (error, CLUTTER_IMAGE_ERROR,
+                         CLUTTER_IMAGE_ERROR_INVALID_DATA,
+                         _("Unable to load the image data"));
+
+  return (self->texture != COGL_INVALID_HANDLE);
+}
+
+static void
+clutter_image_loader_pixbuf_get_image_size (ClutterImageLoader *loader,
+                                            gint               *width,
+                                            gint               *height)
+{
+  ClutterImageLoaderPixbuf *self = CLUTTER_IMAGE_LOADER_PIXBUF (loader);
+
+  if (width)
+    *width = self->image_width;
+
+  if (height)
+    *height = self->image_height;
+}
+
+static CoglHandle
+clutter_image_loader_pixbuf_get_texture_handle (ClutterImageLoader *loader)
+{
+  ClutterImageLoaderPixbuf *self = CLUTTER_IMAGE_LOADER_PIXBUF (loader);
+
+  return self->texture;
+}
+
+static void
+clutter_image_loader_pixbuf_class_init (ClutterImageLoaderPixbufClass *klass)
+{
+  ClutterImageLoaderClass *loader_class = CLUTTER_IMAGE_LOADER_CLASS (klass);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->dispose = clutter_image_loader_pixbuf_dispose;
+
+  loader_class->is_supported = clutter_image_loader_pixbuf_is_supported;
+  loader_class->load_stream = clutter_image_loader_pixbuf_load_stream;
+  loader_class->get_image_size = clutter_image_loader_pixbuf_get_image_size;
+  loader_class->get_texture_handle = clutter_image_loader_pixbuf_get_texture_handle;
+}
+
+static void
+clutter_image_loader_pixbuf_init (ClutterImageLoaderPixbuf *loader)
+{
+}
diff --git a/clutter/image-loaders/clutter-image-loader-pixbuf.h b/clutter/image-loaders/clutter-image-loader-pixbuf.h
new file mode 100644
index 0000000..4e06c4d
--- /dev/null
+++ b/clutter/image-loaders/clutter-image-loader-pixbuf.h
@@ -0,0 +1,19 @@
+#ifndef __CLUTTER_IMAGE_LOADER_PIXBUF_H__
+#define __CLUTTER_IMAGE_LOADER_PIXBUF_H__
+
+#include <clutter/clutter-image-loader.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_IMAGE_LOADER_PIXBUF        (_clutter_image_loader_pixbuf_get_type ())
+#define CLUTTER_IMAGE_LOADER_PIXBUF(obj)        (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_IMAGE_LOADER_PIXBUF, ClutterImageLoaderPixbuf))
+#define CLUTTER_IS_IMAGE_LOADER_PIXBUF(obj)     (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_IMAGE_LOADER_PIXBUF))
+
+typedef struct _ClutterImageLoaderPixbuf        ClutterImageLoaderPixbuf;
+typedef struct _ClutterImageLoaderClass         ClutterImageLoaderPixbufClass;
+
+GType _clutter_image_loader_pixbuf_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __CLUTTER_IMAGE_LOADER_PIXBUF_H__ */
diff --git a/configure.ac b/configure.ac
index 62e2084..8296426 100644
--- a/configure.ac
+++ b/configure.ac
@@ -129,6 +129,7 @@ AC_SUBST([JSON_GLIB_REQ_VERSION], [json_glib_req_version])
 AC_SUBST([ATK_REQ_VERSION], [atk_req_version])
 AC_SUBST([CAIRO_REQ_VERSION], [cairo_req_version])
 AC_SUBST([PANGO_REQ_VERSION], [pango_req_version])
+AC_SUBST([GDK_PIXBUF_REQ_VERSION], [gdk_pixbuf_req_version])
 AC_SUBST([GI_REQ_VERSION], [gi_req_version])
 AC_SUBST([UPROF_REQ_VERSION], [uprof_req_version])
 AC_SUBST([GTK_DOC_REQ_VERSION], [gtk_doc_req_version])
@@ -436,8 +437,30 @@ dnl COGL_ENABLE_EXPERIMENTAL_2_0_API is defined while compiling clutter
 dnl and cogl code we use a define in config.h instead. This helps ensure
 dnl other tools such as glib-mkenums and gir-scanner don't end up
 dnl using the define also.
-AC_DEFINE([COGL_ENABLE_EXPERIMENTAL_2_0_API], [1],
-          [Can use Cogl 2.0 API internally])
+AC_DEFINE([COGL_ENABLE_EXPERIMENTAL_2_0_API], [1], [Can use Cogl 2.0 API internally])
+
+dnl === Image loaders =========================================================
+
+IMAGE_LOADER_CFLAGS=
+IMAGE_LOADER_LIBS=
+IMAGE_LOADER_MODS=
+
+PKG_CHECK_MODULES([GDK_PIXBUF],
+                  [gdk-pixbuf-2.0 >= gdk_pixbuf_req_version],
+                  [
+                    has_gdk_pixbuf_loader=yes
+                    IMAGE_LOADER_MODS="$IMAGE_LOADER_MODS gdkpixbuf"
+                    IMAGE_LOADER_CFLAGS="$IMAGE_LOADER_CFLAGS $GDK_PIXBUF_CFLAGS"
+                    IMAGE_LOADER_LIBS="$IMAGE_LOADER_LIBS $GDK_PIXBUF_LIBS"
+                    AC_DEFINE([CLUTTER_IMAGE_LOADER_GDK_PIXBUF], [1], [GdkPixbuf image loader])
+                  ],
+                  [
+                    has_gdk_pixbuf_loader=no
+                  ])
+
+AM_CONDITIONAL([SUPPORT_GDK_PIXBUF], [test "x$has_gdk_pixbuf_loader" = "xyes"])
+
+IMAGE_LOADER_MODS=${IMAGE_LOADER_MODS#* }
 
 dnl === Clutter configuration =================================================
 
@@ -974,6 +997,7 @@ echo ""
 echo " â?¢ Extra:"
 echo "        Build introspection data: ${enable_introspection}"
 echo "        Build conformance test suite: ${enable_conformance}"
+echo "        Image loader modules: ${IMAGE_LOADER_MODS}"
 
 # Clutter backend related flags
 echo ""



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]