implemented clutter-based renderer
authorVladimir Nadvornik <nadvornik@suse.cz>
Sat, 11 Aug 2012 21:46:42 +0000 (23:46 +0200)
committerVladimir Nadvornik <nadvornik@suse.cz>
Sat, 18 Aug 2012 17:17:13 +0000 (19:17 +0200)
src/Makefile.am
src/pixbuf-renderer.c
src/pixbuf-renderer.h
src/renderer-clutter.c [new file with mode: 0644]
src/renderer-clutter.h [new file with mode: 0644]
src/renderer-tiles.c

index 02d31a6..0342196 100644 (file)
@@ -209,6 +209,8 @@ geeqie_SOURCES = \
        pixbuf-renderer.h       \
        renderer-tiles.c        \
        renderer-tiles.h        \
+       renderer-clutter.c      \
+       renderer-clutter.h      \
        pixbuf_util.c   \
        pixbuf_util.h   \
        preferences.c   \
index 2021a1f..c07b278 100644 (file)
 #include "main.h"
 #include "pixbuf-renderer.h"
 #include "renderer-tiles.h"
+#include "renderer-clutter.h"
 
 #include "intl.h"
 #include "layout.h"
 
 #include <gtk/gtk.h>
 
+#define RENDERER_NEW(pr) renderer_clutter_new(pr)
 
 /* comment this out if not using this from within Geeqie
  * defining GQ_BUILD does these things:
@@ -426,7 +428,7 @@ static void pixbuf_renderer_init(PixbufRenderer *pr)
        
        pr->stereo_mode = PR_STEREO_NONE;
        
-       pr->renderer = (void *)renderer_tiles_new(pr);
+       pr->renderer = RENDERER_NEW(pr);
        
        pr->renderer2 = NULL;
 
@@ -942,12 +944,6 @@ static void pr_scroller_stop(PixbufRenderer *pr)
  *-------------------------------------------------------------------
  */
 
-static void pr_border_clear(PixbufRenderer *pr)
-{
-       pr->renderer->border_clear(pr->renderer);
-       if (pr->renderer2) pr->renderer2->border_clear(pr->renderer2);
-}
-
 void pixbuf_renderer_set_color(PixbufRenderer *pr, GdkColor *color)
 {
        GtkStyle *style;
@@ -973,21 +969,8 @@ void pixbuf_renderer_set_color(PixbufRenderer *pr, GdkColor *color)
 
        gtk_widget_set_style(widget, style);
 
-#if GTK_CHECK_VERSION(2,20,0)
-       if (gtk_widget_get_visible(widget)) pr_border_clear(pr);
-#else
-       if (GTK_WIDGET_VISIBLE(widget)) pr_border_clear(pr);
-#endif
-}
-
-static void pr_redraw(PixbufRenderer *pr, gboolean new_data)
-{
-       pr->renderer->queue_clear(pr->renderer);
-       pr->renderer->redraw(pr->renderer, 0, 0, pr->width, pr->height, TRUE, TILE_RENDER_ALL, new_data, FALSE);
-       if (pr->renderer2) {
-               pr->renderer2->queue_clear(pr->renderer2);
-               pr->renderer2->redraw(pr->renderer2, 0, 0, pr->width, pr->height, TRUE, TILE_RENDER_ALL, new_data, FALSE);
-       }
+       pr->renderer->update_sizes(pr->renderer);
+       if (pr->renderer2) pr->renderer2->update_sizes(pr->renderer2);
 }
 
 /*
@@ -1257,7 +1240,6 @@ void pixbuf_renderer_set_tiles(PixbufRenderer *pr, gint width, gint height,
        pr->func_tile_data = user_data;
 
        pr_zoom_sync(pr, zoom, PR_ZOOM_FORCE | PR_ZOOM_NEW, 0, 0);
-       pr_redraw(pr, TRUE);
 }
 
 void pixbuf_renderer_set_tiles_size(PixbufRenderer *pr, gint width, gint height)
@@ -1766,9 +1748,9 @@ static gboolean pr_zoom_clamp(PixbufRenderer *pr, gdouble zoom,
 
        if (invalidate || invalid)
                {
-               pr->renderer->invalidate_all(pr->renderer);
-               if (pr->renderer2) pr->renderer2->invalidate_all(pr->renderer2);
-               if (!lazy) pr_redraw(pr, TRUE);
+               pr->renderer->update_zoom(pr->renderer, lazy);
+               if (pr->renderer2) pr->renderer2->update_zoom(pr->renderer2, lazy);
+//             if (!lazy) pr_redraw(pr, TRUE);
                }
        if (redrawn) *redrawn = (invalidate || invalid);
 
@@ -1854,12 +1836,7 @@ static void pr_zoom_sync(PixbufRenderer *pr, gdouble zoom,
 
        pr_scroll_clamp(pr);
 
-       /* If the window was not sized, redraw the image - we know there will be no size/expose signal.
-        * But even if a size is claimed, there is no guarantee that the window manager will allow it,
-        * so redraw the window anyway :/
-        */
-       if (sized || clamped) pr_border_clear(pr);
-       
+#if 0  
        if (lazy)
                {
                pr->renderer->queue_clear(pr->renderer);
@@ -1869,6 +1846,9 @@ static void pr_zoom_sync(PixbufRenderer *pr, gdouble zoom,
                {
                pr_redraw(pr, redrawn);
                }
+#endif
+       pr->renderer->update_zoom(pr->renderer, lazy);
+       if (pr->renderer2) pr->renderer2->update_zoom(pr->renderer2, lazy);
 
        pr_scroll_notify_signal(pr);
        pr_zoom_signal(pr);
@@ -1954,8 +1934,6 @@ static void pr_size_sync(PixbufRenderer *pr, gint new_width, gint new_height)
                        }
                }
 
-       pr_border_clear(pr);
-
        pr_scroll_notify_signal(pr);
        if (zoom_changed) pr_zoom_signal(pr);
        pr_update_signal(pr);
@@ -2482,6 +2460,8 @@ static void pr_set_pixbuf(PixbufRenderer *pr, GdkPixbuf *pixbuf, gdouble zoom, P
                }
 
        pr_pixbuf_size_sync(pr);
+       pr->renderer->update_pixbuf(pr->renderer, flags & PR_ZOOM_LAZY);
+       if (pr->renderer2) pr->renderer2->update_pixbuf(pr->renderer2, flags & PR_ZOOM_LAZY);
        pr_zoom_sync(pr, zoom, flags | PR_ZOOM_FORCE | PR_ZOOM_NEW, 0, 0);
 }
 
@@ -2523,7 +2503,15 @@ void pixbuf_renderer_set_orientation(PixbufRenderer *pr, gint orientation)
        pr->orientation = orientation;
 
        pr_pixbuf_size_sync(pr);
+       if (0)
+               {
+               pr->renderer->update_pixbuf(pr->renderer, FALSE);
+               if (pr->renderer2) pr->renderer2->update_pixbuf(pr->renderer2, FALSE);
+               }
        pr_zoom_sync(pr, pr->zoom, PR_ZOOM_FORCE, 0, 0);
+
+       pr->renderer->update_sizes(pr->renderer);
+       if (pr->renderer2) pr->renderer2->update_sizes(pr->renderer2);
 }
 
 gint pixbuf_renderer_get_orientation(PixbufRenderer *pr)
@@ -2544,6 +2532,8 @@ void pixbuf_renderer_set_stereo_data(PixbufRenderer *pr, StereoPixbufData stereo
                pr_stereo_temp_disable(pr, disable);
                }
        pr_pixbuf_size_sync(pr);
+       pr->renderer->update_pixbuf(pr->renderer, FALSE);
+       if (pr->renderer2) pr->renderer2->update_pixbuf(pr->renderer2, FALSE);
        pr_zoom_sync(pr, pr->zoom, PR_ZOOM_FORCE, 0, 0);
 }
 
@@ -2609,7 +2599,6 @@ void pixbuf_renderer_move(PixbufRenderer *pr, PixbufRenderer *source)
                source->source_tiles = NULL;
 
                pr_zoom_sync(pr, source->zoom, PR_ZOOM_FORCE | PR_ZOOM_NEW, 0, 0);
-               pr_redraw(pr, TRUE);
                }
        else
                {
@@ -2693,13 +2682,13 @@ void pixbuf_renderer_zoom_set_limits(PixbufRenderer *pr, gdouble min, gdouble ma
 
 static void pr_stereo_set(PixbufRenderer *pr)
 {
-       if (!pr->renderer) pr->renderer = (void *)renderer_tiles_new(pr);
+       if (!pr->renderer) pr->renderer = RENDERER_NEW(pr);
        
        pr->renderer->stereo_set(pr->renderer, pr->stereo_mode & ~PR_STEREO_MIRROR_RIGHT & ~PR_STEREO_FLIP_RIGHT);
        
        if (pr->stereo_mode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED))
                {
-               if (!pr->renderer2) pr->renderer2 = (void *)renderer_tiles_new(pr);
+               if (!pr->renderer2) pr->renderer2 = RENDERER_NEW(pr);
                pr->renderer2->stereo_set(pr->renderer2, (pr->stereo_mode & ~PR_STEREO_MIRROR_LEFT & ~PR_STEREO_FLIP_LEFT) | PR_STEREO_RIGHT);
                }
        else
@@ -2757,7 +2746,7 @@ static void pr_stereo_temp_disable(PixbufRenderer *pr, gboolean disable)
        pr->stereo_temp_disable = disable;
        if (disable)
                {
-               if (!pr->renderer) pr->renderer = (void *)renderer_tiles_new(pr);
+               if (!pr->renderer) pr->renderer = RENDERER_NEW(pr);
                pr->renderer->stereo_set(pr->renderer, PR_STEREO_NONE);
                if (pr->renderer2) pr->renderer2->free(pr->renderer2);
                pr->renderer2 = NULL;
index 354d8bc..f060902 100644 (file)
@@ -74,20 +74,19 @@ struct _RendererFuncs
 {
        void (*redraw)(void *renderer, gint x, gint y, gint w, gint h,
                      gint clamp, ImageRenderType render, gboolean new_data, gboolean only_existing);
-        void (*area_changed)(void *renderer, gint src_x, gint src_y, gint src_w, gint src_h);
-       void (*queue_clear)(void *renderer);
-       void (*border_clear)(void *renderer);
-       void (*invalidate_all)(void *renderer);
+        void (*area_changed)(void *renderer, gint src_x, gint src_y, gint src_w, gint src_h); /* pixbuf area changed */
        void (*invalidate_region)(void *renderer, gint x, gint y, gint w, gint h);
-       void (*scroll)(void *renderer, gint x_off, gint y_off);
-       void (*update_sizes)(void *renderer);
+       void (*scroll)(void *renderer, gint x_off, gint y_off); /* scroll */
+       void (*update_sizes)(void *renderer); /* window / wiewport / borders / border color has changed */
+       void (*update_pixbuf)(void *renderer, gboolean lazy); /* pixbuf has changed */
+       void (*update_zoom)(void *renderer, gboolean lazy); /* zoom has changed */
 
        gint (*overlay_add)(void *renderer, GdkPixbuf *pixbuf, gint x, gint y, OverlayRendererFlags flags);
        void (*overlay_set)(void *renderer, gint id, GdkPixbuf *pixbuf, gint x, gint y);
        gboolean (*overlay_get)(void *renderer, gint id, GdkPixbuf **pixbuf, gint *x, gint *y);
        void (*overlay_draw)(void *renderer, gint x, gint y, gint w, gint h);
 
-       void (*stereo_set)(void *renderer, gint stereo_mode);
+       void (*stereo_set)(void *renderer, gint stereo_mode); /* set stereo mode */
 
        void (*free)(void *renderer);
 };
diff --git a/src/renderer-clutter.c b/src/renderer-clutter.c
new file mode 100644 (file)
index 0000000..52259fb
--- /dev/null
@@ -0,0 +1,480 @@
+/*
+ * Geeqie
+ * (C) 2006 John Ellis
+ * Copyright (C) 2008 - 2012 The Geeqie Team
+ *
+ * Author: John Ellis
+ * Author: Vladimir Nadvornik
+ *
+ * This software is released under the GNU General Public License (GNU GPL).
+ * Please read the included file COPYING for more information.
+ * This software comes with no warranty of any kind, use at your own risk!
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "main.h"
+#include "pixbuf-renderer.h"
+#include "renderer-clutter.h"
+
+#include "intl.h"
+#include "layout.h"
+
+#include <gtk/gtk.h>
+#include <clutter/clutter.h>
+
+#include <clutter-gtk/clutter-gtk.h>
+
+
+
+#define GQ_BUILD 1
+
+#ifdef GQ_BUILD
+#include "main.h"
+#include "pixbuf_util.h"
+#include "exif.h"
+#else
+typedef enum {
+       EXIF_ORIENTATION_UNKNOWN        = 0,
+       EXIF_ORIENTATION_TOP_LEFT       = 1,
+       EXIF_ORIENTATION_TOP_RIGHT      = 2,
+       EXIF_ORIENTATION_BOTTOM_RIGHT   = 3,
+       EXIF_ORIENTATION_BOTTOM_LEFT    = 4,
+       EXIF_ORIENTATION_LEFT_TOP       = 5,
+       EXIF_ORIENTATION_RIGHT_TOP      = 6,
+       EXIF_ORIENTATION_RIGHT_BOTTOM   = 7,
+       EXIF_ORIENTATION_LEFT_BOTTOM    = 8
+} ExifOrientationType;
+#endif
+
+
+typedef struct _OverlayData OverlayData;
+struct _OverlayData
+{
+       gint id;
+
+       GdkPixbuf *pixbuf;
+       GdkWindow *window;
+
+       gint x;
+       gint y;
+
+       OverlayRendererFlags flags;
+};
+
+typedef struct _RendererClutter RendererClutter;
+
+struct _RendererClutter
+{
+       RendererFuncs f;
+       PixbufRenderer *pr;
+
+       
+       gint stereo_mode;
+       gint stereo_off_x;
+       gint stereo_off_y;
+       
+       gint x_scroll;  /* allow local adjustment and mirroring */
+       gint y_scroll;
+       
+       GtkWidget *widget; /* widget and stage may be shared with other renderers */
+       ClutterActor *stage;
+       ClutterActor *texture;
+       ClutterActor *group;
+};
+
+static void rc_sync_scroll(RendererClutter *rc)
+{
+       PixbufRenderer *pr = rc->pr;
+       
+       rc->x_scroll = (rc->stereo_mode & PR_STEREO_MIRROR) ? 
+                      pr->width - pr->vis_width - pr->x_scroll 
+                      : pr->x_scroll;
+       
+       rc->y_scroll = (rc->stereo_mode & PR_STEREO_FLIP) ? 
+                      pr->height - pr->vis_height - pr->y_scroll 
+                      : pr->y_scroll;
+}
+
+static gint rc_get_orientation(RendererClutter *rc)
+{
+       PixbufRenderer *pr = rc->pr;
+
+       gint orientation = pr->orientation;
+       static const gint mirror[]       = {1,   2, 1, 4, 3, 6, 5, 8, 7};
+       static const gint flip[]         = {1,   4, 3, 2, 1, 8, 7, 6, 5};
+
+       if (rc->stereo_mode & PR_STEREO_MIRROR) orientation = mirror[orientation];
+       if (rc->stereo_mode & PR_STEREO_FLIP) orientation = flip[orientation];
+        return orientation;
+}
+
+
+static void rc_sync_actor(RendererClutter *rc)
+{
+       PixbufRenderer *pr = rc->pr;
+       gint anchor_x = 0;
+       gint anchor_y = 0;
+       
+       rc_sync_scroll(rc);
+       
+       clutter_actor_set_anchor_point(CLUTTER_ACTOR(rc->texture), 0, 0);
+
+       printf("scale %d %d\n", rc->pr->width, rc->pr->height);
+       printf("pos   %d %d        %d %d\n", rc->pr->x_offset, rc->pr->y_offset, rc->x_scroll, rc->y_scroll);
+       
+       switch (rc_get_orientation(rc))
+               {
+               case EXIF_ORIENTATION_TOP_LEFT:
+                       /* normal  */
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Z_AXIS,
+                                               0, 0, 0, 0);
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Y_AXIS,
+                                               0, 0, 0, 0);
+                       clutter_actor_set_size(CLUTTER_ACTOR(rc->texture), pr->width, pr->height);
+                       anchor_x = 0;
+                       anchor_y = 0;
+                       break;
+               case EXIF_ORIENTATION_TOP_RIGHT:
+                       /* mirrored */
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Z_AXIS,
+                                               0, 0, 0, 0);
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Y_AXIS,
+                                               180, 0, 0, 0);
+                       clutter_actor_set_size(CLUTTER_ACTOR(rc->texture), pr->width, pr->height);
+                       anchor_x = pr->width;
+                       anchor_y = 0;
+                       break;
+               case EXIF_ORIENTATION_BOTTOM_RIGHT:
+                       /* upside down */
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Z_AXIS,
+                                               180, 0, 0, 0);
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Y_AXIS,
+                                               0, 0, 0, 0);
+                       clutter_actor_set_size(CLUTTER_ACTOR(rc->texture), pr->width, pr->height);
+                       anchor_x = pr->width;
+                       anchor_y = pr->height;
+                       break;
+               case EXIF_ORIENTATION_BOTTOM_LEFT:
+                       /* flipped */
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Z_AXIS,
+                                               180, 0, 0, 0);
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Y_AXIS,
+                                               180, 0, 0, 0);
+                       clutter_actor_set_size(CLUTTER_ACTOR(rc->texture), pr->width, pr->height);
+                       anchor_x = 0;
+                       anchor_y = pr->height;
+                       break;
+               case EXIF_ORIENTATION_LEFT_TOP:
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Z_AXIS,
+                                               -90, 0, 0, 0);
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Y_AXIS,
+                                               180, 0, 0, 0);
+                       clutter_actor_set_size(CLUTTER_ACTOR(rc->texture), pr->height, pr->width);
+                       anchor_x = 0;
+                       anchor_y = 0;
+                       break;
+               case EXIF_ORIENTATION_RIGHT_TOP:
+                       /* rotated -90 (270) */
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Z_AXIS,
+                                               -90, 0, 0, 0);
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Y_AXIS,
+                                               0, 0, 0, 0);
+                       clutter_actor_set_size(CLUTTER_ACTOR(rc->texture), pr->height, pr->width);
+                       anchor_x = 0;
+                       anchor_y = pr->height;
+                       break;
+               case EXIF_ORIENTATION_RIGHT_BOTTOM:
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Z_AXIS,
+                                               90, 0, 0, 0);
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Y_AXIS,
+                                               180, 0, 0, 0);
+                       clutter_actor_set_size(CLUTTER_ACTOR(rc->texture), pr->height, pr->width);
+                       anchor_x = pr->width;
+                       anchor_y = pr->height;
+                       break;
+               case EXIF_ORIENTATION_LEFT_BOTTOM:
+                       /* rotated 90 */
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Z_AXIS,
+                                               90, 0, 0, 0);
+                       clutter_actor_set_rotation(CLUTTER_ACTOR(rc->texture),
+                                               CLUTTER_Y_AXIS,
+                                               0, 0, 0, 0);
+                       clutter_actor_set_size(CLUTTER_ACTOR(rc->texture), pr->height, pr->width);
+                       anchor_x = pr->width;
+                       anchor_y = 0;
+                       break;
+               default:
+                       /* The other values are out of range */
+                       break;
+               }
+       
+       clutter_actor_set_position(CLUTTER_ACTOR(rc->texture), 
+                               pr->x_offset - rc->x_scroll + anchor_x, 
+                               pr->y_offset - rc->y_scroll + anchor_y);
+
+}
+
+
+static void renderer_area_changed(void *renderer, gint src_x, gint src_y, gint src_w, gint src_h)
+{
+       RendererClutter *rc = (RendererClutter *)renderer;
+       PixbufRenderer *pr = rc->pr;
+       
+       
+       
+       printf("renderer_area_changed %d %d %d %d\n", src_x, src_y, src_w, src_h);
+       if (pr->pixbuf)
+               {
+               CoglHandle texture = clutter_texture_get_cogl_texture(CLUTTER_TEXTURE(rc->texture));
+               
+               cogl_texture_set_region(texture,
+                                       src_x,
+                                       src_y,
+                                       src_x,
+                                       src_y,
+                                       src_w,
+                                       src_h,
+                                       src_w,
+                                       src_h,
+                                       gdk_pixbuf_get_has_alpha(pr->pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
+                                       gdk_pixbuf_get_rowstride(pr->pixbuf),
+                                       gdk_pixbuf_get_pixels(pr->pixbuf));
+               clutter_actor_queue_redraw(CLUTTER_ACTOR(rc->texture));
+               }
+
+}
+
+static void renderer_redraw(void *renderer, gint x, gint y, gint w, gint h,
+                     gint clamp, ImageRenderType render, gboolean new_data, gboolean only_existing)
+{
+       RendererClutter *rc = (RendererClutter *)renderer;
+       PixbufRenderer *pr = rc->pr;
+}
+
+static void renderer_update_pixbuf(void *renderer, gboolean lazy)
+{
+       RendererClutter *rc = (RendererClutter *)renderer;
+       PixbufRenderer *pr = rc->pr;
+       
+       if (pr->pixbuf)
+               {
+               printf("renderer_update_pixbuf\n");
+               
+               /* FIXME use CoglMaterial with multiple textures for background, color management, anaglyph, ... */
+               CoglHandle texture = cogl_texture_new_with_size(gdk_pixbuf_get_width(pr->pixbuf),
+                                                               gdk_pixbuf_get_height(pr->pixbuf),
+                                                               COGL_TEXTURE_NONE,
+                                                               gdk_pixbuf_get_has_alpha(pr->pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888);
+
+               if (texture != COGL_INVALID_HANDLE)
+                       {
+                       clutter_texture_set_cogl_texture(CLUTTER_TEXTURE(rc->texture), texture);
+                       cogl_handle_unref(texture);
+                       }
+               if (!lazy)
+                       {
+                       renderer_area_changed(renderer, 0, 0, gdk_pixbuf_get_width(pr->pixbuf), gdk_pixbuf_get_height(pr->pixbuf));
+                       }
+               }
+
+
+       printf("renderer_update_pixbuf\n");
+       rc_sync_actor(rc);
+}
+
+
+
+static void renderer_update_zoom(void *renderer, gboolean lazy)
+{
+       RendererClutter *rc = (RendererClutter *)renderer;
+       PixbufRenderer *pr = rc->pr;
+
+       printf("renderer_update_zoom\n");
+       rc_sync_actor(rc);
+}
+
+static void renderer_invalidate_region(void *renderer, gint x, gint y, gint w, gint h)
+{
+}
+
+static void renderer_overlay_draw(void *renderer, gint x, gint y, gint w, gint h)
+{
+}
+
+static void renderer_overlay_add(void *renderer, gint x, gint y, gint w, gint h)
+{
+}
+
+static void renderer_overlay_set(void *renderer, gint x, gint y, gint w, gint h)
+{
+}
+
+static void renderer_overlay_get(void *renderer, gint x, gint y, gint w, gint h)
+{
+}
+
+static void renderer_update_sizes(void *renderer)
+{
+       RendererClutter *rc = (RendererClutter *)renderer;
+       ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff }; 
+
+       rc->stereo_off_x = 0;
+       rc->stereo_off_y = 0;
+       
+       if (rc->stereo_mode & PR_STEREO_RIGHT) 
+               {
+               if (rc->stereo_mode & PR_STEREO_HORIZ) 
+                       {
+                       rc->stereo_off_x = rc->pr->viewport_width;
+                       }
+               else if (rc->stereo_mode & PR_STEREO_VERT) 
+                       {
+                       rc->stereo_off_y = rc->pr->viewport_height;
+                       }
+               else if (rc->stereo_mode & PR_STEREO_FIXED) 
+                       {
+                       rc->stereo_off_x = rc->pr->stereo_fixed_x_right;
+                       rc->stereo_off_y = rc->pr->stereo_fixed_y_right;
+                       }
+               }
+       else
+               {
+               if (rc->stereo_mode & PR_STEREO_FIXED) 
+                       {
+                       rc->stereo_off_x = rc->pr->stereo_fixed_x_left;
+                       rc->stereo_off_y = rc->pr->stereo_fixed_y_left;
+                       }
+               }
+        DEBUG_1("update size: %p  %d %d   %d %d", rc, rc->stereo_off_x, rc->stereo_off_y, rc->pr->viewport_width, rc->pr->viewport_height);
+
+       printf("renderer_update_sizes  scale %d %d\n", rc->pr->width, rc->pr->height);
+
+        clutter_stage_set_color(CLUTTER_STAGE(rc->stage), &stage_color);
+
+
+       clutter_actor_set_size(rc->group, rc->pr->viewport_width, rc->pr->viewport_height);
+       clutter_actor_set_position(rc->group, rc->stereo_off_x, rc->stereo_off_y);
+       rc_sync_actor(rc);
+}
+
+static void renderer_scroll(void *renderer, gint x_off, gint y_off)
+{
+       printf("renderer_scroll\n");
+       RendererClutter *rc = (RendererClutter *)renderer;
+       PixbufRenderer *pr = rc->pr;
+
+       rc_sync_actor(rc);
+}
+
+static void renderer_stereo_set(void *renderer, gint stereo_mode)
+{
+       RendererClutter *rc = (RendererClutter *)renderer;
+
+       rc->stereo_mode = stereo_mode;
+}
+
+static void renderer_free(void *renderer)
+{
+       RendererClutter *rc = (RendererClutter *)renderer;
+       GtkWidget *widget = gtk_bin_get_child(GTK_BIN(rc->pr));
+       if (widget)
+               {
+               /* widget still exists */
+               clutter_actor_destroy(rc->group);
+               if (clutter_group_get_n_children(CLUTTER_GROUP(rc->stage)) == 0)
+                       {
+                       printf("destroy %p\n", rc->widget);
+                       /* this was the last user */
+                       gtk_widget_destroy(rc->widget);
+                       }
+               else
+                       {
+                       printf("keep %p\n", rc->widget);
+                       g_object_unref(G_OBJECT(rc->widget));
+                       }
+               }
+       g_free(rc);
+}
+
+RendererFuncs *renderer_clutter_new(PixbufRenderer *pr)
+{
+       RendererClutter *rc = g_new0(RendererClutter, 1);
+       
+       rc->pr = pr;
+       
+       rc->f.redraw = renderer_redraw;
+       rc->f.area_changed = renderer_area_changed;
+       rc->f.update_pixbuf = renderer_update_pixbuf;
+       rc->f.free = renderer_free;
+       rc->f.update_zoom = renderer_update_zoom;
+       rc->f.invalidate_region = renderer_invalidate_region;
+       rc->f.scroll = renderer_scroll;
+       rc->f.update_sizes = renderer_update_sizes;
+
+
+       rc->f.overlay_add = renderer_overlay_add;
+       rc->f.overlay_set = renderer_overlay_set;
+       rc->f.overlay_get = renderer_overlay_get;
+       rc->f.overlay_draw = renderer_overlay_draw;
+
+       rc->f.stereo_set = renderer_stereo_set;
+       
+       
+       rc->stereo_mode = 0;
+       rc->stereo_off_x = 0;
+       rc->stereo_off_y = 0;
+
+
+       rc->widget = gtk_bin_get_child(GTK_BIN(rc->pr));
+       
+       if (rc->widget)
+               {
+               if (!GTK_CLUTTER_IS_EMBED(rc->widget))
+                       {
+                       g_free(rc);
+                       DEBUG_0("pixbuf renderer has a child of other type than gtk_clutter_embed");
+                       return NULL;
+                       }
+               }
+       else 
+               {
+               rc->widget = gtk_clutter_embed_new();
+               gtk_container_add(GTK_CONTAINER(rc->pr), rc->widget);
+               }
+               
+       gtk_event_box_set_above_child (GTK_EVENT_BOX(rc->pr), TRUE);
+        rc->stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (rc->widget));
+        
+        rc->group = clutter_group_new();
+       clutter_container_add_actor(CLUTTER_CONTAINER(rc->stage), rc->group);
+       clutter_actor_set_clip_to_allocation(CLUTTER_ACTOR(rc->group), TRUE);
+  
+       rc->texture = gtk_clutter_texture_new ();
+       clutter_container_add_actor(CLUTTER_CONTAINER(rc->group), rc->texture);
+       g_object_ref(G_OBJECT(rc->widget));
+  
+       gtk_widget_show(rc->widget);
+       return (RendererFuncs *) rc;
+}
+
+
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
diff --git a/src/renderer-clutter.h b/src/renderer-clutter.h
new file mode 100644 (file)
index 0000000..4a802d8
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Geeqie
+ * (C) 2006 John Ellis
+ * Copyright (C) 2008 - 2012 The Geeqie Team
+ *
+ * Author: John Ellis
+ *
+ * This software is released under the GNU General Public License (GNU GPL).
+ * Please read the included file COPYING for more information.
+ * This software comes with no warranty of any kind, use at your own risk!
+ */
+
+#ifndef RENDERER_CLUTTER_H
+#define RENDERER_CLUTTER_H
+
+#include <pixbuf-renderer.h>
+
+
+RendererFuncs *renderer_clutter_new(PixbufRenderer *pr);
+
+#endif
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
index f52a4f2..16c313b 100644 (file)
@@ -2052,20 +2052,21 @@ static void renderer_redraw(void *renderer, gint x, gint y, gint w, gint h,
                 clamp, render, new_data, only_existing);
 }
 
-static void renderer_queue_clear(void *renderer)
+static void renderer_update_pixbuf(void *renderer, gboolean lazy)
 {
        rt_queue_clear((RendererTiles *)renderer);
 }
 
-static void renderer_border_clear(void *renderer)
+static void renderer_update_zoom(void *renderer, gboolean lazy)
 {
-       rt_border_clear((RendererTiles *)renderer);
-}
-
+       RendererTiles *rt = (RendererTiles *)renderer;
+       PixbufRenderer *pr = rt->pr;
 
-static void renderer_invalidate_all(void *renderer)
-{
        rt_tile_invalidate_all((RendererTiles *)renderer);
+       if (!lazy)
+               {
+               renderer_redraw(renderer, 0, 0, pr->width, pr->height, TRUE, TILE_RENDER_ALL, TRUE, FALSE);
+               }
 }
 
 static void renderer_invalidate_region(void *renderer, gint x, gint y, gint w, gint h)
@@ -2112,6 +2113,7 @@ static void renderer_update_sizes(void *renderer)
         DEBUG_1("update size: %p  %d %d   %d %d", rt, rt->stereo_off_x, rt->stereo_off_y, rt->pr->viewport_width, rt->pr->viewport_height);
        rt_sync_scroll(rt);
        rt_overlay_update_sizes(rt);
+       rt_border_clear(rt);
 }
 
 static void renderer_stereo_set(void *renderer, gint stereo_mode)
@@ -2143,10 +2145,9 @@ RendererFuncs *renderer_tiles_new(PixbufRenderer *pr)
        
        rt->f.redraw = renderer_redraw;
        rt->f.area_changed = renderer_area_changed;
-       rt->f.queue_clear = renderer_queue_clear;
-       rt->f.border_clear = renderer_border_clear;
+       rt->f.update_pixbuf = renderer_update_pixbuf;
        rt->f.free = renderer_free;
-       rt->f.invalidate_all = renderer_invalidate_all;
+       rt->f.update_zoom = renderer_update_zoom;
        rt->f.invalidate_region = renderer_invalidate_region;
        rt->f.scroll = rt_scroll;
        rt->f.update_sizes = renderer_update_sizes;