first stereo support
authorVladimir Nadvornik <nadvornik@suse.cz>
Fri, 28 Jan 2011 10:05:07 +0000 (11:05 +0100)
committerVladimir Nadvornik <nadvornik@suse.cz>
Tue, 27 Sep 2011 12:28:51 +0000 (14:28 +0200)
src/image-load.c
src/image.c
src/pixbuf-renderer.c
src/pixbuf-renderer.h
src/renderer-tiles.c
src/renderer-tiles.h

index b661579..e225dbe 100644 (file)
@@ -362,6 +362,11 @@ static void image_loader_sync_pixbuf(ImageLoader *il)
                return;
                }
 
+       if (g_ascii_strcasecmp(".jps", il->fd->extension) == 0)
+               {
+               g_object_set_data(G_OBJECT(pb), "stereo_sbs", GINT_TO_POINTER(1));
+               }
+
        if (il->pixbuf) g_object_unref(il->pixbuf);
 
        il->pixbuf = pb;
index 579e7cd..4f777af 100644 (file)
@@ -1340,11 +1340,11 @@ void image_zoom_set_fill_geometry(ImageWindow *imd, gboolean vertical)
 
        if (vertical)
                {
-               zoom = (gdouble)pr->window_height / height;
+               zoom = (gdouble)pr->viewport_height / height;
                }
        else
                {
-               zoom = (gdouble)pr->window_width / width;
+               zoom = (gdouble)pr->viewport_width / width;
                }
 
        if (zoom < 1.0)
index d2b5389..ce27ecf 100644 (file)
@@ -428,7 +428,12 @@ static void pixbuf_renderer_init(PixbufRenderer *pr)
        pr->norm_center_x = 0.5;
        pr->norm_center_y = 0.5;
        
-       pr->renderer = (void *)renderer_tiles_new(pr);
+       pr->stereo_mode = PR_STEREO_HORIZ;
+       
+       pr->renderer = (void *)renderer_tiles_new(pr, pr->stereo_mode);
+       
+       pr->renderer2 = (pr->stereo_mode && (PR_STEREO_HORIZ || PR_STEREO_VERT)) ?
+                     (void *)renderer_tiles_new(pr, pr->stereo_mode | PR_STEREO_RIGHT) : NULL;
 
        gtk_widget_set_double_buffered(box, FALSE);
        g_signal_connect_after(G_OBJECT(box), "size_allocate",
@@ -444,6 +449,7 @@ static void pixbuf_renderer_finalize(GObject *object)
        pr = PIXBUF_RENDERER(object);
 
        pr->renderer->free(pr->renderer);
+       if (pr->renderer2) pr->renderer->free(pr->renderer2);
 
 
        if (pr->pixbuf) g_object_unref(pr->pixbuf);
@@ -745,22 +751,27 @@ GtkWindow *pixbuf_renderer_get_parent(PixbufRenderer *pr)
 gint pixbuf_renderer_overlay_add(PixbufRenderer *pr, GdkPixbuf *pixbuf, gint x, gint y,
                                 OverlayRendererFlags flags)
 {
+       /* let's assume both renderers returns the same value */
+       if (pr->renderer2) pr->renderer2->overlay_add(pr->renderer2, pixbuf, x, y, flags);
        return pr->renderer->overlay_add(pr->renderer, pixbuf, x, y, flags);
 }
 
 void pixbuf_renderer_overlay_set(PixbufRenderer *pr, gint id, GdkPixbuf *pixbuf, gint x, gint y)
 {
        pr->renderer->overlay_set(pr->renderer, id, pixbuf, x, y);
+       if (pr->renderer2) pr->renderer2->overlay_set(pr->renderer2, id, pixbuf, x, y);
 }
 
 gboolean pixbuf_renderer_overlay_get(PixbufRenderer *pr, gint id, GdkPixbuf **pixbuf, gint *x, gint *y)
 {
+       if (pr->renderer2) pr->renderer2->overlay_get(pr->renderer2, id, pixbuf, x, y);
        return pr->renderer->overlay_get(pr->renderer, id, pixbuf, x, y);
 }
 
 void pixbuf_renderer_overlay_remove(PixbufRenderer *pr, gint id)
 {
        pr->renderer->overlay_set(pr->renderer, id, NULL, 0, 0);
+       if (pr->renderer2) pr->renderer2->overlay_set(pr->renderer2, id, NULL, 0, 0);
 }
 
 /*
@@ -918,7 +929,8 @@ static void pr_scroller_stop(PixbufRenderer *pr)
 
 static void pr_border_clear(PixbufRenderer *pr)
 {
-       pr->renderer->border_draw(pr->renderer, 0, 0, pr->window_width, pr->window_height);
+       pr->renderer->border_draw(pr->renderer, 0, 0, pr->viewport_width, pr->viewport_height);
+       if (pr->renderer2) pr->renderer2->border_draw(pr->renderer2, 0, 0, pr->viewport_width, pr->viewport_height);
 }
 
 void pixbuf_renderer_set_color(PixbufRenderer *pr, GdkColor *color)
@@ -957,6 +969,10 @@ static void pr_redraw(PixbufRenderer *pr, gboolean new_data)
 {
        pr->renderer->queue_clear(pr->renderer);
        pr->renderer->queue(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->queue(pr->renderer2, 0, 0, pr->width, pr->height, TRUE, TILE_RENDER_ALL, new_data, FALSE);
+       }
 }
 
 /*
@@ -1098,7 +1114,8 @@ static SourceTile *pr_source_tile_request(PixbufRenderer *pr, gint x, gint y)
 
        pr->renderer->invalidate_region(pr->renderer, st->x * pr->scale, st->y * pr->scale,
                                  pr->source_tile_width * pr->scale, pr->source_tile_height * pr->scale);
-
+       if (pr->renderer2) pr->renderer2->invalidate_region(pr->renderer2, st->x * pr->scale, st->y * pr->scale,
+                                 pr->source_tile_width * pr->scale, pr->source_tile_height * pr->scale);
        return st;
 }
 
@@ -1185,6 +1202,8 @@ static void pr_source_tile_changed(PixbufRenderer *pr, gint x, gint y, gint widt
                                {
                                        pr->renderer->invalidate_region(pr->renderer, rx * pr->scale, ry * pr->scale,
                                                              rw * pr->scale, rh * pr->scale);
+                                       if (pr->renderer2) pr->renderer2->invalidate_region(pr->renderer2, rx * pr->scale, ry * pr->scale,
+                                                               rw * pr->scale, rh * pr->scale);
                                }
                        g_object_unref(pixbuf);
                        }
@@ -1543,13 +1562,13 @@ static void pixbuf_renderer_sync_scroll_center(PixbufRenderer *pr)
         * of the "broken image" icon.
        */
 
-       if (pr->width > pr->window_width)
+       if (pr->width > pr->viewport_width)
                {
                src_x = pr->x_scroll + pr->vis_width / 2;
                pr->norm_center_x = (gdouble)src_x / pr->width;
                }
        
-       if (pr->height > pr->window_height)
+       if (pr->height > pr->viewport_height)
                {
                src_y = pr->y_scroll + pr->vis_height / 2;
                pr->norm_center_y = (gdouble)src_y / pr->height;
@@ -1603,25 +1622,25 @@ static gboolean pr_size_clamp(PixbufRenderer *pr)
        old_vw = pr->vis_width;
        old_vh = pr->vis_height;
 
-       if (pr->width < pr->window_width)
+       if (pr->width < pr->viewport_width)
                {
                pr->vis_width = pr->width;
-               pr->x_offset = (pr->window_width - pr->width) / 2;
+               pr->x_offset = (pr->viewport_width - pr->width) / 2;
                }
        else
                {
-               pr->vis_width = pr->window_width;
+               pr->vis_width = pr->viewport_width;
                pr->x_offset = 0;
                }
 
-       if (pr->height < pr->window_height)
+       if (pr->height < pr->viewport_height)
                {
                pr->vis_height = pr->height;
-               pr->y_offset = (pr->window_height - pr->height) / 2;
+               pr->y_offset = (pr->viewport_height - pr->height) / 2;
                }
        else
                {
-               pr->vis_height = pr->window_height;
+               pr->vis_height = pr->viewport_height;
                pr->y_offset = 0;
                }
 
@@ -1673,8 +1692,8 @@ static gboolean pr_zoom_clamp(PixbufRenderer *pr, gdouble zoom,
                        }
                else
                        {
-                       max_w = pr->window_width;
-                       max_h = pr->window_height;
+                       max_w = pr->viewport_width;
+                       max_h = pr->viewport_height;
                        }
 
                if ((pr->zoom_expand && !sizeable) || w > max_w || h > max_h)
@@ -1733,6 +1752,7 @@ 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);
                }
        if (redrawn) *redrawn = (invalidate || invalid);
@@ -1828,6 +1848,7 @@ static void pr_zoom_sync(PixbufRenderer *pr, gdouble zoom,
        if (lazy)
                {
                pr->renderer->queue_clear(pr->renderer);
+               if (pr->renderer2) pr->renderer2->queue_clear(pr->renderer2);
                }
        else
                {
@@ -1843,10 +1864,16 @@ static void pr_size_sync(PixbufRenderer *pr, gint new_width, gint new_height)
 {
        gboolean zoom_changed = FALSE;
 
-       if (pr->window_width == new_width && pr->window_height == new_height) return;
+       gint new_viewport_width = (pr->stereo_mode & PR_STEREO_HORIZ) ? new_width / 2 : new_width;
+       gint new_viewport_height = (pr->stereo_mode & PR_STEREO_VERT) ? new_height / 2 : new_height;
+       
+       if (pr->window_width == new_width && pr->window_height == new_height &&
+           pr->viewport_width == new_viewport_width && pr->viewport_height == new_viewport_height) return;
 
        pr->window_width = new_width;
        pr->window_height = new_height;
+       pr->viewport_width = new_viewport_width;
+       pr->viewport_height = new_viewport_height;
 
        if (pr->zoom == 0.0)
                {
@@ -1858,7 +1885,8 @@ static void pr_size_sync(PixbufRenderer *pr, gint new_width, gint new_height)
        pr_size_clamp(pr);
        pr_scroll_clamp(pr);
 
-       pr->renderer->overlay_update_sizes(pr->renderer);
+       pr->renderer->update_sizes(pr->renderer);
+       if (pr->renderer2) pr->renderer2->update_sizes(pr->renderer2);
 
        /* ensure scroller remains visible */
        if (pr->scroller_overlay != -1)
@@ -1912,16 +1940,25 @@ static void pixbuf_renderer_paint(PixbufRenderer *pr, GdkRectangle *area)
 {
        gint x, y;
 
-       pr->renderer->border_draw(pr->renderer, area->x, area->y, area->width, area->height);
 
        x = MAX(0, (gint)area->x - pr->x_offset + pr->x_scroll);
        y = MAX(0, (gint)area->y - pr->y_offset + pr->y_scroll);
 
+       pr->renderer->border_draw(pr->renderer, area->x, area->y, area->width, area->height);
        pr->renderer->queue(pr->renderer,
                              x, y,
                              MIN((gint)area->width, pr->width - x),
                              MIN((gint)area->height, pr->height - y),
                              FALSE, TILE_RENDER_ALL, FALSE, FALSE);
+       if (pr->renderer2) 
+               {
+               pr->renderer2->border_draw(pr->renderer2, area->x, area->y, area->width, area->height);
+               pr->renderer2->queue(pr->renderer2,
+                             x, y,
+                             MIN((gint)area->width, pr->width - x),
+                             MIN((gint)area->height, pr->height - y),
+                             FALSE, TILE_RENDER_ALL, FALSE, FALSE);
+               }
 }
 
 /*
@@ -1957,6 +1994,7 @@ void pixbuf_renderer_scroll(PixbufRenderer *pr, gint x, gint y)
        y_off = pr->y_scroll - old_y;
        
        pr->renderer->scroll(pr->renderer, x_off, y_off);
+       if (pr->renderer2) pr->renderer2->scroll(pr->renderer2, x_off, y_off);
 }
 
 void pixbuf_renderer_scroll_to_point(PixbufRenderer *pr, gint x, gint y,
@@ -2216,6 +2254,7 @@ static void pr_signals_connect(PixbufRenderer *pr)
  */
 static void pr_pixbuf_size_sync(PixbufRenderer *pr)
 {
+       pr->stereo_pixbuf_off = 0;
        if (!pr->pixbuf) return;
        switch (pr->orientation)
                {
@@ -2225,10 +2264,21 @@ static void pr_pixbuf_size_sync(PixbufRenderer *pr)
                case EXIF_ORIENTATION_LEFT_BOTTOM:
                        pr->image_width = gdk_pixbuf_get_height(pr->pixbuf);
                        pr->image_height = gdk_pixbuf_get_width(pr->pixbuf);
+                       if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(pr->pixbuf), "stereo_sbs"))) 
+                               {
+                               pr->image_height /= 2;
+                               pr->stereo_pixbuf_off = pr->image_height;
+                               }
+                       
                        break;
                default:
                        pr->image_width = gdk_pixbuf_get_width(pr->pixbuf);
                        pr->image_height = gdk_pixbuf_get_height(pr->pixbuf);
+                       if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(pr->pixbuf), "stereo_sbs"))) 
+                               {
+                               pr->image_width /= 2;
+                               pr->stereo_pixbuf_off = pr->image_width;
+                               }
                }
 }
 
@@ -2258,7 +2308,8 @@ static void pr_set_pixbuf(PixbufRenderer *pr, GdkPixbuf *pixbuf, gdouble zoom, P
 #endif
                        {
                        gdk_window_clear(box->window);
-                       pr->renderer->overlay_draw(pr->renderer, 0, 0, pr->window_width, pr->window_height);
+                       pr->renderer->overlay_draw(pr->renderer, 0, 0, pr->viewport_width, pr->viewport_height);
+                       if (pr->renderer2) pr->renderer2->overlay_draw(pr->renderer2, 0, 0, pr->viewport_width, pr->viewport_height);
                        }
 
                pr_update_signal(pr);
@@ -2422,6 +2473,7 @@ void pixbuf_renderer_area_changed(PixbufRenderer *pr, gint src_x, gint src_y, gi
        y2 = (gint)ceil((gdouble)(y + height) * pr->scale);
 
        pr->renderer->queue(pr->renderer, x1, y1, x2 - x1, y2 - y1, FALSE, TILE_RENDER_AREA, TRUE, TRUE);
+       if (pr->renderer2) pr->renderer2->queue(pr->renderer2, x1, y1, x2 - x1, y2 - y1, FALSE, TILE_RENDER_AREA, TRUE, TRUE);
 }
 
 void pixbuf_renderer_zoom_adjust(PixbufRenderer *pr, gdouble increment)
index 46dbe5b..77593f8 100644 (file)
@@ -74,6 +74,17 @@ typedef enum {
        /* OVL_HIDE_ON_SCROLL = 1 << 1*/ /* hide temporarily when scrolling (not yet implemented) */
 } OverlayRendererFlags;
 
+typedef enum {
+       PR_STEREO_NONE     = 0,   /* do nothing */
+       PR_STEREO_DUAL     = 1 << 0, /* independent stereo buffers, for example nvidia opengl */
+       PR_STEREO_HORIZ    = 1 << 2, /* side by side */
+       PR_STEREO_VERT     = 1 << 3, /* above below */
+       /* flags for renderer: */
+       PR_STEREO_RIGHT    = 1 << 4, /* above below */
+       PR_STEREO_ANAGLYPH = 1 << 5  /* anaglyph */
+       
+} PixbufRendererStereoMode;
+
 struct _RendererFuncs
 {
        void (*queue)(void *renderer, gint x, gint y, gint w, gint h,
@@ -83,11 +94,11 @@ struct _RendererFuncs
        void (*invalidate_all)(void *renderer);
        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);
 
        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_update_sizes)(void *renderer);
        void (*overlay_draw)(void *renderer, gint x, gint y, gint w, gint h);
 
        void (*free)(void *renderer);
@@ -99,6 +110,7 @@ struct _PixbufRenderer
 
        gint image_width;       /* image actual dimensions (pixels) */
        gint image_height;
+       gint stereo_pixbuf_off; /* offset of the right part of the stereo image in pixbuf */
 
        GdkPixbuf *pixbuf;
 
@@ -193,7 +205,10 @@ struct _PixbufRenderer
 
        gint orientation;
 
+       gint stereo_mode;
+       
        RendererFuncs *renderer;
+       RendererFuncs *renderer2;
 };
 
 struct _PixbufRendererClass
index f1b313a..d9f6206 100644 (file)
@@ -130,7 +130,10 @@ struct _RendererTiles
        guint draw_idle_id; /* event source id */
 
        GdkPixbuf *spare_tile;
-
+       
+       gint stereo_mode;
+       gint stereo_off_x;
+       gint stereo_off_y;
 };
 
 
@@ -176,37 +179,37 @@ static void rt_border_draw(RendererTiles *rt, gint x, gint y, gint w, gint h)
                {
                if (pr_clip_region(x, y, w, h,
                                   0, 0,
-                                  pr->window_width, pr->window_height,
+                                  pr->viewport_width, pr->viewport_height,
                                   &rx, &ry, &rw, &rh))
                        {
-                       gdk_window_clear_area(box->window, rx, ry, rw, rh);
+                       gdk_window_clear_area(box->window, rx + rt->stereo_off_x, ry + rt->stereo_off_y, rw, rh);
                        rt_overlay_draw(rt, rx, ry, rw, rh, NULL);
                        }
                return;
                }
 
-       if (pr->vis_width < pr->window_width)
+       if (pr->vis_width < pr->viewport_width)
                {
                if (pr->x_offset > 0 &&
                    pr_clip_region(x, y, w, h,
                                   0, 0,
-                                  pr->x_offset, pr->window_height,
+                                  pr->x_offset, pr->viewport_height,
                                   &rx, &ry, &rw, &rh))
                        {
-                       gdk_window_clear_area(box->window, rx, ry, rw, rh);
+                       gdk_window_clear_area(box->window, rx + rt->stereo_off_x, ry + rt->stereo_off_y, rw, rh);
                        rt_overlay_draw(rt, rx, ry, rw, rh, NULL);
                        }
-               if (pr->window_width - pr->vis_width - pr->x_offset > 0 &&
+               if (pr->viewport_width - pr->vis_width - pr->x_offset > 0 &&
                    pr_clip_region(x, y, w, h,
                                   pr->x_offset + pr->vis_width, 0,
-                                  pr->window_width - pr->vis_width - pr->x_offset, pr->window_height,
+                                  pr->viewport_width - pr->vis_width - pr->x_offset, pr->viewport_height,
                                   &rx, &ry, &rw, &rh))
                        {
-                       gdk_window_clear_area(box->window, rx, ry, rw, rh);
+                       gdk_window_clear_area(box->window, rx + rt->stereo_off_x, ry + rt->stereo_off_y, rw, rh);
                        rt_overlay_draw(rt, rx, ry, rw, rh, NULL);
                        }
                }
-       if (pr->vis_height < pr->window_height)
+       if (pr->vis_height < pr->viewport_height)
                {
                if (pr->y_offset > 0 &&
                    pr_clip_region(x, y, w, h,
@@ -214,16 +217,16 @@ static void rt_border_draw(RendererTiles *rt, gint x, gint y, gint w, gint h)
                                   pr->vis_width, pr->y_offset,
                                   &rx, &ry, &rw, &rh))
                        {
-                       gdk_window_clear_area(box->window, rx, ry, rw, rh);
+                       gdk_window_clear_area(box->window, rx + rt->stereo_off_x, ry + rt->stereo_off_y, rw, rh);
                        rt_overlay_draw(rt, rx, ry, rw, rh, NULL);
                        }
-               if (pr->window_height - pr->vis_height - pr->y_offset > 0 &&
+               if (pr->viewport_height - pr->vis_height - pr->y_offset > 0 &&
                    pr_clip_region(x, y, w, h,
                                   pr->x_offset, pr->y_offset + pr->vis_height,
-                                  pr->vis_width, pr->window_height - pr->vis_height - pr->y_offset,
+                                  pr->vis_width, pr->viewport_height - pr->vis_height - pr->y_offset,
                                   &rx, &ry, &rw, &rh))
                        {
-                       gdk_window_clear_area(box->window, rx, ry, rw, rh);
+                       gdk_window_clear_area(box->window, rx + rt->stereo_off_x, ry + rt->stereo_off_y, rw, rh);
                        rt_overlay_draw(rt, rx, ry, rw, rh, NULL);
                        }
                }
@@ -232,7 +235,7 @@ static void rt_border_draw(RendererTiles *rt, gint x, gint y, gint w, gint h)
 static void rt_border_clear(RendererTiles *rt)
 {
        PixbufRenderer *pr = rt->pr;
-       rt_border_draw(rt, 0, 0, pr->window_width, pr->window_height);
+       rt_border_draw(rt, 0, 0, pr->viewport_width, pr->viewport_height);
 }
 
 
@@ -502,8 +505,8 @@ static void rt_overlay_get_position(RendererTiles *rt, OverlayData *od,
 
        if (od->flags & OVL_RELATIVE)
                {
-               if (px < 0) px = pr->window_width - pw + px;
-               if (py < 0) py = pr->window_height - ph + py;
+               if (px < 0) px = pr->viewport_width - pw + px;
+               if (py < 0) py = pr->viewport_height - ph + py;
                }
 
        if (x) *x = px;
@@ -1218,6 +1221,7 @@ static void rt_tile_render(RendererTiles *rt, ImageTile *it,
        GtkWidget *box;
        gboolean has_alpha;
        gboolean draw = FALSE;
+       gint stereo_pixbuf_off;
 
        if (it->render_todo == TILE_RENDER_NONE && it->pixmap && !new_data) return;
 
@@ -1242,6 +1246,7 @@ static void rt_tile_render(RendererTiles *rt, ImageTile *it,
        rt_tile_prepare(rt, it);
        has_alpha = (pr->pixbuf && gdk_pixbuf_get_has_alpha(pr->pixbuf));
 
+       stereo_pixbuf_off = (rt->stereo_mode & PR_STEREO_RIGHT) ? pr->stereo_pixbuf_off : 0;
        box = GTK_WIDGET(pr);
 
        /* FIXME checker colors for alpha should be configurable,
@@ -1273,6 +1278,7 @@ static void rt_tile_render(RendererTiles *rt, ImageTile *it,
                                            w, h,
                                            &pb_x, &pb_y,
                                            &pb_w, &pb_h);
+               src_x += stereo_pixbuf_off;
 
                if (has_alpha)
                        {
@@ -1299,7 +1305,7 @@ static void rt_tile_render(RendererTiles *rt, ImageTile *it,
                                                box->style->fg_gc[GTK_WIDGET_STATE(box)],
 #endif
                                                pr->pixbuf,
-                                               it->x + x, it->y + y,
+                                               it->x + x + stereo_pixbuf_off, it->y + y,
                                                x, y,
                                                w, h,
                                                pr->dither_quality, it->x + x, it->y + y);
@@ -1337,6 +1343,7 @@ static void rt_tile_render(RendererTiles *rt, ImageTile *it,
                                            w, h,
                                            &pb_x, &pb_y,
                                            &pb_w, &pb_h);
+
                switch (pr->orientation)
                        {
                        gdouble tmp;
@@ -1352,7 +1359,8 @@ static void rt_tile_render(RendererTiles *rt, ImageTile *it,
                                /* nothing to do */
                                break;
                        }
-
+               src_x += stereo_pixbuf_off * scale_x;
+               
                /* HACK: The pixbuf scalers get kinda buggy(crash) with extremely
                 * small sizes for anything but GDK_INTERP_NEAREST
                 */
@@ -1396,7 +1404,7 @@ static void rt_tile_render(RendererTiles *rt, ImageTile *it,
                                x, y,
                                x, y,
                                w, h,
-                               pr->dither_quality, it->x + x, it->y + y);
+                               pr->dither_quality, it->x + x + rt->stereo_off_x, it->y + y + rt->stereo_off_y);
                }
 
 #if 0
@@ -1426,7 +1434,7 @@ static void rt_tile_expose(RendererTiles *rt, ImageTile *it,
        gdk_draw_drawable(box->window, box->style->fg_gc[GTK_WIDGET_STATE(box)],
 #endif
                          it->pixmap, x, y,
-                         pr->x_offset + (it->x - pr->x_scroll) + x, pr->y_offset + (it->y - pr->y_scroll) + y, w, h);
+                         pr->x_offset + (it->x - pr->x_scroll) + x + rt->stereo_off_x, pr->y_offset + (it->y - pr->y_scroll) + y + rt->stereo_off_y, w, h);
 
        if (rt->overlay_list)
                {
@@ -1869,8 +1877,8 @@ static void rt_scroll(RendererTiles *rt, gint x_off, gint y_off)
                gdk_gc_set_exposures(gc, TRUE);
                gdk_draw_drawable(box->window, gc,
                                  box->window,
-                                 x2 + pr->x_offset, y2 + pr->y_offset,
-                                 x1 + pr->x_offset, y1 + pr->y_offset, w, h);
+                                 x2 + pr->x_offset + rt->stereo_off_x, y2 + pr->y_offset + rt->stereo_off_y,
+                                 x1 + pr->x_offset + rt->stereo_off_x, y1 + pr->y_offset + rt->stereo_off_y, w, h);
                g_object_unref(gc);
 
                rt_overlay_queue_all(rt, x2, y2, x1, y1);
@@ -1941,6 +1949,28 @@ static void renderer_overlay_draw(void *renderer, gint x, gint y, gint w, gint h
        rt_overlay_draw((RendererTiles *)renderer, x, y, w, h, NULL);
 }
 
+static void renderer_update_sizes(void *renderer)
+{
+       RendererTiles *rt = (RendererTiles *)renderer;
+
+       rt_overlay_update_sizes(rt);
+
+       rt->stereo_off_x = 0;
+       rt->stereo_off_x = 0;
+       
+       if (rt->stereo_mode & PR_STEREO_RIGHT) 
+               {
+               if (rt->stereo_mode & PR_STEREO_HORIZ) 
+                       {
+                       rt->stereo_off_x = rt->pr->viewport_width;
+                       }
+               else if (rt->stereo_mode & PR_STEREO_VERT) 
+                       {
+                       rt->stereo_off_y = rt->pr->viewport_height;
+                       }
+               }
+}
+
 static void renderer_free(void *renderer)
 {
        RendererTiles *rt = (RendererTiles *)renderer;
@@ -1955,7 +1985,7 @@ static void renderer_free(void *renderer)
         g_free(rt);
 }
 
-RendererFuncs *renderer_tiles_new(PixbufRenderer *pr)
+RendererFuncs *renderer_tiles_new(PixbufRenderer *pr, gint stereo_mode)
 {
        RendererTiles *rt = g_new0(RendererTiles, 1);
        
@@ -1968,12 +1998,12 @@ RendererFuncs *renderer_tiles_new(PixbufRenderer *pr)
        rt->f.invalidate_all = renderer_invalidate_all;
        rt->f.invalidate_region = renderer_invalidate_region;
        rt->f.scroll = rt_scroll;
+       rt->f.update_sizes = renderer_update_sizes;
 
 
        rt->f.overlay_add = renderer_tiles_overlay_add;
        rt->f.overlay_set = renderer_tiles_overlay_set;
        rt->f.overlay_get = renderer_tiles_overlay_get;
-       rt->f.overlay_update_sizes = rt_overlay_update_sizes;
        rt->f.overlay_draw = renderer_overlay_draw;
        
        rt->tile_width = PR_TILE_SIZE;
@@ -1985,6 +2015,10 @@ RendererFuncs *renderer_tiles_new(PixbufRenderer *pr)
        rt->tile_cache_max = PR_CACHE_SIZE_DEFAULT;
 
        rt->draw_idle_id = 0;
+       
+       rt->stereo_mode = stereo_mode;
+       rt->stereo_off_x = 0;
+       rt->stereo_off_y = 0;
 
        g_signal_connect(G_OBJECT(pr), "hierarchy-changed",
                         G_CALLBACK(rt_hierarchy_changed_cb), rt);
index 168023b..1bd4907 100644 (file)
@@ -19,7 +19,7 @@
 #include <pixbuf-renderer.h>
 
 
-RendererFuncs *renderer_tiles_new(PixbufRenderer *pr);
+RendererFuncs *renderer_tiles_new(PixbufRenderer *pr, gint stereo_flags);
 
 #endif
 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */