From ceb0eefbcf257ad4967ead2e441c6feb8d46f4ff Mon Sep 17 00:00:00 2001 From: Vladimir Nadvornik Date: Sat, 11 Aug 2012 23:46:42 +0200 Subject: [PATCH] implemented clutter-based renderer --- src/Makefile.am | 2 + src/pixbuf-renderer.c | 65 +++--- src/pixbuf-renderer.h | 13 +- src/renderer-clutter.c | 480 +++++++++++++++++++++++++++++++++++++++++ src/renderer-clutter.h | 22 ++ src/renderer-tiles.c | 21 +- 6 files changed, 548 insertions(+), 55 deletions(-) create mode 100644 src/renderer-clutter.c create mode 100644 src/renderer-clutter.h diff --git a/src/Makefile.am b/src/Makefile.am index 02d31a67..03421966 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/pixbuf-renderer.c b/src/pixbuf-renderer.c index 2021a1fb..c07b2780 100644 --- a/src/pixbuf-renderer.c +++ b/src/pixbuf-renderer.c @@ -18,12 +18,14 @@ #include "main.h" #include "pixbuf-renderer.h" #include "renderer-tiles.h" +#include "renderer-clutter.h" #include "intl.h" #include "layout.h" #include +#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; diff --git a/src/pixbuf-renderer.h b/src/pixbuf-renderer.h index 354d8bc2..f0609026 100644 --- a/src/pixbuf-renderer.h +++ b/src/pixbuf-renderer.h @@ -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 index 00000000..52259fb4 --- /dev/null +++ b/src/renderer-clutter.c @@ -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 +#include +#include +#include + +#include "main.h" +#include "pixbuf-renderer.h" +#include "renderer-clutter.h" + +#include "intl.h" +#include "layout.h" + +#include +#include + +#include + + + +#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 index 00000000..4a802d82 --- /dev/null +++ b/src/renderer-clutter.h @@ -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 + + +RendererFuncs *renderer_clutter_new(PixbufRenderer *pr); + +#endif +/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff --git a/src/renderer-tiles.c b/src/renderer-tiles.c index f52a4f27..16c313be 100644 --- a/src/renderer-tiles.c +++ b/src/renderer-tiles.c @@ -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; -- 2.20.1